[SCM] Packaging for Google Go branch, weekly-upstream-sid, updated. upstream-weekly/2011.09.07-4-g842623c

Ondřej Surý ondrej at sury.org
Fri Mar 9 08:44:20 UTC 2012


The following commit has been merged in the weekly-upstream-sid branch:
commit 842623c5dd2819d980ca9c58048d6bc6ed82475f
Author: Ondřej Surý <ondrej at sury.org>
Date:   Tue Mar 6 16:21:44 2012 +0100

    Imported Upstream version 2012.03.04

diff --git a/AUTHORS b/AUTHORS
index 3bb8372..93386c6 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -75,6 +75,7 @@ Fazlul Shahriar <fshahriar at gmail.com>
 Firmansyah Adiputra <frm.adiputra at gmail.com>
 Florian Uekermann <florian at uekermann-online.de>
 Florian Weimer <fw at deneb.enyo.de>
+Francisco Souza <franciscossouza at gmail.com>
 Gary Burd <gary at beagledreams.com>
 Gideon Jan-Wessel Redelinghuys <gjredelinghuys at gmail.com>
 Giles Lean <giles.lean at pobox.com>
@@ -192,6 +193,7 @@ Volker Dobler <dr.volker.dobler at gmail.com>
 Wei Guangjing <vcc.163 at gmail.com>
 William Josephson <wjosephson at gmail.com>
 Yasuhiro Matsumoto <mattn.jp at gmail.com>
+Yissakhar Z. Beck <yissakhar.beck at gmail.com>
 Yongjian Xu <i3dmaster at gmail.com>
 Yoshiyuki Kanno <nekotaroh at gmail.com> <yoshiyuki.kanno at stoic.co.jp>
 Yuusei Kuwana <kuwana at kumama.org>
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index fe7e163..9e5accd 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -118,6 +118,7 @@ Fazlul Shahriar <fshahriar at gmail.com>
 Firmansyah Adiputra <frm.adiputra at gmail.com>
 Florian Uekermann <florian at uekermann-online.de> <f1 at uekermann-online.de>
 Florian Weimer <fw at deneb.enyo.de>
+Francisco Souza <franciscossouza at gmail.com>
 Fumitoshi Ukai <ukai at google.com>
 Gary Burd <gary at beagledreams.com> <gary.burd at gmail.com>
 Gideon Jan-Wessel Redelinghuys <gjredelinghuys at gmail.com>
@@ -278,6 +279,7 @@ Wei Guangjing <vcc.163 at gmail.com>
 William Chan <willchan at chromium.org>
 William Josephson <wjosephson at gmail.com>
 Yasuhiro Matsumoto <mattn.jp at gmail.com>
+Yissakhar Z. Beck <yissakhar.beck at gmail.com>
 Yongjian Xu <i3dmaster at gmail.com>
 Yoshiyuki Kanno <nekotaroh at gmail.com> <yoshiyuki.kanno at stoic.co.jp>
 Yuusei Kuwana <kuwana at kumama.org>
diff --git a/VERSION b/VERSION
index 3f8b016..4cf6a7a 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-weekly.2012-02-22 12235
+weekly.2012-03-04 12439
diff --git a/doc/Makefile b/doc/Makefile
index e834316..ff69bc7 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -6,9 +6,9 @@ HTML=\
 	articles/defer_panic_recover.html\
 	articles/error_handling.html\
 	articles/slices_usage_and_internals.html\
+	articles/laws_of_reflection.html\
 	effective_go.html\
 	go1.html\
-	go_tutorial.html\
 
 all: tmpltohtml $(HTML)
 
diff --git a/doc/articles/defer_panic_recover.html b/doc/articles/defer_panic_recover.html
index 18c0de2..be97045 100644
--- a/doc/articles/defer_panic_recover.html
+++ b/doc/articles/defer_panic_recover.html
@@ -42,7 +42,7 @@ contents of one file to the other:
 }</pre>
 
 <p>
-This works, but there is a bug. If the second call to os.Open fails, the
+This works, but there is a bug. If the call to os.Create fails, the
 function will return without closing the source file. This can be easily
 remedied by putting a call to src.Close() before the second return statement,
 but if the function were more complex the problem might not be so easily
@@ -236,7 +236,7 @@ panic PC=0x2a9cd8
 For a real-world example of <b>panic</b> and <b>recover</b>, see the
 <a href="/pkg/encoding/json/">json package</a> from the Go standard library.
 It decodes JSON-encoded data with a set of recursive functions.
-When malformed JSON is encountered, the parser calls panic is to unwind the
+When malformed JSON is encountered, the parser calls panic to unwind the
 stack to the top-level function call, which recovers from the panic and returns
 an appropriate error value (see the 'error' and 'unmarshal' functions in
 <a href="/src/pkg/encoding/json/decode.go">decode.go</a>).
diff --git a/doc/articles/defer_panic_recover.tmpl b/doc/articles/defer_panic_recover.tmpl
index 60c8eeb..5f48c6e 100644
--- a/doc/articles/defer_panic_recover.tmpl
+++ b/doc/articles/defer_panic_recover.tmpl
@@ -22,7 +22,7 @@ contents of one file to the other:
 {{code "progs/defer.go" `/func CopyFile/` `/STOP/`}}
 
 <p>
-This works, but there is a bug. If the second call to os.Open fails, the
+This works, but there is a bug. If the call to os.Create fails, the
 function will return without closing the source file. This can be easily
 remedied by putting a call to src.Close() before the second return statement,
 but if the function were more complex the problem might not be so easily
@@ -157,7 +157,7 @@ panic PC=0x2a9cd8
 For a real-world example of <b>panic</b> and <b>recover</b>, see the
 <a href="/pkg/encoding/json/">json package</a> from the Go standard library.
 It decodes JSON-encoded data with a set of recursive functions.
-When malformed JSON is encountered, the parser calls panic is to unwind the
+When malformed JSON is encountered, the parser calls panic to unwind the
 stack to the top-level function call, which recovers from the panic and returns
 an appropriate error value (see the 'error' and 'unmarshal' functions in
 <a href="/src/pkg/encoding/json/decode.go">decode.go</a>).
diff --git a/doc/articles/laws_of_reflection.html b/doc/articles/laws_of_reflection.html
new file mode 100644
index 0000000..4df70e0
--- /dev/null
+++ b/doc/articles/laws_of_reflection.html
@@ -0,0 +1,752 @@
+<!--{
+	"Title": "The Laws of Reflection"
+}-->
+<!--
+  DO NOT EDIT: created by
+    tmpltohtml articles/laws_of_reflection.tmpl
+-->
+
+
+<p>
+Reflection in computing is the
+ability of a program to examine its own structure, particularly
+through types; it's a form of metaprogramming. It's also a great
+source of confusion.
+</p>
+
+<p>
+In this article we attempt to clarify things by explaining how
+reflection works in Go. Each language's reflection model is
+different (and many languages don't support it at all), but
+this article is about Go, so for the rest of this article the word
+"reflection" should be taken to mean "reflection in Go".
+</p>
+
+<p><b>Types and interfaces</b></p>
+
+<p>
+Because reflection builds on the type system, let's start with a
+refresher about types in Go.
+</p>
+
+<p>
+Go is statically typed. Every variable has a static type, that is,
+exactly one type known and fixed at compile time: <code>int</code>,
+<code>float32</code>, <code>*MyType</code>, <code>[]byte</code>,
+and so on. If we declare
+</p>
+
+<pre><!--{{code "progs/interface.go" `/type MyInt/` `/STOP/`}}
+-->type MyInt int
+
+var i int
+var j MyInt</pre>
+
+<p>
+then <code>i</code> has type <code>int</code> and <code>j</code>
+has type <code>MyInt</code>. The variables <code>i</code> and
+<code>j</code> have distinct static types and, although they have
+the same underlying type, they cannot be assigned to one another
+without a conversion.
+</p>
+
+<p>
+One important category of type is interface types, which represent
+fixed sets of methods. An interface variable can store any concrete
+(non-interface) value as long as that value implements the
+interface's methods. A well-known pair of examples is
+<code>io.Reader</code> and <code>io.Writer</code>, the types
+<code>Reader</code> and <code>Writer</code> from the <a href=
+"http://golang.org/pkg/io/">io package</a>:
+</p>
+
+<pre><!--{{code "progs/interface.go" `/// Reader/` `/STOP/`}}
+-->// Reader is the interface that wraps the basic Read method.
+type Reader interface {
+    Read(p []byte) (n int, err error)
+}
+
+// Writer is the interface that wraps the basic Write method.
+type Writer interface {
+    Write(p []byte) (n int, err error)
+}</pre>
+
+<p>
+Any type that implements a <code>Read</code> (or
+<code>Write</code>) method with this signature is said to implement
+<code>io.Reader</code> (or <code>io.Writer</code>). For the
+purposes of this discussion, that means that a variable of type
+<code>io.Reader</code> can hold any value whose type has a
+<code>Read</code> method:
+</p>
+
+<pre><!--{{code "progs/interface.go" `/func readers/` `/STOP/`}}
+-->    var r io.Reader
+    r = os.Stdin
+    r = bufio.NewReader(r)
+    r = new(bytes.Buffer)
+    // and so on</pre>
+
+<p>
+It's important to be clear that whatever concrete value
+<code>r</code> may hold, <code>r</code>'s type is always
+<code>io.Reader</code>: Go is statically typed and the static type
+of <code>r</code> is <code>io.Reader</code>.</p>
+
+<p>
+An extremely important example of an interface type is the empty
+interface:
+</p>
+
+<pre>
+interface{}
+</pre>
+
+<p>
+It represents the empty set of methods and is satisfied by any
+value at all, since any value has zero or more methods.
+</p>
+
+<p>
+Some people say that Go's interfaces are dynamically typed, but
+that is misleading. They are statically typed: a variable of
+interface type always has the same static type, and even though at
+run time the value stored in the interface variable may change
+type, that value will always satisfy the interface.
+</p>
+
+<p>
+We need to be precise about all this because reflection and
+interfaces are closely related.
+</p>
+
+<p><b>The representation of an interface</b></p>
+
+<p>
+Russ Cox has written a <a href=
+"http://research.swtch.com/2009/12/go-data-structures-interfaces.html">
+detailed blog post</a> about the representation of interface values
+in Go. It's not necessary to repeat the full story here, but a
+simplified summary is in order.
+</p>
+
+<p>
+A variable of interface type stores a pair: the concrete value
+assigned to the variable, and that value's type descriptor.
+To be more precise, the value is the underlying concrete data item
+that implements the interface and the type describes the full type
+of that item. For instance, after
+</p>
+
+<pre><!--{{code "progs/interface.go" `/func typeAssertions/` `/STOP/`}}
+-->    var r io.Reader
+    tty, err := os.OpenFile("/dev/tty", os.O_RDWR, 0)
+    if err != nil {
+        return nil, err
+    }
+    r = tty</pre>
+
+<p>
+<code>r</code> contains, schematically, the (value, type) pair,
+(<code>tty</code>, <code>*os.File</code>). Notice that the type
+<code>*os.File</code> implements methods other than
+<code>Read</code>; even though the interface value provides access
+only to the <code>Read</code> method, the value inside carries all
+the type information about that value. That's why we can do things
+like this:
+</p>
+
+<pre><!--{{code "progs/interface.go" `/var w io.Writer/` `/STOP/`}}
+-->    var w io.Writer
+    w = r.(io.Writer)</pre>
+
+<p>
+The expression in this assignment is a type assertion; what it
+asserts is that the item inside <code>r</code> also implements
+<code>io.Writer</code>, and so we can assign it to <code>w</code>.
+After the assignment, <code>w</code> will contain the pair
+(<code>tty</code>, <code>*os.File</code>). That's the same pair as
+was held in <code>r</code>. The static type of the interface
+determines what methods may be invoked with an interface variable,
+even though the concrete value inside may have a larger set of
+methods.
+</p>
+
+<p>
+Continuing, we can do this:
+</p>
+
+<pre><!--{{code "progs/interface.go" `/var empty interface{}/` `/STOP/`}}
+-->    var empty interface{}
+    empty = w</pre>
+
+<p>
+and our empty interface value <code>e</code> will again contain
+that same pair, (<code>tty</code>, <code>*os.File</code>). That's
+handy: an empty interface can hold any value and contains all the
+information we could ever need about that value.
+</p>
+
+<p>
+(We don't need a type assertion here because it's known statically
+that <code>w</code> satisfies the empty interface. In the example
+where we moved a value from a <code>Reader</code> to a
+<code>Writer</code>, we needed to be explicit and use a type
+assertion because <code>Writer</code>'s methods are not a
+subset of <code>Reader</code>'s.)
+</p>
+
+<p>
+One important detail is that the pair inside an interface always
+has the form (value, concrete type) and cannot have the form
+(value, interface type). Interfaces do not hold interface
+values.
+</p>
+
+<p>
+Now we're ready to reflect.
+</p>
+
+<p><b>The first law of reflection</b></p>
+
+<p><b>1. Reflection goes from interface value to reflection object.</b></p>
+
+<p>
+At the basic level, reflection is just a mechanism to examine the
+type and value pair stored inside an interface variable. To get
+started, there are two types we need to know about in
+<a href="http://golang.org/pkg/reflect">package reflect</a>:
+<a href="http://golang.org/pkg/reflect/#Type">Type</a>and
+<a href="http://golang.org/pkg/reflect/#Value">Value</a>. Those two types
+give access to the contents of an interface variable, and two
+simple functions, called <code>reflect.TypeOf</code> and
+<code>reflect.ValueOf</code>, retrieve <code>reflect.Type</code>
+and <code>reflect.Value</code> pieces out of an interface value.
+(Also, from the <code>reflect.Value</code> it's easy to get
+to the <code>reflect.Type</code>, but let's keep the
+<code>Value</code> and <code>Type</code> concepts separate for
+now.)
+</p>
+
+<p>
+Let's start with <code>TypeOf</code>:
+</p>
+
+<pre><!--{{code "progs/interface2.go" `/package main/` `/STOP main/`}}
+-->package main
+
+import (
+    "fmt"
+    "reflect"
+)
+
+func main() {
+    var x float64 = 3.4
+    fmt.Println("type:", reflect.TypeOf(x))
+}</pre>
+
+<p>
+This program prints
+</p>
+
+<pre>
+type: float64
+</pre>
+
+<p>
+You might be wondering where the interface is here, since the
+program looks like it's passing the <code>float64</code>
+variable <code>x</code>, not an interface value, to
+<code>reflect.TypeOf</code>. But it's there; as <a href=
+"http://golang.org/pkg/reflect/#Type.TypeOf">godoc reports</a>, the
+signature of <code>reflect.TypeOf</code> includes an empty
+interface:
+</p>
+
+<pre>
+// TypeOf returns the reflection Type of the value in the interface{}.
+func TypeOf(i interface{}) Type
+</pre>
+
+<p>
+When we call <code>reflect.TypeOf(x)</code>, <code>x</code> is
+first stored in an empty interface, which is then passed as the
+argument; <code>reflect.TypeOf</code> unpacks that empty interface
+to recover the type information.
+</p>
+
+<p>
+The <code>reflect.ValueOf</code> function, of course, recovers the
+value (from here on we'll elide the boilerplate and focus just on
+the executable code):
+</p>
+
+<pre><!--{{code "progs/interface2.go" `/var x/` `/STOP/`}}
+-->    var x float64 = 3.4
+    fmt.Println("type:", reflect.TypeOf(x))</pre>
+
+<p>
+prints
+</p>
+
+<pre>
+value: <float64 Value>
+</pre>
+
+<p>
+Both <code>reflect.Type</code> and <code>reflect.Value</code> have
+lots of methods to let us examine and manipulate them. One
+important example is that <code>Value</code> has a
+<code>Type</code> method that returns the <code>Type</code> of a
+<code>reflect.Value</code>. Another is that both <code>Type</code>
+and <code>Value</code> have a <code>Kind</code> method that returns
+a constant indicating what sort of item is stored:
+<code>Uint</code>, <code>Float64</code>, <code>Slice</code>, and so
+on. Also methods on <code>Value</code> with names like
+<code>Int</code> and <code>Float</code> let us grab values (as
+<code>int64</code> and <code>float64</code>) stored inside:
+</p>
+
+<pre><!--{{code "progs/interface2.go" `/START f1/` `/STOP/`}}
+-->    var x float64 = 3.4
+    v := reflect.ValueOf(x)
+    fmt.Println("type:", v.Type())
+    fmt.Println("kind is float64:", v.Kind() == reflect.Float64)
+    fmt.Println("value:", v.Float())</pre>
+
+<p>
+prints
+</p>
+
+<pre>
+type: float64
+kind is float64: true
+value: 3.4
+</pre>
+
+<p>
+There are also methods like <code>SetInt</code> and
+<code>SetFloat</code> but to use them we need to understand
+settability, the subject of the third law of reflection, discussed
+below.
+</p>
+
+<p>
+The reflection library has a couple of properties worth singling
+out. First, to keep the API simple, the "getter" and "setter"
+methods of <code>Value</code> operate on the largest type that can
+hold the value: <code>int64</code> for all the signed integers, for
+instance. That is, the <code>Int</code> method of
+<code>Value</code> returns an <code>int64</code> and the
+<code>SetInt</code> value takes an <code>int64</code>; it may be
+necessary to convert to the actual type involved:
+</p>
+
+<pre><!--{{code "progs/interface2.go" `/START f2/` `/STOP/`}}
+-->    var x uint8 = 'x'
+    v := reflect.ValueOf(x)
+    fmt.Println("type:", v.Type())                            // uint8.
+    fmt.Println("kind is uint8: ", v.Kind() == reflect.Uint8) // true.
+    x = uint8(v.Uint())                                       // v.Uint returns a uint64.</pre>
+
+<p>
+The second property is that the <code>Kind</code> of a reflection
+object describes the underlying type, not the static type. If a
+reflection object contains a value of a user-defined integer type,
+as in
+</p>
+
+<pre><!--{{code "progs/interface2.go" `/START f3/` `/START/`}}
+-->    type MyInt int
+    var x MyInt = 7
+    v := reflect.ValueOf(x)</pre>
+
+<p>
+the <code>Kind</code> of <code>v</code> is still
+<code>reflect.Int</code>, even though the static type of
+<code>x</code> is <code>MyInt</code>, not <code>int</code>. In
+other words, the <code>Kind</code> cannot discriminate an int from
+a <code>MyInt</code> even though the <code>Type</code> can.
+</p>
+
+<p><b>The second law of reflection</b></p>
+
+<p><b>2. Reflection goes from reflection object to interface
+value.</b></p>
+
+<p>
+Like physical reflection, reflection in Go generates its own
+inverse.
+</p>
+
+<p>
+Given a <code>reflect.Value</code> we can recover an interface
+value using the <code>Interface</code> method; in effect the method
+packs the type and value information back into an interface
+representation and returns the result:
+</p>
+
+<pre>
+// Interface returns v's value as an interface{}.
+func (v Value) Interface() interface{}
+</pre>
+
+<p>
+As a consequence we can say
+</p>
+
+<pre><!--{{code "progs/interface2.go" `/START f3b/` `/START/`}}
+-->    y := v.Interface().(float64) // y will have type float64.
+    fmt.Println(y)</pre>
+
+<p>
+to print the <code>float64</code> value represented by the
+reflection object <code>v</code>.
+</p>
+
+<p>
+We can do even better, though. The arguments to
+<code>fmt.Println</code>, <code>fmt.Printf</code> and so on are all
+passed as empty interface values, which are then unpacked by the
+<code>fmt</code> package internally just as we have been doing in
+the previous examples. Therefore all it takes to print the contents
+of a <code>reflect.Value</code> correctly is to pass the result of
+the <code>Interface</code> method to the formatted print
+routine:
+</p>
+
+<pre><!--{{code "progs/interface2.go" `/START f3c/` `/START/`}}
+-->    fmt.Println(v.Interface())</pre>
+
+<p>
+(Why not <code>fmt.Println(v)</code>? Because <code>v</code> is a
+<code>reflect.Value</code>; we want the concrete value it holds.)
+Since our value is a <code>float64</code>, we can even use a
+floating-point format if we want:
+</p>
+
+<pre><!--{{code "progs/interface2.go" `/START f3d/` `/STOP/`}}
+-->    fmt.Printf("value is %7.1e\n", v.Interface())</pre>
+
+<p>
+and get in this case
+</p>
+
+<pre>
+3.4e+00
+</pre>
+
+<p>
+Again, there's no need to type-assert the result of
+<code>v.Interface()</code> to <code>float64</code>; the empty
+interface value has the concrete value's type information inside
+and <code>Printf</code> will recover it.
+</p>
+
+<p>
+In short, the <code>Interface</code> method is the inverse of the
+<code>ValueOf</code> function, except that its result is always of
+static type <code>interface{}</code>.
+</p>
+
+<p>
+Reiterating: Reflection goes from interface values to reflection
+objects and back again.
+</p>
+
+<p><b>The third law of reflection</b></p>
+
+<p><b>3. To modify a reflection object, the value must be settable.</b></p>
+
+<p>
+The third law is the most subtle and confusing, but it's easy
+enough to understand if we start from first principles.
+</p>
+
+<p>
+Here is some code that does not work, but is worth studying.
+</p>
+
+<pre><!--{{code "progs/interface2.go" `/START f4/` `/STOP/`}}
+-->    var x float64 = 3.4
+    v := reflect.ValueOf(x)
+    v.SetFloat(7.1) // Error: will panic.</pre>
+
+<p>
+If you run this code, it will panic with the cryptic message
+</p>
+
+<pre>
+panic: reflect.Value.SetFloat using unaddressable value
+</pre>
+
+<p>
+The problem is not that the value <code>7.1</code> is not
+addressable; it's that <code>v</code> is not settable. Settability
+is a property of a reflection <code>Value</code>, and not all
+reflection <code>Values</code> have it.
+</p>
+
+<p>
+The <code>CanSet</code> method of <code>Value</code> reports the
+settability of a <code>Value</code>; in our case,
+</p>
+
+<pre><!--{{code "progs/interface2.go" `/START f5/` `/STOP/`}}
+-->    var x float64 = 3.4
+    v := reflect.ValueOf(x)
+    fmt.Println("settability of v:", v.CanSet())</pre>
+
+<p>
+prints
+</p>
+
+<pre>
+settability of v: false
+</pre>
+
+<p>
+It is an error to call a <code>Set</code> method on an non-settable
+<code>Value</code>. But what is settability?
+</p>
+
+<p>
+Settability is a bit like addressability, but stricter. It's the
+property that a reflection object can modify the actual storage
+that was used to create the reflection object. Settability is
+determined by whether the reflection object holds the original
+item. When we say
+</p>
+
+<pre><!--{{code "progs/interface2.go" `/START f6/` `/START/`}}
+-->    var x float64 = 3.4
+    v := reflect.ValueOf(x)</pre>
+
+<p>
+we pass a <em>copy</em> of <code>x</code> to
+<code>reflect.ValueOf</code>, so the interface value created as the
+argument to <code>reflect.ValueOf</code> is a <em>copy</em> of
+<code>x</code>, not <code>x</code> itself. Thus, if the
+statement
+</p>
+
+<pre><!--{{code "progs/interface2.go" `/START f6b/` `/STOP/`}}
+-->    v.SetFloat(7.1)</pre>
+
+<p>
+were allowed to succeed, it would not update <code>x</code>, even
+though <code>v</code> looks like it was created from
+<code>x</code>. Instead, it would update the copy of <code>x</code>
+stored inside the reflection value and <code>x</code> itself would
+be unaffected. That would be confusing and useless, so it is
+illegal, and settability is the property used to avoid this
+issue.
+</p>
+
+<p>
+If this seems bizarre, it's not. It's actually a familiar situation
+in unusual garb. Think of passing <code>x</code> to a
+function:
+</p>
+
+<pre>
+f(x)
+</pre>
+
+<p>
+We would not expect <code>f</code> to be able to modify
+<code>x</code> because we passed a copy of <code>x</code>'s value,
+not <code>x</code> itself. If we want <code>f</code> to modify
+<code>x</code> directly we must pass our function the address of
+<code>x</code> (that is, a pointer to <code>x</code>):</p>
+
+<p>
+<code>f(&x)</code>
+</p>
+
+<p>
+This is straightforward and familiar, and reflection works the same
+way. If we want to modify <code>x</code> by reflection, we must
+give the reflection library a pointer to the value we want to
+modify.
+</p>
+
+<p>
+Let's do that. First we initialize <code>x</code> as usual
+and then create a reflection value that points to it, called
+<code>p</code>.
+</p>
+
+<pre><!--{{code "progs/interface2.go" `/START f7/` `/START/`}}
+-->    var x float64 = 3.4
+    p := reflect.ValueOf(&x) // Note: take the address of x.
+    fmt.Println("type of p:", p.Type())
+    fmt.Println("settability of p:", p.CanSet())</pre>
+
+<p>
+The output so far is
+</p>
+
+<pre>
+type of p: *float64
+settability of p: false
+</pre>
+
+<p>
+The reflection object <code>p</code> isn't settable, but it's not
+<code>p</code> we want to set, it's (in effect) <code>*p</code>. To
+get to what <code>p</code> points to, we call the <code>Elem</code>
+method of <code>Value</code>, which indirects through the pointer,
+and save the result in a reflection <code>Value</code> called
+<code>v</code>:
+</p>
+
+<pre><!--{{code "progs/interface2.go" `/START f7b/` `/START/`}}
+-->    v := p.Elem()
+    fmt.Println("settability of v:", v.CanSet())</pre>
+
+<p>
+Now <code>v</code> is a settable reflection object, as the output
+demonstrates,
+</p>
+
+<pre>
+settability of v: true
+</pre>
+
+<p>
+and since it represents <code>x</code>, we are finally able to use
+<code>v.SetFloat</code> to modify the value of
+<code>x</code>:
+</p>
+
+<pre><!--{{code "progs/interface2.go" `/START f7c/` `/STOP/`}}
+-->    v.SetFloat(7.1)
+    fmt.Println(v.Interface())
+    fmt.Println(x)</pre>
+
+<p>
+The output, as expected, is
+</p>
+
+<pre>
+7.1
+7.1
+</pre>
+
+<p>
+Reflection can be hard to understand but it's doing exactly what
+the language does, albeit through reflection <code>Types</code> and
+<code>Values</code> that can disguise what's going on. Just keep in
+mind that reflection Values need the address of something in order
+to modify what they represent.
+</p>
+
+<p><b>Structs</b></p>
+
+<p>
+In our previous example <code>v</code> wasn't a pointer itself, it
+was just derived from one. A common way for this situation to arise
+is when using reflection to modify the fields of a structure. As
+long as we have the address of the structure, we can modify its
+fields.
+</p>
+
+<p>
+Here's a simple example that analyzes a struct value,
+<code>t</code>. We create the reflection object with the address of
+the struct because we'll want to modify it later. Then we set
+<code>typeOfT</code> to its type and iterate over the fields using
+straightforward method calls (see 
+<a href="http://golang.org/pkg/reflect/">package reflect</a> for details).
+Note that we extract the names of the fields from the struct type,
+but the fields themselves are regular <code>reflect.Value</code>
+objects.
+</p>
+
+<pre><!--{{code "progs/interface2.go" `/START f8/` `/STOP/`}}
+-->    type T struct {
+        A int
+        B string
+    }
+    t := T{23, "skidoo"}
+    s := reflect.ValueOf(&t).Elem()
+    typeOfT := s.Type()
+    for i := 0; i < s.NumField(); i++ {
+        f := s.Field(i)
+        fmt.Printf("%d: %s %s = %v\n", i,
+            typeOfT.Field(i).Name, f.Type(), f.Interface())
+    }
+    s.Field(0).SetInt(77)
+    s.Field(1).SetString("Sunset Strip")
+    fmt.Println("t is now", t)</pre>
+
+<p>
+The output of this program is
+</p>
+
+<pre>
+0: A int = 23
+1: B string = skidoo
+</pre>
+
+<p>
+There's one more point about settability introduced in
+passing here: the field names of <code>T</code> are upper case
+(exported) because only exported fields of a struct are
+settable.
+</p>
+
+<p>
+Because <code>s</code> contains a settable reflection object, we
+can modify the fields of the structure.
+</p>
+
+<pre><!--{{code "progs/interface2.go" `/START f8b/` `/STOP/`}}
+-->    s.Field(0).SetInt(77)
+    s.Field(1).SetString("Sunset Strip")
+    fmt.Println("t is now", t)</pre>
+
+<p>
+And here's the result:
+</p>
+
+<pre>
+t is now {77 Sunset Strip}
+</pre>
+
+<p>
+If we modified the program so that <code>s</code> was created from
+<code>t</code>, not <code>&t</code>, the calls to
+<code>SetInt</code> and <code>SetString</code> would fail as the
+fields of <code>t</code> would not be settable.
+</p>
+
+<p><b>Conclusion</b></p>
+
+<p>
+Here again are the laws of reflection:
+</p>
+
+<ol>
+<li>Reflection goes from interface value to reflection
+object.</li>
+<li>Reflection goes from reflection object to interface
+value.</li>
+<li>To modify a reflection object, the value must be settable.</li>
+</ol>
+
+<p>
+Once you understand these laws reflection in Go becomes much easier
+to use, although it remains subtle. It's a powerful tool that
+should be used with care and avoided unless strictly
+necessary.
+</p>
+
+<p>
+There's plenty more to reflection that we haven't covered —
+sending and receiving on channels, allocating memory, using slices
+and maps, calling methods and functions — but this post is
+long enough. We'll cover some of those topics in a later
+article.
+</p>
\ No newline at end of file
diff --git a/doc/articles/laws_of_reflection.tmpl b/doc/articles/laws_of_reflection.tmpl
new file mode 100644
index 0000000..7db5d6d
--- /dev/null
+++ b/doc/articles/laws_of_reflection.tmpl
@@ -0,0 +1,654 @@
+<!--{
+	"Title": "The Laws of Reflection"
+}-->
+{{donotedit}}
+
+<p>
+Reflection in computing is the
+ability of a program to examine its own structure, particularly
+through types; it's a form of metaprogramming. It's also a great
+source of confusion.
+</p>
+
+<p>
+In this article we attempt to clarify things by explaining how
+reflection works in Go. Each language's reflection model is
+different (and many languages don't support it at all), but
+this article is about Go, so for the rest of this article the word
+"reflection" should be taken to mean "reflection in Go".
+</p>
+
+<p><b>Types and interfaces</b></p>
+
+<p>
+Because reflection builds on the type system, let's start with a
+refresher about types in Go.
+</p>
+
+<p>
+Go is statically typed. Every variable has a static type, that is,
+exactly one type known and fixed at compile time: <code>int</code>,
+<code>float32</code>, <code>*MyType</code>, <code>[]byte</code>,
+and so on. If we declare
+</p>
+
+{{code "progs/interface.go" `/type MyInt/` `/STOP/`}}
+
+<p>
+then <code>i</code> has type <code>int</code> and <code>j</code>
+has type <code>MyInt</code>. The variables <code>i</code> and
+<code>j</code> have distinct static types and, although they have
+the same underlying type, they cannot be assigned to one another
+without a conversion.
+</p>
+
+<p>
+One important category of type is interface types, which represent
+fixed sets of methods. An interface variable can store any concrete
+(non-interface) value as long as that value implements the
+interface's methods. A well-known pair of examples is
+<code>io.Reader</code> and <code>io.Writer</code>, the types
+<code>Reader</code> and <code>Writer</code> from the <a href=
+"http://golang.org/pkg/io/">io package</a>:
+</p>
+
+{{code "progs/interface.go" `/// Reader/` `/STOP/`}}
+
+<p>
+Any type that implements a <code>Read</code> (or
+<code>Write</code>) method with this signature is said to implement
+<code>io.Reader</code> (or <code>io.Writer</code>). For the
+purposes of this discussion, that means that a variable of type
+<code>io.Reader</code> can hold any value whose type has a
+<code>Read</code> method:
+</p>
+
+{{code "progs/interface.go" `/func readers/` `/STOP/`}}
+
+<p>
+It's important to be clear that whatever concrete value
+<code>r</code> may hold, <code>r</code>'s type is always
+<code>io.Reader</code>: Go is statically typed and the static type
+of <code>r</code> is <code>io.Reader</code>.</p>
+
+<p>
+An extremely important example of an interface type is the empty
+interface:
+</p>
+
+<pre>
+interface{}
+</pre>
+
+<p>
+It represents the empty set of methods and is satisfied by any
+value at all, since any value has zero or more methods.
+</p>
+
+<p>
+Some people say that Go's interfaces are dynamically typed, but
+that is misleading. They are statically typed: a variable of
+interface type always has the same static type, and even though at
+run time the value stored in the interface variable may change
+type, that value will always satisfy the interface.
+</p>
+
+<p>
+We need to be precise about all this because reflection and
+interfaces are closely related.
+</p>
+
+<p><b>The representation of an interface</b></p>
+
+<p>
+Russ Cox has written a <a href=
+"http://research.swtch.com/2009/12/go-data-structures-interfaces.html">
+detailed blog post</a> about the representation of interface values
+in Go. It's not necessary to repeat the full story here, but a
+simplified summary is in order.
+</p>
+
+<p>
+A variable of interface type stores a pair: the concrete value
+assigned to the variable, and that value's type descriptor.
+To be more precise, the value is the underlying concrete data item
+that implements the interface and the type describes the full type
+of that item. For instance, after
+</p>
+
+{{code "progs/interface.go" `/func typeAssertions/` `/STOP/`}}
+
+<p>
+<code>r</code> contains, schematically, the (value, type) pair,
+(<code>tty</code>, <code>*os.File</code>). Notice that the type
+<code>*os.File</code> implements methods other than
+<code>Read</code>; even though the interface value provides access
+only to the <code>Read</code> method, the value inside carries all
+the type information about that value. That's why we can do things
+like this:
+</p>
+
+{{code "progs/interface.go" `/var w io.Writer/` `/STOP/`}}
+
+<p>
+The expression in this assignment is a type assertion; what it
+asserts is that the item inside <code>r</code> also implements
+<code>io.Writer</code>, and so we can assign it to <code>w</code>.
+After the assignment, <code>w</code> will contain the pair
+(<code>tty</code>, <code>*os.File</code>). That's the same pair as
+was held in <code>r</code>. The static type of the interface
+determines what methods may be invoked with an interface variable,
+even though the concrete value inside may have a larger set of
+methods.
+</p>
+
+<p>
+Continuing, we can do this:
+</p>
+
+{{code "progs/interface.go" `/var empty interface{}/` `/STOP/`}}
+
+<p>
+and our empty interface value <code>e</code> will again contain
+that same pair, (<code>tty</code>, <code>*os.File</code>). That's
+handy: an empty interface can hold any value and contains all the
+information we could ever need about that value.
+</p>
+
+<p>
+(We don't need a type assertion here because it's known statically
+that <code>w</code> satisfies the empty interface. In the example
+where we moved a value from a <code>Reader</code> to a
+<code>Writer</code>, we needed to be explicit and use a type
+assertion because <code>Writer</code>'s methods are not a
+subset of <code>Reader</code>'s.)
+</p>
+
+<p>
+One important detail is that the pair inside an interface always
+has the form (value, concrete type) and cannot have the form
+(value, interface type). Interfaces do not hold interface
+values.
+</p>
+
+<p>
+Now we're ready to reflect.
+</p>
+
+<p><b>The first law of reflection</b></p>
+
+<p><b>1. Reflection goes from interface value to reflection object.</b></p>
+
+<p>
+At the basic level, reflection is just a mechanism to examine the
+type and value pair stored inside an interface variable. To get
+started, there are two types we need to know about in
+<a href="http://golang.org/pkg/reflect">package reflect</a>:
+<a href="http://golang.org/pkg/reflect/#Type">Type</a>and
+<a href="http://golang.org/pkg/reflect/#Value">Value</a>. Those two types
+give access to the contents of an interface variable, and two
+simple functions, called <code>reflect.TypeOf</code> and
+<code>reflect.ValueOf</code>, retrieve <code>reflect.Type</code>
+and <code>reflect.Value</code> pieces out of an interface value.
+(Also, from the <code>reflect.Value</code> it's easy to get
+to the <code>reflect.Type</code>, but let's keep the
+<code>Value</code> and <code>Type</code> concepts separate for
+now.)
+</p>
+
+<p>
+Let's start with <code>TypeOf</code>:
+</p>
+
+{{code "progs/interface2.go" `/package main/` `/STOP main/`}}
+
+<p>
+This program prints
+</p>
+
+<pre>
+type: float64
+</pre>
+
+<p>
+You might be wondering where the interface is here, since the
+program looks like it's passing the <code>float64</code>
+variable <code>x</code>, not an interface value, to
+<code>reflect.TypeOf</code>. But it's there; as <a href=
+"http://golang.org/pkg/reflect/#Type.TypeOf">godoc reports</a>, the
+signature of <code>reflect.TypeOf</code> includes an empty
+interface:
+</p>
+
+<pre>
+// TypeOf returns the reflection Type of the value in the interface{}.
+func TypeOf(i interface{}) Type
+</pre>
+
+<p>
+When we call <code>reflect.TypeOf(x)</code>, <code>x</code> is
+first stored in an empty interface, which is then passed as the
+argument; <code>reflect.TypeOf</code> unpacks that empty interface
+to recover the type information.
+</p>
+
+<p>
+The <code>reflect.ValueOf</code> function, of course, recovers the
+value (from here on we'll elide the boilerplate and focus just on
+the executable code):
+</p>
+
+{{code "progs/interface2.go" `/var x/` `/STOP/`}}
+
+<p>
+prints
+</p>
+
+<pre>
+value: <float64 Value>
+</pre>
+
+<p>
+Both <code>reflect.Type</code> and <code>reflect.Value</code> have
+lots of methods to let us examine and manipulate them. One
+important example is that <code>Value</code> has a
+<code>Type</code> method that returns the <code>Type</code> of a
+<code>reflect.Value</code>. Another is that both <code>Type</code>
+and <code>Value</code> have a <code>Kind</code> method that returns
+a constant indicating what sort of item is stored:
+<code>Uint</code>, <code>Float64</code>, <code>Slice</code>, and so
+on. Also methods on <code>Value</code> with names like
+<code>Int</code> and <code>Float</code> let us grab values (as
+<code>int64</code> and <code>float64</code>) stored inside:
+</p>
+
+{{code "progs/interface2.go" `/START f1/` `/STOP/`}}
+
+<p>
+prints
+</p>
+
+<pre>
+type: float64
+kind is float64: true
+value: 3.4
+</pre>
+
+<p>
+There are also methods like <code>SetInt</code> and
+<code>SetFloat</code> but to use them we need to understand
+settability, the subject of the third law of reflection, discussed
+below.
+</p>
+
+<p>
+The reflection library has a couple of properties worth singling
+out. First, to keep the API simple, the "getter" and "setter"
+methods of <code>Value</code> operate on the largest type that can
+hold the value: <code>int64</code> for all the signed integers, for
+instance. That is, the <code>Int</code> method of
+<code>Value</code> returns an <code>int64</code> and the
+<code>SetInt</code> value takes an <code>int64</code>; it may be
+necessary to convert to the actual type involved:
+</p>
+
+{{code "progs/interface2.go" `/START f2/` `/STOP/`}}
+
+<p>
+The second property is that the <code>Kind</code> of a reflection
+object describes the underlying type, not the static type. If a
+reflection object contains a value of a user-defined integer type,
+as in
+</p>
+
+{{code "progs/interface2.go" `/START f3/` `/START/`}}
+
+<p>
+the <code>Kind</code> of <code>v</code> is still
+<code>reflect.Int</code>, even though the static type of
+<code>x</code> is <code>MyInt</code>, not <code>int</code>. In
+other words, the <code>Kind</code> cannot discriminate an int from
+a <code>MyInt</code> even though the <code>Type</code> can.
+</p>
+
+<p><b>The second law of reflection</b></p>
+
+<p><b>2. Reflection goes from reflection object to interface
+value.</b></p>
+
+<p>
+Like physical reflection, reflection in Go generates its own
+inverse.
+</p>
+
+<p>
+Given a <code>reflect.Value</code> we can recover an interface
+value using the <code>Interface</code> method; in effect the method
+packs the type and value information back into an interface
+representation and returns the result:
+</p>
+
+<pre>
+// Interface returns v's value as an interface{}.
+func (v Value) Interface() interface{}
+</pre>
+
+<p>
+As a consequence we can say
+</p>
+
+{{code "progs/interface2.go" `/START f3b/` `/START/`}}
+
+<p>
+to print the <code>float64</code> value represented by the
+reflection object <code>v</code>.
+</p>
+
+<p>
+We can do even better, though. The arguments to
+<code>fmt.Println</code>, <code>fmt.Printf</code> and so on are all
+passed as empty interface values, which are then unpacked by the
+<code>fmt</code> package internally just as we have been doing in
+the previous examples. Therefore all it takes to print the contents
+of a <code>reflect.Value</code> correctly is to pass the result of
+the <code>Interface</code> method to the formatted print
+routine:
+</p>
+
+{{code "progs/interface2.go" `/START f3c/` `/START/`}}
+
+<p>
+(Why not <code>fmt.Println(v)</code>? Because <code>v</code> is a
+<code>reflect.Value</code>; we want the concrete value it holds.)
+Since our value is a <code>float64</code>, we can even use a
+floating-point format if we want:
+</p>
+
+{{code "progs/interface2.go" `/START f3d/` `/STOP/`}}
+
+<p>
+and get in this case
+</p>
+
+<pre>
+3.4e+00
+</pre>
+
+<p>
+Again, there's no need to type-assert the result of
+<code>v.Interface()</code> to <code>float64</code>; the empty
+interface value has the concrete value's type information inside
+and <code>Printf</code> will recover it.
+</p>
+
+<p>
+In short, the <code>Interface</code> method is the inverse of the
+<code>ValueOf</code> function, except that its result is always of
+static type <code>interface{}</code>.
+</p>
+
+<p>
+Reiterating: Reflection goes from interface values to reflection
+objects and back again.
+</p>
+
+<p><b>The third law of reflection</b></p>
+
+<p><b>3. To modify a reflection object, the value must be settable.</b></p>
+
+<p>
+The third law is the most subtle and confusing, but it's easy
+enough to understand if we start from first principles.
+</p>
+
+<p>
+Here is some code that does not work, but is worth studying.
+</p>
+
+{{code "progs/interface2.go" `/START f4/` `/STOP/`}}
+
+<p>
+If you run this code, it will panic with the cryptic message
+</p>
+
+<pre>
+panic: reflect.Value.SetFloat using unaddressable value
+</pre>
+
+<p>
+The problem is not that the value <code>7.1</code> is not
+addressable; it's that <code>v</code> is not settable. Settability
+is a property of a reflection <code>Value</code>, and not all
+reflection <code>Values</code> have it.
+</p>
+
+<p>
+The <code>CanSet</code> method of <code>Value</code> reports the
+settability of a <code>Value</code>; in our case,
+</p>
+
+{{code "progs/interface2.go" `/START f5/` `/STOP/`}}
+
+<p>
+prints
+</p>
+
+<pre>
+settability of v: false
+</pre>
+
+<p>
+It is an error to call a <code>Set</code> method on an non-settable
+<code>Value</code>. But what is settability?
+</p>
+
+<p>
+Settability is a bit like addressability, but stricter. It's the
+property that a reflection object can modify the actual storage
+that was used to create the reflection object. Settability is
+determined by whether the reflection object holds the original
+item. When we say
+</p>
+
+{{code "progs/interface2.go" `/START f6/` `/START/`}}
+
+<p>
+we pass a <em>copy</em> of <code>x</code> to
+<code>reflect.ValueOf</code>, so the interface value created as the
+argument to <code>reflect.ValueOf</code> is a <em>copy</em> of
+<code>x</code>, not <code>x</code> itself. Thus, if the
+statement
+</p>
+
+{{code "progs/interface2.go" `/START f6b/` `/STOP/`}}
+
+<p>
+were allowed to succeed, it would not update <code>x</code>, even
+though <code>v</code> looks like it was created from
+<code>x</code>. Instead, it would update the copy of <code>x</code>
+stored inside the reflection value and <code>x</code> itself would
+be unaffected. That would be confusing and useless, so it is
+illegal, and settability is the property used to avoid this
+issue.
+</p>
+
+<p>
+If this seems bizarre, it's not. It's actually a familiar situation
+in unusual garb. Think of passing <code>x</code> to a
+function:
+</p>
+
+<pre>
+f(x)
+</pre>
+
+<p>
+We would not expect <code>f</code> to be able to modify
+<code>x</code> because we passed a copy of <code>x</code>'s value,
+not <code>x</code> itself. If we want <code>f</code> to modify
+<code>x</code> directly we must pass our function the address of
+<code>x</code> (that is, a pointer to <code>x</code>):</p>
+
+<p>
+<code>f(&x)</code>
+</p>
+
+<p>
+This is straightforward and familiar, and reflection works the same
+way. If we want to modify <code>x</code> by reflection, we must
+give the reflection library a pointer to the value we want to
+modify.
+</p>
+
+<p>
+Let's do that. First we initialize <code>x</code> as usual
+and then create a reflection value that points to it, called
+<code>p</code>.
+</p>
+
+{{code "progs/interface2.go" `/START f7/` `/START/`}}
+
+<p>
+The output so far is
+</p>
+
+<pre>
+type of p: *float64
+settability of p: false
+</pre>
+
+<p>
+The reflection object <code>p</code> isn't settable, but it's not
+<code>p</code> we want to set, it's (in effect) <code>*p</code>. To
+get to what <code>p</code> points to, we call the <code>Elem</code>
+method of <code>Value</code>, which indirects through the pointer,
+and save the result in a reflection <code>Value</code> called
+<code>v</code>:
+</p>
+
+{{code "progs/interface2.go" `/START f7b/` `/START/`}}
+
+<p>
+Now <code>v</code> is a settable reflection object, as the output
+demonstrates,
+</p>
+
+<pre>
+settability of v: true
+</pre>
+
+<p>
+and since it represents <code>x</code>, we are finally able to use
+<code>v.SetFloat</code> to modify the value of
+<code>x</code>:
+</p>
+
+{{code "progs/interface2.go" `/START f7c/` `/STOP/`}}
+
+<p>
+The output, as expected, is
+</p>
+
+<pre>
+7.1
+7.1
+</pre>
+
+<p>
+Reflection can be hard to understand but it's doing exactly what
+the language does, albeit through reflection <code>Types</code> and
+<code>Values</code> that can disguise what's going on. Just keep in
+mind that reflection Values need the address of something in order
+to modify what they represent.
+</p>
+
+<p><b>Structs</b></p>
+
+<p>
+In our previous example <code>v</code> wasn't a pointer itself, it
+was just derived from one. A common way for this situation to arise
+is when using reflection to modify the fields of a structure. As
+long as we have the address of the structure, we can modify its
+fields.
+</p>
+
+<p>
+Here's a simple example that analyzes a struct value,
+<code>t</code>. We create the reflection object with the address of
+the struct because we'll want to modify it later. Then we set
+<code>typeOfT</code> to its type and iterate over the fields using
+straightforward method calls (see 
+<a href="http://golang.org/pkg/reflect/">package reflect</a> for details).
+Note that we extract the names of the fields from the struct type,
+but the fields themselves are regular <code>reflect.Value</code>
+objects.
+</p>
+
+{{code "progs/interface2.go" `/START f8/` `/STOP/`}}
+
+<p>
+The output of this program is
+</p>
+
+<pre>
+0: A int = 23
+1: B string = skidoo
+</pre>
+
+<p>
+There's one more point about settability introduced in
+passing here: the field names of <code>T</code> are upper case
+(exported) because only exported fields of a struct are
+settable.
+</p>
+
+<p>
+Because <code>s</code> contains a settable reflection object, we
+can modify the fields of the structure.
+</p>
+
+{{code "progs/interface2.go" `/START f8b/` `/STOP/`}}
+
+<p>
+And here's the result:
+</p>
+
+<pre>
+t is now {77 Sunset Strip}
+</pre>
+
+<p>
+If we modified the program so that <code>s</code> was created from
+<code>t</code>, not <code>&t</code>, the calls to
+<code>SetInt</code> and <code>SetString</code> would fail as the
+fields of <code>t</code> would not be settable.
+</p>
+
+<p><b>Conclusion</b></p>
+
+<p>
+Here again are the laws of reflection:
+</p>
+
+<ol>
+<li>Reflection goes from interface value to reflection
+object.</li>
+<li>Reflection goes from reflection object to interface
+value.</li>
+<li>To modify a reflection object, the value must be settable.</li>
+</ol>
+
+<p>
+Once you understand these laws reflection in Go becomes much easier
+to use, although it remains subtle. It's a powerful tool that
+should be used with care and avoided unless strictly
+necessary.
+</p>
+
+<p>
+There's plenty more to reflection that we haven't covered —
+sending and receiving on channels, allocating memory, using slices
+and maps, calling methods and functions — but this post is
+long enough. We'll cover some of those topics in a later
+article.
+</p>
\ No newline at end of file
diff --git a/doc/articles/wiki/Makefile b/doc/articles/wiki/Makefile
new file mode 100644
index 0000000..0cb9071
--- /dev/null
+++ b/doc/articles/wiki/Makefile
@@ -0,0 +1,20 @@
+# 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.
+
+all: index.html
+
+CLEANFILES:=srcextract.bin htmlify.bin get.bin
+
+index.html: wiki.html srcextract.bin htmlify.bin
+	PATH=.:$$PATH awk '/^!/{system(substr($$0,2)); next} {print}' < wiki.html | tr -d '\r' > index.html
+
+test: get.bin
+	bash ./test.sh
+	rm -f get.6 get.bin
+
+%.bin: %.go
+	go build -o $@ $^
+
+clean:
+	rm -f $(CLEANFILES)
diff --git a/doc/codelab/wiki/edit.html b/doc/articles/wiki/edit.html
similarity index 100%
rename from doc/codelab/wiki/edit.html
rename to doc/articles/wiki/edit.html
diff --git a/doc/articles/wiki/final-noclosure.go b/doc/articles/wiki/final-noclosure.go
new file mode 100644
index 0000000..a23cf7a
--- /dev/null
+++ b/doc/articles/wiki/final-noclosure.go
@@ -0,0 +1,104 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"errors"
+	"html/template"
+	"io/ioutil"
+	"net/http"
+	"regexp"
+)
+
+type Page struct {
+	Title string
+	Body  []byte
+}
+
+func (p *Page) save() error {
+	filename := p.Title + ".txt"
+	return ioutil.WriteFile(filename, p.Body, 0600)
+}
+
+func loadPage(title string) (*Page, error) {
+	filename := title + ".txt"
+	body, err := ioutil.ReadFile(filename)
+	if err != nil {
+		return nil, err
+	}
+	return &Page{Title: title, Body: body}, nil
+}
+
+func viewHandler(w http.ResponseWriter, r *http.Request) {
+	title, err := getTitle(w, r)
+	if err != nil {
+		return
+	}
+	p, err := loadPage(title)
+	if err != nil {
+		http.Redirect(w, r, "/edit/"+title, http.StatusFound)
+		return
+	}
+	renderTemplate(w, "view", p)
+}
+
+func editHandler(w http.ResponseWriter, r *http.Request) {
+	title, err := getTitle(w, r)
+	if err != nil {
+		return
+	}
+	p, err := loadPage(title)
+	if err != nil {
+		p = &Page{Title: title}
+	}
+	renderTemplate(w, "edit", p)
+}
+
+func saveHandler(w http.ResponseWriter, r *http.Request) {
+	title, err := getTitle(w, r)
+	if err != nil {
+		return
+	}
+	body := r.FormValue("body")
+	p := &Page{Title: title, Body: []byte(body)}
+	err = p.save()
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+	http.Redirect(w, r, "/view/"+title, http.StatusFound)
+}
+
+func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
+	t, err := template.ParseFiles(tmpl + ".html")
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+	err = t.Execute(w, p)
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+	}
+}
+
+const lenPath = len("/view/")
+
+var titleValidator = regexp.MustCompile("^[a-zA-Z0-9]+$")
+
+func getTitle(w http.ResponseWriter, r *http.Request) (title string, err error) {
+	title = r.URL.Path[lenPath:]
+	if !titleValidator.MatchString(title) {
+		http.NotFound(w, r)
+		err = errors.New("Invalid Page Title")
+	}
+	return
+}
+
+func main() {
+	http.HandleFunc("/view/", viewHandler)
+	http.HandleFunc("/edit/", editHandler)
+	http.HandleFunc("/save/", saveHandler)
+	http.ListenAndServe(":8080", nil)
+}
diff --git a/doc/articles/wiki/final-noerror.go b/doc/articles/wiki/final-noerror.go
new file mode 100644
index 0000000..e11d268
--- /dev/null
+++ b/doc/articles/wiki/final-noerror.go
@@ -0,0 +1,55 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"html/template"
+	"io/ioutil"
+	"net/http"
+)
+
+type Page struct {
+	Title string
+	Body  []byte
+}
+
+func (p *Page) save() error {
+	filename := p.Title + ".txt"
+	return ioutil.WriteFile(filename, p.Body, 0600)
+}
+
+func loadPage(title string) (*Page, error) {
+	filename := title + ".txt"
+	body, err := ioutil.ReadFile(filename)
+	if err != nil {
+		return nil, err
+	}
+	return &Page{Title: title, Body: body}, nil
+}
+
+const lenPath = len("/view/")
+
+func editHandler(w http.ResponseWriter, r *http.Request) {
+	title := r.URL.Path[lenPath:]
+	p, err := loadPage(title)
+	if err != nil {
+		p = &Page{Title: title}
+	}
+	t, _ := template.ParseFiles("edit.html")
+	t.Execute(w, p)
+}
+
+func viewHandler(w http.ResponseWriter, r *http.Request) {
+	title := r.URL.Path[lenPath:]
+	p, _ := loadPage(title)
+	t, _ := template.ParseFiles("view.html")
+	t.Execute(w, p)
+}
+
+func main() {
+	http.HandleFunc("/view/", viewHandler)
+	http.HandleFunc("/edit/", editHandler)
+	http.ListenAndServe(":8080", nil)
+}
diff --git a/doc/articles/wiki/final-parsetemplate.go b/doc/articles/wiki/final-parsetemplate.go
new file mode 100644
index 0000000..6234c08
--- /dev/null
+++ b/doc/articles/wiki/final-parsetemplate.go
@@ -0,0 +1,93 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"html/template"
+	"io/ioutil"
+	"net/http"
+	"regexp"
+)
+
+type Page struct {
+	Title string
+	Body  []byte
+}
+
+func (p *Page) save() error {
+	filename := p.Title + ".txt"
+	return ioutil.WriteFile(filename, p.Body, 0600)
+}
+
+func loadPage(title string) (*Page, error) {
+	filename := title + ".txt"
+	body, err := ioutil.ReadFile(filename)
+	if err != nil {
+		return nil, err
+	}
+	return &Page{Title: title, Body: body}, nil
+}
+
+func viewHandler(w http.ResponseWriter, r *http.Request, title string) {
+	p, err := loadPage(title)
+	if err != nil {
+		http.Redirect(w, r, "/edit/"+title, http.StatusFound)
+		return
+	}
+	renderTemplate(w, "view", p)
+}
+
+func editHandler(w http.ResponseWriter, r *http.Request, title string) {
+	p, err := loadPage(title)
+	if err != nil {
+		p = &Page{Title: title}
+	}
+	renderTemplate(w, "edit", p)
+}
+
+func saveHandler(w http.ResponseWriter, r *http.Request, title string) {
+	body := r.FormValue("body")
+	p := &Page{Title: title, Body: []byte(body)}
+	err := p.save()
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+	http.Redirect(w, r, "/view/"+title, http.StatusFound)
+}
+
+func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
+	t, err := template.ParseFiles(tmpl + ".html")
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+	err = t.Execute(w, p)
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+	}
+}
+
+const lenPath = len("/view/")
+
+var titleValidator = regexp.MustCompile("^[a-zA-Z0-9]+$")
+
+func makeHandler(fn func(http.ResponseWriter, *http.Request, string)) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		title := r.URL.Path[lenPath:]
+		if !titleValidator.MatchString(title) {
+			http.NotFound(w, r)
+			return
+		}
+		fn(w, r, title)
+	}
+}
+
+func main() {
+	http.HandleFunc("/view/", makeHandler(viewHandler))
+	http.HandleFunc("/edit/", makeHandler(editHandler))
+	http.HandleFunc("/save/", makeHandler(saveHandler))
+	http.ListenAndServe(":8080", nil)
+}
diff --git a/doc/articles/wiki/final-template.go b/doc/articles/wiki/final-template.go
new file mode 100644
index 0000000..f295b9d
--- /dev/null
+++ b/doc/articles/wiki/final-template.go
@@ -0,0 +1,67 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"html/template"
+	"io/ioutil"
+	"net/http"
+)
+
+type Page struct {
+	Title string
+	Body  []byte
+}
+
+func (p *Page) save() error {
+	filename := p.Title + ".txt"
+	return ioutil.WriteFile(filename, p.Body, 0600)
+}
+
+func loadPage(title string) (*Page, error) {
+	filename := title + ".txt"
+	body, err := ioutil.ReadFile(filename)
+	if err != nil {
+		return nil, err
+	}
+	return &Page{Title: title, Body: body}, nil
+}
+
+const lenPath = len("/view/")
+
+func editHandler(w http.ResponseWriter, r *http.Request) {
+	title := r.URL.Path[lenPath:]
+	p, err := loadPage(title)
+	if err != nil {
+		p = &Page{Title: title}
+	}
+	renderTemplate(w, "edit", p)
+}
+
+func viewHandler(w http.ResponseWriter, r *http.Request) {
+	title := r.URL.Path[lenPath:]
+	p, _ := loadPage(title)
+	renderTemplate(w, "view", p)
+}
+
+func saveHandler(w http.ResponseWriter, r *http.Request) {
+	title := r.URL.Path[lenPath:]
+	body := r.FormValue("body")
+	p := &Page{Title: title, Body: []byte(body)}
+	p.save()
+	http.Redirect(w, r, "/view/"+title, http.StatusFound)
+}
+
+func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
+	t, _ := template.ParseFiles(tmpl + ".html")
+	t.Execute(w, p)
+}
+
+func main() {
+	http.HandleFunc("/view/", viewHandler)
+	http.HandleFunc("/edit/", editHandler)
+	http.HandleFunc("/save/", saveHandler)
+	http.ListenAndServe(":8080", nil)
+}
diff --git a/doc/articles/wiki/final.go b/doc/articles/wiki/final.go
new file mode 100644
index 0000000..134ad7e
--- /dev/null
+++ b/doc/articles/wiki/final.go
@@ -0,0 +1,97 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"html/template"
+	"io/ioutil"
+	"net/http"
+	"regexp"
+)
+
+type Page struct {
+	Title string
+	Body  []byte
+}
+
+func (p *Page) save() error {
+	filename := p.Title + ".txt"
+	return ioutil.WriteFile(filename, p.Body, 0600)
+}
+
+func loadPage(title string) (*Page, error) {
+	filename := title + ".txt"
+	body, err := ioutil.ReadFile(filename)
+	if err != nil {
+		return nil, err
+	}
+	return &Page{Title: title, Body: body}, nil
+}
+
+func viewHandler(w http.ResponseWriter, r *http.Request, title string) {
+	p, err := loadPage(title)
+	if err != nil {
+		http.Redirect(w, r, "/edit/"+title, http.StatusFound)
+		return
+	}
+	renderTemplate(w, "view", p)
+}
+
+func editHandler(w http.ResponseWriter, r *http.Request, title string) {
+	p, err := loadPage(title)
+	if err != nil {
+		p = &Page{Title: title}
+	}
+	renderTemplate(w, "edit", p)
+}
+
+func saveHandler(w http.ResponseWriter, r *http.Request, title string) {
+	body := r.FormValue("body")
+	p := &Page{Title: title, Body: []byte(body)}
+	err := p.save()
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+	http.Redirect(w, r, "/view/"+title, http.StatusFound)
+}
+
+var templates = make(map[string]*template.Template)
+
+func init() {
+	for _, tmpl := range []string{"edit", "view"} {
+		t := template.Must(template.ParseFiles(tmpl + ".html"))
+		templates[tmpl] = t
+	}
+}
+
+func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
+	err := templates[tmpl].Execute(w, p)
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+	}
+}
+
+const lenPath = len("/view/")
+
+var titleValidator = regexp.MustCompile("^[a-zA-Z0-9]+$")
+
+func makeHandler(fn func(http.ResponseWriter, *http.Request, string)) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		title := r.URL.Path[lenPath:]
+		if !titleValidator.MatchString(title) {
+			http.NotFound(w, r)
+			return
+		}
+		fn(w, r, title)
+	}
+}
+
+func main() {
+	http.HandleFunc("/view/", makeHandler(viewHandler))
+	http.HandleFunc("/edit/", makeHandler(editHandler))
+	http.HandleFunc("/save/", makeHandler(saveHandler))
+	http.ListenAndServe(":8080", nil)
+}
diff --git a/doc/codelab/wiki/get.go b/doc/articles/wiki/get.go
similarity index 100%
rename from doc/codelab/wiki/get.go
rename to doc/articles/wiki/get.go
diff --git a/doc/codelab/wiki/htmlify.go b/doc/articles/wiki/htmlify.go
similarity index 100%
rename from doc/codelab/wiki/htmlify.go
rename to doc/articles/wiki/htmlify.go
diff --git a/doc/codelab/wiki/http-sample.go b/doc/articles/wiki/http-sample.go
similarity index 100%
rename from doc/codelab/wiki/http-sample.go
rename to doc/articles/wiki/http-sample.go
diff --git a/doc/articles/wiki/index.html b/doc/articles/wiki/index.html
new file mode 100644
index 0000000..99ff3a7
--- /dev/null
+++ b/doc/articles/wiki/index.html
@@ -0,0 +1,1002 @@
+<!--{
+	"Title": "Writing Web Applications"
+}-->
+
+<h2>Introduction</h2>
+
+<p>
+Covered in this tutorial:
+</p>
+<ul>
+<li>Creating a data structure with load and save methods</li>
+<li>Using the <code>net/http</code> package to build web applications
+<li>Using the <code>html/template</code> package to process HTML templates</li>
+<li>Using the <code>regexp</code> package to validate user input</li>
+<li>Using closures</li>
+</ul>
+
+<p>
+Assumed knowledge:
+</p>
+<ul>
+<li>Programming experience</li>
+<li>Understanding of basic web technologies (HTTP, HTML)</li>
+<li>Some UNIX/DOS command-line knowledge</li>
+</ul>
+
+<h2>Getting Started</h2>
+
+<p>
+At present, you need to have a FreeBSD, Linux, OS X, or Windows machine to run Go.
+We will use <code>$</code> to represent the command prompt.
+</p>
+
+<p>
+Install Go (see the <a href="/doc/install">Installation Instructions</a>).
+</p>
+
+<p>
+Make a new directory for this tutorial and cd to it:
+</p>
+
+<pre>
+$ mkdir gowiki
+$ cd gowiki
+</pre>
+
+<p>
+Create a file named <code>wiki.go</code>, open it in your favorite editor, and 
+add the following lines:
+</p>
+
+<pre>
+package main
+
+import (
+	"fmt"
+	"io/ioutil"
+)
+</pre>
+
+<p>
+We import the <code>fmt</code> and <code>ioutil</code> packages from the Go 
+standard library. Later, as we implement additional functionality, we will 
+add more packages to this <code>import</code> declaration.
+</p>
+
+<h2>Data Structures</h2>
+
+<p>
+Let's start by defining the data structures. A wiki consists of a series of
+interconnected pages, each of which has a title and a body (the page content).
+Here, we define <code>Page</code> as a struct with two fields representing
+the title and body.
+</p>
+
+<pre>
+type Page struct {
+	Title	string
+	Body	[]byte
+}
+</pre>
+
+<p>
+The type <code>[]byte</code> means "a <code>byte</code> slice". 
+(See <a href="/doc/articles/slices_usage_and_internals.html">Slices: usage and
+internals</a> for more on slices.)
+The <code>Body</code> element is a <code>[]byte</code> rather than
+<code>string</code> because that is the type expected by the <code>io</code>
+libraries we will use, as you'll see below.
+</p>
+
+<p>
+The <code>Page</code> struct describes how page data will be stored in memory. 
+But what about persistent storage? We can address that by creating a 
+<code>save</code> method on <code>Page</code>:
+</p>
+
+<pre>
+func (p *Page) save() error {
+	filename := p.Title + ".txt"
+	return ioutil.WriteFile(filename, p.Body, 0600)
+}
+</pre>
+
+<p>
+This method's signature reads: "This is a method named <code>save</code> that
+takes as its receiver <code>p</code>, a pointer to <code>Page</code> . It takes
+no parameters, and returns a value of type <code>error</code>." 
+</p>
+
+<p>
+This method will save the <code>Page</code>'s <code>Body</code> to a text 
+file. For simplicity, we will use the <code>Title</code> as the file name.
+</p>
+
+<p>
+The <code>save</code> method returns an <code>error</code> value because
+that is the return type of <code>WriteFile</code> (a standard library function
+that writes a byte slice to a file).  The <code>save</code> method returns the
+error value, to let the application handle it should anything go wrong while
+writing the file.  If all goes well, <code>Page.save()</code> will return
+<code>nil</code> (the zero-value for pointers, interfaces, and some other 
+types).
+</p>
+
+<p>
+The octal integer constant <code>0600</code>, passed as the third parameter to
+<code>WriteFile</code>, indicates that the file should be created with
+read-write permissions for the current user only. (See the Unix man page
+<code>open(2)</code> for details.)
+</p>
+
+<p>
+We will want to load pages, too:
+</p>
+
+<pre>
+func loadPage(title string) *Page {
+	filename := title + ".txt"
+	body, _ := ioutil.ReadFile(filename)
+	return &Page{Title: title, Body: body}
+}
+</pre>
+
+<p>
+The function <code>loadPage</code> constructs the file name from
+<code>Title</code>, reads the file's contents into a new
+<code>Page</code>, and returns a pointer to that new <code>page</code>.
+</p>
+
+<p>
+Functions can return multiple values. The standard library function 
+<code>io.ReadFile</code> returns <code>[]byte</code> and <code>error</code>. 
+In <code>loadPage</code>, error isn't being handled yet; the "blank identifier"
+represented by the underscore (<code>_</code>) symbol is used to throw away the
+error return value (in essence, assigning the value to nothing). 
+</p>
+
+<p>
+But what happens if <code>ReadFile</code> encounters an error?  For example,
+the file might not exist. We should not ignore such errors.  Let's modify the
+function to return <code>*Page</code> and <code>error</code>.
+</p>
+
+<pre>
+func loadPage(title string) (*Page, error) {
+	filename := title + ".txt"
+	body, err := ioutil.ReadFile(filename)
+	if err != nil {
+		return nil, err
+	}
+	return &Page{Title: title, Body: body}, nil
+}
+</pre>
+
+<p>
+Callers of this function can now check the second parameter; if it is
+<code>nil</code> then it has successfully loaded a Page. If not, it will be an
+<code>error</code> that can be handled by the caller (see the 
+<a href="/ref/spec#Errors">language specification</a> for details).
+</p>
+
+<p>
+At this point we have a simple data structure and the ability to save to and
+load from a file. Let's write a <code>main</code> function to test what we've
+written:
+</p>
+
+<pre>
+func main() {
+	p1 := &Page{Title: "TestPage", Body: []byte("This is a sample Page.")}
+	p1.save()
+	p2, _ := loadPage("TestPage")
+	fmt.Println(string(p2.Body))
+}
+</pre>
+
+<p>
+After compiling and executing this code, a file named <code>TestPage.txt</code>
+would be created, containing the contents of <code>p1</code>. The file would
+then be read into the struct <code>p2</code>, and its <code>Body</code> element
+printed to the screen.
+</p>
+
+<p>
+You can compile and run the program like this: 
+</p>
+
+<pre>
+$ go build wiki.go
+$ ./wiki
+This is a sample page.
+</pre>
+
+<p>
+(If you're using Windows you must type "<code>wiki</code>" without the 
+"<code>./</code>" to run the program.)
+</p>
+
+<p>
+<a href="part1.go">Click here to view the code we've written so far.</a>
+</p>
+
+<h2>Introducing the <code>net/http</code> package (an interlude)</h2>
+
+<p>
+Here's a full working example of a simple web server:
+</p>
+
+<pre>
+package main
+
+import (
+	"fmt"
+	"net/http"
+)
+
+func handler(w http.ResponseWriter, r *http.Request) {
+	fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:])
+}
+
+func main() {
+	http.HandleFunc("/", handler)
+	http.ListenAndServe(":8080", nil)
+}
+</pre>
+
+<p>
+The <code>main</code> function begins with a call to 
+<code>http.HandleFunc</code>, which tells the <code>http</code> package to 
+handle all requests to the web root (<code>"/"</code>) with 
+<code>handler</code>. 
+</p>
+
+<p>
+It then calls <code>http.ListenAndServe</code>, specifying that it should
+listen on port 8080 on any interface (<code>":8080"</code>). (Don't
+worry about its second parameter, <code>nil</code>, for now.)
+This function will block until the program is terminated.
+</p>
+
+<p>
+The function <code>handler</code> is of the type <code>http.HandlerFunc</code>.
+It takes an <code>http.ResponseWriter</code> and an <code>http.Request</code> as
+its arguments.
+</p>
+
+<p>
+An <code>http.ResponseWriter</code> value assembles the HTTP server's response; by writing 
+to it, we send data to the HTTP client.
+</p>
+
+<p>
+An <code>http.Request</code> is a data structure that represents the client
+HTTP request.  The string <code>r.URL.Path</code> is the path component
+of the request URL.  The trailing <code>[1:]</code> means
+"create a sub-slice of <code>Path</code> from the 1st character to the end." 
+This drops the leading "/" from the path name.
+</p>
+
+<p>
+If you run this program and access the URL: 
+</p>
+<pre>http://localhost:8080/monkeys</pre>
+<p>
+the program would present a page containing:
+</p>
+<pre>Hi there, I love monkeys!</pre>
+
+<h2>Using <code>net/http</code> to serve wiki pages</h2>
+
+<p>
+To use the <code>net/http</code> package, it must be imported:
+</p>
+
+<pre>
+import (
+	"fmt"
+	<b>"net/http"</b>
+	"io/ioutil"
+)
+</pre>
+
+<p>
+Let's create a handler to view a wiki page: 
+</p>
+
+<pre>
+const lenPath = len("/view/")
+
+func viewHandler(w http.ResponseWriter, r *http.Request) {
+	title := r.URL.Path[lenPath:]
+	p, _ := loadPage(title)
+	fmt.Fprintf(w, "<h1>%s</h1><div>%s</div>", p.Title, p.Body)
+}
+</pre>
+
+<p>
+First, this function extracts the page title from <code>r.URL.Path</code>,
+the path component of the request URL. The global constant 
+<code>lenPath</code> is the length of the leading <code>"/view/"</code>
+component of the request path.
+The <code>Path</code> is re-sliced with <code>[lenPath:]</code> to drop the 
+first 6 characters of the string. This is because the path will invariably 
+begin with <code>"/view/"</code>, which is not part of the page title.
+</p>
+
+<p>
+The function then loads the page data, formats the page with a string of simple 
+HTML, and writes it to <code>w</code>, the <code>http.ResponseWriter</code>. 
+</p>
+
+<p>
+Again, note the use of <code>_</code> to ignore the <code>error</code> 
+return value from <code>loadPage</code>. This is done here for simplicity
+and generally considered bad practice. We will attend to this later.
+</p>
+
+<p>
+To use this handler, we create a <code>main</code> function that
+initializes <code>http</code> using the <code>viewHandler</code> to handle
+any requests under the path <code>/view/</code>.
+</p>
+
+<pre>
+func main() {
+	http.HandleFunc("/view/", viewHandler)
+	http.ListenAndServe(":8080", nil)
+}
+</pre>
+
+<p>
+<a href="part2.go">Click here to view the code we've written so far.</a>
+</p>
+
+<p>
+Let's create some page data (as <code>test.txt</code>), compile our code, and
+try serving a wiki page.
+</p>
+
+<p>
+Open <code>test.txt</code> file in your editor, and save the string "Hello world" (without quotes)
+in it.
+</p>
+
+<pre>
+$ go build wiki.go
+$ ./wiki
+</pre>
+
+<p>
+With this web server running, a visit to <code><a
+href="http://localhost:8080/view/test">http://localhost:8080/view/test</a></code>
+should show a page titled "test" containing the words "Hello world".
+</p>
+
+<h2>Editing Pages</h2>
+
+<p>
+A wiki is not a wiki without the ability to edit pages. Let's create two new
+handlers: one named <code>editHandler</code> to display an 'edit page' form,
+and the other named <code>saveHandler</code> to save the data entered via the
+form.
+</p>
+
+<p>
+First, we add them to <code>main()</code>: 
+</p>
+
+<pre>
+func main() {
+	http.HandleFunc("/view/", viewHandler)
+	http.HandleFunc("/edit/", editHandler)
+	http.HandleFunc("/save/", saveHandler)
+	http.ListenAndServe(":8080", nil)
+}
+</pre>
+
+<p>
+The function <code>editHandler</code> loads the page 
+(or, if it doesn't exist, create an empty <code>Page</code> struct), 
+and displays an HTML form.
+</p>
+
+<pre>
+func editHandler(w http.ResponseWriter, r *http.Request) {
+	title := r.URL.Path[lenPath:]
+	p, err := loadPage(title)
+	if err != nil {
+		p = &Page{Title: title}
+	}
+	fmt.Fprintf(w, "<h1>Editing %s</h1>"+
+		"<form action=\"/save/%s\" method=\"POST\">"+
+		"<textarea name=\"body\">%s</textarea><br>"+
+		"<input type=\"submit\" value=\"Save\">"+
+		"</form>",
+		p.Title, p.Title, p.Body)
+}
+</pre>
+
+<p>
+This function will work fine, but all that hard-coded HTML is ugly.
+Of course, there is a better way.
+</p>
+ 
+<h2>The <code>html/template</code> package</h2>
+
+<p>
+The <code>html/template</code> package is part of the Go standard library.
+We can use <code>html/template</code> to keep the HTML in a separate file,
+allowing us to change the layout of our edit page without modifying the
+underlying Go code.
+</p>
+
+<p>
+First, we must add <code>html/template</code> to the list of imports:
+</p>
+
+<pre>
+import (
+	"http"
+	"io/ioutil"
+	"os"
+	<b>"html/template"</b>
+)
+</pre>
+
+<p>
+Let's create a template file containing the HTML form. 
+Open a new file named <code>edit.html</code>, and add the following lines:
+</p>
+
+<pre>
+<h1>Editing {{.Title |html}}</h1>
+
+<form action="/save/{{.Title |html}}" method="POST">
+<div><textarea name="body" rows="20" cols="80">{{printf "%s" .Body |html}}</textarea></div>
+<div><input type="submit" value="Save"></div>
+</form>
+</pre>
+
+<p>
+Modify <code>editHandler</code> to use the template, instead of the hard-coded
+HTML:
+</p>
+
+<pre>
+func editHandler(w http.ResponseWriter, r *http.Request) {
+	title := r.URL.Path[lenPath:]
+	p, err := loadPage(title)
+	if err != nil {
+		p = &Page{Title: title}
+	}
+	t, _ := template.ParseFiles("edit.html")
+	t.Execute(w, p)
+}
+</pre>
+
+<p>
+The function <code>template.ParseFiles</code> will read the contents of 
+<code>edit.html</code> and return a <code>*template.Template</code>. 
+</p>
+
+<p>
+The method <code>t.Execute</code> executes the template, writing the
+generated HTML to the <code>http.ResponseWriter</code>.
+The <code>.Title</code> and <code>.Body</code> dotted identifiers refer to
+<code>p.Title</code> and <code>p.Body</code>.
+</p>
+
+<p>
+Template directives are enclosed in double curly braces.
+The <code>printf "%s" .Body</code> instruction is a function call
+that outputs <code>.Body</code> as a string instead of a stream of bytes,
+the same as a call to <code>fmt.Printf</code>.
+The <code>|html</code> part of each directive pipes the value through the
+<code>html</code> formatter before outputting it, which escapes HTML
+characters (such as replacing <code>></code> with <code>&gt;</code>),
+preventing user data from corrupting the form HTML. 
+</p>
+
+<p>
+Now that we've removed the <code>fmt.Fprintf</code> statement, we can remove
+<code>"fmt"</code> from the <code>import</code> list.
+</p>
+
+<p>
+While we're working with templates, let's create a template for our
+<code>viewHandler</code> called <code>view.html</code>:
+</p>
+
+<pre>
+<h1>{{.Title |html}}</h1>
+
+<p>[<a href="/edit/{{.Title |html}}">edit</a>]</p>
+
+<div>{{printf "%s" .Body |html}}</div>
+</pre>
+
+<p>
+Modify <code>viewHandler</code> accordingly:
+</p>
+
+<pre>
+func viewHandler(w http.ResponseWriter, r *http.Request) {
+	title := r.URL.Path[lenPath:]
+	p, _ := loadPage(title)
+	t, _ := template.ParseFiles("view.html")
+	t.Execute(w, p)
+}
+</pre>
+
+<p>
+Notice that we've used almost exactly the same templating code in both
+handlers. Let's remove this duplication by moving the templating code
+to its own function:
+</p>
+
+<pre>
+func viewHandler(w http.ResponseWriter, r *http.Request) {
+	title := r.URL.Path[lenPath:]
+	p, _ := loadPage(title)
+	renderTemplate(w, "view", p)
+}
+
+func editHandler(w http.ResponseWriter, r *http.Request) {
+	title := r.URL.Path[lenPath:]
+	p, err := loadPage(title)
+	if err != nil {
+		p = &Page{Title: title}
+	}
+	renderTemplate(w, "edit", p)
+}
+
+func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
+	t, _ := template.ParseFiles(tmpl + ".html")
+	t.Execute(w, p)
+}
+</pre>
+
+<p>
+The handlers are now shorter and simpler. 
+</p>
+
+<h2>Handling non-existent pages</h2>
+
+<p>
+What if you visit <a href="http://localhost:8080/view/APageThatDoesntExist">
+<code>/view/APageThatDoesntExist</code></a>? The program will crash. This is 
+because it ignores the error return value from <code>loadPage</code>. Instead,
+if the requested Page doesn't exist, it should redirect the client to the edit
+Page so the content may be created:
+</p>
+
+<pre>
+func viewHandler(w http.ResponseWriter, r *http.Request) {
+	title, err := getTitle(w, r)
+	if err != nil {
+		return
+	}
+	p, err := loadPage(title)
+	if err != nil {
+		http.Redirect(w, r, "/edit/"+title, http.StatusFound)
+		return
+	}
+	renderTemplate(w, "view", p)
+}
+</pre>
+
+<p>
+The <code>http.Redirect</code> function adds an HTTP status code of 
+<code>http.StatusFound</code> (302) and a <code>Location</code>
+header to the HTTP response.
+</p>
+
+<h2>Saving Pages</h2>
+
+<p>
+The function <code>saveHandler</code> will handle the form submission. 
+</p>
+
+<pre>
+func saveHandler(w http.ResponseWriter, r *http.Request) {
+	title := r.URL.Path[lenPath:]
+	body := r.FormValue("body")
+	p := &Page{Title: title, Body: []byte(body)}
+	p.save()
+	http.Redirect(w, r, "/view/"+title, http.StatusFound)
+}
+</pre>
+
+<p>
+The page title (provided in the URL) and the form's only field, 
+<code>Body</code>, are stored in a new <code>Page</code>. 
+The <code>save()</code> method is then called to write the data to a file,
+and the client is redirected to the <code>/view/</code> page.
+</p>
+
+<p>
+The value returned by <code>FormValue</code> is of type <code>string</code>.
+We must convert that value to <code>[]byte</code> before it will fit into 
+the <code>Page</code> struct.  We use <code>[]byte(body)</code> to perform
+the conversion.
+</p>
+
+<h2>Error handling</h2>
+
+<p>
+There are several places in our program where errors are being ignored.  This
+is bad practice, not least because when an error does occur the program will
+crash.  A better solution is to handle the errors and return an error message
+to the user. That way if something does go wrong, the server will continue to
+function and the user will be notified.
+</p>
+
+<p>
+First, let's handle the errors in <code>renderTemplate</code>:
+</p>
+
+<pre>
+func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
+	t, err := template.ParseFiles(tmpl + ".html")
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+	err = t.Execute(w, p)
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+	}
+}
+</pre>
+
+<p>
+The <code>http.Error</code> function sends a specified HTTP response code 
+(in this case "Internal Server Error") and error message.
+Already the decision to put this in a separate function is paying off.
+</p>
+
+<p>
+Now let's fix up <code>saveHandler</code>:
+</p>
+
+<pre>
+func saveHandler(w http.ResponseWriter, r *http.Request) {
+	title, err := getTitle(w, r)
+	if err != nil {
+		return
+	}
+	body := r.FormValue("body")
+	p := &Page{Title: title, Body: []byte(body)}
+	err = p.save()
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+	http.Redirect(w, r, "/view/"+title, http.StatusFound)
+}
+</pre>
+
+<p>
+Any errors that occur during <code>p.save()</code> will be reported 
+to the user.
+</p>
+
+<h2>Template caching</h2>
+
+<p>
+There is an inefficiency in this code: <code>renderTemplate</code> calls 
+<code>ParseFile</code> every time a page is rendered. 
+A better approach would be to call <code>ParseFile</code> once for each 
+template at program initialization, and store the resultant 
+<code>*Template</code> values in a data structure for later use.
+</p>
+
+<p>
+First we create a global map named <code>templates</code> in which to store 
+our <code>*Template</code> values, keyed by <code>string</code> 
+(the template name):
+</p>
+
+<pre>
+var templates = make(map[string]*template.Template)
+</pre>
+
+<p>
+Then we create an <code>init</code> function, which will be called before
+<code>main</code> at program initialization. The function
+<code>template.Must</code> is a convenience wrapper that panics when passed a
+non-nil <code>error</code> value, and otherwise returns the
+<code>*Template</code> unaltered. A panic is appropriate here; if the templates
+can't be loaded the only sensible thing to do is exit the program.
+</p>
+
+<pre>
+func init() {
+	for _, tmpl := range []string{"edit", "view"} {
+		t := template.Must(template.ParseFiles(tmpl + ".html"))
+		templates[tmpl] = t
+	}
+}
+</pre>
+
+<p>
+A <code>for</code> loop is used with a <code>range</code> statement to iterate 
+over an array constant containing the names of the templates we want parsed.
+If we were to add more templates to our program, we would add their names to 
+that array.
+</p>
+
+<p>
+We then modify our <code>renderTemplate</code> function to call 
+the <code>Execute</code> method on the appropriate <code>Template</code> from 
+<code>templates</code>:
+
+<pre>
+func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
+	err := templates[tmpl].Execute(w, p)
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+	}
+}
+</pre>
+
+<h2>Validation</h2>
+
+<p>
+As you may have observed, this program has a serious security flaw: a user
+can supply an arbitrary path to be read/written on the server. To mitigate
+this, we can write a function to validate the title with a regular expression.
+</p>
+
+<p>
+First, add <code>"regexp"</code> to the <code>import</code> list.
+Then we can create a global variable to store our validation regexp:
+</p>
+
+<pre>
+var titleValidator = regexp.MustCompile("^[a-zA-Z0-9]+$")
+</pre>
+
+<p>
+The function <code>regexp.MustCompile</code> will parse and compile the 
+regular expression, and return a <code>regexp.Regexp</code>. 
+<code>MustCompile</code> is distinct from <code>Compile</code> in that it will
+panic if the expression compilation fails, while <code>Compile</code> returns
+an <code>error</code> as a second parameter. 
+</p>
+
+<p>
+Now, let's write a function that extracts the title string from the request 
+URL, and tests it against our <code>TitleValidator</code> expression:
+</p>
+
+<pre>
+func getTitle(w http.ResponseWriter, r *http.Request) (title string, err error) {
+	title = r.URL.Path[lenPath:]
+	if !titleValidator.MatchString(title) {
+		http.NotFound(w, r)
+		err = errors.New("Invalid Page Title")
+	}
+	return
+}
+</pre>
+
+<p>
+If the title is valid, it will be returned along with a <code>nil</code>
+error value.  If the title is invalid, the function will write a 
+"404 Not Found" error to the HTTP connection, and return an error to the 
+handler. 
+</p>
+
+<p>
+Let's put a call to <code>getTitle</code> in each of the handlers:
+</p>
+
+<pre>
+func viewHandler(w http.ResponseWriter, r *http.Request) {
+	title, err := getTitle(w, r)
+	if err != nil {
+		return
+	}
+	p, err := loadPage(title)
+	if err != nil {
+		http.Redirect(w, r, "/edit/"+title, http.StatusFound)
+		return
+	}
+	renderTemplate(w, "view", p)
+}
+
+func editHandler(w http.ResponseWriter, r *http.Request) {
+	title, err := getTitle(w, r)
+	if err != nil {
+		return
+	}
+	p, err := loadPage(title)
+	if err != nil {
+		p = &Page{Title: title}
+	}
+	renderTemplate(w, "edit", p)
+}
+
+func saveHandler(w http.ResponseWriter, r *http.Request) {
+	title, err := getTitle(w, r)
+	if err != nil {
+		return
+	}
+	body := r.FormValue("body")
+	p := &Page{Title: title, Body: []byte(body)}
+	err = p.save()
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+	http.Redirect(w, r, "/view/"+title, http.StatusFound)
+}
+</pre>
+
+<h2>Introducing Function Literals and Closures</h2>
+
+<p>
+Catching the error condition in each handler introduces a lot of repeated code.
+What if we could wrap each of the handlers in a function that does this 
+validation and error checking? Go's 
+<a href="/ref/spec#Function_declarations">function 
+literals</a> provide a powerful means of abstracting functionality 
+that can help us here.
+</p>
+
+<p>
+First, we re-write the function definition of each of the handlers to accept
+a title string:
+</p>
+
+<pre>
+func viewHandler(w http.ResponseWriter, r *http.Request, title string)
+func editHandler(w http.ResponseWriter, r *http.Request, title string)
+func saveHandler(w http.ResponseWriter, r *http.Request, title string)
+</pre>
+
+<p>
+Now let's define a wrapper function that <i>takes a function of the above
+type</i>, and returns a function of type <code>http.HandlerFunc</code>
+(suitable to be passed to the function <code>http.HandleFunc</code>):
+</p>
+
+<pre>
+func makeHandler(fn func (http.ResponseWriter, *http.Request, string)) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		// Here we will extract the page title from the Request,
+		// and call the provided handler 'fn'
+	}
+}
+</pre>
+
+<p>
+The returned function is called a closure because it encloses values defined
+outside of it. In this case, the variable <code>fn</code> (the single argument
+to <code>makeHandler</code>) is enclosed by the closure. The variable
+<code>fn</code> will be one of our save, edit, or view handlers.
+</p>
+
+<p>
+Now we can take the code from <code>getTitle</code> and use it here
+(with some minor modifications):
+</p>
+
+<pre>
+func makeHandler(fn func(http.ResponseWriter, *http.Request, string)) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		title := r.URL.Path[lenPath:]
+		if !titleValidator.MatchString(title) {
+			http.NotFound(w, r)
+			return
+		}
+		fn(w, r, title)
+	}
+}
+</pre>
+
+<p>
+The closure returned by <code>makeHandler</code> is a function that takes
+an <code>http.ResponseWriter</code> and <code>http.Request</code> (in other
+words, an <code>http.HandlerFunc</code>). 
+The closure extracts the <code>title</code> from the request path, and
+validates it with the <code>TitleValidator</code> regexp. If the
+<code>title</code> is invalid, an error will be written to the
+<code>ResponseWriter</code> using the <code>http.NotFound</code> function. 
+If the <code>title</code> is valid, the enclosed handler function
+<code>fn</code> will be called with the <code>ResponseWriter</code>,
+<code>Request</code>, and <code>title</code> as arguments.
+</p>
+
+<p>
+Now we can wrap the handler functions with <code>makeHandler</code> in 
+<code>main</code>, before they are registered with the <code>http</code> 
+package:
+</p>
+
+<pre>
+func main() {
+	http.HandleFunc("/view/", makeHandler(viewHandler))
+	http.HandleFunc("/edit/", makeHandler(editHandler))
+	http.HandleFunc("/save/", makeHandler(saveHandler))
+	http.ListenAndServe(":8080", nil)
+}
+</pre>
+
+<p>
+Finally we remove the calls to <code>getTitle</code> from the handler functions,
+making them much simpler:
+</p>
+
+<pre>
+func viewHandler(w http.ResponseWriter, r *http.Request, title string) {
+	p, err := loadPage(title)
+	if err != nil {
+		http.Redirect(w, r, "/edit/"+title, http.StatusFound)
+		return
+	}
+	renderTemplate(w, "view", p)
+}
+
+func editHandler(w http.ResponseWriter, r *http.Request, title string) {
+	p, err := loadPage(title)
+	if err != nil {
+		p = &Page{Title: title}
+	}
+	renderTemplate(w, "edit", p)
+}
+
+func saveHandler(w http.ResponseWriter, r *http.Request, title string) {
+	body := r.FormValue("body")
+	p := &Page{Title: title, Body: []byte(body)}
+	err := p.save()
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+	http.Redirect(w, r, "/view/"+title, http.StatusFound)
+}
+</pre>
+
+<h2>Try it out!</h2>
+
+<p>
+<a href="final.go">Click here to view the final code listing.</a>
+</p>
+
+<p>
+Recompile the code, and run the app:
+</p>
+
+<pre>
+$ go build wiki.go
+$ ./wiki
+</pre>
+
+<p>
+Visiting <a href="http://localhost:8080/view/ANewPage">http://localhost:8080/view/ANewPage</a>
+should present you with the page edit form. You should then be able to 
+enter some text, click 'Save', and be redirected to the newly created page.
+</p>
+
+<h2>Other tasks</h2>
+
+<p>
+Here are some simple tasks you might want to tackle on your own:
+</p>
+
+<ul>
+<li>Store templates in <code>tmpl/</code> and page data in <code>data/</code>.
+<li>Add a handler to make the web root redirect to 
+	<code>/view/FrontPage</code>.</li>
+<li>Spruce up the page templates by making them valid HTML and adding some
+	CSS rules.</li>
+<li>Implement inter-page linking by converting instances of 
+	<code>[PageName]</code> to <br>
+	<code><a href="/view/PageName">PageName</a></code>.
+	(hint: you could use <code>regexp.ReplaceAllFunc</code> to do this)
+	</li>
+</ul>
diff --git a/doc/codelab/wiki/notemplate.go b/doc/articles/wiki/notemplate.go
similarity index 100%
rename from doc/codelab/wiki/notemplate.go
rename to doc/articles/wiki/notemplate.go
diff --git a/doc/codelab/wiki/part1-noerror.go b/doc/articles/wiki/part1-noerror.go
similarity index 100%
rename from doc/codelab/wiki/part1-noerror.go
rename to doc/articles/wiki/part1-noerror.go
diff --git a/doc/codelab/wiki/part1.go b/doc/articles/wiki/part1.go
similarity index 100%
rename from doc/codelab/wiki/part1.go
rename to doc/articles/wiki/part1.go
diff --git a/doc/codelab/wiki/part2.go b/doc/articles/wiki/part2.go
similarity index 100%
rename from doc/codelab/wiki/part2.go
rename to doc/articles/wiki/part2.go
diff --git a/doc/codelab/wiki/srcextract.go b/doc/articles/wiki/srcextract.go
similarity index 100%
rename from doc/codelab/wiki/srcextract.go
rename to doc/articles/wiki/srcextract.go
diff --git a/doc/articles/wiki/test.sh b/doc/articles/wiki/test.sh
new file mode 100755
index 0000000..58b218a
--- /dev/null
+++ b/doc/articles/wiki/test.sh
@@ -0,0 +1,27 @@
+#!/usr/bin/env bash
+
+set -e
+wiki_pid=
+cleanup() {
+	kill $wiki_pid
+	rm -f test_*.out Test.txt final-test.bin final-test.go
+}
+trap cleanup 0 INT
+
+make get.bin
+addr=$(./get.bin -addr)
+sed s/:8080/$addr/ < final.go > final-test.go
+make final-test.bin
+(./final-test.bin) &
+wiki_pid=$!
+
+sleep 1
+
+./get.bin http://$addr/edit/Test > test_edit.out
+diff -u test_edit.out test_edit.good
+./get.bin -post=body=some%20content http://$addr/save/Test
+diff -u Test.txt test_Test.txt.good
+./get.bin http://$addr/view/Test > test_view.out
+diff -u test_view.out test_view.good
+
+echo PASS
diff --git a/doc/codelab/wiki/test_Test.txt.good b/doc/articles/wiki/test_Test.txt.good
similarity index 100%
rename from doc/codelab/wiki/test_Test.txt.good
rename to doc/articles/wiki/test_Test.txt.good
diff --git a/doc/codelab/wiki/test_edit.good b/doc/articles/wiki/test_edit.good
similarity index 100%
rename from doc/codelab/wiki/test_edit.good
rename to doc/articles/wiki/test_edit.good
diff --git a/doc/codelab/wiki/test_view.good b/doc/articles/wiki/test_view.good
similarity index 100%
rename from doc/codelab/wiki/test_view.good
rename to doc/articles/wiki/test_view.good
diff --git a/doc/codelab/wiki/view.html b/doc/articles/wiki/view.html
similarity index 100%
rename from doc/codelab/wiki/view.html
rename to doc/articles/wiki/view.html
diff --git a/doc/articles/wiki/wiki.html b/doc/articles/wiki/wiki.html
new file mode 100644
index 0000000..10e1e4f
--- /dev/null
+++ b/doc/articles/wiki/wiki.html
@@ -0,0 +1,779 @@
+<!--{
+	"Title": "Writing Web Applications"
+}-->
+
+<h2>Introduction</h2>
+
+<p>
+Covered in this tutorial:
+</p>
+<ul>
+<li>Creating a data structure with load and save methods</li>
+<li>Using the <code>net/http</code> package to build web applications
+<li>Using the <code>html/template</code> package to process HTML templates</li>
+<li>Using the <code>regexp</code> package to validate user input</li>
+<li>Using closures</li>
+</ul>
+
+<p>
+Assumed knowledge:
+</p>
+<ul>
+<li>Programming experience</li>
+<li>Understanding of basic web technologies (HTTP, HTML)</li>
+<li>Some UNIX/DOS command-line knowledge</li>
+</ul>
+
+<h2>Getting Started</h2>
+
+<p>
+At present, you need to have a FreeBSD, Linux, OS X, or Windows machine to run Go.
+We will use <code>$</code> to represent the command prompt.
+</p>
+
+<p>
+Install Go (see the <a href="/doc/install">Installation Instructions</a>).
+</p>
+
+<p>
+Make a new directory for this tutorial and cd to it:
+</p>
+
+<pre>
+$ mkdir gowiki
+$ cd gowiki
+</pre>
+
+<p>
+Create a file named <code>wiki.go</code>, open it in your favorite editor, and 
+add the following lines:
+</p>
+
+<pre>
+package main
+
+import (
+	"fmt"
+	"io/ioutil"
+)
+</pre>
+
+<p>
+We import the <code>fmt</code> and <code>ioutil</code> packages from the Go 
+standard library. Later, as we implement additional functionality, we will 
+add more packages to this <code>import</code> declaration.
+</p>
+
+<h2>Data Structures</h2>
+
+<p>
+Let's start by defining the data structures. A wiki consists of a series of
+interconnected pages, each of which has a title and a body (the page content).
+Here, we define <code>Page</code> as a struct with two fields representing
+the title and body.
+</p>
+
+<pre>
+!srcextract.bin -src=part1.go -name=Page
+</pre>
+
+<p>
+The type <code>[]byte</code> means "a <code>byte</code> slice". 
+(See <a href="/doc/articles/slices_usage_and_internals.html">Slices: usage and
+internals</a> for more on slices.)
+The <code>Body</code> element is a <code>[]byte</code> rather than
+<code>string</code> because that is the type expected by the <code>io</code>
+libraries we will use, as you'll see below.
+</p>
+
+<p>
+The <code>Page</code> struct describes how page data will be stored in memory. 
+But what about persistent storage? We can address that by creating a 
+<code>save</code> method on <code>Page</code>:
+</p>
+
+<pre>
+!srcextract.bin -src=part1.go -name=save
+</pre>
+
+<p>
+This method's signature reads: "This is a method named <code>save</code> that
+takes as its receiver <code>p</code>, a pointer to <code>Page</code> . It takes
+no parameters, and returns a value of type <code>error</code>." 
+</p>
+
+<p>
+This method will save the <code>Page</code>'s <code>Body</code> to a text 
+file. For simplicity, we will use the <code>Title</code> as the file name.
+</p>
+
+<p>
+The <code>save</code> method returns an <code>error</code> value because
+that is the return type of <code>WriteFile</code> (a standard library function
+that writes a byte slice to a file).  The <code>save</code> method returns the
+error value, to let the application handle it should anything go wrong while
+writing the file.  If all goes well, <code>Page.save()</code> will return
+<code>nil</code> (the zero-value for pointers, interfaces, and some other 
+types).
+</p>
+
+<p>
+The octal integer constant <code>0600</code>, passed as the third parameter to
+<code>WriteFile</code>, indicates that the file should be created with
+read-write permissions for the current user only. (See the Unix man page
+<code>open(2)</code> for details.)
+</p>
+
+<p>
+We will want to load pages, too:
+</p>
+
+<pre>
+!srcextract.bin -src=part1-noerror.go -name=loadPage
+</pre>
+
+<p>
+The function <code>loadPage</code> constructs the file name from
+<code>Title</code>, reads the file's contents into a new
+<code>Page</code>, and returns a pointer to that new <code>page</code>.
+</p>
+
+<p>
+Functions can return multiple values. The standard library function 
+<code>io.ReadFile</code> returns <code>[]byte</code> and <code>error</code>. 
+In <code>loadPage</code>, error isn't being handled yet; the "blank identifier"
+represented by the underscore (<code>_</code>) symbol is used to throw away the
+error return value (in essence, assigning the value to nothing). 
+</p>
+
+<p>
+But what happens if <code>ReadFile</code> encounters an error?  For example,
+the file might not exist. We should not ignore such errors.  Let's modify the
+function to return <code>*Page</code> and <code>error</code>.
+</p>
+
+<pre>
+!srcextract.bin -src=part1.go -name=loadPage
+</pre>
+
+<p>
+Callers of this function can now check the second parameter; if it is
+<code>nil</code> then it has successfully loaded a Page. If not, it will be an
+<code>error</code> that can be handled by the caller (see the 
+<a href="/ref/spec#Errors">language specification</a> for details).
+</p>
+
+<p>
+At this point we have a simple data structure and the ability to save to and
+load from a file. Let's write a <code>main</code> function to test what we've
+written:
+</p>
+
+<pre>
+!srcextract.bin -src=part1.go -name=main
+</pre>
+
+<p>
+After compiling and executing this code, a file named <code>TestPage.txt</code>
+would be created, containing the contents of <code>p1</code>. The file would
+then be read into the struct <code>p2</code>, and its <code>Body</code> element
+printed to the screen.
+</p>
+
+<p>
+You can compile and run the program like this: 
+</p>
+
+<pre>
+$ go build wiki.go
+$ ./wiki
+This is a sample page.
+</pre>
+
+<p>
+(If you're using Windows you must type "<code>wiki</code>" without the 
+"<code>./</code>" to run the program.)
+</p>
+
+<p>
+<a href="part1.go">Click here to view the code we've written so far.</a>
+</p>
+
+<h2>Introducing the <code>net/http</code> package (an interlude)</h2>
+
+<p>
+Here's a full working example of a simple web server:
+</p>
+
+<pre>
+!htmlify.bin < http-sample.go
+</pre>
+
+<p>
+The <code>main</code> function begins with a call to 
+<code>http.HandleFunc</code>, which tells the <code>http</code> package to 
+handle all requests to the web root (<code>"/"</code>) with 
+<code>handler</code>. 
+</p>
+
+<p>
+It then calls <code>http.ListenAndServe</code>, specifying that it should
+listen on port 8080 on any interface (<code>":8080"</code>). (Don't
+worry about its second parameter, <code>nil</code>, for now.)
+This function will block until the program is terminated.
+</p>
+
+<p>
+The function <code>handler</code> is of the type <code>http.HandlerFunc</code>.
+It takes an <code>http.ResponseWriter</code> and an <code>http.Request</code> as
+its arguments.
+</p>
+
+<p>
+An <code>http.ResponseWriter</code> value assembles the HTTP server's response; by writing 
+to it, we send data to the HTTP client.
+</p>
+
+<p>
+An <code>http.Request</code> is a data structure that represents the client
+HTTP request.  The string <code>r.URL.Path</code> is the path component
+of the request URL.  The trailing <code>[1:]</code> means
+"create a sub-slice of <code>Path</code> from the 1st character to the end." 
+This drops the leading "/" from the path name.
+</p>
+
+<p>
+If you run this program and access the URL: 
+</p>
+<pre>http://localhost:8080/monkeys</pre>
+<p>
+the program would present a page containing:
+</p>
+<pre>Hi there, I love monkeys!</pre>
+
+<h2>Using <code>net/http</code> to serve wiki pages</h2>
+
+<p>
+To use the <code>net/http</code> package, it must be imported:
+</p>
+
+<pre>
+import (
+	"fmt"
+	<b>"net/http"</b>
+	"io/ioutil"
+)
+</pre>
+
+<p>
+Let's create a handler to view a wiki page: 
+</p>
+
+<pre>
+!srcextract.bin -src=part2.go -name=lenPath
+
+!srcextract.bin -src=part2.go -name=viewHandler
+</pre>
+
+<p>
+First, this function extracts the page title from <code>r.URL.Path</code>,
+the path component of the request URL. The global constant 
+<code>lenPath</code> is the length of the leading <code>"/view/"</code>
+component of the request path.
+The <code>Path</code> is re-sliced with <code>[lenPath:]</code> to drop the 
+first 6 characters of the string. This is because the path will invariably 
+begin with <code>"/view/"</code>, which is not part of the page title.
+</p>
+
+<p>
+The function then loads the page data, formats the page with a string of simple 
+HTML, and writes it to <code>w</code>, the <code>http.ResponseWriter</code>. 
+</p>
+
+<p>
+Again, note the use of <code>_</code> to ignore the <code>error</code> 
+return value from <code>loadPage</code>. This is done here for simplicity
+and generally considered bad practice. We will attend to this later.
+</p>
+
+<p>
+To use this handler, we create a <code>main</code> function that
+initializes <code>http</code> using the <code>viewHandler</code> to handle
+any requests under the path <code>/view/</code>.
+</p>
+
+<pre>
+!srcextract.bin -src=part2.go -name=main
+</pre>
+
+<p>
+<a href="part2.go">Click here to view the code we've written so far.</a>
+</p>
+
+<p>
+Let's create some page data (as <code>test.txt</code>), compile our code, and
+try serving a wiki page.
+</p>
+
+<p>
+Open <code>test.txt</code> file in your editor, and save the string "Hello world" (without quotes)
+in it.
+</p>
+
+<pre>
+$ go build wiki.go
+$ ./wiki
+</pre>
+
+<p>
+With this web server running, a visit to <code><a
+href="http://localhost:8080/view/test">http://localhost:8080/view/test</a></code>
+should show a page titled "test" containing the words "Hello world".
+</p>
+
+<h2>Editing Pages</h2>
+
+<p>
+A wiki is not a wiki without the ability to edit pages. Let's create two new
+handlers: one named <code>editHandler</code> to display an 'edit page' form,
+and the other named <code>saveHandler</code> to save the data entered via the
+form.
+</p>
+
+<p>
+First, we add them to <code>main()</code>: 
+</p>
+
+<pre>
+!srcextract.bin -src=final-noclosure.go -name=main
+</pre>
+
+<p>
+The function <code>editHandler</code> loads the page 
+(or, if it doesn't exist, create an empty <code>Page</code> struct), 
+and displays an HTML form.
+</p>
+
+<pre>
+!srcextract.bin -src=notemplate.go -name=editHandler
+</pre>
+
+<p>
+This function will work fine, but all that hard-coded HTML is ugly.
+Of course, there is a better way.
+</p>
+ 
+<h2>The <code>html/template</code> package</h2>
+
+<p>
+The <code>html/template</code> package is part of the Go standard library.
+We can use <code>html/template</code> to keep the HTML in a separate file,
+allowing us to change the layout of our edit page without modifying the
+underlying Go code.
+</p>
+
+<p>
+First, we must add <code>html/template</code> to the list of imports:
+</p>
+
+<pre>
+import (
+	"http"
+	"io/ioutil"
+	"os"
+	<b>"html/template"</b>
+)
+</pre>
+
+<p>
+Let's create a template file containing the HTML form. 
+Open a new file named <code>edit.html</code>, and add the following lines:
+</p>
+
+<pre>
+!htmlify.bin < edit.html
+</pre>
+
+<p>
+Modify <code>editHandler</code> to use the template, instead of the hard-coded
+HTML:
+</p>
+
+<pre>
+!srcextract.bin -src=final-noerror.go -name=editHandler
+</pre>
+
+<p>
+The function <code>template.ParseFiles</code> will read the contents of 
+<code>edit.html</code> and return a <code>*template.Template</code>. 
+</p>
+
+<p>
+The method <code>t.Execute</code> executes the template, writing the
+generated HTML to the <code>http.ResponseWriter</code>.
+The <code>.Title</code> and <code>.Body</code> dotted identifiers refer to
+<code>p.Title</code> and <code>p.Body</code>.
+</p>
+
+<p>
+Template directives are enclosed in double curly braces.
+The <code>printf "%s" .Body</code> instruction is a function call
+that outputs <code>.Body</code> as a string instead of a stream of bytes,
+the same as a call to <code>fmt.Printf</code>.
+The <code>|html</code> part of each directive pipes the value through the
+<code>html</code> formatter before outputting it, which escapes HTML
+characters (such as replacing <code>></code> with <code>&gt;</code>),
+preventing user data from corrupting the form HTML. 
+</p>
+
+<p>
+Now that we've removed the <code>fmt.Fprintf</code> statement, we can remove
+<code>"fmt"</code> from the <code>import</code> list.
+</p>
+
+<p>
+While we're working with templates, let's create a template for our
+<code>viewHandler</code> called <code>view.html</code>:
+</p>
+
+<pre>
+!htmlify.bin < view.html
+</pre>
+
+<p>
+Modify <code>viewHandler</code> accordingly:
+</p>
+
+<pre>
+!srcextract.bin -src=final-noerror.go -name=viewHandler
+</pre>
+
+<p>
+Notice that we've used almost exactly the same templating code in both
+handlers. Let's remove this duplication by moving the templating code
+to its own function:
+</p>
+
+<pre>
+!srcextract.bin -src=final-template.go -name=viewHandler
+
+!srcextract.bin -src=final-template.go -name=editHandler
+
+!srcextract.bin -src=final-template.go -name=renderTemplate
+</pre>
+
+<p>
+The handlers are now shorter and simpler. 
+</p>
+
+<h2>Handling non-existent pages</h2>
+
+<p>
+What if you visit <a href="http://localhost:8080/view/APageThatDoesntExist">
+<code>/view/APageThatDoesntExist</code></a>? The program will crash. This is 
+because it ignores the error return value from <code>loadPage</code>. Instead,
+if the requested Page doesn't exist, it should redirect the client to the edit
+Page so the content may be created:
+</p>
+
+<pre>
+!srcextract.bin -src=final-noclosure.go -name=viewHandler
+</pre>
+
+<p>
+The <code>http.Redirect</code> function adds an HTTP status code of 
+<code>http.StatusFound</code> (302) and a <code>Location</code>
+header to the HTTP response.
+</p>
+
+<h2>Saving Pages</h2>
+
+<p>
+The function <code>saveHandler</code> will handle the form submission. 
+</p>
+
+<pre>
+!srcextract.bin -src=final-template.go -name=saveHandler
+</pre>
+
+<p>
+The page title (provided in the URL) and the form's only field, 
+<code>Body</code>, are stored in a new <code>Page</code>. 
+The <code>save()</code> method is then called to write the data to a file,
+and the client is redirected to the <code>/view/</code> page.
+</p>
+
+<p>
+The value returned by <code>FormValue</code> is of type <code>string</code>.
+We must convert that value to <code>[]byte</code> before it will fit into 
+the <code>Page</code> struct.  We use <code>[]byte(body)</code> to perform
+the conversion.
+</p>
+
+<h2>Error handling</h2>
+
+<p>
+There are several places in our program where errors are being ignored.  This
+is bad practice, not least because when an error does occur the program will
+crash.  A better solution is to handle the errors and return an error message
+to the user. That way if something does go wrong, the server will continue to
+function and the user will be notified.
+</p>
+
+<p>
+First, let's handle the errors in <code>renderTemplate</code>:
+</p>
+
+<pre>
+!srcextract.bin -src=final-parsetemplate.go -name=renderTemplate
+</pre>
+
+<p>
+The <code>http.Error</code> function sends a specified HTTP response code 
+(in this case "Internal Server Error") and error message.
+Already the decision to put this in a separate function is paying off.
+</p>
+
+<p>
+Now let's fix up <code>saveHandler</code>:
+</p>
+
+<pre>
+!srcextract.bin -src=final-noclosure.go -name=saveHandler
+</pre>
+
+<p>
+Any errors that occur during <code>p.save()</code> will be reported 
+to the user.
+</p>
+
+<h2>Template caching</h2>
+
+<p>
+There is an inefficiency in this code: <code>renderTemplate</code> calls 
+<code>ParseFile</code> every time a page is rendered. 
+A better approach would be to call <code>ParseFile</code> once for each 
+template at program initialization, and store the resultant 
+<code>*Template</code> values in a data structure for later use.
+</p>
+
+<p>
+First we create a global map named <code>templates</code> in which to store 
+our <code>*Template</code> values, keyed by <code>string</code> 
+(the template name):
+</p>
+
+<pre>
+!srcextract.bin -src=final.go -name=templates
+</pre>
+
+<p>
+Then we create an <code>init</code> function, which will be called before
+<code>main</code> at program initialization. The function
+<code>template.Must</code> is a convenience wrapper that panics when passed a
+non-nil <code>error</code> value, and otherwise returns the
+<code>*Template</code> unaltered. A panic is appropriate here; if the templates
+can't be loaded the only sensible thing to do is exit the program.
+</p>
+
+<pre>
+!srcextract.bin -src=final.go -name=init
+</pre>
+
+<p>
+A <code>for</code> loop is used with a <code>range</code> statement to iterate 
+over an array constant containing the names of the templates we want parsed.
+If we were to add more templates to our program, we would add their names to 
+that array.
+</p>
+
+<p>
+We then modify our <code>renderTemplate</code> function to call 
+the <code>Execute</code> method on the appropriate <code>Template</code> from 
+<code>templates</code>:
+
+<pre>
+!srcextract.bin -src=final.go -name=renderTemplate
+</pre>
+
+<h2>Validation</h2>
+
+<p>
+As you may have observed, this program has a serious security flaw: a user
+can supply an arbitrary path to be read/written on the server. To mitigate
+this, we can write a function to validate the title with a regular expression.
+</p>
+
+<p>
+First, add <code>"regexp"</code> to the <code>import</code> list.
+Then we can create a global variable to store our validation regexp:
+</p>
+
+<pre>
+!srcextract.bin -src=final-noclosure.go -name=titleValidator
+</pre>
+
+<p>
+The function <code>regexp.MustCompile</code> will parse and compile the 
+regular expression, and return a <code>regexp.Regexp</code>. 
+<code>MustCompile</code> is distinct from <code>Compile</code> in that it will
+panic if the expression compilation fails, while <code>Compile</code> returns
+an <code>error</code> as a second parameter. 
+</p>
+
+<p>
+Now, let's write a function that extracts the title string from the request 
+URL, and tests it against our <code>TitleValidator</code> expression:
+</p>
+
+<pre>
+!srcextract.bin -src=final-noclosure.go -name=getTitle
+</pre>
+
+<p>
+If the title is valid, it will be returned along with a <code>nil</code>
+error value.  If the title is invalid, the function will write a 
+"404 Not Found" error to the HTTP connection, and return an error to the 
+handler. 
+</p>
+
+<p>
+Let's put a call to <code>getTitle</code> in each of the handlers:
+</p>
+
+<pre>
+!srcextract.bin -src=final-noclosure.go -name=viewHandler
+
+!srcextract.bin -src=final-noclosure.go -name=editHandler
+
+!srcextract.bin -src=final-noclosure.go -name=saveHandler
+</pre>
+
+<h2>Introducing Function Literals and Closures</h2>
+
+<p>
+Catching the error condition in each handler introduces a lot of repeated code.
+What if we could wrap each of the handlers in a function that does this 
+validation and error checking? Go's 
+<a href="/ref/spec#Function_declarations">function 
+literals</a> provide a powerful means of abstracting functionality 
+that can help us here.
+</p>
+
+<p>
+First, we re-write the function definition of each of the handlers to accept
+a title string:
+</p>
+
+<pre>
+func viewHandler(w http.ResponseWriter, r *http.Request, title string)
+func editHandler(w http.ResponseWriter, r *http.Request, title string)
+func saveHandler(w http.ResponseWriter, r *http.Request, title string)
+</pre>
+
+<p>
+Now let's define a wrapper function that <i>takes a function of the above
+type</i>, and returns a function of type <code>http.HandlerFunc</code>
+(suitable to be passed to the function <code>http.HandleFunc</code>):
+</p>
+
+<pre>
+func makeHandler(fn func (http.ResponseWriter, *http.Request, string)) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		// Here we will extract the page title from the Request,
+		// and call the provided handler 'fn'
+	}
+}
+</pre>
+
+<p>
+The returned function is called a closure because it encloses values defined
+outside of it. In this case, the variable <code>fn</code> (the single argument
+to <code>makeHandler</code>) is enclosed by the closure. The variable
+<code>fn</code> will be one of our save, edit, or view handlers.
+</p>
+
+<p>
+Now we can take the code from <code>getTitle</code> and use it here
+(with some minor modifications):
+</p>
+
+<pre>
+!srcextract.bin -src=final.go -name=makeHandler
+</pre>
+
+<p>
+The closure returned by <code>makeHandler</code> is a function that takes
+an <code>http.ResponseWriter</code> and <code>http.Request</code> (in other
+words, an <code>http.HandlerFunc</code>). 
+The closure extracts the <code>title</code> from the request path, and
+validates it with the <code>TitleValidator</code> regexp. If the
+<code>title</code> is invalid, an error will be written to the
+<code>ResponseWriter</code> using the <code>http.NotFound</code> function. 
+If the <code>title</code> is valid, the enclosed handler function
+<code>fn</code> will be called with the <code>ResponseWriter</code>,
+<code>Request</code>, and <code>title</code> as arguments.
+</p>
+
+<p>
+Now we can wrap the handler functions with <code>makeHandler</code> in 
+<code>main</code>, before they are registered with the <code>http</code> 
+package:
+</p>
+
+<pre>
+!srcextract.bin -src=final.go -name=main
+</pre>
+
+<p>
+Finally we remove the calls to <code>getTitle</code> from the handler functions,
+making them much simpler:
+</p>
+
+<pre>
+!srcextract.bin -src=final.go -name=viewHandler
+
+!srcextract.bin -src=final.go -name=editHandler
+
+!srcextract.bin -src=final.go -name=saveHandler
+</pre>
+
+<h2>Try it out!</h2>
+
+<p>
+<a href="final.go">Click here to view the final code listing.</a>
+</p>
+
+<p>
+Recompile the code, and run the app:
+</p>
+
+<pre>
+$ go build wiki.go
+$ ./wiki
+</pre>
+
+<p>
+Visiting <a href="http://localhost:8080/view/ANewPage">http://localhost:8080/view/ANewPage</a>
+should present you with the page edit form. You should then be able to 
+enter some text, click 'Save', and be redirected to the newly created page.
+</p>
+
+<h2>Other tasks</h2>
+
+<p>
+Here are some simple tasks you might want to tackle on your own:
+</p>
+
+<ul>
+<li>Store templates in <code>tmpl/</code> and page data in <code>data/</code>.
+<li>Add a handler to make the web root redirect to 
+	<code>/view/FrontPage</code>.</li>
+<li>Spruce up the page templates by making them valid HTML and adding some
+	CSS rules.</li>
+<li>Implement inter-page linking by converting instances of 
+	<code>[PageName]</code> to <br>
+	<code><a href="/view/PageName">PageName</a></code>.
+	(hint: you could use <code>regexp.ReplaceAllFunc</code> to do this)
+	</li>
+</ul>
diff --git a/doc/code.html b/doc/code.html
index 5ae5707..768a999 100644
--- a/doc/code.html
+++ b/doc/code.html
@@ -5,340 +5,499 @@
 <h2 id="Introduction">Introduction</h2>
 
 <p>
-This document explains how to write a new package
-and how to test code.
-It assumes you have installed Go using the
-<a href="install.html">installation instructions</a>.
+This document demonstrates the development of a simple Go package and
+introduces the <a href="/cmd/go/">go command</a>, the standard way to fetch,
+build, and install Go packages and commands.
+</p>
+
+
+<h2 id="GOPATH">Code organization</h2>
+
+<h3><code>GOPATH</code> and workspaces</h3>
+
+<p>
+One of Go's design goals is to make writing software easier.  To that end, the
+<code>go</code> command doesn't use Makefiles or other configuration files to
+guide program construction. Instead, it uses the source code to find
+dependencies and determine build conditions. This means your source code and
+build scripts are always in sync; they are one and the same.
 </p>
 
 <p>
-Before embarking on a change to an existing
-package or the creation of a new package,
-be sure to send mail to the
-<a href="http://groups.google.com/group/golang-nuts">mailing list</a>
-to let people know what you are thinking of doing.
-Doing so helps avoid duplication of effort and
-enables discussions about design before any code
-has been written.
+The one thing you must do is set a <code>GOPATH</code> environment variable.
+<code>GOPATH</code> tells the <code>go</code> command (and other related tools)
+where to find and install the Go packages on your system.
 </p>
 
-<h2 id="Community_resources">Community resources</h2>
+<p>
+<code>GOPATH</code> is a list of paths. It shares the syntax of your system's
+<code>PATH</code> environment variable. A typical <code>GOPATH</code> on
+a Unix system might look like this:
+</p>
+
+<pre>
+GOPATH=/home/user/ext:/home/user/mygo
+</pre>
 
 <p>
-For real-time help, there may be users or developers on
-<code>#go-nuts</code> on the <a href="http://freenode.net/">Freenode</a> IRC server.
+(On a Windows system use semicolons as the path separator instead of colons.)
 </p>
 
 <p>
-The official mailing list for discussion of the Go language is
-<a href="http://groups.google.com/group/golang-nuts">Go Nuts</a>.
+Each path in the list (in this case <code>/home/user/ext</code> or
+<code>/home/user/mygo</code>) specifies the location of a <i>workspace</i>.
+A workspace contains Go source files and their associated package objects, and
+command executables. It has a prescribed structure of three subdirectories:
 </p>
 
+<ul>
+<li><code>src</code> contains Go source files,
+<li><code>pkg</code> contains compiled package objects, and
+<li><code>bin</code> contains executable commands.
+</ul>
+
 <p>
-Bugs can be reported using the <a href="http://code.google.com/p/go/issues/list">Go issue tracker</a>.
+Subdirectories of the <code>src</code> directory hold independent packages, and
+all source files (<code>.go</code>, <code>.c</code>, <code>.h</code>, and
+<code>.s</code>) in each subdirectory are elements of that subdirectory's
+package.
 </p>
 
 <p>
-For those who wish to keep up with development,
-there is another mailing list, <a href="http://groups.google.com/group/golang-checkins">golang-checkins</a>,
-that receives a message summarizing each checkin to the Go repository.
+When building a program that imports the package "<code>widget</code>" the
+<code>go</code> command looks for <code>src/pkg/widget</code> inside the Go root,
+and then—if the package source isn't found there—it searches
+for <code>src/widget</code> inside each workspace in order.
 </p>
 
+<p>
+Multiple workspaces can offer some flexibility and convenience, but for now
+we'll concern ourselves with only a single workspace.
+</p>
 
-<h2 id="New_package">Creating a new package</h2>
+<p>
+Let's work through a simple example. First, create a <code>$HOME/mygo</code>
+directory and its <code>src</code> subdirectory:
+</p>
 
-<h3>Choosing an import path</h3>
+<pre>
+$ mkdir -p $HOME/mygo/src # create a place to put source code
+</pre>
 
 <p>
-The standard packages are given short names like <code>fmt</code> and
-<code>net/http</code> for convenience.
-For your own projects, choose a name space that is unlikely
-to collide with future additions to the standard library or other
+Next, set it as the <code>GOPATH</code>. You should also add the
+<code>bin</code> subdirectory to your <code>PATH</code> environment variable so
+that you can run the commands therein without specifying their full path.
+To do this, add the following lines to <code>$HOME/.profile</code> (or
+equivalent):
+</p>
+
+<pre>
+export GOPATH=$HOME/mygo
+export PATH=$PATH:$HOME/mygo/bin
+</pre>
+
+
+<h3>Import paths</h3>
+
+<p>
+The standard packages are given short import paths such as <code>"fmt"</code>
+and <code>"net/http"</code> for convenience. 
+For your own projects, it is important to choose a base import path that is
+unlikely to collide with future additions to the standard library or other
 external libraries.
 </p>
 
 <p>
+The best way to choose an import path is to use the location of your version
+control repository.
 For instance, if your source repository is at <code>example.com</code> 
 or <code>code.google.com/p/example</code>, you should begin your package
 paths with that URL, as in "<code>example.com/foo/bar</code>" or
 "<code>code.google.com/p/example/foo/bar</code>".
-This way the <a href="/cmd/go/"><code>go</code> tool</a> can automatically
-check out and build the source code from its import path.
+Using this convention, the <code>go</code> command can automatically check out and
+build the source code by its import path alone.
 </p>
 
 <p>
-If you don't intend your code to be installed in this way, you should at
+If you don't intend to install your code in this way, you should at
 least use a unique prefix like "<code>widgets/</code>", as in
 "<code>widgets/foo/bar</code>". A good rule is to use a prefix such as your
-company or project name since it is unlikely to be used by another group.
+company or project name, since it is unlikely to be used by another group.
 </p>
 
+<p>
+We'll use <code>example/</code> as our base import path:
+</p>
 
-<h3>The <code>go</code> tool and <code>GOPATH</code></h3>
+<pre>
+$ mkdir -p $GOPATH/src/example
+</pre>
+
+
+<h3>Package names</h3>
 
 <p>
-The <a href="/cmd/go/"><code>go</code> tool</a> is the standard means of
-building and installing Go libraries and programs. It is a "zero configuration"
-tool; it determines how to build Go packages from their source code alone.
+The first statement in a Go source file should be
 </p>
 
+<pre>
+package <i>name</i>
+</pre>
+
 <p>
-To use the <code>go</code> tool effectively you must set the
-<code>GOPATH</code> variable.
-<code>GOPATH</code> specifies a list of paths that contain Go source code
-and package binaries. Source code, package objects, and command binaries are
-located inside the <code>GOPATH</code>s' <code>src</code>, <code>pkg</code>,
-and <code>bin</code> subdirectories respectively.
+where <code><i>name</i></code> is the package's default name for imports.
+(All files in a package must use the same <code><i>name</i></code>.)
 </p>
 
 <p>
-You should set <code>GOPATH</code> in your shell profile
-(<code>$HOME/.bashrc</code>, <code>$HOME/.profile</code>, or equivalent).
+Go's convention is that the package name is the last element of the
+import path: the package imported as "<code>crypto/rot13</code>"
+should be named <code>rot13</code>.
+There is no requirement that package names be unique
+across all packages linked into a single binary,
+only that the import paths (their full file names) be unique.
 </p>
 
 <p>
-This shell session demonstrates setting <code>GOPATH</code>, creating a trivial
-<code>widgets/foo</code> package, and building and installing the package.
+Create a new package under <code>example</code> called <code>newmath</code>:
 </p>
 
 <pre>
-$ export GOPATH=$HOME/gocode
-$ mkdir -p $GOPATH/src/widgets/foo
-$ cat > $GOPATH/src/widgets/foo/foo.go
-package foo
-const String = "Go rules!"
-^D
-$ go install widgets/foo
-$ ls $GOPATH/pkg/*/widgets
-foo.a
+$ cd $GOPATH/src/example
+$ mkdir newmath
 </pre>
 
-<p>(<code>^D</code> means to type Control-D.)</p>
+<p>
+Then create a file named <code>$GOPATH/src/example/newmath/sqrt.go</code>
+containing the following Go code:
+</p>
+
+<pre>
+// Package newmath is a trivial example package.
+package newmath
+
+// Sqrt returns an approximation to the square root of x.
+func Sqrt(x float64) float64 {
+        // This is a terrible implementation.
+        // Real code should import "math" and use math.Sqrt.
+        z := 0.0
+        for i := 0; i < 1000; i++ {
+                z -= (z*z - x) / (2 * x)
+        }
+        return z
+}
+</pre>
 
 <p>
-Type <code>go help gopath</code> on the command line for more information
-about <code>GOPATH</code>.
+This package is imported by the path name of the directory it's in, starting
+after the <code>src</code> component:
+</p>
+
+<pre>
+import "example/newmath"
+</pre>
+
+<p>
+See <a href="/doc/effective_go.html#names">Effective Go</a> to learn more about
+Go's naming conventions.
 </p>
 
 
-<h3>Go source files</h3>
+<h2>Building and installing</h2>
 
 <p>
-The first statement in a Go source file should be <code>package
-<i>name</i></code>, where <code><i>name</i></code> is the package's default
-name for imports.
-(All files in a package must use the same <code><i>name</i></code>.)
-Go's convention is that the package name is the last element of the
-import path: the package imported as "<code>crypto/rot13</code>"
-should be named <code>rot13</code>.
-There is no requirement that package names be unique
-across all packages linked into a single binary,
-only that the import paths (their full file names) be unique.
+The <code>go</code> command comprises several subcommands, the most central being
+<code>install</code>. Running <code>go install <i>importpath</i></code> builds
+and installs a package and its dependencies.
+</p>
+
+<p>
+To "install a package" means to write the package object or executable command
+to the <code>pkg</code> or <code>bin</code> subdirectory of the workspace in
+which the source resides.
 </p>
 
+<h3>Building a package</h3>
+
 <p>
-Go compiles all the source files in a package at once, so one file
-can refer to constants, variables, types, and functions in another
-file without special arrangement or declarations.
+To build and install the <code>newmath</code> package, type
 </p>
 
+<pre>
+$ go install example/newmath
+</pre>
+
+<p>
+This command will produce no output if the package and its dependencies
+are built and installed correctly.
+</p>
+
+<p>
+As a convenience, the <code>go</code> command will assume the current directory
+if no import path is specified on the command line. This sequence of commands
+has the same affect as the one above:
+</p>
+
+<pre>
+$ cd $GOPATH/src/example/newmath
+$ go install
+</pre>
+
 <p>
-Writing clean, idiomatic Go code is beyond the scope of this document.
-<a href="effective_go.html">Effective Go</a> is an introduction to
-that topic.
+The resulting workspace directory tree (assuimg we're running Linux on a 64-bit
+system) looks like this:
 </p>
 
-<h2 id="Building_programs">Building programs</h2>
+<pre>
+pkg/
+    linux_amd64/
+        example/
+            newmath.a  # package object
+src/
+    example/
+        newmath/
+            sqrt.go    # package source
+</pre>
+
+
+<h3>Building a command</h3>
+
+<p>
+The <code>go</code> command treats code belonging to <code>package main</code> as
+an executable command and installs the package binary to the
+<code>GOPATH</code>'s <code>bin</code> subdirectory.
+</p>
 
 <p>
-The <a href="/cmd/go/"><code>go</code> tool</a> treats code belonging to
-<code>package main</code> as an executable command, and installs the package
-binary to the <code>GOPATH</code>'s <code>bin</code> subdirectory.
+Add a command named <code>hello</code> to the source tree.
+First create the <code>example/hello</code> directory:
 </p>
 
+<pre>
+$ cd $GOPATH/src/example
+$ mkdir hello
+</pre>
+
 <p>
-Building executable commands is the same as building packages.
-Use "<code>go install</code>":
+Then create the file <code>$GOPATH/src/example/hello/hello.go</code>
+containing the following Go code.
 </p>
 
 <pre>
-$ mkdir -p $GOPATH/src/widgets/bar
-$ cat > $GOPATH/src/widgets/bar/bar.go
+// Hello is a trivial example of a main package.
 package main
 
 import (
-    "fmt"
-    "widgets/foo"
+        "example/newmath"
+        "fmt"
 )
 
 func main() {
-    fmt.Println(foo.String)
+        fmt.Printf("Hello, world.  Sqrt(2) = %v\n", newmath.Sqrt(2))
 }
-^D
-$ go install widgets/bar
-$ $GOPATH/bin/bar
-Go rules!
 </pre>
 
 <p>
-Run <code>go help build</code> and <code>go help install</code> for more
-about building and installing Go binaries.
+Next, run <code>go install</code>, which builds and installs the binary to
+<code>$GOPATH/bin</code>:
 </p>
 
-<h2 id="Testing">Testing</h2>
+<pre>
+$ go install example/hello
+</pre>
 
 <p>
-Go has a lightweight test framework composed of the <code>go</code> tool and
-the <code>testing</code> package.
-You write a test by creating a file with a name ending in <code>_test.go</code>
-that contains functions named <code>TestXXX</code> with signature
-<code>func (t *testing.T)</code>.
-The test framework runs each such function;
-if the function calls a failure function such as <code>t.Error</code> or
-<code>t.Fail</code>, the test is considered to have failed.
-Run <code>go help test</code> and see the
-<a href="/pkg/testing/">testing package documentation</a> for more detail.
+To run the program, invoke it by name as you would any other command:
 </p>
 
+<pre>
+$ $GOPATH/bin/hello
+Hello, world.  Sqrt(2) = 1.414213562373095
+</pre>
+
 <p>
-To run the test, run "<code>go test</code>":
+If you added <code>$HOME/mygo/bin</code> to your <code>PATH</code>, you may omit
+the path to the executable:
 </p>
 
 <pre>
-$ cat > $GOPATH/src/widgets/foo/foo_test.go
-package foo
+$ hello
+Hello, world.  Sqrt(2) = 1.414213562373095
+</pre>
 
-import "testing"
+<p>
+The workspace directory tree now looks like this:
+</p>
 
-func TestString(t *testing.T) {
-    const expect = "Go rules!"
-    if String != expect {
-        t.Errorf("String == %q, want %q", String, expect)
-    }
-}
-^D
-$ go test widgets/foo
-ok  	widgets/foo	0.018s
+<pre>
+bin/
+    hello              # command executable
+pkg/
+    linux_amd64/ 
+        example/
+            newmath.a  # package object
+src/
+    example/
+        hello/
+            hello.go   # command source
+        newmath/
+            sqrt.go    # package source
 </pre>
 
 <p>
-If your change affects performance, add a <code>Benchmark</code> function 
-(run <code>go help testfunc</code>) and run it using <code>go test
--test.bench=.*</code>.
+The <code>go</code> command also provides a <code>build</code> command, which is
+like <code>install</code> except it builds all objects in a temporary directory
+and does not install them under <code>pkg</code> or <code>bin</code>.
+When building a command an executable named after the last element of the
+import path is written to the current directory. When building a package, 
+<code>go build</code> serves merely to test that the package and its
+dependencies can be built. (The resulting package object is thrown away.)
 </p>
 
-<h2 id="pkg_example">An example package with tests</h2>
+
+<h2 id="Testing">Testing</h2>
 
 <p>
-This example package, <code>numbers</code>, consists of the function
-<code>Double</code>, which takes an <code>int</code> and returns that value 
-multiplied by 2. It consists of two files.
+Go has a lightweight test framework composed of the <code>go test</code>
+command and the <code>testing</code> package.
 </p>
 
 <p>
-First, the package implementation, <code>numbers.go</code>:
+You write a test by creating a file with a name ending in <code>_test.go</code>
+that contains functions named <code>TestXXX</code> with signature
+<code>func (t *testing.T)</code>.
+The test framework runs each such function;
+if the function calls a failure function such as <code>t.Error</code> or
+<code>t.Fail</code>, the test is considered to have failed.
+</p>
+
+<p>
+Add a test to the <code>newmath</code> package by creating the file
+<code>$GOPATH/src/example/newmath/sqrt_test.go</code> containing the following
+Go code.
 </p>
 
 <pre>
-package numbers
+package newmath
+
+import "testing"
 
-func Double(i int) int {
-	return i * 2
+func TestSqrt(t *testing.T) {
+	const in, out = 9, 3
+	if x := Sqrt(in); x != out {
+		t.Errorf("Sqrt(%v) = %v, want %v", in, x, out)
+        }
 }
 </pre>
 
 <p>
-Next, the tests, <code>numbers_test.go</code>:
+Now run the test with <code>go test</code>:
 </p>
 
 <pre>
-package numbers
-
-import (
-	"testing"
-)
+$ go test example/newmath
+ok  	example/newmath
+</pre>
 
-type doubleTest struct {
-	in, out int
-}
+<p>
+Run <code><a href="/cmd/go/#Test_packages">go help test</a></code> and see the
+<a href="/pkg/testing/">testing package documentation</a> for more detail.
+</p>
 
-var doubleTests = []doubleTest{
-	doubleTest{1, 2},
-	doubleTest{2, 4},
-	doubleTest{-5, -10},
-}
 
-func TestDouble(t *testing.T) {
-	for _, dt := range doubleTests {
-		v := Double(dt.in)
-		if v != dt.out {
-			t.Errorf("Double(%d) = %d, want %d.", dt.in, v, dt.out)
-		}
-	}
-}
-</pre>
+<h2 id="remote">Remote packages</h2>
 
 <p>
-Running <code>go install</code> will build and install the package to
-the <code>GOPATH</code>'s <code>pkg</code> directory
-(it can then be imported by any other Go program).
+An import path can describe how to obtain the package source code using a
+revision control system such as Git or Mercurial. The <code>go</code> command uses
+this property to automatically fetch packages from remote repositories.
+For instance, the examples described in this document are also kept in a
+Mercurial repository hosted at Google Code,
+<code><a href="http://code.google.com/p/go.example">code.google.com/p/go.example</a></code>.
+If you include the repository URL in the package's import path,
+<code>go get</code> will fetch, build, and install it automatically:
 </p>
 
+<pre>
+$ go get code.google.com/p/go.example/hello
+$ $GOPATH/bin/hello
+Hello, world.  Sqrt(2) = 1.414213562373095
+</pre>
+
 <p>
-Running <code>go test</code> will rebuild the package, including the
-<code>numbers_test.go</code> file, and then run the <code>TestDouble</code>
-function. The output "<code>ok</code>" indicates that all tests passed
-successfully.  Breaking the implementation by changing the multiplier from
-<code>2</code> to <code>3</code> will allow you to see how failing tests are 
-reported.
+If the specified package is not present in a workspace, <code>go get</code>
+will place it inside the first workspace specified by <code>GOPATH</code>.
+(If the package does already exist, <code>go get</code> skips the remote
+fetch and behaves the same as <code>go install</code>.)
 </p>
 
 <p>
-Run <code>go help test</code>, <code>go help testfunc</code>,
-and <code>go help testflag</code> and see the
-<a href="/pkg/testing/">testing package documentation</a> for more detail.
+After issuing the above <code>go get</code> command, the workspace directory
+tree should now now look like this:
 </p>
 
-<h2 id="arch_os_specific">Architecture- and operating system-specific code</h2>
-
-<p>First, a disclaimer: very few Go packages should need to know about the
-hardware and operating system they run on.  In the vast majority of cases the
-language and standard library handle most portability issues.  This section is
-a guide for experienced systems programmers who have a good reason to write
-platform-specific code, such as assembly-language support for fast
-trigonometric functions or code that implements a common interface above
-different operating systems.</p>
-
-<p>To compile such code, use the <code>$GOOS</code> and <code>$GOARCH</code>
-<a href="/doc/install.html#environment">environment variables</a> in your
-source file names.</p>
+<pre>
+bin/
+    hello                 # command executable
+pkg/
+    linux_amd64/ 
+        code.google.com/p/go.example/
+            newmath.a     # package object
+        example/
+            newmath.a     # package object
+src/
+    code.google.com/p/go.example/
+        hello/
+            hello.go      # command source
+        newmath/
+            sqrt.go       # package source
+            sqrt_test.go  # test source
+    example/
+        hello/
+            hello.go      # command source
+        newmath/
+            sqrt.go       # package source
+            sqrt_test.go  # test source
+</pre>
 
-<p>For example, consider the package <code>foo</code> that consists of four
-files:</p>
+<p>
+The <code>hello</code> command hosted at Google Code depends on the
+<code>newmath</code> package within the same repository. The imports in
+<code>hello.go</code> file use the same import path convention, so the <code>go
+get</code> command is able to locate and install the dependent package, too.
+</p>
 
 <pre>
-foo.go
-foo_386.go
-foo_amd64.go
-foo_arm.go
+import "code.google.com/p/go.example/newmath"
 </pre>
 
-describes a package that builds on
-different architectures by parameterizing the file name with
-<code>$GOARCH</code>.</p>
+<p>
+This convention is the easiest way to make your Go packages available for
+others to use.
+The <a href="http://godashboard.appspot.com/package">Go Package Dashboard</a>
+displays a list of packages recently installed with the <code>go</code> command.
+</p>
 
-<p>The general code goes in <code>foo.go</code>, while architecture-specific
-code goes in <code>foo_386.go</code>, <code>foo_amd64.go</code>, and
-<code>foo_arm.go</code>.</p>
+<p>
+For more information on using remote repositories with the <code>go</code> command, see
+<code><a href="/cmd/go/#Remote_import_path_syntax">go help remote</a></code>.
+</p>
 
-<p>If you follow these conventional parameterizations, tools such as the <a
-href="/cmd/go/"><code>go</code> tool</a> will work seamlessly with your
-package:</p>
 
-<pre>
-foo_$GOOS.go
-foo_$GOARCH.go
-foo_$GOOS_$GOARCH.go
-</pre>
+<h2 id="more">Further reading</h2>
 
-<p>The same holds for <code>.s</code> (assembly) and <code>.c</code> files.</p>
+<p>
+See <a href="/doc/effective_go.html">Effective Go</a> for tips on writing
+clear, idiomatic Go code.
+</p>
+
+<p>
+Take <a href="http://tour.golang.org/">A Tour of Go</a> to learn the language
+proper.
+</p>
+
+<p>
+Visit the <a href="/doc/#articles">documentation page</a> for a set of in-depth
+articles about the Go language and its libraries and tools.
+</p>
diff --git a/doc/codelab/wiki/Makefile b/doc/codelab/wiki/Makefile
deleted file mode 100644
index 233917f..0000000
--- a/doc/codelab/wiki/Makefile
+++ /dev/null
@@ -1,25 +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.
-
-include ../../../src/Make.inc
-
-all: index.html
-
-include ../../../src/Make.common
-
-CLEANFILES+=srcextract.bin htmlify.bin get.bin
-
-index.html: wiki.html srcextract.bin htmlify.bin
-	PATH=.:$$PATH awk '/^!/{system(substr($$0,2)); next} {print}' < wiki.html | tr -d '\r' > index.html
-
-test: get.bin
-	bash ./test.sh
-	rm -f get.6 get.bin
-
-%.bin: %.$O
-	$(LD) -o $@ $<
-
-%.$O: %.go
-	$(GC) $(GCFLAGS) $(GCIMPORTS) $*.go
-
diff --git a/doc/codelab/wiki/final-noclosure.go b/doc/codelab/wiki/final-noclosure.go
deleted file mode 100644
index a0428d4..0000000
--- a/doc/codelab/wiki/final-noclosure.go
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-import (
-	"errors"
-	"io/ioutil"
-	"net/http"
-	"regexp"
-	"text/template"
-)
-
-type Page struct {
-	Title string
-	Body  []byte
-}
-
-func (p *Page) save() error {
-	filename := p.Title + ".txt"
-	return ioutil.WriteFile(filename, p.Body, 0600)
-}
-
-func loadPage(title string) (*Page, error) {
-	filename := title + ".txt"
-	body, err := ioutil.ReadFile(filename)
-	if err != nil {
-		return nil, err
-	}
-	return &Page{Title: title, Body: body}, nil
-}
-
-func viewHandler(w http.ResponseWriter, r *http.Request) {
-	title, err := getTitle(w, r)
-	if err != nil {
-		return
-	}
-	p, err := loadPage(title)
-	if err != nil {
-		http.Redirect(w, r, "/edit/"+title, http.StatusFound)
-		return
-	}
-	renderTemplate(w, "view", p)
-}
-
-func editHandler(w http.ResponseWriter, r *http.Request) {
-	title, err := getTitle(w, r)
-	if err != nil {
-		return
-	}
-	p, err := loadPage(title)
-	if err != nil {
-		p = &Page{Title: title}
-	}
-	renderTemplate(w, "edit", p)
-}
-
-func saveHandler(w http.ResponseWriter, r *http.Request) {
-	title, err := getTitle(w, r)
-	if err != nil {
-		return
-	}
-	body := r.FormValue("body")
-	p := &Page{Title: title, Body: []byte(body)}
-	err = p.save()
-	if err != nil {
-		http.Error(w, err.Error(), http.StatusInternalServerError)
-		return
-	}
-	http.Redirect(w, r, "/view/"+title, http.StatusFound)
-}
-
-func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
-	t, err := template.ParseFiles(tmpl + ".html")
-	if err != nil {
-		http.Error(w, err.Error(), http.StatusInternalServerError)
-		return
-	}
-	err = t.Execute(w, p)
-	if err != nil {
-		http.Error(w, err.Error(), http.StatusInternalServerError)
-	}
-}
-
-const lenPath = len("/view/")
-
-var titleValidator = regexp.MustCompile("^[a-zA-Z0-9]+$")
-
-func getTitle(w http.ResponseWriter, r *http.Request) (title string, err error) {
-	title = r.URL.Path[lenPath:]
-	if !titleValidator.MatchString(title) {
-		http.NotFound(w, r)
-		err = errors.New("Invalid Page Title")
-	}
-	return
-}
-
-func main() {
-	http.HandleFunc("/view/", viewHandler)
-	http.HandleFunc("/edit/", editHandler)
-	http.HandleFunc("/save/", saveHandler)
-	http.ListenAndServe(":8080", nil)
-}
diff --git a/doc/codelab/wiki/final-noerror.go b/doc/codelab/wiki/final-noerror.go
deleted file mode 100644
index e86bc1a..0000000
--- a/doc/codelab/wiki/final-noerror.go
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-import (
-	"io/ioutil"
-	"net/http"
-	"text/template"
-)
-
-type Page struct {
-	Title string
-	Body  []byte
-}
-
-func (p *Page) save() error {
-	filename := p.Title + ".txt"
-	return ioutil.WriteFile(filename, p.Body, 0600)
-}
-
-func loadPage(title string) (*Page, error) {
-	filename := title + ".txt"
-	body, err := ioutil.ReadFile(filename)
-	if err != nil {
-		return nil, err
-	}
-	return &Page{Title: title, Body: body}, nil
-}
-
-const lenPath = len("/view/")
-
-func editHandler(w http.ResponseWriter, r *http.Request) {
-	title := r.URL.Path[lenPath:]
-	p, err := loadPage(title)
-	if err != nil {
-		p = &Page{Title: title}
-	}
-	t, _ := template.ParseFiles("edit.html")
-	t.Execute(w, p)
-}
-
-func viewHandler(w http.ResponseWriter, r *http.Request) {
-	title := r.URL.Path[lenPath:]
-	p, _ := loadPage(title)
-	t, _ := template.ParseFiles("view.html")
-	t.Execute(w, p)
-}
-
-func main() {
-	http.HandleFunc("/view/", viewHandler)
-	http.HandleFunc("/edit/", editHandler)
-	http.ListenAndServe(":8080", nil)
-}
diff --git a/doc/codelab/wiki/final-parsetemplate.go b/doc/codelab/wiki/final-parsetemplate.go
deleted file mode 100644
index c068a61..0000000
--- a/doc/codelab/wiki/final-parsetemplate.go
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-import (
-	"io/ioutil"
-	"net/http"
-	"regexp"
-	"text/template"
-)
-
-type Page struct {
-	Title string
-	Body  []byte
-}
-
-func (p *Page) save() error {
-	filename := p.Title + ".txt"
-	return ioutil.WriteFile(filename, p.Body, 0600)
-}
-
-func loadPage(title string) (*Page, error) {
-	filename := title + ".txt"
-	body, err := ioutil.ReadFile(filename)
-	if err != nil {
-		return nil, err
-	}
-	return &Page{Title: title, Body: body}, nil
-}
-
-func viewHandler(w http.ResponseWriter, r *http.Request, title string) {
-	p, err := loadPage(title)
-	if err != nil {
-		http.Redirect(w, r, "/edit/"+title, http.StatusFound)
-		return
-	}
-	renderTemplate(w, "view", p)
-}
-
-func editHandler(w http.ResponseWriter, r *http.Request, title string) {
-	p, err := loadPage(title)
-	if err != nil {
-		p = &Page{Title: title}
-	}
-	renderTemplate(w, "edit", p)
-}
-
-func saveHandler(w http.ResponseWriter, r *http.Request, title string) {
-	body := r.FormValue("body")
-	p := &Page{Title: title, Body: []byte(body)}
-	err := p.save()
-	if err != nil {
-		http.Error(w, err.Error(), http.StatusInternalServerError)
-		return
-	}
-	http.Redirect(w, r, "/view/"+title, http.StatusFound)
-}
-
-func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
-	t, err := template.ParseFiles(tmpl+".html", nil)
-	if err != nil {
-		http.Error(w, err.Error(), http.StatusInternalServerError)
-		return
-	}
-	err = t.Execute(w, p)
-	if err != nil {
-		http.Error(w, err.Error(), http.StatusInternalServerError)
-	}
-}
-
-const lenPath = len("/view/")
-
-var titleValidator = regexp.MustCompile("^[a-zA-Z0-9]+$")
-
-func makeHandler(fn func(http.ResponseWriter, *http.Request, string)) http.HandlerFunc {
-	return func(w http.ResponseWriter, r *http.Request) {
-		title := r.URL.Path[lenPath:]
-		if !titleValidator.MatchString(title) {
-			http.NotFound(w, r)
-			return
-		}
-		fn(w, r, title)
-	}
-}
-
-func main() {
-	http.HandleFunc("/view/", makeHandler(viewHandler))
-	http.HandleFunc("/edit/", makeHandler(editHandler))
-	http.HandleFunc("/save/", makeHandler(saveHandler))
-	http.ListenAndServe(":8080", nil)
-}
diff --git a/doc/codelab/wiki/final-template.go b/doc/codelab/wiki/final-template.go
deleted file mode 100644
index 5386210..0000000
--- a/doc/codelab/wiki/final-template.go
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-import (
-	"io/ioutil"
-	"net/http"
-	"text/template"
-)
-
-type Page struct {
-	Title string
-	Body  []byte
-}
-
-func (p *Page) save() error {
-	filename := p.Title + ".txt"
-	return ioutil.WriteFile(filename, p.Body, 0600)
-}
-
-func loadPage(title string) (*Page, error) {
-	filename := title + ".txt"
-	body, err := ioutil.ReadFile(filename)
-	if err != nil {
-		return nil, err
-	}
-	return &Page{Title: title, Body: body}, nil
-}
-
-const lenPath = len("/view/")
-
-func editHandler(w http.ResponseWriter, r *http.Request) {
-	title := r.URL.Path[lenPath:]
-	p, err := loadPage(title)
-	if err != nil {
-		p = &Page{Title: title}
-	}
-	renderTemplate(w, "edit", p)
-}
-
-func viewHandler(w http.ResponseWriter, r *http.Request) {
-	title := r.URL.Path[lenPath:]
-	p, _ := loadPage(title)
-	renderTemplate(w, "view", p)
-}
-
-func saveHandler(w http.ResponseWriter, r *http.Request) {
-	title := r.URL.Path[lenPath:]
-	body := r.FormValue("body")
-	p := &Page{Title: title, Body: []byte(body)}
-	p.save()
-	http.Redirect(w, r, "/view/"+title, http.StatusFound)
-}
-
-func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
-	t, _ := template.ParseFiles(tmpl+".html", nil)
-	t.Execute(w, p)
-}
-
-func main() {
-	http.HandleFunc("/view/", viewHandler)
-	http.HandleFunc("/edit/", editHandler)
-	http.HandleFunc("/save/", saveHandler)
-	http.ListenAndServe(":8080", nil)
-}
diff --git a/doc/codelab/wiki/final.go b/doc/codelab/wiki/final.go
deleted file mode 100644
index 97f0a16..0000000
--- a/doc/codelab/wiki/final.go
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-import (
-	"io/ioutil"
-	"net/http"
-	"regexp"
-	"text/template"
-)
-
-type Page struct {
-	Title string
-	Body  []byte
-}
-
-func (p *Page) save() error {
-	filename := p.Title + ".txt"
-	return ioutil.WriteFile(filename, p.Body, 0600)
-}
-
-func loadPage(title string) (*Page, error) {
-	filename := title + ".txt"
-	body, err := ioutil.ReadFile(filename)
-	if err != nil {
-		return nil, err
-	}
-	return &Page{Title: title, Body: body}, nil
-}
-
-func viewHandler(w http.ResponseWriter, r *http.Request, title string) {
-	p, err := loadPage(title)
-	if err != nil {
-		http.Redirect(w, r, "/edit/"+title, http.StatusFound)
-		return
-	}
-	renderTemplate(w, "view", p)
-}
-
-func editHandler(w http.ResponseWriter, r *http.Request, title string) {
-	p, err := loadPage(title)
-	if err != nil {
-		p = &Page{Title: title}
-	}
-	renderTemplate(w, "edit", p)
-}
-
-func saveHandler(w http.ResponseWriter, r *http.Request, title string) {
-	body := r.FormValue("body")
-	p := &Page{Title: title, Body: []byte(body)}
-	err := p.save()
-	if err != nil {
-		http.Error(w, err.Error(), http.StatusInternalServerError)
-		return
-	}
-	http.Redirect(w, r, "/view/"+title, http.StatusFound)
-}
-
-var templates = make(map[string]*template.Template)
-
-func init() {
-	for _, tmpl := range []string{"edit", "view"} {
-		t := template.Must(template.ParseFiles(tmpl + ".html"))
-		templates[tmpl] = t
-	}
-}
-
-func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
-	err := templates[tmpl].Execute(w, p)
-	if err != nil {
-		http.Error(w, err.Error(), http.StatusInternalServerError)
-	}
-}
-
-const lenPath = len("/view/")
-
-var titleValidator = regexp.MustCompile("^[a-zA-Z0-9]+$")
-
-func makeHandler(fn func(http.ResponseWriter, *http.Request, string)) http.HandlerFunc {
-	return func(w http.ResponseWriter, r *http.Request) {
-		title := r.URL.Path[lenPath:]
-		if !titleValidator.MatchString(title) {
-			http.NotFound(w, r)
-			return
-		}
-		fn(w, r, title)
-	}
-}
-
-func main() {
-	http.HandleFunc("/view/", makeHandler(viewHandler))
-	http.HandleFunc("/edit/", makeHandler(editHandler))
-	http.HandleFunc("/save/", makeHandler(saveHandler))
-	http.ListenAndServe(":8080", nil)
-}
diff --git a/doc/codelab/wiki/index.html b/doc/codelab/wiki/index.html
deleted file mode 100644
index ae71a40..0000000
--- a/doc/codelab/wiki/index.html
+++ /dev/null
@@ -1,1007 +0,0 @@
-<!-- Codelab: Writing Web Applications -->
-<h2>Introduction</h2>
-
-<p>
-Covered in this codelab:
-</p>
-<ul>
-<li>Creating a data structure with load and save methods</li>
-<li>Using the <code>http</code> package to build web applications
-<li>Using the <code>template</code> package to process HTML templates</li>
-<li>Using the <code>regexp</code> package to validate user input</li>
-<li>Using closures</li>
-</ul>
-
-<p>
-Assumed knowledge:
-</p>
-<ul>
-<li>Programming experience</li>
-<li>Understanding of basic web technologies (HTTP, HTML)</li>
-<li>Some UNIX command-line knowledge</li>
-</ul>
-
-<h2>Getting Started</h2>
-
-<p>
-At present, you need to have a Linux, OS X, or FreeBSD machine to run Go. If
-you don't have access to one, you could set up a Linux Virtual Machine (using 
-<a href="http://www.virtualbox.org/">VirtualBox</a> or similar) or a
-<a href="http://www.google.com/search?q=virtual+private+server">Virtual 
-Private Server</a>.
-</p>
-
-<p>
-Install Go (see the <a href="http://golang.org/doc/install.html">Installation Instructions</a>).
-</p>
-
-<p>
-Make a new directory for this codelab and cd to it:
-</p>
-
-<pre>
-$ mkdir ~/gowiki
-$ cd ~/gowiki
-</pre>
-
-<p>
-Create a file named <code>wiki.go</code>, open it in your favorite editor, and 
-add the following lines:
-</p>
-
-<pre>
-package main
-
-import (
-	"fmt"
-	"io/ioutil"
-	"os"
-)
-</pre>
-
-<p>
-We import the <code>fmt</code>, <code>ioutil</code> and <code>os</code>
-packages from the Go standard library. Later, as we implement additional
-functionality, we will add more packages to this <code>import</code>
-declaration.
-</p>
-
-<h2>Data Structures</h2>
-
-<p>
-Let's start by defining the data structures. A wiki consists of a series of
-interconnected pages, each of which has a title and a body (the page content).
-Here, we define <code>Page</code> as a struct with two fields representing
-the title and body.
-</p>
-
-<pre>
-type Page struct {
-	Title	string
-	Body	[]byte
-}
-</pre>
-
-<p>
-The type <code>[]byte</code> means "a <code>byte</code> slice". 
-(See <a href="http://golang.org/doc/effective_go.html#slices">Effective Go</a> 
-for more on slices.)  
-The <code>Body</code> element is a <code>[]byte</code> rather than
-<code>string</code> because that is the type expected by the <code>io</code>
-libraries we will use, as you'll see below.
-</p>
-
-<p>
-The <code>Page</code> struct describes how page data will be stored in memory. 
-But what about persistent storage? We can address that by creating a 
-<code>save</code> method on <code>Page</code>:
-</p>
-
-<pre>
-func (p *Page) save() error {
-	filename := p.Title + ".txt"
-	return ioutil.WriteFile(filename, p.Body, 0600)
-}
-</pre>
-
-<p>
-This method's signature reads: "This is a method named <code>save</code> that
-takes as its receiver <code>p</code>, a pointer to <code>Page</code> . It takes
-no parameters, and returns a value of type <code>error</code>." 
-</p>
-
-<p>
-This method will save the <code>Page</code>'s <code>Body</code> to a text 
-file. For simplicity, we will use the <code>Title</code> as the file name.
-</p>
-
-<p>
-The <code>save</code> method returns an <code>error</code> value because
-that is the return type of <code>WriteFile</code> (a standard library function
-that writes a byte slice to a file).  The <code>save</code> method returns the
-error value, to let the application handle it should anything go wrong while
-writing the file.  If all goes well, <code>Page.save()</code> will return
-<code>nil</code> (the zero-value for pointers, interfaces, and some other 
-types).
-</p>
-
-<p>
-The octal integer constant <code>0600</code>, passed as the third parameter to
-<code>WriteFile</code>, indicates that the file should be created with
-read-write permissions for the current user only. (See the Unix man page
-<code>open(2)</code> for details.)
-</p>
-
-<p>
-We will want to load pages, too:
-</p>
-
-<pre>
-func loadPage(title string) *Page {
-	filename := title + ".txt"
-	body, _ := ioutil.ReadFile(filename)
-	return &Page{Title: title, Body: body}
-}
-</pre>
-
-<p>
-The function <code>loadPage</code> constructs the file name from
-<code>Title</code>, reads the file's contents into a new
-<code>Page</code>, and returns a pointer to that new <code>page</code>.
-</p>
-
-<p>
-Functions can return multiple values. The standard library function 
-<code>io.ReadFile</code> returns <code>[]byte</code> and <code>error</code>. 
-In <code>loadPage</code>, error isn't being handled yet; the "blank identifier"
-represented by the underscore (<code>_</code>) symbol is used to throw away the
-error return value (in essence, assigning the value to nothing). 
-</p>
-
-<p>
-But what happens if <code>ReadFile</code> encounters an error?  For example,
-the file might not exist. We should not ignore such errors.  Let's modify the
-function to return <code>*Page</code> and <code>error</code>.
-</p>
-
-<pre>
-func loadPage(title string) (*Page, error) {
-	filename := title + ".txt"
-	body, err := ioutil.ReadFile(filename)
-	if err != nil {
-		return nil, err
-	}
-	return &Page{Title: title, Body: body}, nil
-}
-</pre>
-
-<p>
-Callers of this function can now check the second parameter; if it is
-<code>nil</code> then it has successfully loaded a Page. If not, it will be an
-<code>error</code> that can be handled by the caller (see the <a
-href="http://golang.org/pkg/os/#Error">os package documentation</a> for 
-details).
-</p>
-
-<p>
-At this point we have a simple data structure and the ability to save to and
-load from a file. Let's write a <code>main</code> function to test what we've
-written:
-</p>
-
-<pre>
-func main() {
-	p1 := &Page{Title: "TestPage", Body: []byte("This is a sample Page.")}
-	p1.save()
-	p2, _ := loadPage("TestPage")
-	fmt.Println(string(p2.Body))
-}
-</pre>
-
-<p>
-After compiling and executing this code, a file named <code>TestPage.txt</code>
-would be created, containing the contents of <code>p1</code>. The file would
-then be read into the struct <code>p2</code>, and its <code>Body</code> element
-printed to the screen.
-</p>
-
-<p>
-You can compile and run the program like this: 
-</p>
-
-<pre>
-$ 8g wiki.go
-$ 8l wiki.8
-$ ./8.out
-This is a sample page.
-</pre>
-
-<p>
-(The <code>8g</code> and <code>8l</code> commands are applicable to
-<code>GOARCH=386</code>. If you're on an <code>amd64</code> system,
-substitute 6's for the 8's.)
-</p>
-
-<p>
-<a href="part1.go">Click here to view the code we've written so far.</a>
-</p>
-
-<h2>Introducing the <code>http</code> package (an interlude)</h2>
-
-<p>
-Here's a full working example of a simple web server:
-</p>
-
-<pre>
-package main
-
-import (
-	"fmt"
-	"net/http"
-)
-
-func handler(w http.ResponseWriter, r *http.Request) {
-	fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:])
-}
-
-func main() {
-	http.HandleFunc("/", handler)
-	http.ListenAndServe(":8080", nil)
-}
-</pre>
-
-<p>
-The <code>main</code> function begins with a call to 
-<code>http.HandleFunc</code>, which tells the <code>http</code> package to 
-handle all requests to the web root (<code>"/"</code>) with 
-<code>handler</code>. 
-</p>
-
-<p>
-It then calls <code>http.ListenAndServe</code>, specifying that it should
-listen on port 8080 on any interface (<code>":8080"</code>). (Don't
-worry about its second parameter, <code>nil</code>, for now.)
-This function will block until the program is terminated.
-</p>
-
-<p>
-The function <code>handler</code> is of the type <code>http.HandlerFunc</code>.
-It takes an <code>http.ResponseWriter</code> and an <code>http.Request</code> as
-its arguments.
-</p>
-
-<p>
-An <code>http.ResponseWriter</code> value assembles the HTTP server's response; by writing 
-to it, we send data to the HTTP client.
-</p>
-
-<p>
-An <code>http.Request</code> is a data structure that represents the client
-HTTP request.  The string <code>r.URL.Path</code> is the path component
-of the request URL.  The trailing <code>[1:]</code> means
-"create a sub-slice of <code>Path</code> from the 1st character to the end." 
-This drops the leading "/" from the path name.
-</p>
-
-<p>
-If you run this program and access the URL: 
-</p>
-<pre>http://localhost:8080/monkeys</pre>
-<p>
-the program would present a page containing:
-</p>
-<pre>Hi there, I love monkeys!</pre>
-
-<h2>Using <code>http</code> to serve wiki pages</h2>
-
-<p>
-To use the <code>http</code> package, it must be imported:
-</p>
-
-<pre>
-import (
-	"fmt"
-	<b>"http"</b>
-	"io/ioutil"
-	"os"
-)
-</pre>
-
-<p>
-Let's create a handler to view a wiki page: 
-</p>
-
-<pre>
-const lenPath = len("/view/")
-
-func viewHandler(w http.ResponseWriter, r *http.Request) {
-	title := r.URL.Path[lenPath:]
-	p, _ := loadPage(title)
-	fmt.Fprintf(w, "<h1>%s</h1><div>%s</div>", p.Title, p.Body)
-}
-</pre>
-
-<p>
-First, this function extracts the page title from <code>r.URL.Path</code>,
-the path component of the request URL. The global constant 
-<code>lenPath</code> is the length of the leading <code>"/view/"</code>
-component of the request path.
-The <code>Path</code> is re-sliced with <code>[lenPath:]</code> to drop the 
-first 6 characters of the string. This is because the path will invariably 
-begin with <code>"/view/"</code>, which is not part of the page title.
-</p>
-
-<p>
-The function then loads the page data, formats the page with a string of simple 
-HTML, and writes it to <code>w</code>, the <code>http.ResponseWriter</code>. 
-</p>
-
-<p>
-Again, note the use of <code>_</code> to ignore the <code>error</code> 
-return value from <code>loadPage</code>. This is done here for simplicity
-and generally considered bad practice. We will attend to this later.
-</p>
-
-<p>
-To use this handler, we create a <code>main</code> function that
-initializes <code>http</code> using the <code>viewHandler</code> to handle
-any requests under the path <code>/view/</code>.
-</p>
-
-<pre>
-func main() {
-	http.HandleFunc("/view/", viewHandler)
-	http.ListenAndServe(":8080", nil)
-}
-</pre>
-
-<p>
-<a href="part2.go">Click here to view the code we've written so far.</a>
-</p>
-
-<p>
-Let's create some page data (as <code>test.txt</code>), compile our code, and
-try serving a wiki page:
-</p>
-
-<pre>
-$ echo "Hello world" > test.txt
-$ 8g wiki.go
-$ 8l wiki.8
-$ ./8.out
-</pre>
-
-<p>
-With this web server running, a visit to <code><a
-href="http://localhost:8080/view/test">http://localhost:8080/view/test</a></code>
-should show a page titled "test" containing the words "Hello world".
-</p>
-
-<h2>Editing Pages</h2>
-
-<p>
-A wiki is not a wiki without the ability to edit pages. Let's create two new
-handlers: one named <code>editHandler</code> to display an 'edit page' form,
-and the other named <code>saveHandler</code> to save the data entered via the
-form.
-</p>
-
-<p>
-First, we add them to <code>main()</code>: 
-</p>
-
-<pre>
-func main() {
-	http.HandleFunc("/view/", viewHandler)
-	http.HandleFunc("/edit/", editHandler)
-	http.HandleFunc("/save/", saveHandler)
-	http.ListenAndServe(":8080", nil)
-}
-</pre>
-
-<p>
-The function <code>editHandler</code> loads the page 
-(or, if it doesn't exist, create an empty <code>Page</code> struct), 
-and displays an HTML form.
-</p>
-
-<pre>
-func editHandler(w http.ResponseWriter, r *http.Request) {
-	title := r.URL.Path[lenPath:]
-	p, err := loadPage(title)
-	if err != nil {
-		p = &Page{Title: title}
-	}
-	fmt.Fprintf(w, "<h1>Editing %s</h1>"+
-		"<form action=\"/save/%s\" method=\"POST\">"+
-		"<textarea name=\"body\">%s</textarea><br>"+
-		"<input type=\"submit\" value=\"Save\">"+
-		"</form>",
-		p.Title, p.Title, p.Body)
-}
-</pre>
-
-<p>
-This function will work fine, but all that hard-coded HTML is ugly.
-Of course, there is a better way.
-</p>
- 
-<h2>The <code>template</code> package</h2>
-
-<p>
-The <code>template</code> package is part of the Go standard library.
-(A new template package is coming; this code lab will be updated soon.)
-We can
-use <code>template</code> to keep the HTML in a separate file, allowing
-us to change the layout of our edit page without modifying the underlying Go
-code.
-</p>
-
-<p>
-First, we must add <code>template</code> to the list of imports:
-</p>
-
-<pre>
-import (
-	"http"
-	"io/ioutil"
-	"os"
-	<b>"template"</b>
-)
-</pre>
-
-<p>
-Let's create a template file containing the HTML form. 
-Open a new file named <code>edit.html</code>, and add the following lines:
-</p>
-
-<pre>
-<h1>Editing {{.Title |html}}</h1>
-
-<form action="/save/{{.Title |html}}" method="POST">
-<div><textarea name="body" rows="20" cols="80">{{printf "%s" .Body |html}}</textarea></div>
-<div><input type="submit" value="Save"></div>
-</form>
-</pre>
-
-<p>
-Modify <code>editHandler</code> to use the template, instead of the hard-coded
-HTML:
-</p>
-
-<pre>
-func editHandler(w http.ResponseWriter, r *http.Request) {
-	title := r.URL.Path[lenPath:]
-	p, err := loadPage(title)
-	if err != nil {
-		p = &Page{Title: title}
-	}
-	t, _ := template.ParseFiles("edit.html")
-	t.Execute(w, p)
-}
-</pre>
-
-<p>
-The function <code>template.ParseFile</code> will read the contents of 
-<code>edit.html</code> and return a <code>*template.Template</code>. 
-</p>
-
-<p>
-The method <code>t.Execute</code> executes the template, writing the
-generated HTML to the <code>http.ResponseWriter</code>.
-The <code>.Title</code> and <code>.Body</code> dotted identifiers refer to
-<code>p.Title</code> and <code>p.Body</code>.
-</p>
-
-<p>
-Template directives are enclosed in double curly braces.
-The <code>printf "%s" .Body</code> instruction is a function call
-that outputs <code>.Body</code> as a string instead of a stream of bytes,
-the same as a call to <code>fmt.Printf</code>.
-The <code>|html</code> part of each directive pipes the value through the
-<code>html</code> formatter before outputting it, which escapes HTML
-characters (such as replacing <code>></code> with <code>&gt;</code>),
-preventing user data from corrupting the form HTML. 
-</p>
-
-<p>
-Now that we've removed the <code>fmt.Fprintf</code> statement, we can remove
-<code>"fmt"</code> from the <code>import</code> list.
-</p>
-
-<p>
-While we're working with templates, let's create a template for our
-<code>viewHandler</code> called <code>view.html</code>:
-</p>
-
-<pre>
-<h1>{{.Title |html}}</h1>
-
-<p>[<a href="/edit/{{.Title |html}}">edit</a>]</p>
-
-<div>{{printf "%s" .Body |html}}</div>
-</pre>
-
-<p>
-Modify <code>viewHandler</code> accordingly:
-</p>
-
-<pre>
-func viewHandler(w http.ResponseWriter, r *http.Request) {
-	title := r.URL.Path[lenPath:]
-	p, _ := loadPage(title)
-	t, _ := template.ParseFiles("view.html")
-	t.Execute(w, p)
-}
-</pre>
-
-<p>
-Notice that we've used almost exactly the same templating code in both
-handlers. Let's remove this duplication by moving the templating code
-to its own function:
-</p>
-
-<pre>
-func viewHandler(w http.ResponseWriter, r *http.Request) {
-	title := r.URL.Path[lenPath:]
-	p, _ := loadPage(title)
-	renderTemplate(w, "view", p)
-}
-
-func editHandler(w http.ResponseWriter, r *http.Request) {
-	title := r.URL.Path[lenPath:]
-	p, err := loadPage(title)
-	if err != nil {
-		p = &Page{Title: title}
-	}
-	renderTemplate(w, "edit", p)
-}
-
-func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
-	t, _ := template.ParseFiles(tmpl+".html", nil)
-	t.Execute(w, p)
-}
-</pre>
-
-<p>
-The handlers are now shorter and simpler. 
-</p>
-
-<h2>Handling non-existent pages</h2>
-
-<p>
-What if you visit <code>/view/APageThatDoesntExist</code>? The program will 
-crash. This is because it ignores the error return value from
-<code>loadPage</code>. Instead, if the requested Page doesn't exist, it should 
-redirect the client to the edit Page so the content may be created:
-</p>
-
-<pre>
-func viewHandler(w http.ResponseWriter, r *http.Request) {
-	title, err := getTitle(w, r)
-	if err != nil {
-		return
-	}
-	p, err := loadPage(title)
-	if err != nil {
-		http.Redirect(w, r, "/edit/"+title, http.StatusFound)
-		return
-	}
-	renderTemplate(w, "view", p)
-}
-</pre>
-
-<p>
-The <code>http.Redirect</code> function adds an HTTP status code of 
-<code>http.StatusFound</code> (302) and a <code>Location</code>
-header to the HTTP response.
-</p>
-
-<h2>Saving Pages</h2>
-
-<p>
-The function <code>saveHandler</code> will handle the form submission. 
-</p>
-
-<pre>
-func saveHandler(w http.ResponseWriter, r *http.Request) {
-	title := r.URL.Path[lenPath:]
-	body := r.FormValue("body")
-	p := &Page{Title: title, Body: []byte(body)}
-	p.save()
-	http.Redirect(w, r, "/view/"+title, http.StatusFound)
-}
-</pre>
-
-<p>
-The page title (provided in the URL) and the form's only field, 
-<code>Body</code>, are stored in a new <code>Page</code>. 
-The <code>save()</code> method is then called to write the data to a file,
-and the client is redirected to the <code>/view/</code> page.
-</p>
-
-<p>
-The value returned by <code>FormValue</code> is of type <code>string</code>.
-We must convert that value to <code>[]byte</code> before it will fit into 
-the <code>Page</code> struct.  We use <code>[]byte(body)</code> to perform
-the conversion.
-</p>
-
-<h2>Error handling</h2>
-
-<p>
-There are several places in our program where errors are being ignored.  This
-is bad practice, not least because when an error does occur the program will
-crash.  A better solution is to handle the errors and return an error message
-to the user. That way if something does go wrong, the server will continue to
-function and the user will be notified.
-</p>
-
-<p>
-First, let's handle the errors in <code>renderTemplate</code>:
-</p>
-
-<pre>
-func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
-	t, err := template.ParseFiles(tmpl+".html", nil)
-	if err != nil {
-		http.Error(w, err.Error(), http.StatusInternalServerError)
-		return
-	}
-	err = t.Execute(w, p)
-	if err != nil {
-		http.Error(w, err.Error(), http.StatusInternalServerError)
-	}
-}
-</pre>
-
-<p>
-The <code>http.Error</code> function sends a specified HTTP response code 
-(in this case "Internal Server Error") and error message.
-Already the decision to put this in a separate function is paying off.
-</p>
-
-<p>
-Now let's fix up <code>saveHandler</code>:
-</p>
-
-<pre>
-func saveHandler(w http.ResponseWriter, r *http.Request) {
-	title, err := getTitle(w, r)
-	if err != nil {
-		return
-	}
-	body := r.FormValue("body")
-	p := &Page{Title: title, Body: []byte(body)}
-	err = p.save()
-	if err != nil {
-		http.Error(w, err.Error(), http.StatusInternalServerError)
-		return
-	}
-	http.Redirect(w, r, "/view/"+title, http.StatusFound)
-}
-</pre>
-
-<p>
-Any errors that occur during <code>p.save()</code> will be reported 
-to the user.
-</p>
-
-<h2>Template caching</h2>
-
-<p>
-There is an inefficiency in this code: <code>renderTemplate</code> calls 
-<code>ParseFile</code> every time a page is rendered. 
-A better approach would be to call <code>ParseFile</code> once for each 
-template at program initialization, and store the resultant 
-<code>*Template</code> values in a data structure for later use.
-</p>
-
-<p>
-First we create a global map named <code>templates</code> in which to store 
-our <code>*Template</code> values, keyed by <code>string</code> 
-(the template name):
-</p>
-
-<pre>
-var templates = make(map[string]*template.Template)
-</pre>
-
-<p>
-Then we create an <code>init</code> function, which will be called before
-<code>main</code> at program initialization. The function
-<code>template.Must</code> is a convenience wrapper that panics when passed a
-non-nil <code>error</code> value, and otherwise returns the
-<code>*Template</code> unaltered. A panic is appropriate here; if the templates
-can't be loaded the only sensible thing to do is exit the program.
-</p>
-
-<pre>
-func init() {
-	for _, tmpl := range []string{"edit", "view"} {
-		t := template.Must(template.ParseFiles(tmpl + ".html"))
-		templates[tmpl] = t
-	}
-}
-</pre>
-
-<p>
-A <code>for</code> loop is used with a <code>range</code> statement to iterate 
-over an array constant containing the names of the templates we want parsed.
-If we were to add more templates to our program, we would add their names to 
-that array.
-</p>
-
-<p>
-We then modify our <code>renderTemplate</code> function to call 
-the <code>Execute</code> method on the appropriate <code>Template</code> from 
-<code>templates</code>:
-
-<pre>
-func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
-	err := templates[tmpl].Execute(w, p)
-	if err != nil {
-		http.Error(w, err.Error(), http.StatusInternalServerError)
-	}
-}
-</pre>
-
-<h2>Validation</h2>
-
-<p>
-As you may have observed, this program has a serious security flaw: a user
-can supply an arbitrary path to be read/written on the server. To mitigate
-this, we can write a function to validate the title with a regular expression.
-</p>
-
-<p>
-First, add <code>"regexp"</code> to the <code>import</code> list.
-Then we can create a global variable to store our validation regexp:
-</p>
-
-<pre>
-var titleValidator = regexp.MustCompile("^[a-zA-Z0-9]+$")
-</pre>
-
-<p>
-The function <code>regexp.MustCompile</code> will parse and compile the 
-regular expression, and return a <code>regexp.Regexp</code>. 
-<code>MustCompile</code> is distinct from <code>Compile</code> in that it will
-panic if the expression compilation fails, while <code>Compile</code> returns
-an <code>error</code> as a second parameter. 
-</p>
-
-<p>
-Now, let's write a function that extracts the title string from the request 
-URL, and tests it against our <code>TitleValidator</code> expression:
-</p>
-
-<pre>
-func getTitle(w http.ResponseWriter, r *http.Request) (title string, err error) {
-	title = r.URL.Path[lenPath:]
-	if !titleValidator.MatchString(title) {
-		http.NotFound(w, r)
-		err = errors.New("Invalid Page Title")
-	}
-	return
-}
-</pre>
-
-<p>
-If the title is valid, it will be returned along with a <code>nil</code>
-error value.  If the title is invalid, the function will write a 
-"404 Not Found" error to the HTTP connection, and return an error to the 
-handler. 
-</p>
-
-<p>
-Let's put a call to <code>getTitle</code> in each of the handlers:
-</p>
-
-<pre>
-func viewHandler(w http.ResponseWriter, r *http.Request) {
-	title, err := getTitle(w, r)
-	if err != nil {
-		return
-	}
-	p, err := loadPage(title)
-	if err != nil {
-		http.Redirect(w, r, "/edit/"+title, http.StatusFound)
-		return
-	}
-	renderTemplate(w, "view", p)
-}
-
-func editHandler(w http.ResponseWriter, r *http.Request) {
-	title, err := getTitle(w, r)
-	if err != nil {
-		return
-	}
-	p, err := loadPage(title)
-	if err != nil {
-		p = &Page{Title: title}
-	}
-	renderTemplate(w, "edit", p)
-}
-
-func saveHandler(w http.ResponseWriter, r *http.Request) {
-	title, err := getTitle(w, r)
-	if err != nil {
-		return
-	}
-	body := r.FormValue("body")
-	p := &Page{Title: title, Body: []byte(body)}
-	err = p.save()
-	if err != nil {
-		http.Error(w, err.Error(), http.StatusInternalServerError)
-		return
-	}
-	http.Redirect(w, r, "/view/"+title, http.StatusFound)
-}
-</pre>
-
-<h2>Introducing Function Literals and Closures</h2>
-
-<p>
-Catching the error condition in each handler introduces a lot of repeated code.
-What if we could wrap each of the handlers in a function that does this 
-validation and error checking? Go's 
-<a href="http://golang.org/doc/go_spec.html#Function_declarations">function 
-literals</a> provide a powerful means of abstracting functionality 
-that can help us here.
-</p>
-
-<p>
-First, we re-write the function definition of each of the handlers to accept
-a title string:
-</p>
-
-<pre>
-func viewHandler(w http.ResponseWriter, r *http.Request, title string)
-func editHandler(w http.ResponseWriter, r *http.Request, title string)
-func saveHandler(w http.ResponseWriter, r *http.Request, title string)
-</pre>
-
-<p>
-Now let's define a wrapper function that <i>takes a function of the above
-type</i>, and returns a function of type <code>http.HandlerFunc</code>
-(suitable to be passed to the function <code>http.HandleFunc</code>):
-</p>
-
-<pre>
-func makeHandler(fn func (http.ResponseWriter, *http.Request, string)) http.HandlerFunc {
-	return func(w http.ResponseWriter, r *http.Request) {
-		// Here we will extract the page title from the Request,
-		// and call the provided handler 'fn'
-	}
-}
-</pre>
-
-<p>
-The returned function is called a closure because it encloses values defined
-outside of it. In this case, the variable <code>fn</code> (the single argument
-to <code>makeHandler</code>) is enclosed by the closure. The variable
-<code>fn</code> will be one of our save, edit, or view handlers.
-</p>
-
-<p>
-Now we can take the code from <code>getTitle</code> and use it here
-(with some minor modifications):
-</p>
-
-<pre>
-func makeHandler(fn func(http.ResponseWriter, *http.Request, string)) http.HandlerFunc {
-	return func(w http.ResponseWriter, r *http.Request) {
-		title := r.URL.Path[lenPath:]
-		if !titleValidator.MatchString(title) {
-			http.NotFound(w, r)
-			return
-		}
-		fn(w, r, title)
-	}
-}
-</pre>
-
-<p>
-The closure returned by <code>makeHandler</code> is a function that takes
-an <code>http.ResponseWriter</code> and <code>http.Request</code> (in other
-words, an <code>http.HandlerFunc</code>). 
-The closure extracts the <code>title</code> from the request path, and
-validates it with the <code>TitleValidator</code> regexp. If the
-<code>title</code> is invalid, an error will be written to the
-<code>ResponseWriter</code> using the <code>http.NotFound</code> function. 
-If the <code>title</code> is valid, the enclosed handler function
-<code>fn</code> will be called with the <code>ResponseWriter</code>,
-<code>Request</code>, and <code>title</code> as arguments.
-</p>
-
-<p>
-Now we can wrap the handler functions with <code>makeHandler</code> in 
-<code>main</code>, before they are registered with the <code>http</code> 
-package:
-</p>
-
-<pre>
-func main() {
-	http.HandleFunc("/view/", makeHandler(viewHandler))
-	http.HandleFunc("/edit/", makeHandler(editHandler))
-	http.HandleFunc("/save/", makeHandler(saveHandler))
-	http.ListenAndServe(":8080", nil)
-}
-</pre>
-
-<p>
-Finally we remove the calls to <code>getTitle</code> from the handler functions,
-making them much simpler:
-</p>
-
-<pre>
-func viewHandler(w http.ResponseWriter, r *http.Request, title string) {
-	p, err := loadPage(title)
-	if err != nil {
-		http.Redirect(w, r, "/edit/"+title, http.StatusFound)
-		return
-	}
-	renderTemplate(w, "view", p)
-}
-
-func editHandler(w http.ResponseWriter, r *http.Request, title string) {
-	p, err := loadPage(title)
-	if err != nil {
-		p = &Page{Title: title}
-	}
-	renderTemplate(w, "edit", p)
-}
-
-func saveHandler(w http.ResponseWriter, r *http.Request, title string) {
-	body := r.FormValue("body")
-	p := &Page{Title: title, Body: []byte(body)}
-	err := p.save()
-	if err != nil {
-		http.Error(w, err.Error(), http.StatusInternalServerError)
-		return
-	}
-	http.Redirect(w, r, "/view/"+title, http.StatusFound)
-}
-</pre>
-
-<h2>Try it out!</h2>
-
-<p>
-<a href="final.go">Click here to view the final code listing.</a>
-</p>
-
-<p>
-Recompile the code, and run the app:
-</p>
-
-<pre>
-$ 8g wiki.go
-$ 8l wiki.8
-$ ./8.out
-</pre>
-
-<p>
-Visiting <a href="http://localhost:8080/view/ANewPage">http://localhost:8080/view/ANewPage</a>
-should present you with the page edit form. You should then be able to 
-enter some text, click 'Save', and be redirected to the newly created page.
-</p>
-
-<h2>Other tasks</h2>
-
-<p>
-Here are some simple tasks you might want to tackle on your own:
-</p>
-
-<ul>
-<li>Store templates in <code>tmpl/</code> and page data in <code>data/</code>.
-<li>Add a handler to make the web root redirect to 
-	<code>/view/FrontPage</code>.</li>
-<li>Spruce up the page templates by making them valid HTML and adding some
-	CSS rules.</li>
-<li>Implement inter-page linking by converting instances of 
-	<code>[PageName]</code> to <br>
-	<code><a href="/view/PageName">PageName</a></code>.
-	(hint: you could use <code>regexp.ReplaceAllFunc</code> to do this)
-	</li>
-</ul>
diff --git a/doc/codelab/wiki/test.sh b/doc/codelab/wiki/test.sh
deleted file mode 100755
index ed63ff2..0000000
--- a/doc/codelab/wiki/test.sh
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env bash
-
-set -e
-wiki_pid=
-cleanup() {
-	kill $wiki_pid
-	rm -f test_*.out Test.txt final-test.bin final-test.go
-}
-trap cleanup 0 INT
-
-gomake get.bin
-addr=$(./get.bin -addr)
-sed s/:8080/$addr/ < final.go > final-test.go
-gomake final-test.bin
-(./final-test.bin) &
-wiki_pid=$!
-
-sleep 1
-
-./get.bin http://$addr/edit/Test > test_edit.out
-diff -u test_edit.out test_edit.good
-./get.bin -post=body=some%20content http://$addr/save/Test
-diff -u Test.txt test_Test.txt.good
-./get.bin http://$addr/view/Test > test_view.out
-diff -u test_view.out test_view.good
-
-echo PASS
diff --git a/doc/codelab/wiki/wiki.html b/doc/codelab/wiki/wiki.html
deleted file mode 100644
index c3dee3f..0000000
--- a/doc/codelab/wiki/wiki.html
+++ /dev/null
@@ -1,784 +0,0 @@
-<!-- Codelab: Writing Web Applications -->
-<h2>Introduction</h2>
-
-<p>
-Covered in this codelab:
-</p>
-<ul>
-<li>Creating a data structure with load and save methods</li>
-<li>Using the <code>http</code> package to build web applications
-<li>Using the <code>template</code> package to process HTML templates</li>
-<li>Using the <code>regexp</code> package to validate user input</li>
-<li>Using closures</li>
-</ul>
-
-<p>
-Assumed knowledge:
-</p>
-<ul>
-<li>Programming experience</li>
-<li>Understanding of basic web technologies (HTTP, HTML)</li>
-<li>Some UNIX command-line knowledge</li>
-</ul>
-
-<h2>Getting Started</h2>
-
-<p>
-At present, you need to have a Linux, OS X, or FreeBSD machine to run Go. If
-you don't have access to one, you could set up a Linux Virtual Machine (using 
-<a href="http://www.virtualbox.org/">VirtualBox</a> or similar) or a
-<a href="http://www.google.com/search?q=virtual+private+server">Virtual 
-Private Server</a>.
-</p>
-
-<p>
-Install Go (see the <a href="http://golang.org/doc/install.html">Installation Instructions</a>).
-</p>
-
-<p>
-Make a new directory for this codelab and cd to it:
-</p>
-
-<pre>
-$ mkdir ~/gowiki
-$ cd ~/gowiki
-</pre>
-
-<p>
-Create a file named <code>wiki.go</code>, open it in your favorite editor, and 
-add the following lines:
-</p>
-
-<pre>
-package main
-
-import (
-	"fmt"
-	"io/ioutil"
-	"os"
-)
-</pre>
-
-<p>
-We import the <code>fmt</code>, <code>ioutil</code> and <code>os</code>
-packages from the Go standard library. Later, as we implement additional
-functionality, we will add more packages to this <code>import</code>
-declaration.
-</p>
-
-<h2>Data Structures</h2>
-
-<p>
-Let's start by defining the data structures. A wiki consists of a series of
-interconnected pages, each of which has a title and a body (the page content).
-Here, we define <code>Page</code> as a struct with two fields representing
-the title and body.
-</p>
-
-<pre>
-!srcextract.bin -src=part1.go -name=Page
-</pre>
-
-<p>
-The type <code>[]byte</code> means "a <code>byte</code> slice". 
-(See <a href="http://golang.org/doc/effective_go.html#slices">Effective Go</a> 
-for more on slices.)  
-The <code>Body</code> element is a <code>[]byte</code> rather than
-<code>string</code> because that is the type expected by the <code>io</code>
-libraries we will use, as you'll see below.
-</p>
-
-<p>
-The <code>Page</code> struct describes how page data will be stored in memory. 
-But what about persistent storage? We can address that by creating a 
-<code>save</code> method on <code>Page</code>:
-</p>
-
-<pre>
-!srcextract.bin -src=part1.go -name=save
-</pre>
-
-<p>
-This method's signature reads: "This is a method named <code>save</code> that
-takes as its receiver <code>p</code>, a pointer to <code>Page</code> . It takes
-no parameters, and returns a value of type <code>error</code>." 
-</p>
-
-<p>
-This method will save the <code>Page</code>'s <code>Body</code> to a text 
-file. For simplicity, we will use the <code>Title</code> as the file name.
-</p>
-
-<p>
-The <code>save</code> method returns an <code>error</code> value because
-that is the return type of <code>WriteFile</code> (a standard library function
-that writes a byte slice to a file).  The <code>save</code> method returns the
-error value, to let the application handle it should anything go wrong while
-writing the file.  If all goes well, <code>Page.save()</code> will return
-<code>nil</code> (the zero-value for pointers, interfaces, and some other 
-types).
-</p>
-
-<p>
-The octal integer constant <code>0600</code>, passed as the third parameter to
-<code>WriteFile</code>, indicates that the file should be created with
-read-write permissions for the current user only. (See the Unix man page
-<code>open(2)</code> for details.)
-</p>
-
-<p>
-We will want to load pages, too:
-</p>
-
-<pre>
-!srcextract.bin -src=part1-noerror.go -name=loadPage
-</pre>
-
-<p>
-The function <code>loadPage</code> constructs the file name from
-<code>Title</code>, reads the file's contents into a new
-<code>Page</code>, and returns a pointer to that new <code>page</code>.
-</p>
-
-<p>
-Functions can return multiple values. The standard library function 
-<code>io.ReadFile</code> returns <code>[]byte</code> and <code>error</code>. 
-In <code>loadPage</code>, error isn't being handled yet; the "blank identifier"
-represented by the underscore (<code>_</code>) symbol is used to throw away the
-error return value (in essence, assigning the value to nothing). 
-</p>
-
-<p>
-But what happens if <code>ReadFile</code> encounters an error?  For example,
-the file might not exist. We should not ignore such errors.  Let's modify the
-function to return <code>*Page</code> and <code>error</code>.
-</p>
-
-<pre>
-!srcextract.bin -src=part1.go -name=loadPage
-</pre>
-
-<p>
-Callers of this function can now check the second parameter; if it is
-<code>nil</code> then it has successfully loaded a Page. If not, it will be an
-<code>error</code> that can be handled by the caller (see the <a
-href="http://golang.org/pkg/os/#Error">os package documentation</a> for 
-details).
-</p>
-
-<p>
-At this point we have a simple data structure and the ability to save to and
-load from a file. Let's write a <code>main</code> function to test what we've
-written:
-</p>
-
-<pre>
-!srcextract.bin -src=part1.go -name=main
-</pre>
-
-<p>
-After compiling and executing this code, a file named <code>TestPage.txt</code>
-would be created, containing the contents of <code>p1</code>. The file would
-then be read into the struct <code>p2</code>, and its <code>Body</code> element
-printed to the screen.
-</p>
-
-<p>
-You can compile and run the program like this: 
-</p>
-
-<pre>
-$ 8g wiki.go
-$ 8l wiki.8
-$ ./8.out
-This is a sample page.
-</pre>
-
-<p>
-(The <code>8g</code> and <code>8l</code> commands are applicable to
-<code>GOARCH=386</code>. If you're on an <code>amd64</code> system,
-substitute 6's for the 8's.)
-</p>
-
-<p>
-<a href="part1.go">Click here to view the code we've written so far.</a>
-</p>
-
-<h2>Introducing the <code>http</code> package (an interlude)</h2>
-
-<p>
-Here's a full working example of a simple web server:
-</p>
-
-<pre>
-!htmlify.bin < http-sample.go
-</pre>
-
-<p>
-The <code>main</code> function begins with a call to 
-<code>http.HandleFunc</code>, which tells the <code>http</code> package to 
-handle all requests to the web root (<code>"/"</code>) with 
-<code>handler</code>. 
-</p>
-
-<p>
-It then calls <code>http.ListenAndServe</code>, specifying that it should
-listen on port 8080 on any interface (<code>":8080"</code>). (Don't
-worry about its second parameter, <code>nil</code>, for now.)
-This function will block until the program is terminated.
-</p>
-
-<p>
-The function <code>handler</code> is of the type <code>http.HandlerFunc</code>.
-It takes an <code>http.ResponseWriter</code> and an <code>http.Request</code> as
-its arguments.
-</p>
-
-<p>
-An <code>http.ResponseWriter</code> value assembles the HTTP server's response; by writing 
-to it, we send data to the HTTP client.
-</p>
-
-<p>
-An <code>http.Request</code> is a data structure that represents the client
-HTTP request.  The string <code>r.URL.Path</code> is the path component
-of the request URL.  The trailing <code>[1:]</code> means
-"create a sub-slice of <code>Path</code> from the 1st character to the end." 
-This drops the leading "/" from the path name.
-</p>
-
-<p>
-If you run this program and access the URL: 
-</p>
-<pre>http://localhost:8080/monkeys</pre>
-<p>
-the program would present a page containing:
-</p>
-<pre>Hi there, I love monkeys!</pre>
-
-<h2>Using <code>http</code> to serve wiki pages</h2>
-
-<p>
-To use the <code>http</code> package, it must be imported:
-</p>
-
-<pre>
-import (
-	"fmt"
-	<b>"http"</b>
-	"io/ioutil"
-	"os"
-)
-</pre>
-
-<p>
-Let's create a handler to view a wiki page: 
-</p>
-
-<pre>
-!srcextract.bin -src=part2.go -name=lenPath
-
-!srcextract.bin -src=part2.go -name=viewHandler
-</pre>
-
-<p>
-First, this function extracts the page title from <code>r.URL.Path</code>,
-the path component of the request URL. The global constant 
-<code>lenPath</code> is the length of the leading <code>"/view/"</code>
-component of the request path.
-The <code>Path</code> is re-sliced with <code>[lenPath:]</code> to drop the 
-first 6 characters of the string. This is because the path will invariably 
-begin with <code>"/view/"</code>, which is not part of the page title.
-</p>
-
-<p>
-The function then loads the page data, formats the page with a string of simple 
-HTML, and writes it to <code>w</code>, the <code>http.ResponseWriter</code>. 
-</p>
-
-<p>
-Again, note the use of <code>_</code> to ignore the <code>error</code> 
-return value from <code>loadPage</code>. This is done here for simplicity
-and generally considered bad practice. We will attend to this later.
-</p>
-
-<p>
-To use this handler, we create a <code>main</code> function that
-initializes <code>http</code> using the <code>viewHandler</code> to handle
-any requests under the path <code>/view/</code>.
-</p>
-
-<pre>
-!srcextract.bin -src=part2.go -name=main
-</pre>
-
-<p>
-<a href="part2.go">Click here to view the code we've written so far.</a>
-</p>
-
-<p>
-Let's create some page data (as <code>test.txt</code>), compile our code, and
-try serving a wiki page:
-</p>
-
-<pre>
-$ echo "Hello world" > test.txt
-$ 8g wiki.go
-$ 8l wiki.8
-$ ./8.out
-</pre>
-
-<p>
-With this web server running, a visit to <code><a
-href="http://localhost:8080/view/test">http://localhost:8080/view/test</a></code>
-should show a page titled "test" containing the words "Hello world".
-</p>
-
-<h2>Editing Pages</h2>
-
-<p>
-A wiki is not a wiki without the ability to edit pages. Let's create two new
-handlers: one named <code>editHandler</code> to display an 'edit page' form,
-and the other named <code>saveHandler</code> to save the data entered via the
-form.
-</p>
-
-<p>
-First, we add them to <code>main()</code>: 
-</p>
-
-<pre>
-!srcextract.bin -src=final-noclosure.go -name=main
-</pre>
-
-<p>
-The function <code>editHandler</code> loads the page 
-(or, if it doesn't exist, create an empty <code>Page</code> struct), 
-and displays an HTML form.
-</p>
-
-<pre>
-!srcextract.bin -src=notemplate.go -name=editHandler
-</pre>
-
-<p>
-This function will work fine, but all that hard-coded HTML is ugly.
-Of course, there is a better way.
-</p>
- 
-<h2>The <code>template</code> package</h2>
-
-<p>
-The <code>template</code> package is part of the Go standard library.
-(A new template package is coming; this code lab will be updated soon.)
-We can
-use <code>template</code> to keep the HTML in a separate file, allowing
-us to change the layout of our edit page without modifying the underlying Go
-code.
-</p>
-
-<p>
-First, we must add <code>template</code> to the list of imports:
-</p>
-
-<pre>
-import (
-	"http"
-	"io/ioutil"
-	"os"
-	<b>"template"</b>
-)
-</pre>
-
-<p>
-Let's create a template file containing the HTML form. 
-Open a new file named <code>edit.html</code>, and add the following lines:
-</p>
-
-<pre>
-!htmlify.bin < edit.html
-</pre>
-
-<p>
-Modify <code>editHandler</code> to use the template, instead of the hard-coded
-HTML:
-</p>
-
-<pre>
-!srcextract.bin -src=final-noerror.go -name=editHandler
-</pre>
-
-<p>
-The function <code>template.ParseFile</code> will read the contents of 
-<code>edit.html</code> and return a <code>*template.Template</code>. 
-</p>
-
-<p>
-The method <code>t.Execute</code> executes the template, writing the
-generated HTML to the <code>http.ResponseWriter</code>.
-The <code>.Title</code> and <code>.Body</code> dotted identifiers refer to
-<code>p.Title</code> and <code>p.Body</code>.
-</p>
-
-<p>
-Template directives are enclosed in double curly braces.
-The <code>printf "%s" .Body</code> instruction is a function call
-that outputs <code>.Body</code> as a string instead of a stream of bytes,
-the same as a call to <code>fmt.Printf</code>.
-The <code>|html</code> part of each directive pipes the value through the
-<code>html</code> formatter before outputting it, which escapes HTML
-characters (such as replacing <code>></code> with <code>&gt;</code>),
-preventing user data from corrupting the form HTML. 
-</p>
-
-<p>
-Now that we've removed the <code>fmt.Fprintf</code> statement, we can remove
-<code>"fmt"</code> from the <code>import</code> list.
-</p>
-
-<p>
-While we're working with templates, let's create a template for our
-<code>viewHandler</code> called <code>view.html</code>:
-</p>
-
-<pre>
-!htmlify.bin < view.html
-</pre>
-
-<p>
-Modify <code>viewHandler</code> accordingly:
-</p>
-
-<pre>
-!srcextract.bin -src=final-noerror.go -name=viewHandler
-</pre>
-
-<p>
-Notice that we've used almost exactly the same templating code in both
-handlers. Let's remove this duplication by moving the templating code
-to its own function:
-</p>
-
-<pre>
-!srcextract.bin -src=final-template.go -name=viewHandler
-
-!srcextract.bin -src=final-template.go -name=editHandler
-
-!srcextract.bin -src=final-template.go -name=renderTemplate
-</pre>
-
-<p>
-The handlers are now shorter and simpler. 
-</p>
-
-<h2>Handling non-existent pages</h2>
-
-<p>
-What if you visit <code>/view/APageThatDoesntExist</code>? The program will 
-crash. This is because it ignores the error return value from
-<code>loadPage</code>. Instead, if the requested Page doesn't exist, it should 
-redirect the client to the edit Page so the content may be created:
-</p>
-
-<pre>
-!srcextract.bin -src=final-noclosure.go -name=viewHandler
-</pre>
-
-<p>
-The <code>http.Redirect</code> function adds an HTTP status code of 
-<code>http.StatusFound</code> (302) and a <code>Location</code>
-header to the HTTP response.
-</p>
-
-<h2>Saving Pages</h2>
-
-<p>
-The function <code>saveHandler</code> will handle the form submission. 
-</p>
-
-<pre>
-!srcextract.bin -src=final-template.go -name=saveHandler
-</pre>
-
-<p>
-The page title (provided in the URL) and the form's only field, 
-<code>Body</code>, are stored in a new <code>Page</code>. 
-The <code>save()</code> method is then called to write the data to a file,
-and the client is redirected to the <code>/view/</code> page.
-</p>
-
-<p>
-The value returned by <code>FormValue</code> is of type <code>string</code>.
-We must convert that value to <code>[]byte</code> before it will fit into 
-the <code>Page</code> struct.  We use <code>[]byte(body)</code> to perform
-the conversion.
-</p>
-
-<h2>Error handling</h2>
-
-<p>
-There are several places in our program where errors are being ignored.  This
-is bad practice, not least because when an error does occur the program will
-crash.  A better solution is to handle the errors and return an error message
-to the user. That way if something does go wrong, the server will continue to
-function and the user will be notified.
-</p>
-
-<p>
-First, let's handle the errors in <code>renderTemplate</code>:
-</p>
-
-<pre>
-!srcextract.bin -src=final-parsetemplate.go -name=renderTemplate
-</pre>
-
-<p>
-The <code>http.Error</code> function sends a specified HTTP response code 
-(in this case "Internal Server Error") and error message.
-Already the decision to put this in a separate function is paying off.
-</p>
-
-<p>
-Now let's fix up <code>saveHandler</code>:
-</p>
-
-<pre>
-!srcextract.bin -src=final-noclosure.go -name=saveHandler
-</pre>
-
-<p>
-Any errors that occur during <code>p.save()</code> will be reported 
-to the user.
-</p>
-
-<h2>Template caching</h2>
-
-<p>
-There is an inefficiency in this code: <code>renderTemplate</code> calls 
-<code>ParseFile</code> every time a page is rendered. 
-A better approach would be to call <code>ParseFile</code> once for each 
-template at program initialization, and store the resultant 
-<code>*Template</code> values in a data structure for later use.
-</p>
-
-<p>
-First we create a global map named <code>templates</code> in which to store 
-our <code>*Template</code> values, keyed by <code>string</code> 
-(the template name):
-</p>
-
-<pre>
-!srcextract.bin -src=final.go -name=templates
-</pre>
-
-<p>
-Then we create an <code>init</code> function, which will be called before
-<code>main</code> at program initialization. The function
-<code>template.Must</code> is a convenience wrapper that panics when passed a
-non-nil <code>error</code> value, and otherwise returns the
-<code>*Template</code> unaltered. A panic is appropriate here; if the templates
-can't be loaded the only sensible thing to do is exit the program.
-</p>
-
-<pre>
-!srcextract.bin -src=final.go -name=init
-</pre>
-
-<p>
-A <code>for</code> loop is used with a <code>range</code> statement to iterate 
-over an array constant containing the names of the templates we want parsed.
-If we were to add more templates to our program, we would add their names to 
-that array.
-</p>
-
-<p>
-We then modify our <code>renderTemplate</code> function to call 
-the <code>Execute</code> method on the appropriate <code>Template</code> from 
-<code>templates</code>:
-
-<pre>
-!srcextract.bin -src=final.go -name=renderTemplate
-</pre>
-
-<h2>Validation</h2>
-
-<p>
-As you may have observed, this program has a serious security flaw: a user
-can supply an arbitrary path to be read/written on the server. To mitigate
-this, we can write a function to validate the title with a regular expression.
-</p>
-
-<p>
-First, add <code>"regexp"</code> to the <code>import</code> list.
-Then we can create a global variable to store our validation regexp:
-</p>
-
-<pre>
-!srcextract.bin -src=final-noclosure.go -name=titleValidator
-</pre>
-
-<p>
-The function <code>regexp.MustCompile</code> will parse and compile the 
-regular expression, and return a <code>regexp.Regexp</code>. 
-<code>MustCompile</code> is distinct from <code>Compile</code> in that it will
-panic if the expression compilation fails, while <code>Compile</code> returns
-an <code>error</code> as a second parameter. 
-</p>
-
-<p>
-Now, let's write a function that extracts the title string from the request 
-URL, and tests it against our <code>TitleValidator</code> expression:
-</p>
-
-<pre>
-!srcextract.bin -src=final-noclosure.go -name=getTitle
-</pre>
-
-<p>
-If the title is valid, it will be returned along with a <code>nil</code>
-error value.  If the title is invalid, the function will write a 
-"404 Not Found" error to the HTTP connection, and return an error to the 
-handler. 
-</p>
-
-<p>
-Let's put a call to <code>getTitle</code> in each of the handlers:
-</p>
-
-<pre>
-!srcextract.bin -src=final-noclosure.go -name=viewHandler
-
-!srcextract.bin -src=final-noclosure.go -name=editHandler
-
-!srcextract.bin -src=final-noclosure.go -name=saveHandler
-</pre>
-
-<h2>Introducing Function Literals and Closures</h2>
-
-<p>
-Catching the error condition in each handler introduces a lot of repeated code.
-What if we could wrap each of the handlers in a function that does this 
-validation and error checking? Go's 
-<a href="http://golang.org/doc/go_spec.html#Function_declarations">function 
-literals</a> provide a powerful means of abstracting functionality 
-that can help us here.
-</p>
-
-<p>
-First, we re-write the function definition of each of the handlers to accept
-a title string:
-</p>
-
-<pre>
-func viewHandler(w http.ResponseWriter, r *http.Request, title string)
-func editHandler(w http.ResponseWriter, r *http.Request, title string)
-func saveHandler(w http.ResponseWriter, r *http.Request, title string)
-</pre>
-
-<p>
-Now let's define a wrapper function that <i>takes a function of the above
-type</i>, and returns a function of type <code>http.HandlerFunc</code>
-(suitable to be passed to the function <code>http.HandleFunc</code>):
-</p>
-
-<pre>
-func makeHandler(fn func (http.ResponseWriter, *http.Request, string)) http.HandlerFunc {
-	return func(w http.ResponseWriter, r *http.Request) {
-		// Here we will extract the page title from the Request,
-		// and call the provided handler 'fn'
-	}
-}
-</pre>
-
-<p>
-The returned function is called a closure because it encloses values defined
-outside of it. In this case, the variable <code>fn</code> (the single argument
-to <code>makeHandler</code>) is enclosed by the closure. The variable
-<code>fn</code> will be one of our save, edit, or view handlers.
-</p>
-
-<p>
-Now we can take the code from <code>getTitle</code> and use it here
-(with some minor modifications):
-</p>
-
-<pre>
-!srcextract.bin -src=final.go -name=makeHandler
-</pre>
-
-<p>
-The closure returned by <code>makeHandler</code> is a function that takes
-an <code>http.ResponseWriter</code> and <code>http.Request</code> (in other
-words, an <code>http.HandlerFunc</code>). 
-The closure extracts the <code>title</code> from the request path, and
-validates it with the <code>TitleValidator</code> regexp. If the
-<code>title</code> is invalid, an error will be written to the
-<code>ResponseWriter</code> using the <code>http.NotFound</code> function. 
-If the <code>title</code> is valid, the enclosed handler function
-<code>fn</code> will be called with the <code>ResponseWriter</code>,
-<code>Request</code>, and <code>title</code> as arguments.
-</p>
-
-<p>
-Now we can wrap the handler functions with <code>makeHandler</code> in 
-<code>main</code>, before they are registered with the <code>http</code> 
-package:
-</p>
-
-<pre>
-!srcextract.bin -src=final.go -name=main
-</pre>
-
-<p>
-Finally we remove the calls to <code>getTitle</code> from the handler functions,
-making them much simpler:
-</p>
-
-<pre>
-!srcextract.bin -src=final.go -name=viewHandler
-
-!srcextract.bin -src=final.go -name=editHandler
-
-!srcextract.bin -src=final.go -name=saveHandler
-</pre>
-
-<h2>Try it out!</h2>
-
-<p>
-<a href="final.go">Click here to view the final code listing.</a>
-</p>
-
-<p>
-Recompile the code, and run the app:
-</p>
-
-<pre>
-$ 8g wiki.go
-$ 8l wiki.8
-$ ./8.out
-</pre>
-
-<p>
-Visiting <a href="http://localhost:8080/view/ANewPage">http://localhost:8080/view/ANewPage</a>
-should present you with the page edit form. You should then be able to 
-enter some text, click 'Save', and be redirected to the newly created page.
-</p>
-
-<h2>Other tasks</h2>
-
-<p>
-Here are some simple tasks you might want to tackle on your own:
-</p>
-
-<ul>
-<li>Store templates in <code>tmpl/</code> and page data in <code>data/</code>.
-<li>Add a handler to make the web root redirect to 
-	<code>/view/FrontPage</code>.</li>
-<li>Spruce up the page templates by making them valid HTML and adding some
-	CSS rules.</li>
-<li>Implement inter-page linking by converting instances of 
-	<code>[PageName]</code> to <br>
-	<code><a href="/view/PageName">PageName</a></code>.
-	(hint: you could use <code>regexp.ReplaceAllFunc</code> to do this)
-	</li>
-</ul>
diff --git a/doc/contrib.html b/doc/contrib.html
index f6789b1..76cee1f 100644
--- a/doc/contrib.html
+++ b/doc/contrib.html
@@ -3,22 +3,27 @@
 	"Path": "/project/"
 }-->
 
-<h2 id="the_go_project">The Go Project</h2>
+<div id="manual-nav"></div>
 
-<h3 id="source"><a href="https://code.google.com/p/go/source">Source Code</a></h3>
-<p>Check out the Go source code.</p>
+<p>
+Go is an open source project developed by a team at
+<a href="http://google.com/">Google</a> and many
+<a href="/CONTRIBUTORS">contributors</a> from the open source community.
+</p>
 
-<h3 id="build_status"><a href="http://build.golang.org/">Build Status</a></h3>
-<p>View the status of Go builds across the supported operating
-systems and architectures.</p>
+<p>
+Go is distributed under a <a href="/LICENSE">BSD-style license</a>.
+</p>
+
+<h2 id="resources">Developer Resources</h2>
 
-<h3 id="roadmap"><a href="/doc/devel/roadmap.html">Roadmap</a></h3>
-<p>Features and ideas being developed or discussed by the Go team.</p>
+<h3 id="source"><a href="https://code.google.com/p/go/source">Source Code</a></h3>
+<p>Check out the Go source code.</p>
 
 <h3 id="release"><a href="/doc/devel/release.html">Release History</a></h3>
 <p>A summary of the changes between Go releases.</p>
 
-<h3 id="release"><a href="/doc/devel/weekly.html">Weekly Snapshot History</a></h3>
+<h3 id="weekly"><a href="/doc/devel/weekly.html">Weekly Snapshot History</a></h3>
 <p>A summary of the changes between weekly snapshots of Go.</p>
 
 <h3 id="golang-dev"><a href="http://groups.google.com/group/golang-dev">Developer Mailing List</a></h3>
@@ -30,6 +35,11 @@ href="http://groups.google.com/group/golang-nuts">golang-nuts</a>.</p>
 <h3 id="golang-checkins"><a href="http://groups.google.com/group/golang-checkins">Checkins Mailing List</a></h3>
 <p>A mailing list that receives a message summarizing each checkin to the Go repository.</p>
 
+<h3 id="build_status"><a href="http://build.golang.org/">Build Status</a></h3>
+<p>View the status of Go builds across the supported operating
+systems and architectures.</p>
+
+
 <h2 id="howto">How you can help</h2>
 
 <h3><a href="http://code.google.com/p/go/issues">Reporting issues</a></h3>
@@ -62,3 +72,26 @@ open issues that interest you. Those labeled
 <a href="http://code.google.com/p/go/issues/list?q=status=HelpWanted">HelpWanted</a>
 are particularly in need of outside help.
 </p>
+
+
+<h2 id="community">The Go Community</h2>
+
+<h3 id="mailinglist"><a href="http://groups.google.com/group/golang-nuts">Go Nuts Mailing List</a></h3>
+<p>The <a href="http://groups.google.com/group/golang-nuts">golang-nuts</a> 
+mailing list is for general Go discussion.</p>
+
+<h3 id="projects"><a href="http://godashboard.appspot.com/project">Go Project Dashboard</a></h3>
+<p>A list of external Go projects including programs and libraries.</p>
+
+<h3 id="irc"><a href="irc:irc.freenode.net/go-nuts">Go IRC Channel</a></h3>
+<p><b>#go-nuts</b> on <b>irc.freenode.net</b> is the official Go IRC channel.</p>
+
+<h3 id="plus"><a href="https://plus.google.com/101406623878176903605/posts">The Go Programming Language at Google+</a></h3>
+<p>The Go project's Google+ page.</p>
+
+<h3 id="twitter"><a href="http://twitter.com/go_nuts">@go_nuts at Twitter</a></h3>
+<p>The Go project's official Twitter account.</p>
+
+<h3 id="blog"><a href="http://blog.golang.org/">The Go Blog</a></h3>
+<p>The official blog of the Go project, featuring news and in-depth articles by
+the Go team and guests.</p>
diff --git a/doc/contribute.html b/doc/contribute.html
index 5af9af4..73233c5 100644
--- a/doc/contribute.html
+++ b/doc/contribute.html
@@ -7,7 +7,7 @@
 <p>
 This document explains how to contribute changes to the Go project.
 It assumes you have installed Go using the
-<a href="install.html">installation instructions</a> and
+<a href="/doc/install">installation instructions</a> and
 have <a href="code.html">written and tested your code</a>.
 (Note that the <code>gccgo</code> frontend lives elsewhere;
 see <a href="gccgo_contribute.html">Contributing to gccgo</a>.)
diff --git a/doc/debugging_with_gdb.html b/doc/debugging_with_gdb.html
index d5c1a88..43977b7 100644
--- a/doc/debugging_with_gdb.html
+++ b/doc/debugging_with_gdb.html
@@ -1,5 +1,6 @@
 <!--{
-	"Title": "Debugging Go Code with GDB"
+	"Title": "Debugging Go Code with GDB",
+	"Path": "/ref/gdb"
 }-->
 
 <p><i>
diff --git a/doc/devel/index.html b/doc/devel/index.html
deleted file mode 100644
index 7fcfe8d..0000000
--- a/doc/devel/index.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<!-- The Go project -->
-
-<ul>
-<li><a href="roadmap.html">Roadmap</a></li>
-<li><a href="release.html">Release history</a></li>
-<li><a href="weekly.html">Weekly snapshot history</a></li>
-<li><a href="http://build.golang.org/">Build status</a></li>
-</ul>
-<ul>
-<li><a href="../contribute.html">Contributing code</a></li>
-</ul>
diff --git a/doc/devel/roadmap.html b/doc/devel/roadmap.html
deleted file mode 100644
index d3c4947..0000000
--- a/doc/devel/roadmap.html
+++ /dev/null
@@ -1,135 +0,0 @@
-<!-- Roadmap -->
-
-<h2 id="Roadmap">Go Roadmap</h2>
-
-<p>
-This page lists features and ideas being developed or discussed by the
-Go team.  This list will be updated as work continues.
-
-<p>
-The roadmap should be discussed on
-the <a href="http://groups.google.com/group/golang-nuts">golang-nuts
-mailing list</a>.
-
-<h3 id="Language_roadmap">
-Language roadmap</h3>
-
-<p>
-This is a list of language changes that are being considered.
-Appearance on this list is no guarantee that the change will be
-accepted.
-
-<ul>
-<li>
-Possibly rewrite restriction on goto across variable declarations.
-<li>
-Variant types.  A way to define a type as being the union of some set
-of types.
-<li>
-Generics.  An active topic of discussion.
-<li>
-Methods for operators, to allow a type to use arithmetic notation for
-expressions.
-<li>
-Possibly allow top-level packages to be given names other than main.
-</ul>
-
-<h3 id="Implementation_roadmap">
-Implementation roadmap</h3>
-
-<ul>
-<li>
-Improved garbage collector.
-<li>
-Debugger.
-<li>
-Improved implementation documentation.
-</ul>
-
-<h4 id="Gc_roadmap">
-Gc compiler roadmap</h4>
-
-<ul>
-<li>
-Implement goto restrictions.
-<li>
-Improved optimization.
-<li>
-Use escape analysis to keep more data on stack.
-</ul>
-
-<h4 id="Gccgo_roadmap">
-Gccgo compiler roadmap</h4>
-
-<ul>
-<li>
-Implement goto restrictions.
-<li>
-Use goroutines rather than threads.
-<li>
-Separate gcc interface from frontend proper.
-<li>
-Use escape analysis to keep more data on stack.
-</ul>
-
-<h4 id="Tools_roadmap">
-Tools roadmap</h4>
-
-<ul>
-<li>
-Strengthen goinstall until it can displace make for most builds.
-</ul>
-
-<h4 id="Packages_roadmap">
-Packages roadmap</h4>
-
-<ul>
-<li>
-Faster, RE2-like regular expressions.
-<li>
-Comprehensive support for international text.
-<li>
-Support for international dates, times, etc.
-<li>
-Support for multilingual messages.
-</ul>
-
-
-<h3 id="done">Done</h3>
-
-<ul>
-<li>
-gc: Generate DWARF debug info.
-<li>
-gc: Provide gdb support for runtime facilities.
-<li>
-Safe compilation mode: generate code that is guaranteed not to obtain an invalid memory address other than via <code>import "unsafe"</code>.
-<li>
-Gccgo: garbage collection.
-<li>
-SWIG support.
-<li>		
-Simpler semicolon rules.
-<li>		
-A more general definition of <code>...</code> in parameter lists.
-<li>		
-Explicit conversions from <code>string</code>		
-to <code>[]byte</code> and <code>[]int</code>.		
-<li>
-A function that will be run by the garbage collector when an item is freed
-(runtime.SetFinalizer).
-<li>
-Public continuous build and benchmark infrastructure (gobuilder).
-<li>
-Package manager (goinstall).
-<li>
-A means of recovering from a panic (recover).
-<li>
-5g: Better floating point support.
-<li>
-Improved CGO including some mechanism for calling back from C to Go.
-<li>
-Faster, allocation-light reflection.
-<li>
-App Engine support.
-</ul>
diff --git a/doc/devel/weekly.html b/doc/devel/weekly.html
index 032a1e9..ba88c36 100644
--- a/doc/devel/weekly.html
+++ b/doc/devel/weekly.html
@@ -14,6 +14,124 @@ hg pull
 hg update weekly.<i>YYYY-MM-DD</i>
 </pre>
 
+<h2 id="2012-03-04">2012-03-04</h2>
+
+<pre>
+This snapshot includes a major re-design of the go/build package.
+Its FindTree, ScanDir, Tree, and DirInfo types have been replaced with the
+Import and Package types. There is no gofix. Code that uses go/build will need
+to be updated manually to use the package's new interface.
+
+Other changes:
+* 6a/6l: add IMUL3Q and SHLDL.
+* all: remove unused unexported functions and constants (thanks Rémy Oudompheng).
+* build: add GO_ prefix to LDFLAGS and GCFLAGS (thanks Gustavo Niemeyer).
+* cmd/cc: fix an out of bounds array access (thanks Anthony Martin),
+	grow some global arrays.
+* cmd/dist: force line-buffering stdout/stderr on Unix (thanks Shenghou Ma),
+	recognize CC="ccache clang" as clang.
+* cmd/go: avoid repeated include dirs (thanks Rémy Oudompheng),
+	fix -I flag for gc command (thanks Gustavo Niemeyer),
+	fix verbose command displaying (thanks Gustavo Niemeyer),
+	fixes for gccgo (thanks Rémy Oudompheng),
+	many fixes,
+	test -i should not disable -c (thanks Shenghou Ma).
+* cmd/vet: don't give error for Printf("%+5.2e", x) (thanks Shenghou Ma).
+* cmd/yacc/units.y: update comment, give better error messages when $GOROOT not set (thanks Shenghou Ma).
+* crypto/tls: force OS X target version to 10.6 for API compatibility (thanks Mikkel Krautz).
+* crypto/x509: fix typo in Verify documentation (thanks Mikkel Krautz).
+* dist: treat CC as one unit (thanks Scott Lawrence).
+* doc/go1: add justification discussions to major changes,
+	minor corrections and updates.
+* doc: describe API changes to go/build,
+	elaborate available checks for cmd/vet (thanks Shenghou Ma),
+	expand code.html to discuss the go tool in more depth,
+	instruct FreeBSD/Linux users to rm the old version first,
+	remove Go for C++ Programmers,
+	remove roadmap document,
+	remove tutorial,
+	update codelab/wiki to Go 1 (thanks Shenghou Ma),
+* encoding/gob: fix "// +build" comment for debug.go (thanks Shenghou Ma),
+	more hardening for lengths of input strings.
+* encoding/json: drop MarshalForHTML; gofix calls to Marshal,
+	escape output from Marshalers.
+* encoding/xml: fix anonymous field Unmarshal example (thanks Gustavo Niemeyer),
+	fix xml test tag usage (thanks Gustavo Niemeyer).
+* gc: disallow absolute import paths,
+	fix escape analysis + inlining + closure bug,
+	fix string comparisons for new bool rules (thanks Anthony Martin),
+	reject import paths containing special characters (thanks Anthony Martin).
+* go/ast: examples for ast.Print, ast.Inspect.
+* go/doc, godoc: fix range of type declarations.
+* go/parser: check import path restrictions,
+	expand test cases for bad import.
+* go/printer, gofmt: improved comment placement.
+* go/printer: fix printing of variadic function calls (thanks Anthony Martin),
+	fix test for new import path restrictions (thanks Anthony Martin),
+	replace multiline logic,
+	simpler exprList code, more tests.
+* godoc: add Examples link to top-level index,
+	bring back highlighting, selections, and alerts,
+	consistent placement of documentation sections,
+	don't show directories w/o packages in flat dir mode,
+	don't show testdata directories,
+	fix codewalks.
+* gotype: provide -comments flag.
+* html/template: make doctype check case-insensitive (thanks Scott Lawrence),
+	use correct method signature in introduction example (thanks Mike Rosset).
+* io: document that I/O is not necessarily safe for parallel access.
+* ld: allow more -L options (thanks Shenghou Ma),
+	fix alignment of rodata section.
+* misc: add zsh completion for go tool (thanks Rémy Oudompheng).
+* misc/bash: Completion for go tool (thanks Yissakhar Z. Beck).
+* misc/dashboard: fix bug in UI template,
+	record install counts for external packages.
+* misc/dist: implement binary distribution scripts in go.
+* misc/gobuilder: send commit time in RFC3339 format.
+* misc/xcode: move Xcode3 specific files into sub directory.
+* net/http/cgi: add an empty response test,
+	fix empty response.
+* net/http/httptest: make Server.Close wait for outstanding requests to finish.
+* net/http/httputil: fix DumpRequestOut on https URLs,
+	make https DumpRequestOut less racy.
+* net/http: add overlooked 418 status code, per RFC 2324,
+	fix ProxyFromEnvironment bug, docs, add tests,
+	make a test more paranoid & reliable on Windows.
+* net/rpc: silence read error on closing connection.
+* net: add stubs for NetBSD (thanks Benny Siegert),
+	make -external flag for tests default to true (thanks Mikio Hara),
+	reorganize test files (thanks Mikio Hara).
+* os: diagnose chdir error during StartProcess,
+	implement UserTime/SystemTime on windows (thanks Alex Brainman),
+	implement sameFile on windows (thanks Alex Brainman),
+	release process handle at the end of windows (*Process).Wait (thanks Alex Brainman),
+	sleep 5ms after process has exited on windows (thanks Alex Brainman).
+* path/filepath: note that SplitList is different from strings.Split,
+	steer people away from HasPrefix.
+* reflect: don't panic comparing functions in DeepEqual.
+	make Value.Interface return immutable data.
+* runtime/pprof: support OS X CPU profiling.
+* runtime: add sanity checks to the runtime-gdb.py prettyprinters,
+	check for ARM syscall failures (thanks Shenghou Ma),
+	darwin and linux signal masking,
+	run init on main thread,
+	size arena to fit in virtual address space limit.
+* spec: allow disallow of \uFFFD in import path,
+	apply method sets, embedding to all types, not just named types,
+	clarifications around exports, uniqueness of identifiers,
+	import path implementation restriction,
+	inside functions, variables must be evaluated,
+	use the term "lexical token" (rather then "lexical symbol").
+* sync: add Once example, remove old WaitGroup example.
+* test/bench/shootout: update post-Makefile.
+* test: add documentation, misc fixes.
+* testing: add -test.example flag to control execution of examples.
+* text/template: add example showing use of custom function,
+	add examples that use multiple templates,
+	fix redefinition bugs.
+* time: add a comment about how to use the Duration constants.
+</pre>
+
 <h2 id="2012-02-22">2012-02-22</h2>
 
 <pre>
diff --git a/doc/docs.html b/doc/docs.html
index dbe74ad..52ec28e 100644
--- a/doc/docs.html
+++ b/doc/docs.html
@@ -20,6 +20,15 @@ interpreted language.
 
 <div id="manual-nav"></div>
 
+<h2>Installing Go</h2>
+
+<h3><a href="/doc/install">Getting Started</a></h3>
+<p>
+Instructions for downloading and installing the Go compilers, tools, and
+libraries.
+</p>
+
+
 <h2 id="learning">Learning Go</h2>
 
 <h3 id="go_tour"><a href="http://tour.golang.org/">A Tour of Go</a></h3>
@@ -32,25 +41,19 @@ learned. You can <a href="http://tour.golang.org/">take the tour online</a> or
 <a href="http://code.google.com/p/go-tour/">install it locally</a>.
 </p>
 
-<h3 id="orig_tutorial"><a href="go_tutorial.html">A Tutorial for the Go Programming Language</a></h3>
+<h3 id="code"><a href="code.html">How to write Go code</a></h3>
 <p>
-The first tutorial. An introductory text that touches upon several core
-concepts: syntax, types, allocation, constants, I/O, sorting, printing,
-goroutines, and channels.
+How to use the <a href="/cmd/go/">go command</a> to fetch, build, and install
+packages, commands, and run tests.
 </p>
 
 <h3 id="effective_go"><a href="effective_go.html">Effective Go</a></h3>
 <p>
 A document that gives tips for writing clear, idiomatic Go code.
-A must read for any new Go programmer. It augments the tutorial and
+A must read for any new Go programmer. It augments the tour and
 the language specification, both of which should be read first.
 </p>
 
-<h3 id="code"><a href="code.html">How to write Go code</a></h3>
-<p>
-How to write a new package and how to test code.
-</p>
-
 <h3 id="appengine"><a href="http://code.google.com/appengine/docs/go/gettingstarted/">Getting Started with Go on App Engine</a></h3>
 <p>
 How to develop and deploy a simple Go project with
@@ -62,16 +65,15 @@ How to develop and deploy a simple Go project with
 Answers to common questions about Go.
 </p>
 
-<h3>Other introductory articles</h3>
-
-<ul>
-<li><a href="codelab/wiki/">Writing Web Applications</a> - 
-	building a simple web application.</li>
-<li><a href="go_for_cpp_programmers.html">Go for C++ Programmers</a></li>
-</ul>
+<h3 id="wiki"><a href="http://code.google.com/p/go-wiki/wiki">Go Language Community Wiki</a></h3>
+<p>A wiki maintained by the Go community.</p>
 
 <h2 id="articles">Go Articles</h2>
 
+<h3 id="blog"><a href="http://blog.golang.org/">The Go Blog</a></h3>
+<p>The official blog of the Go project, featuring news and in-depth articles by
+the Go team and guests.</p>
+
 <h3>Codewalks</h3>
 <p>
 Guided tours of Go programs. 
@@ -80,6 +82,7 @@ Guided tours of Go programs.
 <li><a href="/doc/codewalk/functions">First-Class Functions in Go</a></li>
 <li><a href="/doc/codewalk/markov">Generating arbitrary text: a Markov chain algorithm</a></li>
 <li><a href="/doc/codewalk/sharemem">Share Memory by Communicating</a></li>
+<li><a href="/doc/articles/wiki/">Writing Web Applications</a> - building a simple web application.</li>
 </ul>
 
 <h3>Language</h3>
@@ -99,7 +102,7 @@ Guided tours of Go programs.
 <ul>
 <li><a href="http://blog.golang.org/2011/01/json-and-go.html">JSON and Go</a> - using the <a href="/pkg/encoding/json/">json</a> package.</li>
 <li><a href="http://blog.golang.org/2011/03/gobs-of-data.html">Gobs of data</a> - the design and use of the <a href="/pkg/encoding/gob/">gob</a> package.</li>
-<li><a href="http://blog.golang.org/2011/09/laws-of-reflection.html">The Laws of Reflection</a> - the fundamentals of the <a href="/pkg/reflect/">reflect</a> package.</li>
+<li><a href="/doc/articles/laws_of_reflection.html">The Laws of Reflection</a> - the fundamentals of the <a href="/pkg/reflect/">reflect</a> package.</li>
 <li><a href="http://blog.golang.org/2011/09/go-image-package.html">The Go image package</a> - the fundamentals of the <a href="/pkg/image/">image</a> package.</li>
 <li><a href="http://blog.golang.org/2011/09/go-imagedraw-package.html">The Go image/draw package</a> - the fundamentals of the <a href="/pkg/image/draw/">image/draw</a> package.</li>
 </ul>
@@ -112,9 +115,15 @@ Guided tours of Go programs.
 <li><a href="http://blog.golang.org/2011/06/profiling-go-programs.html">Profiling Go Programs</a></li>
 </ul>
 
-<h2 id="videos_talks">Videos and Talks</h2>
+<h2 id="talks">Talks</h2>
 
-<h3 id="writing_web_apps"><a href="http://www.youtube.com/watch?v=-i0hat7pdpk">Writing Web Apps in Go</a></h3>
+<p>
+The talks marked with a red asterisk (<font color="red">*</font>) were written
+before Go 1 and contain some examples that are no longer correct, but they are
+still of value.
+</p>
+
+<h3 id="writing_web_apps"><a href="http://www.youtube.com/watch?v=-i0hat7pdpk">Writing Web Apps in Go</a><font color="red">*</font></h3>
 <p>
 A talk by Rob Pike and Andrew Gerrand presented at Google I/O 2011.
 It walks through the construction and deployment of a simple web application
@@ -122,7 +131,7 @@ and unveils the <a href="http://blog.golang.org/2011/05/go-and-google-app-engine
 See the <a href="/doc/talks/io2011/Writing_Web_Apps_in_Go.pdf">presentation slides</a>.
 </p>
 
-<h3 id="real_world_go"><a href="http://www.youtube.com/watch?v=7QDVRowyUQA">Real World Go</a></h3>
+<h3 id="real_world_go"><a href="http://www.youtube.com/watch?v=7QDVRowyUQA">Real World Go</a><font color="red">*</font></h3>
 <p>
 A talk by Andrew Gerrand presented at Google I/O Bootcamp 2011.
 It gives a broad overview of Go's type system and concurrency model
@@ -130,7 +139,14 @@ and provides four examples of Go programs that solve real problems.
 See the <a href="/doc/talks/io2011/Real_World_Go.pdf">presentation slides</a>.
 </p>
 
-<h3 id="go_programming"><a href="http://www.youtube.com/watch?v=jgVhBThJdXc">Go Programming</a></h3>
+<h3 id="integrated_apps"><a href="http://www.youtube.com/watch?v=Mo1YKpIF1PQ">Building Integrated Apps on Google's Cloud Platform</a></h3>
+<p>
+A talk by Andrew Gerrand presented at Google Developer Day Japan 2011.
+It discusses the development of a web application that runs on Google
+App Engine and renders images that it stores on Google Cloud Storage.
+</p>
+
+<h3 id="go_programming"><a href="http://www.youtube.com/watch?v=jgVhBThJdXc">Go Programming</a><font color="red">*</font></h3>
 <p>
 A presentation delivered by Rob Pike and Russ Cox at Google I/O 2010.  It
 illustrates how programming in Go differs from other languages through a set of
@@ -138,7 +154,7 @@ examples demonstrating features particular to Go.  These include concurrency,
 embedded types, methods on any type, and program construction using interfaces. 
 </p>
 
-<h3 id="practical_go_programming"><a href="http://www.youtube.com/watch?v=2-pPAvqyluI">Practical Go Programming</a></h3>
+<h3 id="practical_go_programming"><a href="http://www.youtube.com/watch?v=2-pPAvqyluI">Practical Go Programming</a><font color="red">*</font></h3>
 <p>
 This talk presents the development of a complete web application in Go.
 It looks at design, storage, concurrency, and scaling issues in detail, using
@@ -146,119 +162,35 @@ the simple example of an URL shortening service.
 See the <a href="http://wh3rd.net/practical-go/">presentation slides</a>.
 </p>
 
-<h3 id="techtalk"><a href="http://www.youtube.com/watch?v=rKnDgT73v8s">The Go Tech Talk</a></h3>
+<h3 id="talks_more">More</h3>
 <p>
-An hour-long talk delivered by Rob Pike at Google in October 2009. 
-The language's first public introduction. (See the <a href="talks/go_talk-20091030.pdf">slides in PDF format</a>.) The language has changed since it was made,
-but it's still a good introduction.
+See the <a href="http://code.google.com/p/go-wiki/wiki/GoTalks">GoTalks
+page</a> at the <a href="http://code.google.com/p/go-wiki/wiki">Go Wiki</a> for
+more Go talks.
 </p>
 
-<h3 id="jaoo_go"><a href="/doc/ExpressivenessOfGo.pdf">The Expressiveness Of Go</a></h3>
-<p>
-A discussion of the qualities that make Go an expressive and comprehensible
-language.  The talk was presented by Rob Pike at JAOO 2010.
-The recording of the event was lost due to a hardware error.
-</p>
-
-<h3 id="oscon_go"><a href="http://www.oscon.com/oscon2010/public/schedule/detail/14760">Another Go at Language Design</a></h3>
-<p>
-A tour, with some background, of the major features of Go, intended for
-an audience new to the language.  The talk was presented at OSCON 2010.
-See the <a href="http://assets.en.oreilly.com/1/event/45/Another%20Go%20at%20Language%20Design%20Presentation.pdf">presentation slides</a>.
-</p>
-<p>
-This talk was also delivered at Sydney University in September 2010. A video
-of the lecture is available 
-<a href="http://sydney.edu.au/engineering/it/videos/seminar_pike">here</a>.
-</p>
-
-<h3 id="emerging_go"><a href="http://www.oscon.com/oscon2010/public/schedule/detail/15464">Go Emerging Languages Conference Talk</a></h3>
-<p>
-Rob Pike's Emerging Languages Conference presentation delivered in July 2010. See the <a href="http://assets.en.oreilly.com/1/event/45/Go%20Presentation.pdf">presentation slides</a>. Abstract:
-</p>
-<p><i>
-Go’s approach to concurrency differs from that of many languages, even those
-(such as Erlang) that make concurrency central, yet it has deep roots. The path
-from Hoare’s 1978 paper to Go provides insight into how and why Go works as it
-does.
-</i></p>
-
-<h3 id="go_frontend_gcc"><a href="talks/gofrontend-gcc-summit-2010.pdf">The Go frontend for GCC</a></h3>
-<p>
-A description of the Go language frontend for gcc.
-Ian Lance Taylor's paper delivered at the GCC Summit 2010.
-</p>
+<h2 id="nonenglish">Non-English Documentation</h2>
 
-<h3 id="promo_video"><a href="http://www.youtube.com/watch?v=wwoWei-GAPo">The Go Promo Video</a></h3>
 <p>
-A short promotional video featuring Russ Cox demonstrating Go's fast compiler.
+See the <a href="http://code.google.com/p/go-wiki/wiki/NonEnglish">NonEnglish</a> page 
+at the <a href="http://code.google.com/p/go-wiki/wiki">Go Wiki</a> for localized
+documentation.
 </p>
 
-<h2 id="developer_info">The Go Community</h2>
+<h2 id="community">The Go Community</h2>
 
 <h3 id="mailinglist"><a href="http://groups.google.com/group/golang-nuts">Go Nuts Mailing List</a></h3>
 <p>The <a href="http://groups.google.com/group/golang-nuts">golang-nuts</a> 
 mailing list is for general Go discussion.</p>
 
-<h3 id=""><a href="http://godashboard.appspot.com/package">Go Packages Dashboard</a></h3>
-<p>A list of the most popular <a href="/cmd/goinstall/">goinstall</a>'d
-Go libraries.</p>
-
-<h3 id=""><a href="http://godashboard.appspot.com/project">Go Project Dashboard</a></h3>
+<h3 id="projects"><a href="http://godashboard.appspot.com/project">Go Project Dashboard</a></h3>
 <p>A list of external Go projects including programs and libraries.</p>
 
 <h3 id="irc"><a href="irc:irc.freenode.net/go-nuts">Go IRC Channel</a></h3>
 <p><b>#go-nuts</b> on <b>irc.freenode.net</b> is the official Go IRC channel.</p>
 
+<h3 id="plus"><a href="https://plus.google.com/101406623878176903605/posts">The Go Programming Language at Google+</a></h3>
+<p>The Go project's Google+ page.</p>
+
 <h3 id="twitter"><a href="http://twitter.com/go_nuts">@go_nuts at Twitter</a></h3>
 <p>The Go project's official Twitter account.</p>
-
-<h2 id="tutorials_nonenglish">Non-English Documentation</h2>
-
-<h4 id="docs_be">Belarusian — Беларуская</h4>
-
-<ul>
-<li><a href="http://www.designcontest.com/show/faq-be">faq-be</a> - Frequently Asked Questions.</li>
-</ul>
-
-<h4 id="docs_cn">Chinese — 中文</h4>
-
-<ul>
-<li><a href="http://go-tour-zh.appspot.com/">A Tour of Go</a></li>
-<li><a href="http://code.google.com/p/golang-china/">golang-china</a> - a broad range of Go documentation.</li>
-<li><a href="http://code.google.com/p/ac-me/downloads/detail?name=fango.pdf">Effective Go and Tutorial</a></li>
-</ul>
-
-<h4 id="docs_cz">Czech — Čeština</h4>
-
-<ul>
-<li><a href="http://www.abclinuxu.cz/clanky/google-go-pravidla-reflexe">Pravidla reflexe</a> - a translation of <a href="http://blog.golang.org/2011/09/laws-of-reflection.html">The Laws of Reflection</a>.</li>
-</ul>
-
-<h4 id="docs_fr">French — Français</h4>
-
-<ul>
-<li>
-<a href="http://code.google.com/p/golang-france/">golang-france</a> - Go documentation.
-</ul>
-
-<h4 id="docs_de">German — Deutsch</h4>
-
-<ul>
-<li><a href="http://bitloeffel.de/DOC/golang/go_tutorial_de.html">Eine Anleitung zum Programmieren in Go</a> - the Go Tutorial.</li>
-<li><a href="http://bitloeffel.de/DOC/golang/effective_go_de.html">Wirkungsvoll Go programmieren</a> - Effective Go.</li>
-<li><a href="http://bitloeffel.de/DOC/golang/code_de.html">Wie man Go-Kode schreibt</a> - How to Write Go Code.</li>
-</ul>
-
-<h4 id="docs_jp">Japanese — 日本語</h4>
-<ul>
-<li><a href="http://go-tour-jp.appspot.com/">A Tour of Go</a></li>
-<li><a href="http://golang.jp/">golang.jp</a> - Go documentation and news.</li>
-</ul>
-
-<h4 id="docs_kr">Korean — 한국어</h4>
-<ul>
-<li><a href="http://go-tour-kr.appspot.com">A Tour of Go</a></li>
-<li><a href="http://code.google.com/p/golang-korea">golang-korea</a> - Go documentation and news.</li>
-</ul>
-
diff --git a/doc/effective_go.html b/doc/effective_go.html
index e3e19bd..b9e62b6 100644
--- a/doc/effective_go.html
+++ b/doc/effective_go.html
@@ -31,8 +31,10 @@ will be easy for other Go programmers to understand.
 
 <p>
 This document gives tips for writing clear, idiomatic Go code.
-It augments the <a href="go_spec.html">language specification</a>
-and the <a href="go_tutorial.html">tutorial</a>, both of which you
+It augments the <a href="/ref/spec">language specification</a>,
+the <a href="http://tour.golang.org/">Tour of Go</a>,
+and <a href="/doc/code.html">How to Write Go Code</a>,
+all of which you
 should read first.
 </p>
 
@@ -67,7 +69,7 @@ With Go we take an unusual
 approach and let the machine
 take care of most formatting issues.
 The <code>gofmt</code> program
-(also available as <code>go tool fmt</code>, which
+(also available as <code>go fmt</code>, which
 operates at the package level rather than source file level)
 reads a Go program
 and emits the source in a standard style of indentation
@@ -1454,7 +1456,7 @@ fmt.Println(fmt.Sprint("Hello ", 23))
 </pre>
 <p>
 As mentioned in
-the <a href="go_tutorial.html">tutorial</a>, <code>fmt.Fprint</code>
+the <a href="http://code.google.com/p/go-tour/">Tour</a>, <code>fmt.Fprint</code>
 and friends take as a first argument any object
 that implements the <code>io.Writer</code> interface; the variables <code>os.Stdout</code>
 and <code>os.Stderr</code> are familiar instances.
@@ -1615,40 +1617,49 @@ Now we have the missing piece we needed to explain the design of
 the <code>append</code> built-in function.  The signature of <code>append</code>
 is different from our custom <code>Append</code> function above.
 Schematically, it's like this:
+</p>
 <pre>
 func append(slice []<i>T</i>, elements...T) []<i>T</i>
 </pre>
+<p>
 where <i>T</i> is a placeholder for any given type.  You can't
 actually write a function in Go where the type <code>T</code>
 is determined by the caller.
 That's why <code>append</code> is built in: it needs support from the
 compiler.
+</p>
 <p>
 What <code>append</code> does is append the elements to the end of
 the slice and return the result.  The result needs to be returned
 because, as with our hand-written <code>Append</code>, the underlying
 array may change.  This simple example
+</p>
 <pre>
 x := []int{1,2,3}
 x = append(x, 4, 5, 6)
 fmt.Println(x)
 </pre>
+<p>
 prints <code>[1 2 3 4 5 6]</code>.  So <code>append</code> works a
 little like <code>Printf</code>, collecting an arbitrary number of
 arguments.
+</p>
 <p>
 But what if we wanted to do what our <code>Append</code> does and
 append a slice to a slice?  Easy: use <code>...</code> at the call
 site, just as we did in the call to <code>Output</code> above.  This
 snippet produces identical output to the one above.
+</p>
 <pre>
 x := []int{1,2,3}
 y := []int{4,5,6}
 x = append(x, y...)
 fmt.Println(x)
 </pre>
+<p>
 Without that <code>...</code>, it wouldn't compile because the types
 would be wrong; <code>y</code> is not of type <code>int</code>.
+</p>
 
 <h2 id="initialization">Initialization</h2>
 
diff --git a/doc/effective_go.tmpl b/doc/effective_go.tmpl
index 5763cac..9a0333d 100644
--- a/doc/effective_go.tmpl
+++ b/doc/effective_go.tmpl
@@ -27,8 +27,10 @@ will be easy for other Go programmers to understand.
 
 <p>
 This document gives tips for writing clear, idiomatic Go code.
-It augments the <a href="go_spec.html">language specification</a>
-and the <a href="go_tutorial.html">tutorial</a>, both of which you
+It augments the <a href="/ref/spec">language specification</a>,
+the <a href="http://tour.golang.org/">Tour of Go</a>,
+and <a href="/doc/code.html">How to Write Go Code</a>,
+all of which you
 should read first.
 </p>
 
@@ -63,7 +65,7 @@ With Go we take an unusual
 approach and let the machine
 take care of most formatting issues.
 The <code>gofmt</code> program
-(also available as <code>go tool fmt</code>, which
+(also available as <code>go fmt</code>, which
 operates at the package level rather than source file level)
 reads a Go program
 and emits the source in a standard style of indentation
@@ -1450,7 +1452,7 @@ fmt.Println(fmt.Sprint("Hello ", 23))
 </pre>
 <p>
 As mentioned in
-the <a href="go_tutorial.html">tutorial</a>, <code>fmt.Fprint</code>
+the <a href="http://code.google.com/p/go-tour/">Tour</a>, <code>fmt.Fprint</code>
 and friends take as a first argument any object
 that implements the <code>io.Writer</code> interface; the variables <code>os.Stdout</code>
 and <code>os.Stderr</code> are familiar instances.
@@ -1611,40 +1613,49 @@ Now we have the missing piece we needed to explain the design of
 the <code>append</code> built-in function.  The signature of <code>append</code>
 is different from our custom <code>Append</code> function above.
 Schematically, it's like this:
+</p>
 <pre>
 func append(slice []<i>T</i>, elements...T) []<i>T</i>
 </pre>
+<p>
 where <i>T</i> is a placeholder for any given type.  You can't
 actually write a function in Go where the type <code>T</code>
 is determined by the caller.
 That's why <code>append</code> is built in: it needs support from the
 compiler.
+</p>
 <p>
 What <code>append</code> does is append the elements to the end of
 the slice and return the result.  The result needs to be returned
 because, as with our hand-written <code>Append</code>, the underlying
 array may change.  This simple example
+</p>
 <pre>
 x := []int{1,2,3}
 x = append(x, 4, 5, 6)
 fmt.Println(x)
 </pre>
+<p>
 prints <code>[1 2 3 4 5 6]</code>.  So <code>append</code> works a
 little like <code>Printf</code>, collecting an arbitrary number of
 arguments.
+</p>
 <p>
 But what if we wanted to do what our <code>Append</code> does and
 append a slice to a slice?  Easy: use <code>...</code> at the call
 site, just as we did in the call to <code>Output</code> above.  This
 snippet produces identical output to the one above.
+</p>
 <pre>
 x := []int{1,2,3}
 y := []int{4,5,6}
 x = append(x, y...)
 fmt.Println(x)
 </pre>
+<p>
 Without that <code>...</code>, it wouldn't compile because the types
 would be wrong; <code>y</code> is not of type <code>int</code>.
+</p>
 
 <h2 id="initialization">Initialization</h2>
 
diff --git a/doc/gccgo_contribute.html b/doc/gccgo_contribute.html
index e3f6bf4..8ca13e4 100644
--- a/doc/gccgo_contribute.html
+++ b/doc/gccgo_contribute.html
@@ -7,15 +7,15 @@
 <p>
 These are some notes on contributing to the gccgo frontend for GCC.
 For information on contributing to parts of Go other than gccgo,
-see <a href="contribute.html">Contributing to the Go project</a>.  For
+see <a href="/doc/contribute.html">Contributing to the Go project</a>.  For
 information on building gccgo for yourself,
-see <a href="gccgo_install.html">Setting up and using gccgo</a>.
+see <a href="/doc/gccgo_install.html">Setting up and using gccgo</a>.
 </p>
 
 <h2>Legal Prerequisites</h2>
 
 <p>
-You must follow the <a href="contribute.html#copyright">Go copyright
+You must follow the <a href="/doc/contribute.html#copyright">Go copyright
 rules</a> for all changes to the gccgo frontend and the associated
 libgo library.  Code that is part of GCC rather than gccgo must follow
 the general <a href="http://gcc.gnu.org/contribute.html">GCC
diff --git a/doc/gccgo_install.html b/doc/gccgo_install.html
index d5fff7b..ae35943 100644
--- a/doc/gccgo_install.html
+++ b/doc/gccgo_install.html
@@ -1,6 +1,6 @@
 <!--{
 	"Title": "Setting up and using gccgo",
-	"Path": "/install/gccgo/"
+	"Path": "/doc/install/gccgo"
 }-->
 
 <p>
@@ -15,7 +15,7 @@ License</a>.
 
 <p>
 Note that <code>gccgo</code> is not the <code>6g</code> compiler; see
-the <a href="install.html">Installing Go</a> instructions for that
+the <a href="/doc/install">Installing Go</a> instructions for that
 compiler.
 </p>
 
@@ -34,7 +34,7 @@ repository: <code>svn://gcc.gnu.org/svn/gcc/branches/gccgo</code>.
 Note that although <code>gcc.gnu.org</code> is the most convenient way
 to get the source code for the compiler, that is not where the master
 sources live.  If you want to contribute changes to the gccgo
-compiler, see <a href="gccgo_contribute.html">Contributing to
+compiler, see <a href="/doc/gccgo_contribute.html">Contributing to
 gccgo</a>.
 </p>
 
diff --git a/doc/go1.html b/doc/go1.html
index 4bc4f66..8b67cd3 100644
--- a/doc/go1.html
+++ b/doc/go1.html
@@ -10,29 +10,46 @@
 <h2 id="introduction">Introduction to Go 1</h2>
 
 <p>
-For a full explanation of the motivation and design of Go 1, see XXX.
-Here follows a summary.
+Go version 1, Go 1 for short, defines a language and a set of core libraries
+that provide a stable foundation for creating reliable products, projects, and
+publications.
 </p>
 
 <p>
-Go 1 is intended to be a stable language and core library set that
-will form a reliable foundation for people and organizations that
-want to make a long-term commitment to developing in the Go programming
-language. Go will continue to develop, but in a way that guarantees
-code written to the Go 1 specification will continue to work. For
-instance, Go 1 will be a supported platform on Google App Engine
-for the next few years. Incompatible changes to the environment,
-should they arise, will be done in a distinct version.
+The driving motivation for Go 1 is stability for its users. People should be able to
+write Go programs and expect that they will continue to compile and run without
+change, on a time scale of years, including in production environments such as
+Google App Engine. Similarly, people should be able to write books about Go, be
+able to say which version of Go the book is describing, and have that version
+number still be meaningful much later.
 </p>
 
 <p>
-This document describes the changes in the language and libraries
-in Go 1, relative to the previous release, r60 (at the time of
-writing, tagged as r60.3). It also explains how to update code at
-r60 to compile and run under Go 1. Finally, it outlines the new
-<code>go</code> command for building Go programs and the new binary
-release process being introduced. Most of these topics have more
-thorough presentations elsewhere; such documents are linked below.
+Code that compiles in Go 1 should, with few exceptions, continue to compile and
+run throughout the lifetime of that version, even as we issue updates and bug
+fixes such as Go version 1.1, 1.2, and so on. Other than critical fixes, changes
+made to the language and library for subsequent releases of Go 1 may
+add functionality but will not break existing Go 1 programs.
+<a href="go1compat.html">The Go 1 compatibility document</a>
+explains the compatibility guidelines in more detail.
+</p>
+
+<p>
+Go 1 is a representation of Go as it used today, not a wholesale rethinking of
+the language. We avoided designing new features and instead focused on cleaning
+up problems and inconsistencies and improving portability. There are a number
+changes to the Go language and packages that we had considered for some time and
+prototyped but not released primarily because they are significant and
+backwards-incompatible. Go 1 was an opportunity to get them out, which is
+helpful for the long term, but also means that Go 1 introduces incompatibilities
+for old programs. Fortunately, the <code>go</code> <code>fix</code> tool can
+automate much of the work needed to bring programs up to the Go 1 standard.
+</p>
+
+<p>
+This document outlines the major changes in Go 1 that will affect programmers
+updating existing code; its reference point is the prior release, r60 (tagged as
+r60.3). It also explains how to update code from r60 to run under Go 1.
 </p>
 
 <h2 id="language">Changes to the language</h2>
@@ -40,9 +57,11 @@ thorough presentations elsewhere; such documents are linked below.
 <h3 id="append">Append</h3>
 
 <p>
-The <code>append</code> built-in function is variadic, so one can
-append to a byte slice using the <code>...</code> syntax in the
-call.
+The <code>append</code> predeclared variadic function makes it easy to grow a slice
+by adding elements to the end.
+A common use is to add bytes to the end of a byte slice when generating output.
+However, <code>append</code> did not provide a way to append a string to a <code>[]byte</code>,
+which is another common case.
 </p>
 
 <pre><!--{{code "progs/go1.go" `/greeting := ..byte/` `/append.*hello/`}}
@@ -52,7 +71,8 @@ call.
 <p>
 By analogy with the similar property of <code>copy</code>, Go 1
 permits a string to be appended (byte-wise) directly to a byte
-slice; the conversion is no longer necessary:
+slice, reducing the friction between strings and byte slices.
+The conversion is no longer necessary:
 </p>
 
 <pre><!--{{code "progs/go1.go" `/append.*world/`}}
@@ -66,10 +86,20 @@ This is a new feature, so existing code needs no changes.
 <h3 id="close">Close</h3>
 
 <p>
-The <code>close</code> built-in function lets a sender tell a receiver
-that no more data will be transmitted on the channel.  In Go 1 the
-type system enforces the directionality when possible: it is illegal
-to call <code>close</code> on a receive-only channel:
+The <code>close</code> predeclared function provides a mechanism
+for a sender to signal that no more values will be sent.
+It is important to the implementation of <code>for</code> <code>range</code>
+loops over channels and is helpful in other situations.
+Partly by design and partly because of race conditions that can occur otherwise,
+it is intended for use only by the goroutine sending on the channel,
+not by the goroutine receiving data.
+However, before Go 1 there was no compile-time checking that <code>close</code>
+was being used correctly.
+</p>
+
+<p>
+To close this gap, at least in part, Go 1 disallows <code>close</code> on receive-only channels.
+Attempting to close such a channel is a compile-time error.
 </p>
 
 <pre>
@@ -137,9 +167,18 @@ will, among other things, elide explicit element types wherever permitted.
 <h3 id="init">Goroutines during init</h3>
 
 <p>
-Go 1 allows goroutines to be created and run during initialization.
-(They used to be created but were not run until after initialization
-completed.) Code that uses goroutines can now be called from
+The old language defined that <code>go</code> statements executed during initialization created goroutines but that they did not begin to run until initialization of the entire program was complete.
+This introduced clumsiness in many places and, in effect, limited the utility
+of the <code>init</code> construct:
+if it was possible for another package to use the library during initialization, the library
+was forced to avoid goroutines.
+This design was done for reasons of simplicity and safety but,
+as our confidence in the language grew, it seemed unnecessary.
+Running goroutines during initialization is no more complex or unsafe than running them during normal execution.
+</p>
+
+<p>
+In Go 1, code that uses goroutines can be called from
 <code>init</code> routines and global initialization expressions
 without introducing a deadlock.
 </p>
@@ -163,7 +202,16 @@ There was no such code in the standard repository.
 <h3 id="rune">The rune type</h3>
 
 <p>
-Go 1 introduces a new basic type, <code>rune</code>, to be used to represent
+The language spec allows the <code>int</code> type to be 32 or 64 bits wide, but current implementations set <code>int</code> to 32 bits even on 64-bit platforms.
+It would be preferable to have <code>int</code> be 64 bits on 64-bit platforms.
+(There are important consequences for indexing large slices.)
+However, this change would waste space when processing Unicode characters with
+the old language because the <code>int</code> type was also used to hold Unicode code points: each code point would waste an extra 32 bits of storage if <code>int</code> grew from 32 bits to 64.
+</p>
+
+<p>
+To make changing to 64-bit <code>int</code> feasible,
+Go 1 introduces a new basic type, <code>rune</code>, to represent
 individual Unicode code points.
 It is an alias for <code>int32</code>, analogous to <code>byte</code>
 as an alias for <code>uint8</code>.
@@ -220,14 +268,21 @@ it is discussed <a href="#errors">below</a>.
 <h3 id="delete">Deleting from maps</h3>
 
 <p>
-The original syntax for deleting an element in a map was:
+In the old language, to delete the entry with key <code>k</code> from map <code>m</code>, one wrote the statement,
 </p>
 
 <pre>
-    m[k] = ignored, false
+    m[k] = value, false
 </pre>
 
 <p>
+This syntax was a peculiar special case, the only two-to-one assignment.
+It required passing a value (usually ignored) that is evaluated but discarded,
+plus a boolean that was nearly always the constant <code>false</code>.
+It did the job but was odd and a point of contention.
+</p>
+
+<p>
 In Go 1, that syntax has gone; instead there is a new built-in
 function, <code>delete</code>.  The call
 </p>
@@ -242,7 +297,7 @@ There is no return value. Deleting a non-existent entry is a no-op.
 
 <p>
 <em>Updating</em>:
-Running <code>go fix</code> will convert expressions of the form <code>m[k] = ignored,
+Running <code>go</code> <code>fix</code> will convert expressions of the form <code>m[k] = value,
 false</code> into <code>delete(m, k)</code> when it is clear that
 the ignored value can be safely discarded from the program and
 <code>false</code> refers to the predefined boolean constant.
@@ -253,6 +308,13 @@ will flag other uses of the syntax for inspection by the programmer.
 <h3 id="iteration">Iterating in maps</h3>
 
 <p>
+The old language specification did not define the order of iteration for maps,
+and in practice it differed across hardware platforms.
+This caused tests that iterated over maps to be fragile and non-portable, with the
+unpleasant property that a test might always pass on one machine but break on another.
+</p>
+
+<p>
 In Go 1, the order in which elements are visited when iterating
 over a map using a <code>for</code> <code>range</code> statement
 is defined to be unpredictable, even if the same loop is run multiple
@@ -260,6 +322,11 @@ times with the same map.
 Code should not assume that the elements are visited in any particular order.
 </p>
 
+<p>
+This change means that code that depends on iteration order is very likely to break early and be fixed long before it becomes a problem.
+Just as important, it allows the map implementation to ensure better map balancing even when programs are using range loops to select an element from a map.
+</p>
+
 <pre><!--{{code "progs/go1.go" `/Sunday/` `/^	}/`}}
 -->    m := map[string]int{"Sunday": 0, "Monday": 1}
     for name, value := range m {
@@ -281,8 +348,14 @@ was unspecified. This change codifies the unpredictability.
 <h3 id="multiple_assignment">Multiple assignment</h3>
 
 <p>
-Go 1 fully specifies the evaluation order in multiple assignment
-statements. In particular, if the left-hand side of the assignment
+The language specification has long guaranteed that in assignments
+the right-hand-side expressions are all evaluated before any left-hand-side expressions are assigned.
+To guarantee predictable behavior,
+Go 1 refines the specification further.
+</p>
+
+<p>
+If the left-hand side of the assignment
 statement contains expressions that require evaluation, such as
 function calls or array indexing operations, these will all be done
 using the usual left-to-right rule before any variables are assigned
@@ -316,7 +389,11 @@ that depended on the previous unspecified behavior was already incorrect.
 <h3 id="shadowing">Returns and shadowed variables</h3>
 
 <p>
-A shadowed variable is one that has the same name as another variable in an inner scope.
+A common mistake is to use <code>return</code> (without arguments) after an assignment to a variable that has the same name as a result variable but is not the same variable.
+This situation is called <em>shadowing</em>: the result variable has been shadowed by another variable with the same name declared in an inner scope.
+</p>
+
+<p>
 In functions with named return values,
 the Go 1 compilers disallow return statements without arguments if any of the named return values is shadowed at the point of the return statement.
 (It isn't part of the specification, because this is one area we are still exploring;
@@ -350,9 +427,17 @@ The few cases that arose in the standard repository were mostly bugs.
 <h3 id="unexported">Copying structs with unexported fields</h3>
 
 <p>
-Go 1 relaxes the rules about accessing structs with unexported (lower-case) fields,
-permitting a client package to assign (and therefore copy) such a struct.
-Of course, the client package still cannot access such fields individually.
+The old language did not allow a package to make a copy of a struct value containing unexported fields belonging to a different package.
+There was, however, a required exception for a method receiver;
+also, the implementations of <code>copy</code> and <code>append</code> have never honored the restriction.
+</p>
+
+<p>
+Go 1 will allow packages to copy struct values containing unexported fields from other packages.
+Besides resolving the inconsistency,
+this change admits a new kind of API: a package can return an opaque value without resorting to a pointer or interface.
+The new implementations of <code>time.Time</code> and
+<code>reflect.Value</code> are examples of types taking advantage of this new property.
 </p>
 
 <p>
@@ -397,18 +482,26 @@ will show that the secret field of the struct has been copied to the new value.
 This is a new feature, so existing code needs no changes.
 </p>
 
-<h3 id="equality">Equality of structs and arrays</h3>
+<h3 id="equality">Equality</h3>
 
 <p>
-Go 1 defines equality and inequality (<code>==</code> and
-<code>!=</code>) for struct and array values, respectively, provided
-the elements of the data structures can themselves be compared.
-That is, if equality is defined for all the fields of a struct (or
-an array element), then it is defined for the struct (or array).
+Before Go 1, the language did not define equality on struct and array values.
+This meant,
+among other things, that structs and arrays could not be used as map keys.
+On the other hand, Go did define equality on function and map values.
+Function equality was problematic in the presence of closures
+(when are two closures equal?)
+while map equality compared pointers, not the maps' content, which was usually
+not what the user would want.
 </p>
 
 <p>
-As a result, structs and arrays can now be used as map keys:
+Go 1 addressed these issues.
+First, structs and arrays can be compared for equality and inequality
+(<code>==</code> and <code>!=</code>),
+and therefore be used as map keys,
+provided they are composed from elements for which equality is also defined,
+using element-wise comparison.
 </p>
 
 <pre><!--{{code "progs/go1.go" `/type Day struct/` `/Printf/`}}
@@ -425,6 +518,12 @@ As a result, structs and arrays can now be used as map keys:
     fmt.Printf("Christmas is a holiday: %t\n", holiday[Christmas])</pre>
 
 <p>
+Second, Go 1 removes the definition of equality for function values,
+except for comparison with <code>nil</code>.
+Finally, map equality is gone too, also except for comparison with <code>nil</code>.
+</p>
+
+<p>
 Note that equality is still undefined for slices, for which the
 calculation is in general infeasible.  Also note that the ordered
 comparison operators (<code><</code> <code><=</code>
@@ -433,18 +532,7 @@ structs and arrays.
 
 <p>
 <em>Updating</em>:
-This is a new feature, so existing code needs no changes.
-</p>
-
-<h3 id="funcs">Function and map equality</h3>
-
-<p>
-Go 1 disallows checking for equality of functions and maps,
-respectively, except to compare them directly to <code>nil</code>.
-</p>
-
-<p>
-<em>Updating</em>:
+Struct and array equality is a new feature, so existing code needs no changes.
 Existing code that depends on function or map equality will be
 rejected by the compiler and will need to be fixed by hand.
 Few programs will be affected, but the fix may require some
@@ -454,6 +542,12 @@ redesign.
 <h2 id="packages">The package hierarchy</h2>
 
 <p>
+Go 1 addresses many deficiencies in the old standard library and
+cleans up a number of packages, making them more internally consistent
+and portable.
+</p>
+
+<p>
 This section describes how the packages have been rearranged in Go 1.
 Some have moved, some have been renamed, some have been deleted.
 New packages are described in later sections.
@@ -535,7 +629,7 @@ and <code>template</code>.
 
 <p>
 <em>Updating</em>:
-Running <code>go fix</code> will update all imports and package renames for packages that
+Running <code>go</code> <code>fix</code> will update all imports and package renames for packages that
 remain inside the standard repository.  Programs that import packages
 that are no longer in the standard repository will need to be edited
 by hand.
@@ -556,11 +650,16 @@ Several packages have moved under <code>exp</code> at the time of Go 1's release
 
 <ul>
 <li><code>ebnf</code></li>
+<li><code>html</code><sup>†</sup></li>
 <li><code>go/types</code></li>
-<li><code>os/signal</code></li>
 </ul>
 
 <p>
+(<sup>†</sup>The <code>EscapeString</code> and <code>UnescapeString</code> types remain
+in package <code>html</code>.)
+</p>
+
+<p>
 All these packages are available under the same names, with the prefix <code>exp/</code>: <code>exp/ebnf</code> etc.
 </p>
 
@@ -578,7 +677,7 @@ If they are installed, they now reside in <code>$GOROOT/bin/tool</code>.
 <em>Updating</em>:
 Code that uses packages in <code>exp</code> will need to be updated by hand,
 or else compiled from an installation that has <code>exp</code> available.
-The <code>go fix</code> tool or the compiler will complain about such uses.
+The <code>go</code> <code>fix</code> tool or the compiler will complain about such uses.
 </p>
 
 <h3 id="old">The package tree old</h3>
@@ -603,7 +702,7 @@ The packages in their new locations are:
 <em>Updating</em>:
 Code that uses packages now in <code>old</code> will need to be updated by hand,
 or else compiled from an installation that has <code>old</code> available.
-The <code>go fix</code> tool will warn about such uses.
+The <code>go</code> <code>fix</code> tool will warn about such uses.
 </p>
 
 <h3 id="deleted">Deleted packages</h3>
@@ -684,7 +783,7 @@ This table lists the old and new import paths:
 
 <p>
 <em>Updating</em>:
-Running <code>go fix</code> will update imports of these packages to use the new import paths.
+Running <code>go</code> <code>fix</code> will update imports of these packages to use the new import paths.
 Installations that depend on these packages will need to install them using
 a <code>go install</code> command.
 </p>
@@ -699,8 +798,19 @@ affect the most programs.
 <h3 id="errors">The error type and errors package</h3>
 
 <p>
-As mentioned above, Go 1 introduces a new built-in interface type called <code>error</code>.
-Its intent is to replace the old <code>os.Error</code> type with a more central concept.
+The placement of <code>os.Error</code> in package <code>os</code> is mostly historical: errors first came up when implementing package <code>os</code>, and they seemed system-related at the time.
+Since then it has become clear that errors are more fundamental than the operating system.  For example, it would be nice to use <code>Errors</code> in packages that <code>os</code> depends on, like <code>syscall</code>.
+Also, having <code>Error</code> in <code>os</code> introduces many dependencies on <code>os</code> that would otherwise not exist.
+</p>
+
+<p>
+Go 1 solves these problems by introducing a built-in <code>error</code> interface type and a separate <code>errors</code> package (analogous to <code>bytes</code> and <code>strings</code>) that contains utility functions.
+It replaces <code>os.NewError</code> with
+<a href="/pkg/errors/#New"><code>errors.New</code></a>,
+giving errors a more central place in the environment.
+</p>
+
+<p>
 So the widely-used <code>String</code> method does not cause accidental satisfaction
 of the <code>error</code> interface, the <code>error</code> interface uses instead
 the name <code>Error</code> for that method:
@@ -749,7 +859,7 @@ to turn a string into an error. It replaces the old <code>os.NewError</code>.
 		
 <p>
 <em>Updating</em>:
-Running <code>go fix</code> will update almost all code affected by the change.
+Running <code>go</code> <code>fix</code> will update almost all code affected by the change.
 Code that defines error types with a <code>String</code> method will need to be updated
 by hand to rename the methods to <code>Error</code>.
 </p>
@@ -757,18 +867,30 @@ by hand to rename the methods to <code>Error</code>.
 <h3 id="errno">System call errors</h3>
 
 <p>
+The old <code>syscall</code> package, which predated <code>os.Error</code>
+(and just about everything else),
+returned errors as <code>int</code> values.
+In turn, the <code>os</code> package forwarded many of these errors, such
+as <code>EINVAL</code>, but using a different set of errors on each platform.
+This behavior was unpleasant and unportable.
+</p>
+
+<p>
 In Go 1, the
 <a href="/pkg/syscall/"><code>syscall</code></a>
-package returns an <code>error</code> for system call errors,
-rather than plain integer <code>errno</code> values.
+package instead returns an <code>error</code> for system call errors.
 On Unix, the implementation is done by a 
 <a href="/pkg/syscall/#Errno"><code>syscall.Errno</code></a> type
 that satisfies <code>error</code> and replaces the old <code>os.Errno</code>.
 </p>
 
 <p>
+The changes affecting <code>os.EINVAL</code> and relatives are
+described <a href="#os">elsewhere</a>.
+
+<p>
 <em>Updating</em>:
-Running <code>go fix</code> will update almost all code affected by the change.
+Running <code>go</code> <code>fix</code> will update almost all code affected by the change.
 Regardless, most code should use the <code>os</code> package
 rather than <code>syscall</code> and so will be unaffected.
 </p>
@@ -776,7 +898,14 @@ rather than <code>syscall</code> and so will be unaffected.
 <h3 id="time">Time</h3>
 
 <p>
-One of the most sweeping changes in the Go 1 library is the
+Time is always a challenge to support well in a programming language.
+The old Go <code>time</code> package had <code>int64</code> units, no
+real type safety,
+and no distinction between absolute times and durations.
+</p>
+
+<p>
+One of the most sweeping changes in the Go 1 library is therefore a
 complete redesign of the 
 <a href="/pkg/time/"><code>time</code></a> package.
 Instead of an integer number of nanoseconds as an <code>int64</code>,
@@ -824,7 +953,7 @@ func sleepUntil(wakeup time.Time) {
         return
     }
     delta := wakeup.Sub(now) // A Duration.
-    log.Printf("Sleeping for %.3fs", delta.Seconds())
+    fmt.Printf("Sleeping for %.3fs\n", delta.Seconds())
     time.Sleep(delta)
 }</pre>
 
@@ -836,7 +965,7 @@ its representation of file time stamps.
 
 <p>
 <em>Updating</em>:
-The <code>go fix</code> tool will update many uses of the old <code>time</code> package to use the new
+The <code>go</code> <code>fix</code> tool will update many uses of the old <code>time</code> package to use the new
 types and methods, although it does not replace values such as <code>1e9</code>
 representing nanoseconds per second.
 Also, because of type changes in some of the values that arise,
@@ -851,8 +980,10 @@ may have the wrong type or require further analysis.
 <p>
 This section describes smaller changes, such as those to less commonly
 used packages or that affect
-few programs beyond the need to run <code>go fix</code>.
+few programs beyond the need to run <code>go</code> <code>fix</code>.
 This category includes packages that are new in Go 1.
+Collectively they improve portability, regularize behavior, and
+make the interfaces more modern and Go-like.
 </p>
 
 <h3 id="archive_zip">The archive/zip package</h3>
@@ -879,7 +1010,7 @@ If the argument size is too small or invalid, it is adjusted.
 
 <p>
 <em>Updating</em>:
-Running <code>go fix</code> will update calls that assign the error to _.
+Running <code>go</code> <code>fix</code> will update calls that assign the error to _.
 Calls that aren't fixed will be caught by the compiler and must be updated by hand.
 </p>
 
@@ -899,7 +1030,7 @@ to <code>Writer</code> and <code>Reader</code>. Package <code>flate</code>'s
 
 <p>
 <em>Updating</em>
-Running <code>go fix</code> will update old names and calls that assign the error to _.
+Running <code>go</code> <code>fix</code> will update old names and calls that assign the error to _.
 Calls that aren't fixed will be caught by the compiler and must be updated by hand.
 </p>
 
@@ -951,7 +1082,7 @@ a function that returns a <code>hash.Hash</code>, such as <code>md5.New</code>.
 
 <p>
 <em>Updating</em>:
-Running <code>go fix</code> will perform the needed changes.
+Running <code>go</code> <code>fix</code> will perform the needed changes.
 </p>
 
 <h3 id="crypto_x509">The crypto/x509 package</h3>
@@ -998,7 +1129,7 @@ as <a href="/pkg/encoding/gob/"><code>encoding/gob</code></a>.
 The old <code>Parser</code> type is renamed
 <a href="/pkg/encoding/xml/#Decoder"><code>Decoder</code></a> and has a new
 <a href="/pkg/encoding/xml/#Decoder.Decode"><code>Decode</code></a> method. An
-<a href="/pkg/encoding/xml/#Encoder"><code>Encoder</code></a> type was also     introducted.
+<a href="/pkg/encoding/xml/#Encoder"><code>Encoder</code></a> type was also introduced.
 </p>
 
 <p>
@@ -1021,7 +1152,7 @@ of the XML element being marshaled.
 
 <p>
 <em>Updating</em>:
-Running <code>go fix</code> will update most uses of the package except for some calls to
+Running <code>go</code> <code>fix</code> will update most uses of the package except for some calls to
 <code>Unmarshal</code>. Special care must be taken with field tags,
 since the fix tool will not update them and if not fixed by hand they will
 misbehave silently in some cases. For example, the old
@@ -1158,9 +1289,25 @@ accepts a function argument instead.
 </p>
 
 <p>
+In package <a href="/pkg/go/build/"><code>go/build</code></a>, the API
+has been nearly completely replaced.
+The package still computes Go package information
+but it does not run the build: the <code>Cmd</code> and <code>Script</code>
+types are gone.
+(To build code, use the new
+<a href="/cmd/go/"><code>go</code></a> command instead.)
+The <code>DirInfo</code> type is now named
+<a href="/pkg/go/build/#Package"><code>Package</code></a>.
+<code>FindTree</code> and <code>ScanDir</code> are replaced by
+<a href="/pkg/go/build/#Import"><code>Import</code></a>
+and
+<a href="/pkg/go/build/#ImportDir"><code>ImportDir</code></a>.
+</p>
+
+<p>
 <em>Updating</em>:
 Code that uses packages in <code>go</code> will have to be updated by hand; the
-compiler will reject incorrect uses. Templates used in conjuction with any of the
+compiler will reject incorrect uses. Templates used in conjunction with any of the
 <code>go/doc</code> types may need manual fixes; the renamed fields will lead
 to run-time errors.
 </p>
@@ -1185,7 +1332,7 @@ The previous behavior can be recreated by adding a <code>nil</code> argument to
 Existing implementations of <code>hash.Hash</code> will need to add a
 <code>BlockSize</code> method.  Hashes that process the input one byte at
 a time can implement <code>BlockSize</code> to return 1.
-Running <code>go fix</code> will update calls to the <code>Sum</code> methods of the various
+Running <code>go</code> <code>fix</code> will update calls to the <code>Sum</code> methods of the various
 implementations of <code>hash.Hash</code>.
 </p>
 
@@ -1233,7 +1380,7 @@ now panic if an attempt is made to register the same pattern twice.
 
 <p>
 <em>Updating</em>:
-Running <code>go fix</code> will update the few programs that are affected except for
+Running <code>go</code> <code>fix</code> will update the few programs that are affected except for
 uses of <code>RawURL</code>, which must be fixed by hand.
 </p>
 
@@ -1349,7 +1496,7 @@ and
 
 <p>
 <em>Updating</em>:
-Running <code>go fix</code> will update almost all code affected by the change.
+Running <code>go</code> <code>fix</code> will update almost all code affected by the change.
 </p>
 
 <h3 id="log_syslog">The log/syslog package</h3>
@@ -1464,8 +1611,26 @@ the <code>Process</code> type persists.
 </p>
 
 <p>
+The <code>Waitmsg</code> type returned by
+<a href="/pkg/os/#Process.Wait"><code>Process.Wait</code></a>
+has been replaced with a more portable
+<a href="/pkg/os/#ProcessState"><code>ProcessState</code></a>
+type with accessor methods to recover information about the
+process.
+Because of changes to <code>Wait</code>, the <code>ProcessState</code>
+value always describes an exited process.
+Portability concerns simplified the interface in other ways, but the values returned by the
+<a href="/pkg/os/#ProcessState.Sys"><code>ProcessState.Sys</code></a> and
+<a href="/pkg/os/#ProcessState.SysUsage"><code>ProcessState.SysUsage</code></a>
+methods can be type-asserted to underlying system-specific data structures such as
+<a href="/pkg/syscall/#WaitStatus"><code>syscall.WaitStatus</code></a> and
+<a href="/pkg/syscall/#Rusage"><code>syscall.Rusage</code></a> on Unix.
+</p>
+
+<p>
 <em>Updating</em>:
-All changes will be caught by the compiler and must be updated by hand.
+Running <code>go</code> <code>fix</code> will drop a zero argument to <code>Process.Wait</code>.
+All other changes will be caught by the compiler and must be updated by hand.
 </p>
 
 <h4 id="os_fileinfo">The os.FileInfo type</h4>
@@ -1550,13 +1715,46 @@ and
 
 <p>
 <em>Updating</em>:
-Running <code>go fix</code> will update code that uses the old equivalent of the current <code>os.FileInfo</code>
+Running <code>go</code> <code>fix</code> will update code that uses the old equivalent of the current <code>os.FileInfo</code>
 and <code>os.FileMode</code> API.
 Code that needs system-specific file details will need to be updated by hand.
 Code that uses the old POSIX error values from the <code>os</code> package
 will fail to compile and will also need to be updated by hand.
 </p>
 
+<h3 id="os_signal">The os/signal package</h3>
+
+<p>
+The <code>os/signal</code> package in Go 1 replaces the
+<code>Incoming</code> function, which returned a channel
+that received all incoming signals,
+with the selective <code>Notify</code> function, which asks
+for delivery of specific signals on an existing channel.
+</p>
+
+<p>
+<em>Updating</em>:
+Code must be updated by hand.
+A literal translation of
+</p>
+<pre>
+c := signal.Incoming()
+</pre>
+<p>
+is
+</p>
+<pre>
+c := make(chan os.Signal)
+signal.Notify(c) // ask for all signals
+</pre>
+<p>
+but most code should list the specific signals it wants to handle instead:
+</p>
+<pre>
+c := make(chan os.Signal)
+signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT)
+</pre>
+
 <h3 id="path_filepath">The path/filepath package</h3>
 
 <p>
@@ -1569,7 +1767,7 @@ instead of a <code>Visitor</code> interface value.
 </p>
 
 <pre>
-    type WalkFunc func(path string, info *os.FileInfo, err os.Error) os.Error
+    type WalkFunc func(path string, info os.FileInfo, err error) error
 </pre>
 
 <p>
@@ -1602,38 +1800,19 @@ will need to be updated by hand.
 The compiler will catch code using the old interface.
 </p>
 
-<h3 id="os_signal">The os/signal package</h3>
+<h3 id="regexp">The regexp package</h3>
 
 <p>
-The <code>os/signal</code> package in Go 1 replaces the
-<code>Incoming</code> function, which returned a channel
-that received all incoming signals,
-with the selective <code>Notify</code> function, which asks
-for delivery of specific signals on an existing channel.
+The <a href="/pkg/regexp/"><code>regexp</code></a> package has been rewritten.
+It has the same interface but the specification of the regular expressions 
+it supports has changed from the old "egrep" form to that of
+<a href="http://code.google.com/p/re2/">RE2</a>.
 </p>
 
 <p>
 <em>Updating</em>:
-Code must be updated by hand.
-A literal translation of
-</p>
-<pre>
-c := signal.Incoming()
-</pre>
-<p>
-is
-</p>
-<pre>
-c := make(chan os.Signal)
-signal.Notify(c) // ask for all signals
-</pre>
-<p>
-but most code should list the specific signals it wants to handle instead:
+Code that uses the package should have its regular expressions checked by hand.
 </p>
-<pre>
-c := make(chan os.Signal)
-signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT)
-</pre>
 
 <h3 id="runtime">The runtime package</h3>
 
@@ -1671,7 +1850,7 @@ have been renamed to <code>runtime.NumCgoCall</code> and <code>runtime.NumGorout
 
 <p>
 <em>Updating</em>:
-Running <code>go fix</code> will update code for the function renamings.
+Running <code>go</code> <code>fix</code> will update code for the function renamings.
 Other code will need to be updated by hand.
 </p>
 
@@ -1762,11 +1941,11 @@ for full details.
 		
 <p>
 <em>Updating</em>:
-Running <code>go fix</code> will update almost all code affected by the change.
+Running <code>go</code> <code>fix</code> will update almost all code affected by the change.
 <br>
 § <code>Atoi</code> persists but <code>Atoui</code> and <code>Atof32</code> do not, so
 they may require
-a cast that must be added by hand; the <code>go fix</code> tool will warn about it.
+a cast that must be added by hand; the <code>go</code> <code>fix</code> tool will warn about it.
 </p>
 
 
diff --git a/doc/go1.tmpl b/doc/go1.tmpl
index 2f0b326..e5f161e 100644
--- a/doc/go1.tmpl
+++ b/doc/go1.tmpl
@@ -6,29 +6,46 @@
 <h2 id="introduction">Introduction to Go 1</h2>
 
 <p>
-For a full explanation of the motivation and design of Go 1, see XXX.
-Here follows a summary.
+Go version 1, Go 1 for short, defines a language and a set of core libraries
+that provide a stable foundation for creating reliable products, projects, and
+publications.
 </p>
 
 <p>
-Go 1 is intended to be a stable language and core library set that
-will form a reliable foundation for people and organizations that
-want to make a long-term commitment to developing in the Go programming
-language. Go will continue to develop, but in a way that guarantees
-code written to the Go 1 specification will continue to work. For
-instance, Go 1 will be a supported platform on Google App Engine
-for the next few years. Incompatible changes to the environment,
-should they arise, will be done in a distinct version.
+The driving motivation for Go 1 is stability for its users. People should be able to
+write Go programs and expect that they will continue to compile and run without
+change, on a time scale of years, including in production environments such as
+Google App Engine. Similarly, people should be able to write books about Go, be
+able to say which version of Go the book is describing, and have that version
+number still be meaningful much later.
 </p>
 
 <p>
-This document describes the changes in the language and libraries
-in Go 1, relative to the previous release, r60 (at the time of
-writing, tagged as r60.3). It also explains how to update code at
-r60 to compile and run under Go 1. Finally, it outlines the new
-<code>go</code> command for building Go programs and the new binary
-release process being introduced. Most of these topics have more
-thorough presentations elsewhere; such documents are linked below.
+Code that compiles in Go 1 should, with few exceptions, continue to compile and
+run throughout the lifetime of that version, even as we issue updates and bug
+fixes such as Go version 1.1, 1.2, and so on. Other than critical fixes, changes
+made to the language and library for subsequent releases of Go 1 may
+add functionality but will not break existing Go 1 programs.
+<a href="go1compat.html">The Go 1 compatibility document</a>
+explains the compatibility guidelines in more detail.
+</p>
+
+<p>
+Go 1 is a representation of Go as it used today, not a wholesale rethinking of
+the language. We avoided designing new features and instead focused on cleaning
+up problems and inconsistencies and improving portability. There are a number
+changes to the Go language and packages that we had considered for some time and
+prototyped but not released primarily because they are significant and
+backwards-incompatible. Go 1 was an opportunity to get them out, which is
+helpful for the long term, but also means that Go 1 introduces incompatibilities
+for old programs. Fortunately, the <code>go</code> <code>fix</code> tool can
+automate much of the work needed to bring programs up to the Go 1 standard.
+</p>
+
+<p>
+This document outlines the major changes in Go 1 that will affect programmers
+updating existing code; its reference point is the prior release, r60 (tagged as
+r60.3). It also explains how to update code from r60 to run under Go 1.
 </p>
 
 <h2 id="language">Changes to the language</h2>
@@ -36,9 +53,11 @@ thorough presentations elsewhere; such documents are linked below.
 <h3 id="append">Append</h3>
 
 <p>
-The <code>append</code> built-in function is variadic, so one can
-append to a byte slice using the <code>...</code> syntax in the
-call.
+The <code>append</code> predeclared variadic function makes it easy to grow a slice
+by adding elements to the end.
+A common use is to add bytes to the end of a byte slice when generating output.
+However, <code>append</code> did not provide a way to append a string to a <code>[]byte</code>,
+which is another common case.
 </p>
 
 {{code "progs/go1.go" `/greeting := ..byte/` `/append.*hello/`}}
@@ -46,7 +65,8 @@ call.
 <p>
 By analogy with the similar property of <code>copy</code>, Go 1
 permits a string to be appended (byte-wise) directly to a byte
-slice; the conversion is no longer necessary:
+slice, reducing the friction between strings and byte slices.
+The conversion is no longer necessary:
 </p>
 
 {{code "progs/go1.go" `/append.*world/`}}
@@ -59,10 +79,20 @@ This is a new feature, so existing code needs no changes.
 <h3 id="close">Close</h3>
 
 <p>
-The <code>close</code> built-in function lets a sender tell a receiver
-that no more data will be transmitted on the channel.  In Go 1 the
-type system enforces the directionality when possible: it is illegal
-to call <code>close</code> on a receive-only channel:
+The <code>close</code> predeclared function provides a mechanism
+for a sender to signal that no more values will be sent.
+It is important to the implementation of <code>for</code> <code>range</code>
+loops over channels and is helpful in other situations.
+Partly by design and partly because of race conditions that can occur otherwise,
+it is intended for use only by the goroutine sending on the channel,
+not by the goroutine receiving data.
+However, before Go 1 there was no compile-time checking that <code>close</code>
+was being used correctly.
+</p>
+
+<p>
+To close this gap, at least in part, Go 1 disallows <code>close</code> on receive-only channels.
+Attempting to close such a channel is a compile-time error.
 </p>
 
 <pre>
@@ -102,9 +132,18 @@ will, among other things, elide explicit element types wherever permitted.
 <h3 id="init">Goroutines during init</h3>
 
 <p>
-Go 1 allows goroutines to be created and run during initialization.
-(They used to be created but were not run until after initialization
-completed.) Code that uses goroutines can now be called from
+The old language defined that <code>go</code> statements executed during initialization created goroutines but that they did not begin to run until initialization of the entire program was complete.
+This introduced clumsiness in many places and, in effect, limited the utility
+of the <code>init</code> construct:
+if it was possible for another package to use the library during initialization, the library
+was forced to avoid goroutines.
+This design was done for reasons of simplicity and safety but,
+as our confidence in the language grew, it seemed unnecessary.
+Running goroutines during initialization is no more complex or unsafe than running them during normal execution.
+</p>
+
+<p>
+In Go 1, code that uses goroutines can be called from
 <code>init</code> routines and global initialization expressions
 without introducing a deadlock.
 </p>
@@ -121,7 +160,16 @@ There was no such code in the standard repository.
 <h3 id="rune">The rune type</h3>
 
 <p>
-Go 1 introduces a new basic type, <code>rune</code>, to be used to represent
+The language spec allows the <code>int</code> type to be 32 or 64 bits wide, but current implementations set <code>int</code> to 32 bits even on 64-bit platforms.
+It would be preferable to have <code>int</code> be 64 bits on 64-bit platforms.
+(There are important consequences for indexing large slices.)
+However, this change would waste space when processing Unicode characters with
+the old language because the <code>int</code> type was also used to hold Unicode code points: each code point would waste an extra 32 bits of storage if <code>int</code> grew from 32 bits to 64.
+</p>
+
+<p>
+To make changing to 64-bit <code>int</code> feasible,
+Go 1 introduces a new basic type, <code>rune</code>, to represent
 individual Unicode code points.
 It is an alias for <code>int32</code>, analogous to <code>byte</code>
 as an alias for <code>uint8</code>.
@@ -171,14 +219,21 @@ it is discussed <a href="#errors">below</a>.
 <h3 id="delete">Deleting from maps</h3>
 
 <p>
-The original syntax for deleting an element in a map was:
+In the old language, to delete the entry with key <code>k</code> from map <code>m</code>, one wrote the statement,
 </p>
 
 <pre>
-    m[k] = ignored, false
+    m[k] = value, false
 </pre>
 
 <p>
+This syntax was a peculiar special case, the only two-to-one assignment.
+It required passing a value (usually ignored) that is evaluated but discarded,
+plus a boolean that was nearly always the constant <code>false</code>.
+It did the job but was odd and a point of contention.
+</p>
+
+<p>
 In Go 1, that syntax has gone; instead there is a new built-in
 function, <code>delete</code>.  The call
 </p>
@@ -192,7 +247,7 @@ There is no return value. Deleting a non-existent entry is a no-op.
 
 <p>
 <em>Updating</em>:
-Running <code>go fix</code> will convert expressions of the form <code>m[k] = ignored,
+Running <code>go</code> <code>fix</code> will convert expressions of the form <code>m[k] = value,
 false</code> into <code>delete(m, k)</code> when it is clear that
 the ignored value can be safely discarded from the program and
 <code>false</code> refers to the predefined boolean constant.
@@ -203,6 +258,13 @@ will flag other uses of the syntax for inspection by the programmer.
 <h3 id="iteration">Iterating in maps</h3>
 
 <p>
+The old language specification did not define the order of iteration for maps,
+and in practice it differed across hardware platforms.
+This caused tests that iterated over maps to be fragile and non-portable, with the
+unpleasant property that a test might always pass on one machine but break on another.
+</p>
+
+<p>
 In Go 1, the order in which elements are visited when iterating
 over a map using a <code>for</code> <code>range</code> statement
 is defined to be unpredictable, even if the same loop is run multiple
@@ -210,6 +272,11 @@ times with the same map.
 Code should not assume that the elements are visited in any particular order.
 </p>
 
+<p>
+This change means that code that depends on iteration order is very likely to break early and be fixed long before it becomes a problem.
+Just as important, it allows the map implementation to ensure better map balancing even when programs are using range loops to select an element from a map.
+</p>
+
 {{code "progs/go1.go" `/Sunday/` `/^	}/`}}
 
 <p>
@@ -226,8 +293,14 @@ was unspecified. This change codifies the unpredictability.
 <h3 id="multiple_assignment">Multiple assignment</h3>
 
 <p>
-Go 1 fully specifies the evaluation order in multiple assignment
-statements. In particular, if the left-hand side of the assignment
+The language specification has long guaranteed that in assignments
+the right-hand-side expressions are all evaluated before any left-hand-side expressions are assigned.
+To guarantee predictable behavior,
+Go 1 refines the specification further.
+</p>
+
+<p>
+If the left-hand side of the assignment
 statement contains expressions that require evaluation, such as
 function calls or array indexing operations, these will all be done
 using the usual left-to-right rule before any variables are assigned
@@ -251,7 +324,11 @@ that depended on the previous unspecified behavior was already incorrect.
 <h3 id="shadowing">Returns and shadowed variables</h3>
 
 <p>
-A shadowed variable is one that has the same name as another variable in an inner scope.
+A common mistake is to use <code>return</code> (without arguments) after an assignment to a variable that has the same name as a result variable but is not the same variable.
+This situation is called <em>shadowing</em>: the result variable has been shadowed by another variable with the same name declared in an inner scope.
+</p>
+
+<p>
 In functions with named return values,
 the Go 1 compilers disallow return statements without arguments if any of the named return values is shadowed at the point of the return statement.
 (It isn't part of the specification, because this is one area we are still exploring;
@@ -285,9 +362,17 @@ The few cases that arose in the standard repository were mostly bugs.
 <h3 id="unexported">Copying structs with unexported fields</h3>
 
 <p>
-Go 1 relaxes the rules about accessing structs with unexported (lower-case) fields,
-permitting a client package to assign (and therefore copy) such a struct.
-Of course, the client package still cannot access such fields individually.
+The old language did not allow a package to make a copy of a struct value containing unexported fields belonging to a different package.
+There was, however, a required exception for a method receiver;
+also, the implementations of <code>copy</code> and <code>append</code> have never honored the restriction.
+</p>
+
+<p>
+Go 1 will allow packages to copy struct values containing unexported fields from other packages.
+Besides resolving the inconsistency,
+this change admits a new kind of API: a package can return an opaque value without resorting to a pointer or interface.
+The new implementations of <code>time.Time</code> and
+<code>reflect.Value</code> are examples of types taking advantage of this new property.
 </p>
 
 <p>
@@ -332,23 +417,37 @@ will show that the secret field of the struct has been copied to the new value.
 This is a new feature, so existing code needs no changes.
 </p>
 
-<h3 id="equality">Equality of structs and arrays</h3>
+<h3 id="equality">Equality</h3>
 
 <p>
-Go 1 defines equality and inequality (<code>==</code> and
-<code>!=</code>) for struct and array values, respectively, provided
-the elements of the data structures can themselves be compared.
-That is, if equality is defined for all the fields of a struct (or
-an array element), then it is defined for the struct (or array).
+Before Go 1, the language did not define equality on struct and array values.
+This meant,
+among other things, that structs and arrays could not be used as map keys.
+On the other hand, Go did define equality on function and map values.
+Function equality was problematic in the presence of closures
+(when are two closures equal?)
+while map equality compared pointers, not the maps' content, which was usually
+not what the user would want.
 </p>
 
 <p>
-As a result, structs and arrays can now be used as map keys:
+Go 1 addressed these issues.
+First, structs and arrays can be compared for equality and inequality
+(<code>==</code> and <code>!=</code>),
+and therefore be used as map keys,
+provided they are composed from elements for which equality is also defined,
+using element-wise comparison.
 </p>
 
 {{code "progs/go1.go" `/type Day struct/` `/Printf/`}}
 
 <p>
+Second, Go 1 removes the definition of equality for function values,
+except for comparison with <code>nil</code>.
+Finally, map equality is gone too, also except for comparison with <code>nil</code>.
+</p>
+
+<p>
 Note that equality is still undefined for slices, for which the
 calculation is in general infeasible.  Also note that the ordered
 comparison operators (<code><</code> <code><=</code>
@@ -357,18 +456,7 @@ structs and arrays.
 
 <p>
 <em>Updating</em>:
-This is a new feature, so existing code needs no changes.
-</p>
-
-<h3 id="funcs">Function and map equality</h3>
-
-<p>
-Go 1 disallows checking for equality of functions and maps,
-respectively, except to compare them directly to <code>nil</code>.
-</p>
-
-<p>
-<em>Updating</em>:
+Struct and array equality is a new feature, so existing code needs no changes.
 Existing code that depends on function or map equality will be
 rejected by the compiler and will need to be fixed by hand.
 Few programs will be affected, but the fix may require some
@@ -378,6 +466,12 @@ redesign.
 <h2 id="packages">The package hierarchy</h2>
 
 <p>
+Go 1 addresses many deficiencies in the old standard library and
+cleans up a number of packages, making them more internally consistent
+and portable.
+</p>
+
+<p>
 This section describes how the packages have been rearranged in Go 1.
 Some have moved, some have been renamed, some have been deleted.
 New packages are described in later sections.
@@ -459,7 +553,7 @@ and <code>template</code>.
 
 <p>
 <em>Updating</em>:
-Running <code>go fix</code> will update all imports and package renames for packages that
+Running <code>go</code> <code>fix</code> will update all imports and package renames for packages that
 remain inside the standard repository.  Programs that import packages
 that are no longer in the standard repository will need to be edited
 by hand.
@@ -480,11 +574,16 @@ Several packages have moved under <code>exp</code> at the time of Go 1's release
 
 <ul>
 <li><code>ebnf</code></li>
+<li><code>html</code><sup>†</sup></li>
 <li><code>go/types</code></li>
-<li><code>os/signal</code></li>
 </ul>
 
 <p>
+(<sup>†</sup>The <code>EscapeString</code> and <code>UnescapeString</code> types remain
+in package <code>html</code>.)
+</p>
+
+<p>
 All these packages are available under the same names, with the prefix <code>exp/</code>: <code>exp/ebnf</code> etc.
 </p>
 
@@ -502,7 +601,7 @@ If they are installed, they now reside in <code>$GOROOT/bin/tool</code>.
 <em>Updating</em>:
 Code that uses packages in <code>exp</code> will need to be updated by hand,
 or else compiled from an installation that has <code>exp</code> available.
-The <code>go fix</code> tool or the compiler will complain about such uses.
+The <code>go</code> <code>fix</code> tool or the compiler will complain about such uses.
 </p>
 
 <h3 id="old">The package tree old</h3>
@@ -527,7 +626,7 @@ The packages in their new locations are:
 <em>Updating</em>:
 Code that uses packages now in <code>old</code> will need to be updated by hand,
 or else compiled from an installation that has <code>old</code> available.
-The <code>go fix</code> tool will warn about such uses.
+The <code>go</code> <code>fix</code> tool will warn about such uses.
 </p>
 
 <h3 id="deleted">Deleted packages</h3>
@@ -608,7 +707,7 @@ This table lists the old and new import paths:
 
 <p>
 <em>Updating</em>:
-Running <code>go fix</code> will update imports of these packages to use the new import paths.
+Running <code>go</code> <code>fix</code> will update imports of these packages to use the new import paths.
 Installations that depend on these packages will need to install them using
 a <code>go install</code> command.
 </p>
@@ -623,8 +722,19 @@ affect the most programs.
 <h3 id="errors">The error type and errors package</h3>
 
 <p>
-As mentioned above, Go 1 introduces a new built-in interface type called <code>error</code>.
-Its intent is to replace the old <code>os.Error</code> type with a more central concept.
+The placement of <code>os.Error</code> in package <code>os</code> is mostly historical: errors first came up when implementing package <code>os</code>, and they seemed system-related at the time.
+Since then it has become clear that errors are more fundamental than the operating system.  For example, it would be nice to use <code>Errors</code> in packages that <code>os</code> depends on, like <code>syscall</code>.
+Also, having <code>Error</code> in <code>os</code> introduces many dependencies on <code>os</code> that would otherwise not exist.
+</p>
+
+<p>
+Go 1 solves these problems by introducing a built-in <code>error</code> interface type and a separate <code>errors</code> package (analogous to <code>bytes</code> and <code>strings</code>) that contains utility functions.
+It replaces <code>os.NewError</code> with
+<a href="/pkg/errors/#New"><code>errors.New</code></a>,
+giving errors a more central place in the environment.
+</p>
+
+<p>
 So the widely-used <code>String</code> method does not cause accidental satisfaction
 of the <code>error</code> interface, the <code>error</code> interface uses instead
 the name <code>Error</code> for that method:
@@ -663,7 +773,7 @@ to turn a string into an error. It replaces the old <code>os.NewError</code>.
 		
 <p>
 <em>Updating</em>:
-Running <code>go fix</code> will update almost all code affected by the change.
+Running <code>go</code> <code>fix</code> will update almost all code affected by the change.
 Code that defines error types with a <code>String</code> method will need to be updated
 by hand to rename the methods to <code>Error</code>.
 </p>
@@ -671,18 +781,30 @@ by hand to rename the methods to <code>Error</code>.
 <h3 id="errno">System call errors</h3>
 
 <p>
+The old <code>syscall</code> package, which predated <code>os.Error</code>
+(and just about everything else),
+returned errors as <code>int</code> values.
+In turn, the <code>os</code> package forwarded many of these errors, such
+as <code>EINVAL</code>, but using a different set of errors on each platform.
+This behavior was unpleasant and unportable.
+</p>
+
+<p>
 In Go 1, the
 <a href="/pkg/syscall/"><code>syscall</code></a>
-package returns an <code>error</code> for system call errors,
-rather than plain integer <code>errno</code> values.
+package instead returns an <code>error</code> for system call errors.
 On Unix, the implementation is done by a 
 <a href="/pkg/syscall/#Errno"><code>syscall.Errno</code></a> type
 that satisfies <code>error</code> and replaces the old <code>os.Errno</code>.
 </p>
 
 <p>
+The changes affecting <code>os.EINVAL</code> and relatives are
+described <a href="#os">elsewhere</a>.
+
+<p>
 <em>Updating</em>:
-Running <code>go fix</code> will update almost all code affected by the change.
+Running <code>go</code> <code>fix</code> will update almost all code affected by the change.
 Regardless, most code should use the <code>os</code> package
 rather than <code>syscall</code> and so will be unaffected.
 </p>
@@ -690,7 +812,14 @@ rather than <code>syscall</code> and so will be unaffected.
 <h3 id="time">Time</h3>
 
 <p>
-One of the most sweeping changes in the Go 1 library is the
+Time is always a challenge to support well in a programming language.
+The old Go <code>time</code> package had <code>int64</code> units, no
+real type safety,
+and no distinction between absolute times and durations.
+</p>
+
+<p>
+One of the most sweeping changes in the Go 1 library is therefore a
 complete redesign of the 
 <a href="/pkg/time/"><code>time</code></a> package.
 Instead of an integer number of nanoseconds as an <code>int64</code>,
@@ -740,7 +869,7 @@ its representation of file time stamps.
 
 <p>
 <em>Updating</em>:
-The <code>go fix</code> tool will update many uses of the old <code>time</code> package to use the new
+The <code>go</code> <code>fix</code> tool will update many uses of the old <code>time</code> package to use the new
 types and methods, although it does not replace values such as <code>1e9</code>
 representing nanoseconds per second.
 Also, because of type changes in some of the values that arise,
@@ -755,8 +884,10 @@ may have the wrong type or require further analysis.
 <p>
 This section describes smaller changes, such as those to less commonly
 used packages or that affect
-few programs beyond the need to run <code>go fix</code>.
+few programs beyond the need to run <code>go</code> <code>fix</code>.
 This category includes packages that are new in Go 1.
+Collectively they improve portability, regularize behavior, and
+make the interfaces more modern and Go-like.
 </p>
 
 <h3 id="archive_zip">The archive/zip package</h3>
@@ -783,7 +914,7 @@ If the argument size is too small or invalid, it is adjusted.
 
 <p>
 <em>Updating</em>:
-Running <code>go fix</code> will update calls that assign the error to _.
+Running <code>go</code> <code>fix</code> will update calls that assign the error to _.
 Calls that aren't fixed will be caught by the compiler and must be updated by hand.
 </p>
 
@@ -803,7 +934,7 @@ to <code>Writer</code> and <code>Reader</code>. Package <code>flate</code>'s
 
 <p>
 <em>Updating</em>
-Running <code>go fix</code> will update old names and calls that assign the error to _.
+Running <code>go</code> <code>fix</code> will update old names and calls that assign the error to _.
 Calls that aren't fixed will be caught by the compiler and must be updated by hand.
 </p>
 
@@ -855,7 +986,7 @@ a function that returns a <code>hash.Hash</code>, such as <code>md5.New</code>.
 
 <p>
 <em>Updating</em>:
-Running <code>go fix</code> will perform the needed changes.
+Running <code>go</code> <code>fix</code> will perform the needed changes.
 </p>
 
 <h3 id="crypto_x509">The crypto/x509 package</h3>
@@ -902,7 +1033,7 @@ as <a href="/pkg/encoding/gob/"><code>encoding/gob</code></a>.
 The old <code>Parser</code> type is renamed
 <a href="/pkg/encoding/xml/#Decoder"><code>Decoder</code></a> and has a new
 <a href="/pkg/encoding/xml/#Decoder.Decode"><code>Decode</code></a> method. An
-<a href="/pkg/encoding/xml/#Encoder"><code>Encoder</code></a> type was also     introducted.
+<a href="/pkg/encoding/xml/#Encoder"><code>Encoder</code></a> type was also introduced.
 </p>
 
 <p>
@@ -925,7 +1056,7 @@ of the XML element being marshaled.
 
 <p>
 <em>Updating</em>:
-Running <code>go fix</code> will update most uses of the package except for some calls to
+Running <code>go</code> <code>fix</code> will update most uses of the package except for some calls to
 <code>Unmarshal</code>. Special care must be taken with field tags,
 since the fix tool will not update them and if not fixed by hand they will
 misbehave silently in some cases. For example, the old
@@ -1061,9 +1192,25 @@ accepts a function argument instead.
 </p>
 
 <p>
+In package <a href="/pkg/go/build/"><code>go/build</code></a>, the API
+has been nearly completely replaced.
+The package still computes Go package information
+but it does not run the build: the <code>Cmd</code> and <code>Script</code>
+types are gone.
+(To build code, use the new
+<a href="/cmd/go/"><code>go</code></a> command instead.)
+The <code>DirInfo</code> type is now named
+<a href="/pkg/go/build/#Package"><code>Package</code></a>.
+<code>FindTree</code> and <code>ScanDir</code> are replaced by
+<a href="/pkg/go/build/#Import"><code>Import</code></a>
+and
+<a href="/pkg/go/build/#ImportDir"><code>ImportDir</code></a>.
+</p>
+
+<p>
 <em>Updating</em>:
 Code that uses packages in <code>go</code> will have to be updated by hand; the
-compiler will reject incorrect uses. Templates used in conjuction with any of the
+compiler will reject incorrect uses. Templates used in conjunction with any of the
 <code>go/doc</code> types may need manual fixes; the renamed fields will lead
 to run-time errors.
 </p>
@@ -1088,7 +1235,7 @@ The previous behavior can be recreated by adding a <code>nil</code> argument to
 Existing implementations of <code>hash.Hash</code> will need to add a
 <code>BlockSize</code> method.  Hashes that process the input one byte at
 a time can implement <code>BlockSize</code> to return 1.
-Running <code>go fix</code> will update calls to the <code>Sum</code> methods of the various
+Running <code>go</code> <code>fix</code> will update calls to the <code>Sum</code> methods of the various
 implementations of <code>hash.Hash</code>.
 </p>
 
@@ -1136,7 +1283,7 @@ now panic if an attempt is made to register the same pattern twice.
 
 <p>
 <em>Updating</em>:
-Running <code>go fix</code> will update the few programs that are affected except for
+Running <code>go</code> <code>fix</code> will update the few programs that are affected except for
 uses of <code>RawURL</code>, which must be fixed by hand.
 </p>
 
@@ -1252,7 +1399,7 @@ and
 
 <p>
 <em>Updating</em>:
-Running <code>go fix</code> will update almost all code affected by the change.
+Running <code>go</code> <code>fix</code> will update almost all code affected by the change.
 </p>
 
 <h3 id="log_syslog">The log/syslog package</h3>
@@ -1367,8 +1514,26 @@ the <code>Process</code> type persists.
 </p>
 
 <p>
+The <code>Waitmsg</code> type returned by
+<a href="/pkg/os/#Process.Wait"><code>Process.Wait</code></a>
+has been replaced with a more portable
+<a href="/pkg/os/#ProcessState"><code>ProcessState</code></a>
+type with accessor methods to recover information about the
+process.
+Because of changes to <code>Wait</code>, the <code>ProcessState</code>
+value always describes an exited process.
+Portability concerns simplified the interface in other ways, but the values returned by the
+<a href="/pkg/os/#ProcessState.Sys"><code>ProcessState.Sys</code></a> and
+<a href="/pkg/os/#ProcessState.SysUsage"><code>ProcessState.SysUsage</code></a>
+methods can be type-asserted to underlying system-specific data structures such as
+<a href="/pkg/syscall/#WaitStatus"><code>syscall.WaitStatus</code></a> and
+<a href="/pkg/syscall/#Rusage"><code>syscall.Rusage</code></a> on Unix.
+</p>
+
+<p>
 <em>Updating</em>:
-All changes will be caught by the compiler and must be updated by hand.
+Running <code>go</code> <code>fix</code> will drop a zero argument to <code>Process.Wait</code>.
+All other changes will be caught by the compiler and must be updated by hand.
 </p>
 
 <h4 id="os_fileinfo">The os.FileInfo type</h4>
@@ -1449,13 +1614,46 @@ and
 
 <p>
 <em>Updating</em>:
-Running <code>go fix</code> will update code that uses the old equivalent of the current <code>os.FileInfo</code>
+Running <code>go</code> <code>fix</code> will update code that uses the old equivalent of the current <code>os.FileInfo</code>
 and <code>os.FileMode</code> API.
 Code that needs system-specific file details will need to be updated by hand.
 Code that uses the old POSIX error values from the <code>os</code> package
 will fail to compile and will also need to be updated by hand.
 </p>
 
+<h3 id="os_signal">The os/signal package</h3>
+
+<p>
+The <code>os/signal</code> package in Go 1 replaces the
+<code>Incoming</code> function, which returned a channel
+that received all incoming signals,
+with the selective <code>Notify</code> function, which asks
+for delivery of specific signals on an existing channel.
+</p>
+
+<p>
+<em>Updating</em>:
+Code must be updated by hand.
+A literal translation of
+</p>
+<pre>
+c := signal.Incoming()
+</pre>
+<p>
+is
+</p>
+<pre>
+c := make(chan os.Signal)
+signal.Notify(c) // ask for all signals
+</pre>
+<p>
+but most code should list the specific signals it wants to handle instead:
+</p>
+<pre>
+c := make(chan os.Signal)
+signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT)
+</pre>
+
 <h3 id="path_filepath">The path/filepath package</h3>
 
 <p>
@@ -1468,7 +1666,7 @@ instead of a <code>Visitor</code> interface value.
 </p>
 
 <pre>
-    type WalkFunc func(path string, info *os.FileInfo, err os.Error) os.Error
+    type WalkFunc func(path string, info os.FileInfo, err error) error
 </pre>
 
 <p>
@@ -1487,38 +1685,19 @@ will need to be updated by hand.
 The compiler will catch code using the old interface.
 </p>
 
-<h3 id="os_signal">The os/signal package</h3>
+<h3 id="regexp">The regexp package</h3>
 
 <p>
-The <code>os/signal</code> package in Go 1 replaces the
-<code>Incoming</code> function, which returned a channel
-that received all incoming signals,
-with the selective <code>Notify</code> function, which asks
-for delivery of specific signals on an existing channel.
+The <a href="/pkg/regexp/"><code>regexp</code></a> package has been rewritten.
+It has the same interface but the specification of the regular expressions 
+it supports has changed from the old "egrep" form to that of
+<a href="http://code.google.com/p/re2/">RE2</a>.
 </p>
 
 <p>
 <em>Updating</em>:
-Code must be updated by hand.
-A literal translation of
-</p>
-<pre>
-c := signal.Incoming()
-</pre>
-<p>
-is
-</p>
-<pre>
-c := make(chan os.Signal)
-signal.Notify(c) // ask for all signals
-</pre>
-<p>
-but most code should list the specific signals it wants to handle instead:
+Code that uses the package should have its regular expressions checked by hand.
 </p>
-<pre>
-c := make(chan os.Signal)
-signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT)
-</pre>
 
 <h3 id="runtime">The runtime package</h3>
 
@@ -1556,7 +1735,7 @@ have been renamed to <code>runtime.NumCgoCall</code> and <code>runtime.NumGorout
 
 <p>
 <em>Updating</em>:
-Running <code>go fix</code> will update code for the function renamings.
+Running <code>go</code> <code>fix</code> will update code for the function renamings.
 Other code will need to be updated by hand.
 </p>
 
@@ -1647,11 +1826,11 @@ for full details.
 		
 <p>
 <em>Updating</em>:
-Running <code>go fix</code> will update almost all code affected by the change.
+Running <code>go</code> <code>fix</code> will update almost all code affected by the change.
 <br>
 § <code>Atoi</code> persists but <code>Atoui</code> and <code>Atof32</code> do not, so
 they may require
-a cast that must be added by hand; the <code>go fix</code> tool will warn about it.
+a cast that must be added by hand; the <code>go</code> <code>fix</code> tool will warn about it.
 </p>
 
 
diff --git a/doc/go_faq.html b/doc/go_faq.html
index 5e213ff..d95da0f 100644
--- a/doc/go_faq.html
+++ b/doc/go_faq.html
@@ -756,7 +756,7 @@ Similar situations to those described here can arise whenever interfaces are use
 Just keep in mind that if any concrete value
 has been stored in the interface, the interface will not be <code>nil</code>.
 For more information, see
-<a href="http://blog.golang.org/2011/09/laws-of-reflection.html">this blog post</a>.
+<a href="/doc/articles/laws_of_reflection.html">The Laws of Reflection</a>.
 </p>
 
 
@@ -1060,7 +1060,7 @@ What operations are atomic? What about mutexes?</h3>
 
 <p>
 We haven't fully defined it all yet, but some details about atomicity are
-available in the <a href="go_mem.html">Go Memory Model specification</a>.
+available in the <a href="/ref/mem">Go Memory Model specification</a>.
 </p>
 
 <p>
@@ -1113,7 +1113,7 @@ will experience performance degradation when using
 multiple OS threads.
 This is because sending data between threads involves switching
 contexts, which has significant cost.
-For instance, the <a href="/doc/go_spec.html#An_example_package">prime sieve example</a>
+For instance, the <a href="/ref/spec#An_example_package">prime sieve example</a>
 from the Go specification has no significant parallelism although it launches many
 goroutines; increasing <code>GOMAXPROCS</code> is more likely to slow it down than
 to speed it up.
@@ -1131,7 +1131,7 @@ should recognize such cases and optimize its use of OS threads. For now,
 Why do T and *T have different method sets?</h3>
 
 <p>
-From the <a href="http://golang.org/doc/go_spec.html#Types">Go Spec</a>:
+From the <a href="/ref/spec#Types">Go Spec</a>:
 </p>
 
 <blockquote>
@@ -1524,7 +1524,9 @@ declaration should present the same order as <code>:=</code> so
 <pre>
     var a uint64 = 1
 </pre>
+<p>
 has the same effect as
+</p>
 <pre>
     a := uint64(1)
 </pre>
diff --git a/doc/go_for_cpp_programmers.html b/doc/go_for_cpp_programmers.html
deleted file mode 100644
index 8e21519..0000000
--- a/doc/go_for_cpp_programmers.html
+++ /dev/null
@@ -1,709 +0,0 @@
-<!--{
-	"Title": "Go For C++ Programmers"
-}-->
-
-<p>
-Go is a systems programming language intended to be a general-purpose
-systems language, like C++.
-These are some notes on Go for experienced C++ programmers. This
-document discusses the differences between Go and C++, and says little
-to nothing about the similarities.
-
-<p>
-For a more general introduction to Go, see the
-<a href="go_tutorial.html">Go tutorial</a> and
-<a href="effective_go.html">Effective Go</a>.
-
-<p>
-For a detailed description of the Go language, see the
-<a href="go_spec.html">Go spec</a>.
-
-<h2 id="Conceptual_Differences">Conceptual Differences</h2>
-
-<ul>
-<li>Go does not have classes with constructors or destructors.
-    Instead of class methods, a class inheritance hierarchy,
-    and virtual functions, Go provides <em>interfaces</em>, which are
-    <a href="#Interfaces">discussed in more detail below</a>.
-    Interfaces are also used where C++ uses templates.
-
-<li>Go uses garbage collection. It is not necessary (or possible)
-    to release memory explicitly. The garbage collection is (intended to be)
-    incremental and highly efficient on modern processors.
-
-<li>Go has pointers but not pointer arithmetic. You cannot
-    use a pointer variable to walk through the bytes of a string.
-
-<li>Arrays in Go are first class values. When an array is used as a
-    function parameter, the function receives a copy of the array, not
-    a pointer to it. However, in practice functions often use slices
-    for parameters; slices hold pointers to underlying arrays.  Slices
-    are <a href="#Slices">discussed further below</a>.
-
-<li>Strings are provided by the language. They may not be changed once they
-    have been created.
-
-<li>Hash tables are provided by the language. They are called maps.
-
-<li>Separate threads of execution, and communication channels between
-    them, are provided by the language. This
-    is <a href="#Goroutines">discussed further below</a>.
-
-<li>Certain types (maps and channels, described further below)
-    are passed by reference, not by value. That is, passing a map to a
-    function does not copy the map, and if the function changes the map
-    the change will be seen by the caller.  In C++ terms, one can
-    think of these as being reference types.
-
-<li>Go does not use header files. Instead, each source file is part of a
-    defined <em>package</em>. When a package defines an object
-    (type, constant, variable, function) with a name starting with an
-    upper case letter, that object is visible to any other file which
-    imports that package.
-
-<li>Go does not support implicit type conversion. Operations that mix
-    different types require casts (called conversions in Go).
-
-<li>Go does not support function overloading and does not support user
-    defined operators.
-
-<li>Go does not support <code>const</code> or <code>volatile</code> qualifiers.
-
-<li>Go uses <code>nil</code> for invalid pointers, where C++ uses
-    <code>NULL</code> or simply <code>0</code>.
-</ul>
-
-<h2 id="Syntax">Syntax</h2>
-
-<p>
-The declaration syntax is reversed compared to C++. You write the name
-followed by the type. Unlike in C++, the syntax for a type does not match
-the way in which the variable is used. Type declarations may be read
-easily from left to right.
-
-<pre>
-<b>Go                           C++</b>
-var v1 int                // int v1;
-var v2 string             // const std::string v2;  (approximately)
-var v3 [10]int            // int v3[10];
-var v4 []int              // int* v4;  (approximately)
-var v5 struct { f int }   // struct { int f; } v5;
-var v6 *int               // int* v6;  (but no pointer arithmetic)
-var v7 map[string]int     // unordered_map<string, int>* v7;  (approximately)
-var v8 func(a int) int    // int (*v8)(int a);
-</pre>
-
-<p>
-Declarations generally take the form of a keyword followed by the name
-of the object being declared.  The keyword is one of <code>var</code>,
-<code>func</code>,
-<code>const</code>, or <code>type</code>.  Method declarations are a minor
-exception in that
-the receiver appears before the name of the object being declared; see
-the <a href="#Interfaces">discussion of interfaces</a>.
-
-<p>
-You can also use a keyword followed by a series of declarations in
-parentheses.
-
-<pre>
-var (
-    i int
-    m float64
-)
-</pre>
-
-<p>
-When declaring a function, you must either provide a name for each parameter
-or not provide a name for any parameter; you can't omit some names
-and provide others.  You may group several names with the same type:
-
-<pre>
-func f(i, j, k int, s, t string)
-</pre>
-
-<p>
-A variable may be initialized when it is declared.  When this is done,
-specifying the type is permitted but not required.  When the type is
-not specified, the type of the variable is the type of the
-initialization expression.
-
-<pre>
-var v = *p
-</pre>
-
-<p>
-See also the <a href="#Constants">discussion of constants, below</a>.
-If a variable is not initialized explicitly, the type must be specified.
-In that case it will be
-implicitly initialized to the type's zero value (0, nil, etc.).  There are no
-uninitialized variables in Go.
-
-<p>
-Within a function, a short declaration syntax is available with
-<code>:=</code> .
-
-<pre>
-v1 := v2
-</pre>
-
-<p>
-This is equivalent to
-
-<pre>
-var v1 = v2
-</pre>
-
-<p>
-Go permits multiple assignments, which are done in parallel.
-
-<pre>
-i, j = j, i    // Swap i and j.
-</pre>
-
-<p>
-Functions may have multiple return values, indicated by a list in
-parentheses.  The returned values can be stored by assignment
-to a list of variables.
-
-<pre>
-func f() (i int, j int) { ... }
-v1, v2 = f()
-</pre>
-
-<p>
-Go code uses very few semicolons in practice.  Technically, all Go
-statements are terminated by a semicolon.  However, Go treats the end
-of a non-blank line as a semicolon unless the line is clearly
-incomplete (the exact rules are
-in <a href="go_spec.html#Semicolons">the language specification</a>).
-A consequence of this is that in some cases Go does not permit you to
-use a line break.  For example, you may not write
-<pre>
-func g()
-{                  // INVALID
-}
-</pre>
-A semicolon will be inserted after <code>g()</code>, causing it to be
-a function declaration rather than a function definition.  Similarly,
-you may not write
-<pre>
-if x {
-}
-else {             // INVALID
-}
-</pre>
-A semicolon will be inserted after the <code>}</code> preceding
-the <code>else</code>, causing a syntax error.
-
-<p>
-Since semicolons do end statements, you may continue using them as in
-C++.  However, that is not the recommended style.  Idiomatic Go code
-omits unnecessary semicolons, which in practice is all of them other
-than the initial <code>for</code> loop clause and cases where you want several
-short statements on a single line.
-
-<p>
-While we're on the topic, we recommend that rather than worry about
-semicolons and brace placement, you format your code with
-the <code>gofmt</code> program.  That will produce a single standard
-Go style, and let you worry about your code rather than your
-formatting.  While the style may initially seem odd, it is as good as
-any other style, and familiarity will lead to comfort.
-
-<p>
-When using a pointer to a struct, you use <code>.</code> instead
-of <code>-></code>.
-Thus syntactically speaking a structure and a pointer to a structure
-are used in the same way.
-
-<pre>
-type myStruct struct { i int }
-var v9 myStruct              // v9 has structure type
-var p9 *myStruct             // p9 is a pointer to a structure
-f(v9.i, p9.i)
-</pre>
-
-<p>
-Go does not require parentheses around the condition of an <code>if</code>
-statement, or the expressions of a <code>for</code> statement, or the value of a
-<code>switch</code> statement.  On the other hand, it does require curly braces
-around the body of an <code>if</code> or <code>for</code> statement.
-
-<pre>
-if a < b { f() }             // Valid
-if (a < b) { f() }           // Valid (condition is a parenthesized expression)
-if (a < b) f()               // INVALID
-for i = 0; i < 10; i++ {}    // Valid
-for (i = 0; i < 10; i++) {}  // INVALID
-</pre>
-
-<p>
-Go does not have a <code>while</code> statement nor does it have a
-<code>do/while</code>
-statement.  The <code>for</code> statement may be used with a single condition,
-which makes it equivalent to a <code>while</code> statement.  Omitting the
-condition entirely is an endless loop.
-
-<p>
-Go permits <code>break</code> and <code>continue</code> to specify a label.
-The label must
-refer to a <code>for</code>, <code>switch</code>, or <code>select</code>
-statement.
-
-<p>
-In a <code>switch</code> statement, <code>case</code> labels do not fall
-through.  You can
-make them fall through using the <code>fallthrough</code> keyword.  This applies
-even to adjacent cases.
-
-<pre>
-switch i {
-case 0:  // empty case body
-case 1:
-    f()  // f is not called when i == 0!
-}
-</pre>
-
-<p>
-But a <code>case</code> can have multiple values.
-
-<pre>
-switch i {
-case 0, 1:
-    f()  // f is called if i == 0 || i == 1.
-}
-</pre>
-
-<p>
-The values in a <code>case</code> need not be constants—or even integers;
-any type
-that supports the equality comparison operator, such as strings or
-pointers, can be used—and if the <code>switch</code>
-value is omitted it defaults to <code>true</code>.
-
-<pre>
-switch {
-case i < 0:
-    f1()
-case i == 0:
-    f2()
-case i > 0:
-    f3()
-}
-</pre>
-
-<p>
-The <code>++</code> and <code>--</code> operators may only be used in
-statements, not in expressions.
-You cannot write <code>c = *p++</code>.  <code>*p++</code> is parsed as
-<code>(*p)++</code>.
-
-<p>
-The <code>defer</code> statement may be used to call a function after
-the function containing the <code>defer</code> statement returns.
-
-<pre>
-fd := open("filename")
-defer close(fd)         // fd will be closed when this function returns.
-</pre>
-
-<h2 id="Constants">Constants </h2>
-
-<p>
-In Go constants may be <i>untyped</i>. This applies even to constants
-named with a <code>const</code> declaration, if no
-type is given in the declaration and the initializer expression uses only
-untyped constants.
-A value derived from an untyped constant becomes typed when it
-is used within a context that
-requires a typed value. This permits constants to be used relatively
-freely without requiring general implicit type conversion.
-
-<pre>
-var a uint
-f(a + 1)  // untyped numeric constant "1" becomes typed as uint
-</pre>
-
-<p>
-The language does not impose any limits on the size of an untyped
-numeric constant or constant expression. A limit is only applied when
-a constant is used where a type is required.
-
-<pre>
-const huge = 1 << 100
-f(huge >> 98)
-</pre>
-
-<p>
-Go does not support enums.  Instead, you can use the special name
-<code>iota</code> in a single <code>const</code> declaration to get a
-series of increasing
-value.  When an initialization expression is omitted for a <code>const</code>,
-it reuses the preceding expression.
-
-<pre>
-const (
-    red = iota   // red == 0
-    blue         // blue == 1
-    green        // green == 2
-)
-</pre>
-
-<h2 id="Slices">Slices</h2>
-
-<p>
-A slice is conceptually a struct with three fields: a
-pointer to an array, a length, and a capacity.
-Slices support
-the <code>[]</code> operator to access elements of the underlying array.
-The builtin
-<code>len</code> function returns the
-length of the slice.  The builtin <code>cap</code> function returns the
-capacity.
-
-<p>
-Given an array, or another slice, a new slice is created via
-<code>a[I:J]</code>.  This
-creates a new slice which refers to <code>a</code>, starts at
-index <code>I</code>, and ends before index
-<code>J</code>.  It has length <code>J - I</code>.
-The new slice refers to the same array
-to which <code>a</code>
-refers.  That is, changes made using the new slice may be seen using
-<code>a</code>.  The
-capacity of the new slice is simply the capacity of <code>a</code> minus
-<code>I</code>.  The capacity
-of an array is the length of the array.  You may also assign an array pointer
-to a variable of slice type; given <code>var s []int; var a[10] int</code>,
-the assignment <code>s = &a</code> is equivalent to
-<code>s = a[0:len(a)]</code>.
-
-<p>
-What this means is that Go uses slices for some cases where C++ uses pointers.
-If you create a value of type <code>[100]byte</code> (an array of 100 bytes,
-perhaps a
-buffer) and you want to pass it to a function without copying it, you should
-declare the function parameter to have type <code>[]byte</code>, and pass the
-address
-of the array.  Unlike in C++, it is not
-necessary to pass the length of the buffer; it is efficiently accessible via
-<code>len</code>.
-
-<p>
-The slice syntax may also be used with a string.  It returns a new string,
-whose value is a substring of the original string.
-Because strings are immutable, string slices can be implemented
-without allocating new storage for the slices's contents.
-
-<h2 id="Making_values">Making values</h2>
-
-<p>
-Go has a builtin function <code>new</code> which takes a type and
-allocates space
-on the heap. The allocated space will be zero-initialized for the type.
-For example, <code>new(int)</code> allocates a new int on the heap,
-initializes it with the value <code>0</code>,
-and returns its address, which has type <code>*int</code>.
-Unlike in C++, <code>new</code> is a function, not an operator;
-<code>new int</code> is a syntax error.
-
-<p>
-Map and channel values must be allocated using the builtin function
-<code>make</code>.
-A variable declared with map or channel type without an initializer will be
-automatically initialized to <code>nil</code>.
-Calling <code>make(map[int]int)</code> returns a newly allocated value of
-type <code>map[int]int</code>.
-Note that <code>make</code> returns a value, not a pointer.  This is
-consistent with
-the fact that map and channel values are passed by reference.  Calling
-<code>make</code> with
-a map type takes an optional argument which is the expected capacity of the
-map.  Calling <code>make</code> with a channel type takes an optional
-argument which sets the
-buffering capacity of the channel; the default is 0 (unbuffered).
-
-<p>
-The <code>make</code> function may also be used to allocate a slice.
-In this case it
-allocates memory for the underlying array and returns a slice referring to it.
-There is one required argument, which is the number of elements in the slice.
-A second, optional, argument is the capacity of the slice.  For example,
-<code>make([]int, 10, 20)</code>.  This is identical to
-<code>new([20]int)[0:10]</code>.  Since
-Go uses garbage collection, the newly allocated array will be discarded
-sometime after there are no references to the returned slice.
-
-<h2 id="Interfaces">Interfaces</h2>
-
-<p>
-Where C++ provides classes, subclasses and templates,
-Go provides interfaces.  A
-Go interface is similar to a C++ pure abstract class: a class with no
-data members, with methods which are all pure virtual.  However, in
-Go, any type which provides the methods named in the interface may be
-treated as an implementation of the interface.  No explicitly declared
-inheritance is required.  The implementation of the interface is
-entirely separate from the interface itself.
-
-<p>
-A method looks like an ordinary function definition, except that it
-has a <em>receiver</em>.  The receiver is similar to
-the <code>this</code> pointer in a C++ class method.
-
-<pre>
-type myType struct { i int }
-func (p *myType) get() int { return p.i }
-</pre>
-
-<p>
-This declares a method <code>get</code> associated with <code>myType</code>.
-The receiver is named <code>p</code> in the body of the function.
-
-<p>
-Methods are defined on named types.  If you convert the value
-to a different type, the new value will have the methods of the new type,
-not the old type.
-
-<p>
-You may define methods on a builtin type by declaring a new named type
-derived from it.  The new type is distinct from the builtin type.
-
-<pre>
-type myInteger int
-func (p myInteger) get() int { return int(p) } // Conversion required.
-func f(i int) { }
-var v myInteger
-// f(v) is invalid.
-// f(int(v)) is valid; int(v) has no defined methods.
-</pre>
-
-<p>
-Given this interface:
-
-<pre>
-type myInterface interface {
-	get() int
-	set(i int)
-}
-</pre>
-
-<p>
-we can make <code>myType</code> satisfy the interface by adding
-
-<pre>
-func (p *myType) set(i int) { p.i = i }
-</pre>
-
-<p>
-Now any function which takes <code>myInterface</code> as a parameter
-will accept a
-variable of type <code>*myType</code>.
-
-<pre>
-func getAndSet(x myInterface) {}
-func f1() {
-	var p myType
-	getAndSet(&p)
-}
-</pre>
-
-<p>
-In other words, if we view <code>myInterface</code> as a C++ pure abstract
-base
-class, defining <code>set</code> and <code>get</code> for
-<code>*myType</code> made <code>*myType</code> automatically
-inherit from <code>myInterface</code>.  A type may satisfy multiple interfaces.
-
-<p>
-An anonymous field may be used to implement something much like a C++ child
-class.
-
-<pre>
-type myChildType struct { myType; j int }
-func (p *myChildType) get() int { p.j++; return p.myType.get() }
-</pre>
-
-<p>
-This effectively implements <code>myChildType</code> as a child of
-<code>myType</code>.
-
-<pre>
-func f2() {
-	var p myChildType
-	getAndSet(&p)
-}
-</pre>
-
-<p>
-The <code>set</code> method is effectively inherited from
-<code>myType</code>, because
-methods associated with the anonymous field are promoted to become methods
-of the enclosing type.  In this case, because <code>myChildType</code> has an
-anonymous field of type <code>myType</code>, the methods of
-<code>myType</code> also become methods of <code>myChildType</code>.
-In this example, the <code>get</code> method was
-overridden, and the <code>set</code> method was inherited.
-
-<p>
-This is not precisely the same as a child class in C++.
-When a method of an anonymous field is called,
-its receiver is the field, not the surrounding struct.
-In other words, methods on anonymous fields are not virtual functions.
-When you want the equivalent of a virtual function, use an interface.
-
-<p>
-A variable which has an interface type may be converted to have a
-different interface type using a special construct called a type assertion.
-This is implemented dynamically
-at run time, like C++ <code>dynamic_cast</code>.  Unlike
-<code>dynamic_cast</code>, there does
-not need to be any declared relationship between the two interfaces.
-
-<pre>
-type myPrintInterface interface {
-  print()
-}
-func f3(x myInterface) {
-	x.(myPrintInterface).print()  // type assertion to myPrintInterface
-}
-</pre>
-
-<p>
-The conversion to <code>myPrintInterface</code> is entirely dynamic.
-It will
-work as long as the underlying type of x (the <em>dynamic type</em>) defines
-a <code>print</code> method.
-
-<p>
-Because the conversion is dynamic, it may be used to implement generic
-programming similar to templates in C++.  This is done by
-manipulating values of the minimal interface.
-
-<pre>
-type Any interface { }
-</pre>
-
-<p>
-Containers may be written in terms of <code>Any</code>, but the caller
-must unbox using a type assertion to recover
-values of the contained type.  As the typing is dynamic rather
-than static, there is no equivalent of the way that a C++ template may
-inline the relevant operations.  The operations are fully type-checked
-at run time, but all operations will involve a function call.
-
-<pre>
-type iterator interface {
-	get() Any
-	set(v Any)
-	increment()
-	equal(arg *iterator) bool
-}
-</pre>
-
-<h2 id="Goroutines">Goroutines</h2>
-
-<p>
-Go permits starting a new thread of execution (a <em>goroutine</em>)
-using the <code>go</code>
-statement.  The <code>go</code> statement runs a function in a
-different, newly created, goroutine.
-All goroutines in a single program share the same address space.
-
-<p>
-Internally, goroutines act like coroutines that are multiplexed among
-multiple operating system threads.  You do not have to worry
-about these details.
-
-<pre>
-func server(i int) {
-    for {
-        print(i)
-        sys.sleep(10)
-    }
-}
-go server(1)
-go server(2)
-</pre>
-
-<p>
-(Note that the <code>for</code> statement in the <code>server</code>
-function is equivalent to a C++ <code>while (true)</code> loop.)
-
-<p>
-Goroutines are (intended to be) cheap.
-
-<p>
-Function literals (which Go implements as closures)
-can be useful with the <code>go</code> statement.
-
-<pre>
-var g int
-go func(i int) {
-	s := 0
-	for j := 0; j < i; j++ { s += j }
-	g = s
-}(1000)  // Passes argument 1000 to the function literal.
-</pre>
-
-<h2 id="Channels">Channels</h2>
-
-<p>
-Channels are used to communicate between goroutines.  Any value may be
-sent over a channel.  Channels are (intended to be) efficient and
-cheap.  To send a value on a channel, use <code><-</code> as a binary
-operator.  To
-receive a value on a channel, use <code><-</code> as a unary operator.
-When calling
-functions, channels are passed by reference.
-
-<p>
-The Go library provides mutexes, but you can also use
-a single goroutine with a shared channel.
-Here is an example of using a manager function to control access to a
-single value.
-
-<pre>
-type cmd struct { get bool; val int }
-func manager(ch chan cmd) {
-	var val int = 0
-	for {
-		c := <- ch
-		if c.get { c.val = val; ch <- c }
-		else { val = c.val }
-	}
-}
-</pre>
-
-<p>
-In that example the same channel is used for input and output.
-This is incorrect if there are multiple goroutines communicating
-with the manager at once: a goroutine waiting for a response
-from the manager might receive a request from another goroutine
-instead.
-A solution is to pass in a channel.
-
-<pre>
-type cmd2 struct { get bool; val int; ch <- chan int }
-func manager2(ch chan cmd2) {
-	var val int = 0
-	for {
-		c := <- ch
-		if c.get { c.ch <- val }
-		else { val = c.val }
-	}
-}
-</pre>
-
-<p>
-To use <code>manager2</code>, given a channel to it:
-
-<pre>
-func f4(ch <- chan cmd2) int {
-	myCh := make(chan int)
-	c := cmd2{ true, 0, myCh }   // Composite literal syntax.
-	ch <- c
-	return <-myCh
-}
-</pre>
diff --git a/doc/go_mem.html b/doc/go_mem.html
index 2e34177..a003241 100644
--- a/doc/go_mem.html
+++ b/doc/go_mem.html
@@ -1,6 +1,7 @@
 <!--{
 	"Title": "The Go Memory Model",
-	"Subtitle": "Version of June 10, 2011"
+	"Subtitle": "Version of June 10, 2011",
+	"Path": "/ref/mem"
 }-->
 
 <style>
diff --git a/doc/go_spec.html b/doc/go_spec.html
index 6cc1b2c..ebd79bb 100644
--- a/doc/go_spec.html
+++ b/doc/go_spec.html
@@ -1,6 +1,7 @@
 <!--{
 	"Title": "The Go Programming Language Specification",
-	"Subtitle": "Version of February 22, 2012"
+	"Subtitle": "Version of March 1, 2012",
+	"Path": "/ref/spec"
 }-->
 
 <!--
@@ -67,7 +68,7 @@ operators, in increasing precedence:
 
 <p>
 Lower-case production names are used to identify lexical tokens.
-Non-terminals are in CamelCase. Lexical symbols are enclosed in
+Non-terminals are in CamelCase. Lexical tokens are enclosed in
 double quotes <code>""</code> or back quotes <code>``</code>.
 </p>
 
@@ -678,13 +679,14 @@ and <code>T4</code> is <code>[]T1</code>.
 A type may have a <i>method set</i> associated with it
 (§<a href="#Interface_types">Interface types</a>, §<a href="#Method_declarations">Method declarations</a>).
 The method set of an <a href="#Interface_types">interface type</a> is its interface.
-The method set of any other named type <code>T</code>
+The method set of any other type <code>T</code>
 consists of all methods with receiver type <code>T</code>.
 The method set of the corresponding pointer type <code>*T</code>
 is the set of all methods with receiver <code>*T</code> or <code>T</code>
 (that is, it also contains the method set of <code>T</code>).
 Any other type has an empty method set.
-In a method set, each method must have a unique <a href="#MethodName">method name</a>.
+In a method set, each method must have a
+<a href="#Uniqueness_of_identifiers">unique</a> <a href="#MethodName">method name</a>.
 </p>
 
 <p>
@@ -696,10 +698,11 @@ using a receiver of that type.
 
 <h3 id="Boolean_types">Boolean types</h3>
 
+<p>
 A <i>boolean type</i> represents the set of Boolean truth values
 denoted by the predeclared constants <code>true</code>
 and <code>false</code>. The predeclared boolean type is <code>bool</code>.
-
+</p>
 
 <h3 id="Numeric_types">Numeric types</h3>
 
@@ -894,7 +897,7 @@ A struct is a sequence of named elements, called fields, each of which has a
 name and a type. Field names may be specified explicitly (IdentifierList) or
 implicitly (AnonymousField).
 Within a struct, non-<a href="#Blank_identifier">blank</a> field names must
-be unique.
+be <a href="#Uniqueness_of_identifiers">unique</a>.
 </p>
 
 <pre class="ebnf">
@@ -954,7 +957,7 @@ struct {
 <p>
 Fields and methods (§<a href="#Method_declarations">Method declarations</a>) of an anonymous field are
 promoted to be ordinary fields and methods of the struct (§<a href="#Selectors">Selectors</a>).
-The following rules apply for a struct type named <code>S</code> and
+The following rules apply for a struct type <code>S</code> and
 a type named <code>T</code>:
 </p>
 <ul>
@@ -1006,8 +1009,8 @@ BaseType = Type .
 </pre>
 
 <pre>
-*int
-*map[string]*chan int
+*Point
+*[4]int
 </pre>
 
 <h3 id="Function_types">Function types</h3>
@@ -1045,11 +1048,10 @@ may be invoked with zero or more arguments for that parameter.
 
 <pre>
 func()
-func(x int)
-func() int
-func(prefix string, values ...int)
-func(a, b int, z float32) bool
+func(x int) int
+func(a, _ int, z float32) bool
 func(a, b int, z float32) (bool)
+func(prefix string, values ...int)
 func(a, b int, z float64, opt ...interface{}) (success bool)
 func(int, int, float64) (float64, *[]int)
 func(n int) func(p *T)
@@ -1074,7 +1076,8 @@ InterfaceTypeName  = TypeName .
 </pre>
 
 <p>
-As with all method sets, in an interface type, each method must have a unique name.
+As with all method sets, in an interface type, each method must have a
+<a href="#Uniqueness_of_identifiers">unique</a> name.
 </p>
 
 <pre>
@@ -1538,10 +1541,19 @@ the body of any nested function.
 </p>
 
 
+<h3 id="Blank_identifier">Blank identifier</h3>
+
+<p>
+The <i>blank identifier</i>, represented by the underscore character <code>_</code>, may be used in a declaration like
+any other identifier but the declaration does not introduce a new binding.
+</p>
+
+
 <h3 id="Predeclared_identifiers">Predeclared identifiers</h3>
 
 <p>
-The following identifiers are implicitly declared in the universe block:
+The following identifiers are implicitly declared in the
+<a href="#Blocks">universe block</a>:
 </p>
 <pre class="grammar">
 Types:
@@ -1564,28 +1576,31 @@ Functions:
 <h3 id="Exported_identifiers">Exported identifiers</h3>
 
 <p>
-An identifier may be <i>exported</i> to permit access to it from another package
-using a <a href="#Qualified_identifiers">qualified identifier</a>. An identifier
-is exported if both:
+An identifier may be <i>exported</i> to permit access to it from another package.
+An identifier is exported if both:
 </p>
 <ol>
-	<li>the first character of the identifier's name is a Unicode upper case letter (Unicode class "Lu"); and</li>
-	<li>the identifier is declared in the <a href="#Blocks">package block</a> or denotes a field or method of a type
-	    declared in that block.</li>
+	<li>the first character of the identifier's name is a Unicode upper case
+	letter (Unicode class "Lu"); and</li>
+	<li>the identifier is declared in the <a href="#Blocks">package block</a>
+	or it is a <a href="#Struct_types">field name</a> or
+	<a href="#MethodName">method name</a>.</li>
 </ol>
 <p>
 All other identifiers are not exported.
 </p>
 
 
-<h3 id="Blank_identifier">Blank identifier</h3>
+<h3 id="Uniqueness_of_identifiers">Uniqueness of identifiers</h3>
 
 <p>
-The <i>blank identifier</i>, represented by the underscore character <code>_</code>, may be used in a declaration like
-any other identifier but the declaration does not introduce a new binding.
+Given a set of identifiers, an identifier is called <i>unique</i> if it is
+<i>different</i> from every other in the set.
+Two identifiers are different if they are spelled differently, or if they
+appear in different <a href="#Packages">packages</a> and are not
+<a href="Exported_identifiers">exported</a>. Otherwise, they are the same.
 </p>
 
-
 <h3 id="Constant_declarations">Constant declarations</h3>
 
 <p>
@@ -1832,6 +1847,13 @@ of the expression list.
 If the type is absent and the corresponding expression evaluates to an
 untyped <a href="#Constants">constant</a>, the type of the declared variable
 is as described in §<a href="#Assignments">Assignments</a>.
+</p>
+
+<p>
+Implementation restriction: A compiler may make it illegal to declare a variable
+inside a <a href="#Function_declarations">function body</a> if the variable is
+never used.
+</p>
 
 <h3 id="Short_variable_declarations">Short variable declarations</h3>
 
@@ -1844,8 +1866,8 @@ ShortVarDecl = IdentifierList ":=" ExpressionList .
 </pre>
 
 <p>
-It is a shorthand for a regular variable declaration with
-initializer expressions but no types:
+It is a shorthand for a regular <a href="#Variable_declarations">variable declaration</a>
+with initializer expressions but no types:
 </p>
 
 <pre class="grammar">
@@ -1935,7 +1957,7 @@ is visible only within selectors for that type.
 
 <p>
 For a base type, the non-<a href="#Blank_identifier">blank</a> names of
-methods bound to it must be unique.
+methods bound to it must be <a href="#Uniqueness_of_identifiers">unique</a>.
 If the base type is a <a href="#Struct_types">struct type</a>,
 the non-blank method and field names must be distinct.
 </p>
@@ -2004,7 +2026,8 @@ BasicLit   = int_lit | float_lit | imaginary_lit | char_lit | string_lit .
 <h3 id="Qualified_identifiers">Qualified identifiers</h3>
 
 <p>
-A qualified identifier is a non-<a href="#Blank_identifier">blank</a> identifier qualified by a package name prefix.
+A qualified identifier is a non-<a href="#Blank_identifier">blank</a> identifier
+qualified by a package name prefix.
 </p>
 
 <pre class="ebnf">
@@ -2012,21 +2035,16 @@ QualifiedIdent = [ PackageName "." ] identifier .
 </pre>
 
 <p>
-A qualified identifier accesses an identifier in a separate package.
-The identifier must be <a href="#Exported_identifiers">exported</a> by that
-package, which means that it must begin with a Unicode upper case letter.
+A qualified identifier accesses an identifier in a different package, which
+must be <a href="#Import_declarations">imported</a>.
+The identifier must be <a href="#Exported_identifiers">exported</a> and
+declared in the <a href="#Blocks">package block</a> of that package.
 </p>
 
 <pre>
-math.Sin
+math.Sin	// denotes the Sin function in package math
 </pre>
 
-<!--
-<p>
-<span class="alert">TODO: Unify this section with Selectors - it's the same syntax.</span>
-</p>
--->
-
 <h3 id="Composite_literals">Composite literals</h3>
 
 <p>
@@ -2329,8 +2347,8 @@ where <code>T</code> is not an interface type,
 <code>x.f</code> denotes the field or method at the shallowest depth
 in <code>T</code> where there
 is such an <code>f</code>.
-If there is not exactly one <code>f</code> with shallowest depth, the selector
-expression is illegal.
+If there is not exactly <a href="#Uniqueness_of_identifiers">one <code>f</code></a>
+with shallowest depth, the selector expression is illegal.
 </li>
 <li>
 For a variable <code>x</code> of type <code>I</code>
@@ -2784,13 +2802,13 @@ var s uint = 33
 var i = 1<<s           // 1 has type int
 var j int32 = 1<<s     // 1 has type int32; j == 0
 var k = uint64(1<<s)   // 1 has type uint64; k == 1<<33
-var m int = 1.0<<s     // legal: 1.0 has type int
-var n = 1.0<<s != 0    // legal: 1.0 has type int; n == false if ints are 32bits in size
-var o = 1<<s == 2<<s   // legal: 1 and 2 have type int; o == true if ints are 32bits in size
+var m int = 1.0<<s     // 1.0 has type int
+var n = 1.0<<s != 0    // 1.0 has type int; n == false if ints are 32bits in size
+var o = 1<<s == 2<<s   // 1 and 2 have type int; o == true if ints are 32bits in size
 var p = 1<<s == 1<<33  // illegal if ints are 32bits in size: 1 has type int, but 1<<33 overflows int
 var u = 1.0<<s         // illegal: 1.0 has type float64, cannot shift
 var v float32 = 1<<s   // illegal: 1 has type float32, cannot shift
-var w int64 = 1.0<<33  // legal: 1.0<<33 is a constant shift expression
+var w int64 = 1.0<<33  // 1.0<<33 is a constant shift expression
 </pre>
 
 <h3 id="Operator_precedence">Operator precedence</h3>
@@ -4238,7 +4256,9 @@ iteration variables as in an <a href="#Assignments">assignment statement</a>.
 </p>
 
 <p>
-The iteration variables may be declared by the "range" clause (<code>:=</code>).
+The iteration variables may be declared by the "range" clause using a form of
+<a href="#Short_variable_declarations">short variable declaration</a>
+(<code>:=</code>).
 In this case their types are set to the types of the respective iteration values
 and their <a href="#Declarations_and_scope">scope</a> ends at the end of the "for"
 statement; they are re-used in each iteration.
@@ -4889,7 +4909,7 @@ a no-op. Calling <code>delete</code> with a nil map causes a
 </p>
 
 
-<h3 id="Complex_numbers">Assembling and disassembling complex numbers</h3>
+<h3 id="Complex_numbers">Manipulating complex numbers</h3>
 
 <p>
 Three functions assemble and disassemble complex numbers.
@@ -5065,11 +5085,12 @@ An implementation may require that all source files for a package inhabit the sa
 <h3 id="Import_declarations">Import declarations</h3>
 
 <p>
-An import declaration states that the source file containing the
-declaration uses identifiers
-<a href="#Exported_identifiers">exported</a> by the <i>imported</i>
-package and enables access to them.  The import names an
-identifier (PackageName) to be used for access and an ImportPath
+An import declaration states that the source file containing the declaration
+depends on functionality of the <i>imported</i> package
+(<a href="#Program_initialization_and_execution">§Program initialization and execution</a>)
+and it enables access to <a href="#Exported_identifiers">exported</a> identifiers
+of that package.
+The import names an identifier (PackageName) to be used for access and an ImportPath
 that specifies the package to be imported.
 </p>
 
@@ -5081,13 +5102,14 @@ ImportPath       = string_lit .
 
 <p>
 The PackageName is used in <a href="#Qualified_identifiers">qualified identifiers</a>
-to access the exported identifiers of the package within the importing source file.
+to access exported identifiers of the package within the importing source file.
 It is declared in the <a href="#Blocks">file block</a>.
 If the PackageName is omitted, it defaults to the identifier specified in the
 <a href="#Package_clause">package clause</a> of the imported package.
 If an explicit period (<code>.</code>) appears instead of a name, all the
-package's exported identifiers will be declared in the current file's
-file block and can be accessed without a qualifier.
+package's exported identifiers declared in that package's
+<a href="#Blocks">package block</a> will be declared in the importing source
+file's file block and can be accessed without a qualifier.
 </p>
 
 <p>
@@ -5097,6 +5119,16 @@ package and may be relative to a repository of installed packages.
 </p>
 
 <p>
+Implementation restriction: A compiler may restrict ImportPaths to
+non-empty strings using only characters belonging to
+<a href="http://www.unicode.org/versions/Unicode6.0.0/">Unicode's</a>
+L, M, N, P, and S general categories (the Graphic characters without
+spaces) and may also exclude the characters
+<code>!"#$%&'()*,:;<=>?[\]^`{|}</code>
+and the Unicode replacement character U+FFFD.
+</p>
+
+<p>
 Assume we have compiled a package containing the package clause
 <code>package math</code>, which exports function <code>Sin</code>, and
 installed the compiled package in the file identified by
diff --git a/doc/go_tutorial.html b/doc/go_tutorial.html
deleted file mode 100644
index 5892623..0000000
--- a/doc/go_tutorial.html
+++ /dev/null
@@ -1,1452 +0,0 @@
-<!--{
-	"Title": "A Tutorial for the Go Programming Language"
-}-->
-<!--
-  DO NOT EDIT: created by
-    tmpltohtml go_tutorial.tmpl
--->
-
-
-<h2>Introduction</h2>
-<p>
-This document is a tutorial introduction to the basics of the Go programming
-language, intended for programmers familiar with C or C++. It is not a comprehensive
-guide to the language; at the moment the document closest to that is the
-<a href='/doc/go_spec.html'>language specification</a>.
-After you've read this tutorial, you should look at
-<a href='/doc/effective_go.html'>Effective Go</a>,
-which digs deeper into how the language is used and
-talks about the style and idioms of programming in Go.
-An interactive introduction to Go is available, called
-<a href='http://tour.golang.org/'>A Tour of Go</a>.
-<p>
-The presentation here proceeds through a series of modest programs to illustrate
-key features of the language.  All the programs work (at time of writing) and are
-checked into the repository in the directory <a href='/doc/progs'><code>/doc/progs/</code></a>.
-<p>
-<h2>Hello, World</h2>
-<p>
-Let's start in the usual way:
-<p>
-<pre><!--{{code "progs/helloworld.go" `/package/` "$"}}
--->package main
-
-import fmt "fmt" // Package implementing formatted I/O.
-
-func main() {
-    fmt.Printf("Hello, world; or Καλημέρα κόσμε; or こんにちは 世界\n")
-}</pre>
-<p>
-Every Go source file declares, using a <code>package</code> statement, which package it's part of.
-It may also import other packages to use their facilities.
-This program imports the package <code>fmt</code> to gain access to
-our old, now capitalized and package-qualified, friend, <code>fmt.Printf</code>.
-<p>
-Functions are introduced with the <code>func</code> keyword.
-The <code>main</code> package's <code>main</code> function is where the program starts running (after
-any initialization).
-<p>
-String constants can contain Unicode characters, encoded in UTF-8.
-(In fact, Go source files are defined to be encoded in UTF-8.)
-<p>
-The comment convention is the same as in C++:
-<p>
-<pre>
-/* ... */
-// ...
-</pre>
-<p>
-Later we'll have much more to say about printing.
-<p>
-<h2>Semicolons</h2>
-<p>
-You might have noticed that our program has no semicolons.  In Go
-code, the only place you typically see semicolons is separating the
-clauses of <code>for</code> loops and the like; they are not necessary after
-every statement.
-<p>
-In fact, what happens is that the formal language uses semicolons,
-much as in C or Java, but they are inserted automatically
-at the end of every line that looks like the end of a statement. You
-don't need to type them yourself.
-<p>
-For details about how this is done you can see the language
-specification, but in practice all you need to know is that you
-never need to put a semicolon at the end of a line.  (You can put
-them in if you want to write multiple statements per line.) As an
-extra help, you can also leave out a semicolon immediately before
-a closing brace.
-<p>
-This approach makes for clean-looking, semicolon-free code.  The
-one surprise is that it's important to put the opening
-brace of a construct such as an <code>if</code> statement on the same line as
-the <code>if</code>; if you don't, there are situations that may not compile
-or may give the wrong result.  The language forces the brace style
-to some extent.
-<p>
-<h2>Compiling</h2>
-<p>
-Go is a compiled language.  At the moment there are two compilers.
-<code>Gccgo</code> is a Go compiler that uses the GCC back end.  There is also a
-suite of compilers with different (and odd) names for each architecture:
-<code>6g</code> for the 64-bit x86, <code>8g</code> for the 32-bit x86, and more.  These
-compilers run significantly faster but generate less efficient code
-than <code>gccgo</code>.  At the time of writing (late 2009), they also have
-a more robust run-time system although <code>gccgo</code> is catching up.
-<p>
-Here's how to compile and run our program.  With <code>6g</code>, say,
-<p>
-<pre>
-$ 6g helloworld.go  # compile; object goes into helloworld.6
-$ 6l helloworld.6   # link; output goes into 6.out
-$ ./6.out
-Hello, world; or Καλημέρα κόσμε; or こんにちは 世界
-$
-</pre>
-<p>
-With <code>gccgo</code> it looks a little more traditional.
-<p>
-<pre>
-$ gccgo helloworld.go
-$ ./a.out
-Hello, world; or Καλημέρα κόσμε; or こんにちは 世界
-$
-</pre>
-<p>
-<h2>Echo</h2>
-<p>
-Next up, here's a version of the Unix utility <code>echo(1)</code>:
-<p>
-<pre><!--{{code "progs/echo.go" `/package/` "$"}}
--->package main
-
-import (
-    "flag" // command line option parser
-    "os"
-)
-
-var omitNewline = flag.Bool("n", false, "don't print final newline")
-
-const (
-    Space   = " "
-    Newline = "\n"
-)
-
-func main() {
-    flag.Parse() // Scans the arg list and sets up flags
-    var s string = ""
-    for i := 0; i < flag.NArg(); i++ {
-        if i > 0 {
-            s += Space
-        }
-        s += flag.Arg(i)
-    }
-    if !*omitNewline {
-        s += Newline
-    }
-    os.Stdout.WriteString(s)
-}</pre>
-<p>
-This program is small but it's doing a number of new things.  In the last example,
-we saw <code>func</code> introduce a function.  The keywords <code>var</code>, <code>const</code>, and <code>type</code>
-(not used yet) also introduce declarations, as does <code>import</code>.
-Notice that we can group declarations of the same sort into
-parenthesized lists, one item per line, as in the <code>import</code> and <code>const</code> clauses here.
-But it's not necessary to do so; we could have said
-<p>
-<pre>
-const Space = " "
-const Newline = "\n"
-</pre>
-<p>
-This program imports the <code>"os"</code> package to access its <code>Stdout</code> variable, of type
-<code>*os.File</code>.  The <code>import</code> statement is actually a declaration: in its general form,
-as used in our ``hello world'' program,
-it names the identifier (<code>fmt</code>)
-that will be used to access members of the package imported from the file (<code>"fmt"</code>),
-found in the current directory or in a standard location.
-In this program, though, we've dropped the explicit name from the imports; by default,
-packages are imported using the name defined by the imported package,
-which by convention is of course the file name itself.  Our ``hello world'' program
-could have said just <code>import "fmt"</code>.
-<p>
-You can specify your
-own import names if you want but it's only necessary if you need to resolve
-a naming conflict.
-<p>
-Given <code>os.Stdout</code> we can use its <code>WriteString</code> method to print the string.
-<p>
-After importing the <code>flag</code> package, we use a <code>var</code> declaration
-to create and initialize a global variable, called <code>omitNewline</code>,
-to hold the value of echo's <code>-n</code> flag. 
-The variable  has type <code>*bool</code>, pointer to <code>bool</code>.
-<p>
-In <code>main.main</code>, we parse the arguments (the call to <code>flag.Parse</code>) and then create a local
-string variable with which to build the output.
-<p>
-The declaration statement has the form
-<p>
-<pre>
-var s string = ""
-</pre>
-<p>
-This is the <code>var</code> keyword, followed by the name of the variable, followed by
-its type, followed by an equals sign and an initial value for the variable.
-<p>
-Go tries to be terse, and this declaration could be shortened.  Since the
-string constant is of type string, we don't have to tell the compiler that.
-We could write
-<p>
-<pre>
-var s = ""
-</pre>
-<p>
-or we could go even shorter and write the idiom
-<p>
-<pre>
-s := ""
-</pre>
-<p>
-The <code>:=</code> operator is used a lot in Go to represent an initializing declaration.
-There's one in the <code>for</code> clause on the next line:
-<p>
-<pre><!--{{code "progs/echo.go" `/for/`}}
--->    for i := 0; i < flag.NArg(); i++ {</pre>
-<p>
-The <code>flag</code> package has parsed the arguments and left the non-flag arguments
-in a list that can be iterated over in the obvious way.
-<p>
-The Go <code>for</code> statement differs from that of C in a number of ways.  First,
-it's the only looping construct; there is no <code>while</code> or <code>do</code>.  Second,
-there are no parentheses on the clause, but the braces on the body
-are mandatory.  The same applies to the <code>if</code> and <code>switch</code> statements.
-Later examples will show some other ways <code>for</code> can be written.
-<p>
-The body of the loop builds up the string <code>s</code> by appending (using <code>+=</code>)
-the arguments and separating spaces. After the loop, if the <code>-n</code> flag is not
-set, the program appends a newline. Finally, it writes the result.
-<p>
-Notice that <code>main.main</code> is a niladic function with no return type.
-It's defined that way.  Falling off the end of <code>main.main</code> means
-''success''; if you want to signal an erroneous return, call
-<p>
-<pre>
-os.Exit(1)
-</pre>
-<p>
-The <code>os</code> package contains other essentials for getting
-started; for instance, <code>os.Args</code> is a slice used by the
-<code>flag</code> package to access the command-line arguments.
-<p>
-<h2>An Interlude about Types</h2>
-<p>
-Go has some familiar types such as <code>int</code> and <code>uint</code> (unsigned <code>int</code>), which represent
-values of the ''appropriate'' size for the machine. It also defines
-explicitly-sized types such as <code>int8</code>, <code>float64</code>, and so on, plus
-unsigned integer types such as <code>uint</code>, <code>uint32</code>, etc.
-These are distinct types; even if <code>int</code> and <code>int32</code> are both 32 bits in size,
-they are not the same type.  There is also a <code>byte</code> synonym for
-<code>uint8</code>, which is the element type for strings.
-<p>
-Floating-point types are always sized: <code>float32</code> and <code>float64</code>,
-plus <code>complex64</code> (two <code>float32s</code>) and <code>complex128</code>
-(two <code>float64s</code>).  Complex numbers are outside the
-scope of this tutorial.
-<p>
-Speaking of <code>string</code>, that's a built-in type as well.  Strings are
-<i>immutable values</i>—they are not just arrays of <code>byte</code> values.
-Once you've built a string <i>value</i>, you can't change it, although
-of course you can change a string <i>variable</i> simply by
-reassigning it.  This snippet from <code>strings.go</code> is legal code:
-<p>
-<pre><!--{{code "progs/strings.go" `/hello/` `/ciao/`}}
--->    s := "hello"
-    if s[1] != 'e' {
-        os.Exit(1)
-    }
-    s = "good bye"
-    var p *string = &s
-    *p = "ciao"</pre>
-<p>
-However the following statements are illegal because they would modify
-a <code>string</code> value:
-<p>
-<pre>
-s[0] = 'x'
-(*p)[1] = 'y'
-</pre>
-<p>
-In C++ terms, Go strings are a bit like <code>const strings</code>, while pointers
-to strings are analogous to <code>const string</code> references.
-<p>
-Yes, there are pointers.  However, Go simplifies their use a little;
-read on.
-<p>
-Arrays are declared like this:
-<p>
-<pre>
-var arrayOfInt [10]int
-</pre>
-<p>
-Arrays, like strings, are values, but they are mutable. This differs
-from C, in which <code>arrayOfInt</code> would be usable as a pointer to <code>int</code>.
-In Go, since arrays are values, it's meaningful (and useful) to talk
-about pointers to arrays.
-<p>
-The size of the array is part of its type; however, one can declare
-a <i>slice</i> variable to hold a reference to any array, of any size,
-with the same element type.
-A <i>slice
-expression</i> has the form <code>a[low : high]</code>, representing
-the internal array indexed from <code>low</code> through <code>high-1</code>; the resulting
-slice is indexed from <code>0</code> through <code>high-low-1</code>.
-In short, slices look a lot like arrays but with
-no explicit size (<code>[]</code> vs. <code>[10]</code>) and they reference a segment of
-an underlying, usually anonymous, regular array.  Multiple slices
-can share data if they represent pieces of the same array;
-multiple arrays can never share data.
-<p>
-Slices are much more common in Go programs than
-regular arrays; they're more flexible, have reference semantics,
-and are efficient.  What they lack is the precise control of storage
-layout of a regular array; if you want to have a hundred elements
-of an array stored within your structure, you should use a regular
-array. To create one, use a compound value <i>constructor</i>—an
-expression formed
-from a type followed by a brace-bounded expression like this:
-<p>
-<pre>
-[3]int{1,2,3}
-</pre>
-<p>
-In this case the constructor builds an array of 3 <code>ints</code>.
-<p>
-When passing an array to a function, you almost always want
-to declare the formal parameter to be a slice.  When you call
-the function, slice the array to create
-(efficiently) a slice reference and pass that.
-By default, the lower and upper bounds of a slice match the
-ends of the existing object, so the concise notation <code>[:]</code>
-will slice the whole array.
-<p>
-Using slices one can write this function (from <code>sum.go</code>):
-<p>
-<pre><!--{{code "progs/sum.go" `/sum/` `/^}/`}}
--->func sum(a []int) int { // returns an int
-    s := 0
-    for i := 0; i < len(a); i++ {
-        s += a[i]
-    }
-    return s
-}</pre>
-<p>
-Note how the return type (<code>int</code>) is defined for <code>sum</code> by stating it
-after the parameter list.
-<p>
-To call the function, we slice the array.  This code (we'll show
-a simpler way in a moment) constructs
-an array and slices it:
-<p>
-<pre>
-x := [3]int{1,2,3}
-s := sum(x[:])
-</pre>
-<p>
-If you are creating a regular array but want the compiler to count the
-elements for you, use <code>...</code> as the array size:
-<p>
-<pre>
-x := [...]int{1,2,3}
-s := sum(x[:])
-</pre>
-<p>
-That's fussier than necessary, though.
-In practice, unless you're meticulous about storage layout within a
-data structure, a slice itself—using empty brackets with no size—is all you need:
-<p>
-<pre>
-s := sum([]int{1,2,3})
-</pre>
-<p>
-There are also maps, which you can initialize like this:
-<p>
-<pre>
-m := map[string]int{"one":1 , "two":2}
-</pre>
-<p>
-The built-in function <code>len</code>, which returns number of elements,
-makes its first appearance in <code>sum</code>.  It works on strings, arrays,
-slices, maps, and channels.
-<p>
-By the way, another thing that works on strings, arrays, slices, maps
-and channels is the <code>range</code> clause on <code>for</code> loops.  Instead of writing
-<p>
-<pre>
-for i := 0; i < len(a); i++ { ... }
-</pre>
-<p>
-to loop over the elements of a slice (or map or ...) , we could write
-<p>
-<pre>
-for i, v := range a { ... }
-</pre>
-<p>
-This assigns <code>i</code> to the index and <code>v</code> to the value of the successive
-elements of the target of the range.   See
-<a href='/doc/effective_go.html'>Effective Go</a>
-for more examples of its use.
-<p>
-<p>
-<h2>An Interlude about Allocation</h2>
-<p>
-Most types in Go are values. If you have an <code>int</code> or a <code>struct</code>
-or an array, assignment
-copies the contents of the object.
-To allocate a new variable, use the built-in function <code>new</code>, which
-returns a pointer to the allocated storage.
-<p>
-<pre>
-type T struct { a, b int }
-var t *T = new(T)
-</pre>
-<p>
-or the more idiomatic
-<p>
-<pre>
-t := new(T)
-</pre>
-<p>
-Some types—maps, slices, and channels (see below)—have reference semantics.
-If you're holding a slice or a map and you modify its contents, other variables
-referencing the same underlying data will see the modification.  For these three
-types you want to use the built-in function <code>make</code>:
-<p>
-<pre>
-m := make(map[string]int)
-</pre>
-<p>
-This statement initializes a new map ready to store entries.
-If you just declare the map, as in
-<p>
-<pre>
-var m map[string]int
-</pre>
-<p>
-it creates a <code>nil</code> reference that cannot hold anything. To use the map,
-you must first initialize the reference using <code>make</code> or by assignment from an
-existing map.
-<p>
-Note that <code>new(T)</code> returns type <code>*T</code> while <code>make(T)</code> returns type
-<code>T</code>.  If you (mistakenly) allocate a reference object with <code>new</code> rather than <code>make</code>,
-you receive a pointer to a nil reference, equivalent to
-declaring an uninitialized variable and taking its address.
-<p>
-<h2>An Interlude about Constants</h2>
-<p>
-Although integers come in lots of sizes in Go, integer constants do not.
-There are no constants like <code>0LL</code> or <code>0x0UL</code>.   Instead, integer
-constants are evaluated as large-precision values that
-can overflow only when they are assigned to an integer variable with
-too little precision to represent the value.
-<p>
-<pre>
-const hardEight = (1 << 100) >> 97  // legal
-</pre>
-<p>
-There are nuances that deserve redirection to the legalese of the
-language specification but here are some illustrative examples:
-<p>
-<pre>
-var a uint64 = 0  // a has type uint64, value 0
-a := uint64(0)    // equivalent; uses a "conversion"
-i := 0x1234       // i gets default type: int
-var j int = 1e6   // legal - 1000000 is representable in an int
-x := 1.5          // a float64, the default type for floating constants
-i3div2 := 3/2     // integer division - result is 1
-f3div2 := 3./2.   // floating-point division - result is 1.5
-</pre>
-<p>
-Conversions only work for simple cases such as converting <code>ints</code> of one
-sign or size to another and between integers and floating-point numbers,
-plus a couple of other instances outside the scope of a tutorial.
-There are no automatic numeric conversions of any kind in Go,
-other than that of making constants have concrete size and type when
-assigned to a variable.
-<p>
-<h2>An I/O Package</h2>
-<p>
-Next we'll look at a simple package for doing Unix file I/O with an
-open/close/read/write interface.
-Here's the start of <code>file.go</code>:
-<p>
-<pre><!--{{code "progs/file.go" `/package/` `/^}/`}}
--->package file
-
-import (
-    "os"
-    "syscall"
-)
-
-type File struct {
-    fd   int    // file descriptor number
-    name string // file name at Open time
-}</pre>
-<p>
-The first few lines declare the name of the
-package—<code>file</code>—and then import two packages.  The <code>os</code>
-package hides the differences
-between various operating systems to give a consistent view of files and
-so on; here we're going to use its error handling utilities
-and reproduce the rudiments of its file I/O.
-<p>
-The other item is the low-level, external <code>syscall</code> package, which provides
-a primitive interface to the underlying operating system's calls.
-The <code>syscall</code> package is very system-dependent, and the way it's
-used here works only on Unix-like systems,
-but the general ideas explored here apply broadly.
-(A Windows version is available in
-<a href="progs/file_windows.go"><code>file_windows.go</code></a>.)
-<p>
-Next is a type definition: the <code>type</code> keyword introduces a type declaration,
-in this case a data structure called <code>File</code>.
-To make things a little more interesting, our <code>File</code> includes the name of the file
-that the file descriptor refers to.
-<p>
-Because <code>File</code> starts with a capital letter, the type is available outside the package,
-that is, by users of the package.   In Go the rule about visibility of information is
-simple: if a name (of a top-level type, function, method, constant or variable, or of
-a structure field or method) is capitalized, users of the package may see it. Otherwise, the
-name and hence the thing being named is visible only inside the package in which
-it is declared.  This is more than a convention; the rule is enforced by the compiler.
-In Go, the term for publicly visible names is ''exported''.
-<p>
-In the case of <code>File</code>, all its fields are lower case and so invisible to users, but we
-will soon give it some exported, upper-case methods.
-<p>
-First, though, here is a factory to create a <code>File</code>:
-<p>
-<pre><!--{{code "progs/file.go" `/newFile/` `/^}/`}}
--->func newFile(fd int, name string) *File {
-    if fd < 0 {
-        return nil
-    }
-    return &File{fd, name}
-}</pre>
-<p>
-This returns a pointer to a new <code>File</code> structure with the file descriptor and name
-filled in.  This code uses Go's notion of a ''composite literal'', analogous to
-the ones used to build maps and arrays, to construct a new heap-allocated
-object.  We could write
-<p>
-<pre>
-n := new(File)
-n.fd = fd
-n.name = name
-return n
-</pre>
-<p>
-but for simple structures like <code>File</code> it's easier to return the address of a 
-composite literal, as is done here in the <code>return</code> statement from <code>newFile</code>.
-<p>
-We can use the factory to construct some familiar, exported variables of type <code>*File</code>:
-<p>
-<pre><!--{{code "progs/file.go" `/var/` `/^\)/`}}
--->var (
-    Stdin  = newFile(syscall.Stdin, "/dev/stdin")
-    Stdout = newFile(syscall.Stdout, "/dev/stdout")
-    Stderr = newFile(syscall.Stderr, "/dev/stderr")
-)</pre>
-<p>
-The <code>newFile</code> function was not exported because it's internal. The proper,
-exported factory to use is <code>OpenFile</code> (we'll explain that name in a moment):
-<p>
-<pre><!--{{code "progs/file.go" `/func.OpenFile/` `/^}/`}}
--->func OpenFile(name string, mode int, perm uint32) (file *File, err error) {
-    r, err := syscall.Open(name, mode, perm)
-    return newFile(r, name), err
-}</pre>
-<p>
-There are a number of new things in these few lines.  First, <code>OpenFile</code> returns
-multiple values, a <code>File</code> and an error (more about errors in a moment).
-We declare the
-multi-value return as a parenthesized list of declarations; syntactically
-they look just like a second parameter list.  The function
-<code>syscall.Open</code>
-also has a multi-value return, which we can grab with the multi-variable
-declaration on the first line; it declares <code>r</code> and <code>e</code> to hold the two values,
-both of type <code>int</code> (although you'd have to look at the <code>syscall</code> package
-to see that).  Finally, <code>OpenFile</code> returns two values: a pointer to the new <code>File</code>
-and the error.  If <code>syscall.Open</code> fails, the file descriptor <code>r</code> will
-be negative and <code>newFile</code> will return <code>nil</code>.
-<p>
-About those errors:  The Go language includes a general notion of an error:
-a pre-defined type <code>error</code> with properties (described below)
-that make it a good basis for representing and handling errors.
-It's a good idea to use its facility in your own interfaces, as we do here, for
-consistent error handling throughout Go code.   In <code>Open</code> we use a
-conversion to translate Unix's integer <code>errno</code> value into the integer type
-<code>os.Errno</code>, which is an implementation of <code>error</code>
-<p>
-Why <code>OpenFile</code> and not <code>Open</code>? To mimic Go's <code>os</code> package, which
-our exercise is emulating. The <code>os</code> package takes the opportunity
-to make the two commonest cases - open for read and create for
-write - the simplest, just <code>Open</code> and <code>Create</code>.  <code>OpenFile</code> is the
-general case, analogous to the Unix system call <code>Open</code>.  Here is
-the implementation of our <code>Open</code> and <code>Create</code>; they're trivial
-wrappers that eliminate common errors by capturing
-the tricky standard arguments to open and, especially, to create a file:
-<p>
-<pre><!--{{code "progs/file.go" `/^const/` `/^}/`}}
--->const (
-    O_RDONLY = syscall.O_RDONLY
-    O_RDWR   = syscall.O_RDWR
-    O_CREATE = syscall.O_CREAT
-    O_TRUNC  = syscall.O_TRUNC
-)
-
-func Open(name string) (file *File, err error) {
-    return OpenFile(name, O_RDONLY, 0)
-}</pre>
-<p>
-<pre><!--{{code "progs/file.go" `/func.Create/` `/^}/`}}
--->func Create(name string) (file *File, err error) {
-    return OpenFile(name, O_RDWR|O_CREATE|O_TRUNC, 0666)
-}</pre>
-<p>
-Back to our main story.
-Now that we can build <code>Files</code>, we can write methods for them. To declare
-a method of a type, we define a function to have an explicit receiver
-of that type, placed
-in parentheses before the function name. Here are some methods for <code>*File</code>,
-each of which declares a receiver variable <code>file</code>.
-<p>
-<pre><!--{{code "progs/file.go" `/Close/` "$"}}
--->func (file *File) Close() error {
-    if file == nil {
-        return os.ErrInvalid
-    }
-    err := syscall.Close(file.fd)
-    file.fd = -1 // so it can't be closed again
-    return err
-}
-
-func (file *File) Read(b []byte) (ret int, err error) {
-    if file == nil {
-        return -1, os.ErrInvalid
-    }
-    r, err := syscall.Read(file.fd, b)
-    return int(r), err
-}
-
-func (file *File) Write(b []byte) (ret int, err error) {
-    if file == nil {
-        return -1, os.ErrInvalid
-    }
-    r, err := syscall.Write(file.fd, b)
-    return int(r), err
-}
-
-func (file *File) String() string {
-    return file.name
-}</pre>
-<p>
-There is no implicit <code>this</code> and the receiver variable must be used to access
-members of the structure.  Methods are not declared within
-the <code>struct</code> declaration itself.  The <code>struct</code> declaration defines only data members.
-In fact, methods can be created for almost any type you name, such as an integer or
-array, not just for <code>structs</code>.   We'll see an example with arrays later.
-<p>
-The <code>String</code> method is so called because of a printing convention we'll
-describe later.
-<p>
-The methods use the public variable <code>os.ErrInvalid</code> to return the (<code>error</code>
-version of the) Unix error code <code>EINVAL</code>.  The <code>os</code> library defines a standard
-set of such error values.
-<p>
-We can now use our new package:
-<p>
-<pre><!--{{code "progs/helloworld3.go" `/package/` "$"}}
--->package main
-
-import (
-    "./file"
-    "fmt"
-    "os"
-)
-
-func main() {
-    hello := []byte("hello, world\n")
-    file.Stdout.Write(hello)
-    f, err := file.Open("/does/not/exist")
-    if f == nil {
-        fmt.Printf("can't open file; err=%s\n", err.Error())
-        os.Exit(1)
-    }
-}</pre>
-<p>
-The ''<code>./</code>'' in the import of ''<code>./file</code>'' tells the compiler
-to use our own package rather than
-something from the directory of installed packages.
-(Also, ''<code>file.go</code>'' must be compiled before we can import the
-package.)
-<p>
-Now we can compile and run the program. On Unix, this would be the result:
-<p>
-<pre>
-$ 6g file.go                       # compile file package
-$ 6g helloworld3.go                # compile main package
-$ 6l -o helloworld3 helloworld3.6  # link - no need to mention "file"
-$ ./helloworld3
-hello, world
-can't open file; err=No such file or directory
-$
-</pre>
-<p>
-<h2>Rotting cats</h2>
-<p>
-Building on the <code>file</code> package, here's a simple version of the Unix utility <code>cat(1)</code>,
-<code>progs/cat.go</code>:
-<p>
-<pre><!--{{code "progs/cat.go" `/package/` "$"}}
--->package main
-
-import (
-    "./file"
-    "flag"
-    "fmt"
-    "os"
-)
-
-func cat(f *file.File) {
-    const NBUF = 512
-    var buf [NBUF]byte
-    for {
-        switch nr, er := f.Read(buf[:]); true {
-        case nr < 0:
-            fmt.Fprintf(os.Stderr, "cat: error reading from %s: %s\n", f, er)
-            os.Exit(1)
-        case nr == 0: // EOF
-            return
-        case nr > 0:
-            if nw, ew := file.Stdout.Write(buf[0:nr]); nw != nr {
-                fmt.Fprintf(os.Stderr, "cat: error writing from %s: %s\n", f, ew)
-                os.Exit(1)
-            }
-        }
-    }
-}
-
-func main() {
-    flag.Parse() // Scans the arg list and sets up flags
-    if flag.NArg() == 0 {
-        cat(file.Stdin)
-    }
-    for i := 0; i < flag.NArg(); i++ {
-        f, err := file.Open(flag.Arg(i))
-        if f == nil {
-            fmt.Fprintf(os.Stderr, "cat: can't open %s: error %s\n", flag.Arg(i), err)
-            os.Exit(1)
-        }
-        cat(f)
-        f.Close()
-    }
-}</pre>
-<p>
-By now this should be easy to follow, but the <code>switch</code> statement introduces some
-new features.  Like a <code>for</code> loop, an <code>if</code> or <code>switch</code> can include an
-initialization statement.  The <code>switch</code> statement in <code>cat</code> uses one to create variables
-<code>nr</code> and <code>er</code> to hold the return values from the call to <code>f.Read</code>.  (The <code>if</code> a few lines later
-has the same idea.)  The <code>switch</code> statement is general: it evaluates the cases
-from  top to bottom looking for the first case that matches the value; the
-case expressions don't need to be constants or even integers, as long as
-they all have the same type.
-<p>
-Since the <code>switch</code> value is just <code>true</code>, we could leave it off—as is also
-the situation
-in a <code>for</code> statement, a missing value means <code>true</code>.  In fact, such a <code>switch</code>
-is a form of <code>if-else</code> chain. While we're here, it should be mentioned that in
-<code>switch</code> statements each <code>case</code> has an implicit <code>break</code>.
-<p>
-The argument to <code>file.Stdout.Write</code> is created by slicing the array <code>buf</code>.
-Slices provide the standard Go way to handle I/O buffers.
-<p>
-Now let's make a variant of <code>cat</code> that optionally does <code>rot13</code> on its input.
-It's easy to do by just processing the bytes, but instead we will exploit
-Go's notion of an <i>interface</i>.
-<p>
-The <code>cat</code> subroutine uses only two methods of <code>f</code>: <code>Read</code> and <code>String</code>,
-so let's start by defining an interface that has exactly those two methods.
-Here is code from <code>progs/cat_rot13.go</code>:
-<p>
-<pre><!--{{code "progs/cat_rot13.go" `/type.reader/` `/^}/`}}
--->type reader interface {
-    Read(b []byte) (ret int, err error)
-    String() string
-}</pre>
-<p>
-Any type that has the two methods of <code>reader</code>—regardless of whatever
-other methods the type may also have—is said to <i>implement</i> the
-interface.  Since <code>file.File</code> implements these methods, it implements the
-<code>reader</code> interface.  We could tweak the <code>cat</code> subroutine to accept a <code>reader</code>
-instead of a <code>*file.File</code> and it would work just fine, but let's embellish a little
-first by writing a second type that implements <code>reader</code>, one that wraps an
-existing <code>reader</code> and does <code>rot13</code> on the data. To do this, we just define
-the type and implement the methods and with no other bookkeeping,
-we have a second implementation of the <code>reader</code> interface.
-<p>
-<pre><!--{{code "progs/cat_rot13.go" `/type.rotate13/` `/end.of.rotate13/`}}
--->type rotate13 struct {
-    source reader
-}
-
-func newRotate13(source reader) *rotate13 {
-    return &rotate13{source}
-}
-
-func (r13 *rotate13) Read(b []byte) (ret int, err error) {
-    r, e := r13.source.Read(b)
-    for i := 0; i < r; i++ {
-        b[i] = rot13(b[i])
-    }
-    return r, e
-}
-
-func (r13 *rotate13) String() string {
-    return r13.source.String()
-}</pre>
-<p>
-(The <code>rot13</code> function called in <code>Read</code> is trivial and not worth reproducing here.)
-<p>
-To use the new feature, we define a flag:
-<p>
-<pre><!--{{code "progs/cat_rot13.go" `/rot13Flag/`}}
--->var rot13Flag = flag.Bool("rot13", false, "rot13 the input")</pre>
-<p>
-and use it from within a mostly unchanged <code>cat</code> function:
-<p>
-<pre><!--{{code "progs/cat_rot13.go" `/func.cat/` `/^}/`}}
--->func cat(r reader) {
-    const NBUF = 512
-    var buf [NBUF]byte
-
-    if *rot13Flag {
-        r = newRotate13(r)
-    }
-    for {
-        switch nr, er := r.Read(buf[:]); {
-        case nr < 0:
-            fmt.Fprintf(os.Stderr, "cat: error reading from %s: %s\n", r, er)
-            os.Exit(1)
-        case nr == 0: // EOF
-            return
-        case nr > 0:
-            nw, ew := file.Stdout.Write(buf[0:nr])
-            if nw != nr {
-                fmt.Fprintf(os.Stderr, "cat: error writing from %s: %s\n", r, ew)
-                os.Exit(1)
-            }
-        }
-    }
-}</pre>
-<p>
-(We could also do the wrapping in <code>main</code> and leave <code>cat</code> mostly alone, except
-for changing the type of the argument; consider that an exercise.)
-The <code>if</code> at the top of <code>cat</code> sets it all up: If the <code>rot13</code> flag is true, wrap the <code>reader</code>
-we received into a <code>rotate13</code> and proceed.  Note that the interface variables
-are values, not pointers: the argument is of type <code>reader</code>, not <code>*reader</code>,
-even though under the covers it holds a pointer to a <code>struct</code>.
-<p>
-Here it is in action:
-<p>
-<pre>
-$ echo abcdefghijklmnopqrstuvwxyz | ./cat
-abcdefghijklmnopqrstuvwxyz
-$ echo abcdefghijklmnopqrstuvwxyz | ./cat --rot13
-nopqrstuvwxyzabcdefghijklm
-$
-</pre>
-<p>
-Fans of dependency injection may take cheer from how easily interfaces
-allow us to substitute the implementation of a file descriptor.
-<p>
-Interfaces are a distinctive feature of Go.  An interface is implemented by a
-type if the type implements all the methods declared in the interface.
-This means
-that a type may implement an arbitrary number of different interfaces.
-There is no type hierarchy; things can be much more <i>ad hoc</i>,
-as we saw with <code>rot13</code>.  The type <code>file.File</code> implements <code>reader</code>; it could also
-implement a <code>writer</code>, or any other interface built from its methods that
-fits the current situation. Consider the <i>empty interface</i>
-<p>
-<pre>
-type Empty interface {}
-</pre>
-<p>
-<i>Every</i> type implements the empty interface, which makes it
-useful for things like containers.
-<p>
-<h2>Sorting</h2>
-<p>
-Interfaces provide a simple form of polymorphism.  They completely
-separate the definition of what an object does from how it does it, allowing
-distinct implementations to be represented at different times by the
-same interface variable.
-<p>
-As an example, consider this simple sort algorithm taken from <code>progs/sort.go</code>:
-<p>
-<pre><!--{{code "progs/sort.go" `/func.Sort/` `/^}/`}}
--->func Sort(data Interface) {
-    for i := 1; i < data.Len(); i++ {
-        for j := i; j > 0 && data.Less(j, j-1); j-- {
-            data.Swap(j, j-1)
-        }
-    }
-}</pre>
-<p>
-The code needs only three methods, which we wrap into sort's <code>Interface</code>:
-<p>
-<pre><!--{{code "progs/sort.go" `/interface/` `/^}/`}}
--->type Interface interface {
-    Len() int
-    Less(i, j int) bool
-    Swap(i, j int)
-}</pre>
-<p>
-We can apply <code>Sort</code> to any type that implements <code>Len</code>, <code>Less</code>, and <code>Swap</code>.
-The <code>sort</code> package includes the necessary methods to allow sorting of
-arrays of integers, strings, etc.; here's the code for arrays of <code>int</code>
-<p>
-<pre><!--{{code "progs/sort.go" `/type.*IntSlice/` `/Swap/`}}
--->type IntSlice []int
-
-func (p IntSlice) Len() int           { return len(p) }
-func (p IntSlice) Less(i, j int) bool { return p[i] < p[j] }
-func (p IntSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }</pre>
-<p>
-Here we see methods defined for non-<code>struct</code> types.  You can define methods
-for any type you define and name in your package.
-<p>
-And now a routine to test it out, from <code>progs/sortmain.go</code>.  This
-uses a function in the <code>sort</code> package, omitted here for brevity,
-to test that the result is sorted.
-<p>
-<pre><!--{{code "progs/sortmain.go" `/func.ints/` `/^}/`}}
--->func ints() {
-    data := []int{74, 59, 238, -784, 9845, 959, 905, 0, 0, 42, 7586, -5467984, 7586}
-    a := sort.IntSlice(data)
-    sort.Sort(a)
-    if !sort.IsSorted(a) {
-        panic("fail")
-    }
-}</pre>
-<p>
-If we have a new type we want to be able to sort, all we need to do is
-to implement the three methods for that type, like this:
-<p>
-<pre><!--{{code "progs/sortmain.go" `/type.day/` `/Swap/`}}
--->type day struct {
-    num       int
-    shortName string
-    longName  string
-}
-
-type dayArray struct {
-    data []*day
-}
-
-func (p *dayArray) Len() int           { return len(p.data) }
-func (p *dayArray) Less(i, j int) bool { return p.data[i].num < p.data[j].num }
-func (p *dayArray) Swap(i, j int)      { p.data[i], p.data[j] = p.data[j], p.data[i] }</pre>
-<p>
-<p>
-<h2>Printing</h2>
-<p>
-The examples of formatted printing so far have been modest.  In this section
-we'll talk about how formatted I/O can be done well in Go.
-<p>
-We've seen simple uses of the package <code>fmt</code>, which
-implements <code>Printf</code>, <code>Fprintf</code>, and so on.
-Within the <code>fmt</code> package, <code>Printf</code> is declared with this signature:
-<p>
-<pre>
-Printf(format string, v ...interface{}) (n int, errno error)
-</pre>
-<p>
-The token <code>...</code> introduces a variable-length argument list that in C would
-be handled using the <code>stdarg.h</code> macros.
-In Go, variadic functions are passed a slice of the arguments of the
-specified type.  In <code>Printf</code>'s case, the declaration says <code>...interface{}</code>
-so the actual type is a slice of empty interface values, <code>[]interface{}</code>.
-<code>Printf</code> can examine the arguments by iterating over the slice
-and, for each element, using a type switch or the reflection library
-to interpret the value.
-It's off topic here but such run-time type analysis
-helps explain some of the nice properties of Go's <code>Printf</code>,
-due to the ability of <code>Printf</code> to discover the type of its arguments
-dynamically.
-<p>
-For example, in C each format must correspond to the type of its
-argument.  It's easier in many cases in Go.  Instead of <code>%llud</code> you
-can just say <code>%d</code>; <code>Printf</code> knows the size and signedness of the
-integer and can do the right thing for you.  The snippet
-<p>
-<pre><!--{{code "progs/print.go" 10 11}}
--->    var u64 uint64 = 1<<64 - 1
-    fmt.Printf("%d %d\n", u64, int64(u64))</pre>
-<p>
-prints
-<p>
-<pre>
-18446744073709551615 -1
-</pre>
-<p>
-In fact, if you're lazy the format <code>%v</code> will print, in a simple
-appropriate style, any value, even an array or structure.  The output of
-<p>
-<pre><!--{{code "progs/print.go" 14 20}}
--->    type T struct {
-        a int
-        b string
-    }
-    t := T{77, "Sunset Strip"}
-    a := []int{1, 2, 3, 4}
-    fmt.Printf("%v %v %v\n", u64, t, a)</pre>
-<p>
-is
-<p>
-<pre>
-18446744073709551615 {77 Sunset Strip} [1 2 3 4]
-</pre>
-<p>
-You can drop the formatting altogether if you use <code>Print</code> or <code>Println</code>
-instead of <code>Printf</code>.  Those routines do fully automatic formatting.
-The <code>Print</code> function just prints its elements out using the equivalent
-of <code>%v</code> while <code>Println</code> inserts spaces between arguments
-and adds a newline.  The output of each of these two lines is identical
-to that of the <code>Printf</code> call above.
-<p>
-<pre><!--{{code "progs/print.go" 21 22}}
--->    fmt.Print(u64, " ", t, " ", a, "\n")
-    fmt.Println(u64, t, a)</pre>
-<p>
-If you have your own type you'd like <code>Printf</code> or <code>Print</code> to format,
-just give it a <code>String</code> method that returns a string.  The print
-routines will examine the value to inquire whether it implements
-the method and if so, use it rather than some other formatting.
-Here's a simple example.
-<p>
-<pre><!--{{code "progs/print_string.go" 9 "$"}}
--->type testType struct {
-    a int
-    b string
-}
-
-func (t *testType) String() string {
-    return fmt.Sprint(t.a) + " " + t.b
-}
-
-func main() {
-    t := &testType{77, "Sunset Strip"}
-    fmt.Println(t)
-}</pre>
-<p>
-Since <code>*testType</code> has a <code>String</code> method, the
-default formatter for that type will use it and produce the output
-<p>
-<pre>
-77 Sunset Strip
-</pre>
-<p>
-Observe that the <code>String</code> method calls <code>Sprint</code> (the obvious Go
-variant that returns a string) to do its formatting; special formatters
-can use the <code>fmt</code> library recursively.
-<p>
-Another feature of <code>Printf</code> is that the format <code>%T</code> will print a string
-representation of the type of a value, which can be handy when debugging
-polymorphic code.
-<p>
-It's possible to write full custom print formats with flags and precisions
-and such, but that's getting a little off the main thread so we'll leave it
-as an exploration exercise.
-<p>
-You might ask, though, how <code>Printf</code> can tell whether a type implements
-the <code>String</code> method.  Actually what it does is ask if the value can
-be converted to an interface variable that implements the method.
-Schematically, given a value <code>v</code>, it does this:
-<p>
-<p>
-<pre>
-type Stringer interface {
-    String() string
-}
-</pre>
-<p>
-<pre>
-s, ok := v.(Stringer)  // Test whether v implements "String()"
-if ok {
-    result = s.String()
-} else {
-    result = defaultOutput(v)
-}
-</pre>
-<p>
-The code uses a ``type assertion'' (<code>v.(Stringer)</code>) to test if the value stored in
-<code>v</code> satisfies the <code>Stringer</code> interface; if it does, <code>s</code>
-will become an interface variable implementing the method and <code>ok</code> will
-be <code>true</code>.  We then use the interface variable to call the method.
-(The ''comma, ok'' pattern is a Go idiom used to test the success of
-operations such as type conversion, map update, communications, and so on,
-although this is the only appearance in this tutorial.)
-If the value does not satisfy the interface, <code>ok</code> will be false.
-<p>
-In this snippet the name <code>Stringer</code> follows the convention that we add ''[e]r''
-to interfaces describing simple method sets like this.
-<p>
-A related interface is that defined by the <code>error</code> builtin type, which is just
-<p>
-<pre>
-type error interface {
-    Error() string
-}
-</pre>
-<p>
-Other than the method name (<code>Error</code> vs. <code>String</code>), this looks like
-a <code>Stringer</code>; the different name guarantees that types that implement <code>Stringer</code>
-don't accidentally satisfy the <code>error</code> interface.
-Naturally, <code>Printf</code> and its relatives recognize the <code>error</code> interface,
-just as they do <code>Stringer</code>,
-so it's trivial to print an error as a string.
-<p>
-One last wrinkle.  To complete the suite, besides <code>Printf</code> etc. and <code>Sprintf</code>
-etc., there are also <code>Fprintf</code> etc.  Unlike in C, <code>Fprintf</code>'s first argument is
-not a file.  Instead, it is a variable of type <code>io.Writer</code>, which is an
-interface type defined in the <code>io</code> library:
-<p>
-<pre>
-type Writer interface {
-    Write(p []byte) (n int, err error)
-}
-</pre>
-<p>
-(This interface is another conventional name, this time for <code>Write</code>; there are also
-<code>io.Reader</code>, <code>io.ReadWriter</code>, and so on.)
-Thus you can call <code>Fprintf</code> on any type that implements a standard <code>Write</code>
-method, not just files but also network channels, buffers, whatever
-you want.
-<p>
-<h2>Prime numbers</h2>
-<p>
-Now we come to processes and communication—concurrent programming.
-It's a big subject so to be brief we assume some familiarity with the topic.
-<p>
-A classic program in the style is a prime sieve.
-(The sieve of Eratosthenes is computationally more efficient than
-the algorithm presented here, but we are more interested in concurrency than
-algorithmics at the moment.)
-It works by taking a stream of all the natural numbers and introducing
-a sequence of filters, one for each prime, to winnow the multiples of
-that prime.  At each step we have a sequence of filters of the primes
-so far, and the next number to pop out is the next prime, which triggers
-the creation of the next filter in the chain.
-<p>
-Here's a flow diagram; each box represents a filter element whose
-creation is triggered by the first number that flowed from the
-elements before it.
-<p>
-<br>
-<p>
-     <img src='sieve.gif'>
-<p>
-<br>
-<p>
-To create a stream of integers, we use a Go <i>channel</i>, which,
-borrowing from CSP's descendants, represents a communications
-channel that can connect two concurrent computations.
-In Go, channel variables are references to a run-time object that
-coordinates the communication; as with maps and slices, use
-<code>make</code> to create a new channel.
-<p>
-Here is the first function in <code>progs/sieve.go</code>:
-<p>
-<pre><!--{{code "progs/sieve.go" `/Send/` `/^}/`}}
--->// Send the sequence 2, 3, 4, ... to channel 'ch'.
-func generate(ch chan int) {
-    for i := 2; ; i++ {
-        ch <- i // Send 'i' to channel 'ch'.
-    }
-}</pre>
-<p>
-The <code>generate</code> function sends the sequence 2, 3, 4, 5, ... to its
-argument channel, <code>ch</code>, using the binary communications operator <code><-</code>.
-Channel operations block, so if there's no recipient for the value on <code>ch</code>,
-the send operation will wait until one becomes available.
-<p>
-The <code>filter</code> function has three arguments: an input channel, an output
-channel, and a prime number.  It copies values from the input to the
-output, discarding anything divisible by the prime.  The unary communications
-operator <code><-</code> (receive) retrieves the next value on the channel.
-<p>
-<pre><!--{{code "progs/sieve.go" `/Copy.the/` `/^}/`}}
--->// Copy the values from channel 'in' to channel 'out',
-// removing those divisible by 'prime'.
-func filter(in, out chan int, prime int) {
-    for {
-        i := <-in // Receive value of new variable 'i' from 'in'.
-        if i%prime != 0 {
-            out <- i // Send 'i' to channel 'out'.
-        }
-    }
-}</pre>
-<p>
-The generator and filters execute concurrently.  Go has
-its own model of process/threads/light-weight processes/coroutines,
-so to avoid notational confusion we call concurrently executing
-computations in Go <i>goroutines</i>.  To start a goroutine,
-invoke the function, prefixing the call with the keyword <code>go</code>;
-this starts the function running in parallel with the current
-computation but in the same address space:
-<p>
-<pre>
-go sum(hugeArray) // calculate sum in the background
-</pre>
-<p>
-If you want to know when the calculation is done, pass a channel
-on which it can report back:
-<p>
-<pre>
-ch := make(chan int)
-go sum(hugeArray, ch)
-// ... do something else for a while
-result := <-ch  // wait for, and retrieve, result
-</pre>
-<p>
-Back to our prime sieve.  Here's how the sieve pipeline is stitched
-together:
-<p>
-<pre><!--{{code "progs/sieve.go" `/func.main/` `/^}/`}}
--->func main() {
-    ch := make(chan int)       // Create a new channel.
-    go generate(ch)            // Start generate() as a goroutine.
-    for i := 0; i < 100; i++ { // Print the first hundred primes.
-        prime := <-ch
-        fmt.Println(prime)
-        ch1 := make(chan int)
-        go filter(ch, ch1, prime)
-        ch = ch1
-    }
-}</pre>
-<p>
-The first line of <code>main</code> creates the initial channel to pass to <code>generate</code>, which it
-then starts up.  As each prime pops out of the channel, a new <code>filter</code>
-is added to the pipeline and <i>its</i> output becomes the new value
-of <code>ch</code>.
-<p>
-The sieve program can be tweaked to use a pattern common
-in this style of programming.  Here is a variant version
-of <code>generate</code>, from <code>progs/sieve1.go</code>:
-<p>
-<pre><!--{{code "progs/sieve1.go" `/func.generate/` `/^}/`}}
--->func generate() chan int {
-    ch := make(chan int)
-    go func() {
-        for i := 2; ; i++ {
-            ch <- i
-        }
-    }()
-    return ch
-}</pre>
-<p>
-This version does all the setup internally. It creates the output
-channel, launches a goroutine running a function literal, and
-returns the channel to the caller.  It is a factory for concurrent
-execution, starting the goroutine and returning its connection.
-<p>
-The function literal notation used in the <code>go</code> statement allows us to construct an
-anonymous function and invoke it on the spot. Notice that the local
-variable <code>ch</code> is available to the function literal and lives on even
-after <code>generate</code> returns.
-<p>
-The same change can be made to <code>filter</code>:
-<p>
-<pre><!--{{code "progs/sieve1.go" `/func.filter/` `/^}/`}}
--->func filter(in chan int, prime int) chan int {
-    out := make(chan int)
-    go func() {
-        for {
-            if i := <-in; i%prime != 0 {
-                out <- i
-            }
-        }
-    }()
-    return out
-}</pre>
-<p>
-The <code>sieve</code> function's main loop becomes simpler and clearer as a
-result, and while we're at it let's turn it into a factory too:
-<p>
-<pre><!--{{code "progs/sieve1.go" `/func.sieve/` `/^}/`}}
--->func sieve() chan int {
-    out := make(chan int)
-    go func() {
-        ch := generate()
-        for {
-            prime := <-ch
-            out <- prime
-            ch = filter(ch, prime)
-        }
-    }()
-    return out
-}</pre>
-<p>
-Now <code>main</code>'s interface to the prime sieve is a channel of primes:
-<p>
-<pre><!--{{code "progs/sieve1.go" `/func.main/` `/^}/`}}
--->func main() {
-    primes := sieve()
-    for i := 0; i < 100; i++ { // Print the first hundred primes.
-        fmt.Println(<-primes)
-    }
-}</pre>
-<p>
-<h2>Multiplexing</h2>
-<p>
-With channels, it's possible to serve multiple independent client goroutines without
-writing an explicit multiplexer.  The trick is to send the server a channel in the message,
-which it will then use to reply to the original sender.
-A realistic client-server program is a lot of code, so here is a very simple substitute
-to illustrate the idea.  It starts by defining a <code>request</code> type, which embeds a channel
-that will be used for the reply.
-<p>
-<pre><!--{{code "progs/server.go" `/type.request/` `/^}/`}}
--->type request struct {
-    a, b   int
-    replyc chan int
-}</pre>
-<p>
-The server will be trivial: it will do simple binary operations on integers.  Here's the
-code that invokes the operation and responds to the request:
-<p>
-<pre><!--{{code "progs/server.go" `/type.binOp/` `/^}/`}}
--->type binOp func(a, b int) int
-
-func run(op binOp, req *request) {
-    reply := op(req.a, req.b)
-    req.replyc <- reply
-}</pre>
-<p>
-The type declaration makes <code>binOp</code> represent a function taking two integers and
-returning a third.
-<p>
-The <code>server</code> routine loops forever, receiving requests and, to avoid blocking due to
-a long-running operation, starting a goroutine to do the actual work.
-<p>
-<pre><!--{{code "progs/server.go" `/func.server/` `/^}/`}}
--->func server(op binOp, service <-chan *request) {
-    for {
-        req := <-service
-        go run(op, req) // don't wait for it
-    }
-}</pre>
-<p>
-There's a new feature in the signature of <code>server</code>: the type of the
-<code>service</code> channel specifies the direction of communication.
-A channel of plain <code>chan</code> type can be used both for sending and receiving.
-However, the type used when declaring a channel can be decorated with an arrow to
-indicate that the channel can be used only to send (<code>chan<-</code>) or to
-receive (<code><-chan</code>) data.
-The arrow points towards or away from the <code>chan</code> to indicate whether data flows into or out of
-the channel.
-In the <code>server</code> function, <code>service <-chan *request</code> is a "receive only" channel
-that the function can use only to <em>read</em> new requests.
-<p>
-We instantiate a server in a familiar way, starting it and returning a channel
-connected to it:
-<p>
-<pre><!--{{code "progs/server.go" `/func.startServer/` `/^}/`}}
--->func startServer(op binOp) chan<- *request {
-    req := make(chan *request)
-    go server(op, req)
-    return req
-}</pre>
-<p>
-The returned channel is send only, even though the channel was created bidirectionally.
-The read end is passed to <code>server</code>, while the send end is returned
-to the caller of <code>startServer</code>, so the two halves of the channel
-are distinguished, just as we did in <code>startServer</code>.
-<p>
-Bidirectional channels can be assigned to unidirectional channels but not the
-other way around, so if you annotate your channel directions when you declare
-them, such as in function signatures, the type system can help you set up and
-use channels correctly.
-Note that it's pointless to <code>make</code> unidirectional channels, since you can't
-use them to communicate. Their purpose is served by variables assigned from bidirectional channels
-to distinguish the input and output halves.
-<p>
-Here's a simple test.  It starts a server with an addition operator and sends out
-<code>N</code> requests without waiting for the replies.  Only after all the requests are sent
-does it check the results.
-<p>
-<pre><!--{{code "progs/server.go" `/func.main/` `/^}/`}}
--->func main() {
-    adder := startServer(func(a, b int) int { return a + b })
-    const N = 100
-    var reqs [N]request
-    for i := 0; i < N; i++ {
-        req := &reqs[i]
-        req.a = i
-        req.b = i + N
-        req.replyc = make(chan int)
-        adder <- req
-    }
-    for i := N - 1; i >= 0; i-- { // doesn't matter what order
-        if <-reqs[i].replyc != N+2*i {
-            fmt.Println("fail at", i)
-        }
-    }
-    fmt.Println("done")
-}</pre>
-<p>
-One annoyance with this program is that it doesn't shut down the server cleanly; when <code>main</code> returns
-there are a number of lingering goroutines blocked on communication.  To solve this,
-we can provide a second, <code>quit</code> channel to the server:
-<p>
-<pre><!--{{code "progs/server1.go" `/func.startServer/` `/^}/`}}
--->func startServer(op binOp) (service chan *request, quit chan bool) {
-    service = make(chan *request)
-    quit = make(chan bool)
-    go server(op, service, quit)
-    return service, quit
-}</pre>
-<p>
-It passes the quit channel to the <code>server</code> function, which uses it like this:
-<p>
-<pre><!--{{code "progs/server1.go" `/func.server/` `/^}/`}}
--->func server(op binOp, service <-chan *request, quit <-chan bool) {
-    for {
-        select {
-        case req := <-service:
-            go run(op, req) // don't wait for it
-        case <-quit:
-            return
-        }
-    }
-}</pre>
-<p>
-Inside <code>server</code>, the <code>select</code> statement chooses which of the multiple communications
-listed by its cases can proceed.  If all are blocked, it waits until one can proceed; if
-multiple can proceed, it chooses one at random.  In this instance, the <code>select</code> allows
-the server to honor requests until it receives a quit message, at which point it
-returns, terminating its execution.
-<p>
-<p>
-All that's left is to strobe the <code>quit</code> channel
-at the end of main:
-<p>
-<pre><!--{{code "progs/server1.go" `/adder,.quit/`}}
--->    adder, quit := startServer(func(a, b int) int { return a + b })</pre>
-...
-<pre><!--{{code "progs/server1.go" `/quit....true/`}}
--->    quit <- true</pre>
-<p>
-There's a lot more to Go programming and concurrent programming in general but this
-quick tour should give you some of the basics.
diff --git a/doc/go_tutorial.tmpl b/doc/go_tutorial.tmpl
deleted file mode 100644
index 3318918..0000000
--- a/doc/go_tutorial.tmpl
+++ /dev/null
@@ -1,1040 +0,0 @@
-<!--{
-	"Title": "A Tutorial for the Go Programming Language"
-}-->
-{{donotedit}}
-
-<h2>Introduction</h2>
-<p>
-This document is a tutorial introduction to the basics of the Go programming
-language, intended for programmers familiar with C or C++. It is not a comprehensive
-guide to the language; at the moment the document closest to that is the
-<a href='/doc/go_spec.html'>language specification</a>.
-After you've read this tutorial, you should look at
-<a href='/doc/effective_go.html'>Effective Go</a>,
-which digs deeper into how the language is used and
-talks about the style and idioms of programming in Go.
-An interactive introduction to Go is available, called
-<a href='http://tour.golang.org/'>A Tour of Go</a>.
-<p>
-The presentation here proceeds through a series of modest programs to illustrate
-key features of the language.  All the programs work (at time of writing) and are
-checked into the repository in the directory <a href='/doc/progs'><code>/doc/progs/</code></a>.
-<p>
-<h2>Hello, World</h2>
-<p>
-Let's start in the usual way:
-<p>
-{{code "progs/helloworld.go" `/package/` "$"}}
-<p>
-Every Go source file declares, using a <code>package</code> statement, which package it's part of.
-It may also import other packages to use their facilities.
-This program imports the package <code>fmt</code> to gain access to
-our old, now capitalized and package-qualified, friend, <code>fmt.Printf</code>.
-<p>
-Functions are introduced with the <code>func</code> keyword.
-The <code>main</code> package's <code>main</code> function is where the program starts running (after
-any initialization).
-<p>
-String constants can contain Unicode characters, encoded in UTF-8.
-(In fact, Go source files are defined to be encoded in UTF-8.)
-<p>
-The comment convention is the same as in C++:
-<p>
-<pre>
-/* ... */
-// ...
-</pre>
-<p>
-Later we'll have much more to say about printing.
-<p>
-<h2>Semicolons</h2>
-<p>
-You might have noticed that our program has no semicolons.  In Go
-code, the only place you typically see semicolons is separating the
-clauses of <code>for</code> loops and the like; they are not necessary after
-every statement.
-<p>
-In fact, what happens is that the formal language uses semicolons,
-much as in C or Java, but they are inserted automatically
-at the end of every line that looks like the end of a statement. You
-don't need to type them yourself.
-<p>
-For details about how this is done you can see the language
-specification, but in practice all you need to know is that you
-never need to put a semicolon at the end of a line.  (You can put
-them in if you want to write multiple statements per line.) As an
-extra help, you can also leave out a semicolon immediately before
-a closing brace.
-<p>
-This approach makes for clean-looking, semicolon-free code.  The
-one surprise is that it's important to put the opening
-brace of a construct such as an <code>if</code> statement on the same line as
-the <code>if</code>; if you don't, there are situations that may not compile
-or may give the wrong result.  The language forces the brace style
-to some extent.
-<p>
-<h2>Compiling</h2>
-<p>
-Go is a compiled language.  At the moment there are two compilers.
-<code>Gccgo</code> is a Go compiler that uses the GCC back end.  There is also a
-suite of compilers with different (and odd) names for each architecture:
-<code>6g</code> for the 64-bit x86, <code>8g</code> for the 32-bit x86, and more.  These
-compilers run significantly faster but generate less efficient code
-than <code>gccgo</code>.  At the time of writing (late 2009), they also have
-a more robust run-time system although <code>gccgo</code> is catching up.
-<p>
-Here's how to compile and run our program.  With <code>6g</code>, say,
-<p>
-<pre>
-$ 6g helloworld.go  # compile; object goes into helloworld.6
-$ 6l helloworld.6   # link; output goes into 6.out
-$ ./6.out
-Hello, world; or Καλημέρα κόσμε; or こんにちは 世界
-$
-</pre>
-<p>
-With <code>gccgo</code> it looks a little more traditional.
-<p>
-<pre>
-$ gccgo helloworld.go
-$ ./a.out
-Hello, world; or Καλημέρα κόσμε; or こんにちは 世界
-$
-</pre>
-<p>
-<h2>Echo</h2>
-<p>
-Next up, here's a version of the Unix utility <code>echo(1)</code>:
-<p>
-{{code "progs/echo.go" `/package/` "$"}}
-<p>
-This program is small but it's doing a number of new things.  In the last example,
-we saw <code>func</code> introduce a function.  The keywords <code>var</code>, <code>const</code>, and <code>type</code>
-(not used yet) also introduce declarations, as does <code>import</code>.
-Notice that we can group declarations of the same sort into
-parenthesized lists, one item per line, as in the <code>import</code> and <code>const</code> clauses here.
-But it's not necessary to do so; we could have said
-<p>
-<pre>
-const Space = " "
-const Newline = "\n"
-</pre>
-<p>
-This program imports the <code>"os"</code> package to access its <code>Stdout</code> variable, of type
-<code>*os.File</code>.  The <code>import</code> statement is actually a declaration: in its general form,
-as used in our ``hello world'' program,
-it names the identifier (<code>fmt</code>)
-that will be used to access members of the package imported from the file (<code>"fmt"</code>),
-found in the current directory or in a standard location.
-In this program, though, we've dropped the explicit name from the imports; by default,
-packages are imported using the name defined by the imported package,
-which by convention is of course the file name itself.  Our ``hello world'' program
-could have said just <code>import "fmt"</code>.
-<p>
-You can specify your
-own import names if you want but it's only necessary if you need to resolve
-a naming conflict.
-<p>
-Given <code>os.Stdout</code> we can use its <code>WriteString</code> method to print the string.
-<p>
-After importing the <code>flag</code> package, we use a <code>var</code> declaration
-to create and initialize a global variable, called <code>omitNewline</code>,
-to hold the value of echo's <code>-n</code> flag. 
-The variable  has type <code>*bool</code>, pointer to <code>bool</code>.
-<p>
-In <code>main.main</code>, we parse the arguments (the call to <code>flag.Parse</code>) and then create a local
-string variable with which to build the output.
-<p>
-The declaration statement has the form
-<p>
-<pre>
-var s string = ""
-</pre>
-<p>
-This is the <code>var</code> keyword, followed by the name of the variable, followed by
-its type, followed by an equals sign and an initial value for the variable.
-<p>
-Go tries to be terse, and this declaration could be shortened.  Since the
-string constant is of type string, we don't have to tell the compiler that.
-We could write
-<p>
-<pre>
-var s = ""
-</pre>
-<p>
-or we could go even shorter and write the idiom
-<p>
-<pre>
-s := ""
-</pre>
-<p>
-The <code>:=</code> operator is used a lot in Go to represent an initializing declaration.
-There's one in the <code>for</code> clause on the next line:
-<p>
-{{code  "progs/echo.go" `/for/`}}
-<p>
-The <code>flag</code> package has parsed the arguments and left the non-flag arguments
-in a list that can be iterated over in the obvious way.
-<p>
-The Go <code>for</code> statement differs from that of C in a number of ways.  First,
-it's the only looping construct; there is no <code>while</code> or <code>do</code>.  Second,
-there are no parentheses on the clause, but the braces on the body
-are mandatory.  The same applies to the <code>if</code> and <code>switch</code> statements.
-Later examples will show some other ways <code>for</code> can be written.
-<p>
-The body of the loop builds up the string <code>s</code> by appending (using <code>+=</code>)
-the arguments and separating spaces. After the loop, if the <code>-n</code> flag is not
-set, the program appends a newline. Finally, it writes the result.
-<p>
-Notice that <code>main.main</code> is a niladic function with no return type.
-It's defined that way.  Falling off the end of <code>main.main</code> means
-''success''; if you want to signal an erroneous return, call
-<p>
-<pre>
-os.Exit(1)
-</pre>
-<p>
-The <code>os</code> package contains other essentials for getting
-started; for instance, <code>os.Args</code> is a slice used by the
-<code>flag</code> package to access the command-line arguments.
-<p>
-<h2>An Interlude about Types</h2>
-<p>
-Go has some familiar types such as <code>int</code> and <code>uint</code> (unsigned <code>int</code>), which represent
-values of the ''appropriate'' size for the machine. It also defines
-explicitly-sized types such as <code>int8</code>, <code>float64</code>, and so on, plus
-unsigned integer types such as <code>uint</code>, <code>uint32</code>, etc.
-These are distinct types; even if <code>int</code> and <code>int32</code> are both 32 bits in size,
-they are not the same type.  There is also a <code>byte</code> synonym for
-<code>uint8</code>, which is the element type for strings.
-<p>
-Floating-point types are always sized: <code>float32</code> and <code>float64</code>,
-plus <code>complex64</code> (two <code>float32s</code>) and <code>complex128</code>
-(two <code>float64s</code>).  Complex numbers are outside the
-scope of this tutorial.
-<p>
-Speaking of <code>string</code>, that's a built-in type as well.  Strings are
-<i>immutable values</i>—they are not just arrays of <code>byte</code> values.
-Once you've built a string <i>value</i>, you can't change it, although
-of course you can change a string <i>variable</i> simply by
-reassigning it.  This snippet from <code>strings.go</code> is legal code:
-<p>
-{{code "progs/strings.go" `/hello/` `/ciao/`}}
-<p>
-However the following statements are illegal because they would modify
-a <code>string</code> value:
-<p>
-<pre>
-s[0] = 'x'
-(*p)[1] = 'y'
-</pre>
-<p>
-In C++ terms, Go strings are a bit like <code>const strings</code>, while pointers
-to strings are analogous to <code>const string</code> references.
-<p>
-Yes, there are pointers.  However, Go simplifies their use a little;
-read on.
-<p>
-Arrays are declared like this:
-<p>
-<pre>
-var arrayOfInt [10]int
-</pre>
-<p>
-Arrays, like strings, are values, but they are mutable. This differs
-from C, in which <code>arrayOfInt</code> would be usable as a pointer to <code>int</code>.
-In Go, since arrays are values, it's meaningful (and useful) to talk
-about pointers to arrays.
-<p>
-The size of the array is part of its type; however, one can declare
-a <i>slice</i> variable to hold a reference to any array, of any size,
-with the same element type.
-A <i>slice
-expression</i> has the form <code>a[low : high]</code>, representing
-the internal array indexed from <code>low</code> through <code>high-1</code>; the resulting
-slice is indexed from <code>0</code> through <code>high-low-1</code>.
-In short, slices look a lot like arrays but with
-no explicit size (<code>[]</code> vs. <code>[10]</code>) and they reference a segment of
-an underlying, usually anonymous, regular array.  Multiple slices
-can share data if they represent pieces of the same array;
-multiple arrays can never share data.
-<p>
-Slices are much more common in Go programs than
-regular arrays; they're more flexible, have reference semantics,
-and are efficient.  What they lack is the precise control of storage
-layout of a regular array; if you want to have a hundred elements
-of an array stored within your structure, you should use a regular
-array. To create one, use a compound value <i>constructor</i>—an
-expression formed
-from a type followed by a brace-bounded expression like this:
-<p>
-<pre>
-[3]int{1,2,3}
-</pre>
-<p>
-In this case the constructor builds an array of 3 <code>ints</code>.
-<p>
-When passing an array to a function, you almost always want
-to declare the formal parameter to be a slice.  When you call
-the function, slice the array to create
-(efficiently) a slice reference and pass that.
-By default, the lower and upper bounds of a slice match the
-ends of the existing object, so the concise notation <code>[:]</code>
-will slice the whole array.
-<p>
-Using slices one can write this function (from <code>sum.go</code>):
-<p>
-{{code "progs/sum.go" `/sum/` `/^}/`}}
-<p>
-Note how the return type (<code>int</code>) is defined for <code>sum</code> by stating it
-after the parameter list.
-<p>
-To call the function, we slice the array.  This code (we'll show
-a simpler way in a moment) constructs
-an array and slices it:
-<p>
-<pre>
-x := [3]int{1,2,3}
-s := sum(x[:])
-</pre>
-<p>
-If you are creating a regular array but want the compiler to count the
-elements for you, use <code>...</code> as the array size:
-<p>
-<pre>
-x := [...]int{1,2,3}
-s := sum(x[:])
-</pre>
-<p>
-That's fussier than necessary, though.
-In practice, unless you're meticulous about storage layout within a
-data structure, a slice itself—using empty brackets with no size—is all you need:
-<p>
-<pre>
-s := sum([]int{1,2,3})
-</pre>
-<p>
-There are also maps, which you can initialize like this:
-<p>
-<pre>
-m := map[string]int{"one":1 , "two":2}
-</pre>
-<p>
-The built-in function <code>len</code>, which returns number of elements,
-makes its first appearance in <code>sum</code>.  It works on strings, arrays,
-slices, maps, and channels.
-<p>
-By the way, another thing that works on strings, arrays, slices, maps
-and channels is the <code>range</code> clause on <code>for</code> loops.  Instead of writing
-<p>
-<pre>
-for i := 0; i < len(a); i++ { ... }
-</pre>
-<p>
-to loop over the elements of a slice (or map or ...) , we could write
-<p>
-<pre>
-for i, v := range a { ... }
-</pre>
-<p>
-This assigns <code>i</code> to the index and <code>v</code> to the value of the successive
-elements of the target of the range.   See
-<a href='/doc/effective_go.html'>Effective Go</a>
-for more examples of its use.
-<p>
-<p>
-<h2>An Interlude about Allocation</h2>
-<p>
-Most types in Go are values. If you have an <code>int</code> or a <code>struct</code>
-or an array, assignment
-copies the contents of the object.
-To allocate a new variable, use the built-in function <code>new</code>, which
-returns a pointer to the allocated storage.
-<p>
-<pre>
-type T struct { a, b int }
-var t *T = new(T)
-</pre>
-<p>
-or the more idiomatic
-<p>
-<pre>
-t := new(T)
-</pre>
-<p>
-Some types—maps, slices, and channels (see below)—have reference semantics.
-If you're holding a slice or a map and you modify its contents, other variables
-referencing the same underlying data will see the modification.  For these three
-types you want to use the built-in function <code>make</code>:
-<p>
-<pre>
-m := make(map[string]int)
-</pre>
-<p>
-This statement initializes a new map ready to store entries.
-If you just declare the map, as in
-<p>
-<pre>
-var m map[string]int
-</pre>
-<p>
-it creates a <code>nil</code> reference that cannot hold anything. To use the map,
-you must first initialize the reference using <code>make</code> or by assignment from an
-existing map.
-<p>
-Note that <code>new(T)</code> returns type <code>*T</code> while <code>make(T)</code> returns type
-<code>T</code>.  If you (mistakenly) allocate a reference object with <code>new</code> rather than <code>make</code>,
-you receive a pointer to a nil reference, equivalent to
-declaring an uninitialized variable and taking its address.
-<p>
-<h2>An Interlude about Constants</h2>
-<p>
-Although integers come in lots of sizes in Go, integer constants do not.
-There are no constants like <code>0LL</code> or <code>0x0UL</code>.   Instead, integer
-constants are evaluated as large-precision values that
-can overflow only when they are assigned to an integer variable with
-too little precision to represent the value.
-<p>
-<pre>
-const hardEight = (1 << 100) >> 97  // legal
-</pre>
-<p>
-There are nuances that deserve redirection to the legalese of the
-language specification but here are some illustrative examples:
-<p>
-<pre>
-var a uint64 = 0  // a has type uint64, value 0
-a := uint64(0)    // equivalent; uses a "conversion"
-i := 0x1234       // i gets default type: int
-var j int = 1e6   // legal - 1000000 is representable in an int
-x := 1.5          // a float64, the default type for floating constants
-i3div2 := 3/2     // integer division - result is 1
-f3div2 := 3./2.   // floating-point division - result is 1.5
-</pre>
-<p>
-Conversions only work for simple cases such as converting <code>ints</code> of one
-sign or size to another and between integers and floating-point numbers,
-plus a couple of other instances outside the scope of a tutorial.
-There are no automatic numeric conversions of any kind in Go,
-other than that of making constants have concrete size and type when
-assigned to a variable.
-<p>
-<h2>An I/O Package</h2>
-<p>
-Next we'll look at a simple package for doing Unix file I/O with an
-open/close/read/write interface.
-Here's the start of <code>file.go</code>:
-<p>
-{{code "progs/file.go" `/package/` `/^}/`}}
-<p>
-The first few lines declare the name of the
-package—<code>file</code>—and then import two packages.  The <code>os</code>
-package hides the differences
-between various operating systems to give a consistent view of files and
-so on; here we're going to use its error handling utilities
-and reproduce the rudiments of its file I/O.
-<p>
-The other item is the low-level, external <code>syscall</code> package, which provides
-a primitive interface to the underlying operating system's calls.
-The <code>syscall</code> package is very system-dependent, and the way it's
-used here works only on Unix-like systems,
-but the general ideas explored here apply broadly.
-(A Windows version is available in
-<a href="progs/file_windows.go"><code>file_windows.go</code></a>.)
-<p>
-Next is a type definition: the <code>type</code> keyword introduces a type declaration,
-in this case a data structure called <code>File</code>.
-To make things a little more interesting, our <code>File</code> includes the name of the file
-that the file descriptor refers to.
-<p>
-Because <code>File</code> starts with a capital letter, the type is available outside the package,
-that is, by users of the package.   In Go the rule about visibility of information is
-simple: if a name (of a top-level type, function, method, constant or variable, or of
-a structure field or method) is capitalized, users of the package may see it. Otherwise, the
-name and hence the thing being named is visible only inside the package in which
-it is declared.  This is more than a convention; the rule is enforced by the compiler.
-In Go, the term for publicly visible names is ''exported''.
-<p>
-In the case of <code>File</code>, all its fields are lower case and so invisible to users, but we
-will soon give it some exported, upper-case methods.
-<p>
-First, though, here is a factory to create a <code>File</code>:
-<p>
-{{code "progs/file.go" `/newFile/` `/^}/`}}
-<p>
-This returns a pointer to a new <code>File</code> structure with the file descriptor and name
-filled in.  This code uses Go's notion of a ''composite literal'', analogous to
-the ones used to build maps and arrays, to construct a new heap-allocated
-object.  We could write
-<p>
-<pre>
-n := new(File)
-n.fd = fd
-n.name = name
-return n
-</pre>
-<p>
-but for simple structures like <code>File</code> it's easier to return the address of a 
-composite literal, as is done here in the <code>return</code> statement from <code>newFile</code>.
-<p>
-We can use the factory to construct some familiar, exported variables of type <code>*File</code>:
-<p>
-{{code "progs/file.go" `/var/` `/^\)/`}}
-<p>
-The <code>newFile</code> function was not exported because it's internal. The proper,
-exported factory to use is <code>OpenFile</code> (we'll explain that name in a moment):
-<p>
-{{code "progs/file.go" `/func.OpenFile/` `/^}/`}}
-<p>
-There are a number of new things in these few lines.  First, <code>OpenFile</code> returns
-multiple values, a <code>File</code> and an error (more about errors in a moment).
-We declare the
-multi-value return as a parenthesized list of declarations; syntactically
-they look just like a second parameter list.  The function
-<code>syscall.Open</code>
-also has a multi-value return, which we can grab with the multi-variable
-declaration on the first line; it declares <code>r</code> and <code>e</code> to hold the two values,
-both of type <code>int</code> (although you'd have to look at the <code>syscall</code> package
-to see that).  Finally, <code>OpenFile</code> returns two values: a pointer to the new <code>File</code>
-and the error.  If <code>syscall.Open</code> fails, the file descriptor <code>r</code> will
-be negative and <code>newFile</code> will return <code>nil</code>.
-<p>
-About those errors:  The Go language includes a general notion of an error:
-a pre-defined type <code>error</code> with properties (described below)
-that make it a good basis for representing and handling errors.
-It's a good idea to use its facility in your own interfaces, as we do here, for
-consistent error handling throughout Go code.   In <code>Open</code> we use a
-conversion to translate Unix's integer <code>errno</code> value into the integer type
-<code>os.Errno</code>, which is an implementation of <code>error</code>
-<p>
-Why <code>OpenFile</code> and not <code>Open</code>? To mimic Go's <code>os</code> package, which
-our exercise is emulating. The <code>os</code> package takes the opportunity
-to make the two commonest cases - open for read and create for
-write - the simplest, just <code>Open</code> and <code>Create</code>.  <code>OpenFile</code> is the
-general case, analogous to the Unix system call <code>Open</code>.  Here is
-the implementation of our <code>Open</code> and <code>Create</code>; they're trivial
-wrappers that eliminate common errors by capturing
-the tricky standard arguments to open and, especially, to create a file:
-<p>
-{{code "progs/file.go" `/^const/` `/^}/`}}
-<p>
-{{code "progs/file.go" `/func.Create/` `/^}/`}}
-<p>
-Back to our main story.
-Now that we can build <code>Files</code>, we can write methods for them. To declare
-a method of a type, we define a function to have an explicit receiver
-of that type, placed
-in parentheses before the function name. Here are some methods for <code>*File</code>,
-each of which declares a receiver variable <code>file</code>.
-<p>
-{{code "progs/file.go" `/Close/` "$"}}
-<p>
-There is no implicit <code>this</code> and the receiver variable must be used to access
-members of the structure.  Methods are not declared within
-the <code>struct</code> declaration itself.  The <code>struct</code> declaration defines only data members.
-In fact, methods can be created for almost any type you name, such as an integer or
-array, not just for <code>structs</code>.   We'll see an example with arrays later.
-<p>
-The <code>String</code> method is so called because of a printing convention we'll
-describe later.
-<p>
-The methods use the public variable <code>os.ErrInvalid</code> to return the (<code>error</code>
-version of the) Unix error code <code>EINVAL</code>.  The <code>os</code> library defines a standard
-set of such error values.
-<p>
-We can now use our new package:
-<p>
-{{code "progs/helloworld3.go" `/package/` "$"}}
-<p>
-The ''<code>./</code>'' in the import of ''<code>./file</code>'' tells the compiler
-to use our own package rather than
-something from the directory of installed packages.
-(Also, ''<code>file.go</code>'' must be compiled before we can import the
-package.)
-<p>
-Now we can compile and run the program. On Unix, this would be the result:
-<p>
-<pre>
-$ 6g file.go                       # compile file package
-$ 6g helloworld3.go                # compile main package
-$ 6l -o helloworld3 helloworld3.6  # link - no need to mention "file"
-$ ./helloworld3
-hello, world
-can't open file; err=No such file or directory
-$
-</pre>
-<p>
-<h2>Rotting cats</h2>
-<p>
-Building on the <code>file</code> package, here's a simple version of the Unix utility <code>cat(1)</code>,
-<code>progs/cat.go</code>:
-<p>
-{{code "progs/cat.go" `/package/` "$"}}
-<p>
-By now this should be easy to follow, but the <code>switch</code> statement introduces some
-new features.  Like a <code>for</code> loop, an <code>if</code> or <code>switch</code> can include an
-initialization statement.  The <code>switch</code> statement in <code>cat</code> uses one to create variables
-<code>nr</code> and <code>er</code> to hold the return values from the call to <code>f.Read</code>.  (The <code>if</code> a few lines later
-has the same idea.)  The <code>switch</code> statement is general: it evaluates the cases
-from  top to bottom looking for the first case that matches the value; the
-case expressions don't need to be constants or even integers, as long as
-they all have the same type.
-<p>
-Since the <code>switch</code> value is just <code>true</code>, we could leave it off—as is also
-the situation
-in a <code>for</code> statement, a missing value means <code>true</code>.  In fact, such a <code>switch</code>
-is a form of <code>if-else</code> chain. While we're here, it should be mentioned that in
-<code>switch</code> statements each <code>case</code> has an implicit <code>break</code>.
-<p>
-The argument to <code>file.Stdout.Write</code> is created by slicing the array <code>buf</code>.
-Slices provide the standard Go way to handle I/O buffers.
-<p>
-Now let's make a variant of <code>cat</code> that optionally does <code>rot13</code> on its input.
-It's easy to do by just processing the bytes, but instead we will exploit
-Go's notion of an <i>interface</i>.
-<p>
-The <code>cat</code> subroutine uses only two methods of <code>f</code>: <code>Read</code> and <code>String</code>,
-so let's start by defining an interface that has exactly those two methods.
-Here is code from <code>progs/cat_rot13.go</code>:
-<p>
-{{code "progs/cat_rot13.go" `/type.reader/` `/^}/`}}
-<p>
-Any type that has the two methods of <code>reader</code>—regardless of whatever
-other methods the type may also have—is said to <i>implement</i> the
-interface.  Since <code>file.File</code> implements these methods, it implements the
-<code>reader</code> interface.  We could tweak the <code>cat</code> subroutine to accept a <code>reader</code>
-instead of a <code>*file.File</code> and it would work just fine, but let's embellish a little
-first by writing a second type that implements <code>reader</code>, one that wraps an
-existing <code>reader</code> and does <code>rot13</code> on the data. To do this, we just define
-the type and implement the methods and with no other bookkeeping,
-we have a second implementation of the <code>reader</code> interface.
-<p>
-{{code "progs/cat_rot13.go" `/type.rotate13/` `/end.of.rotate13/`}}
-<p>
-(The <code>rot13</code> function called in <code>Read</code> is trivial and not worth reproducing here.)
-<p>
-To use the new feature, we define a flag:
-<p>
-{{code "progs/cat_rot13.go" `/rot13Flag/`}}
-<p>
-and use it from within a mostly unchanged <code>cat</code> function:
-<p>
-{{code "progs/cat_rot13.go" `/func.cat/` `/^}/`}}
-<p>
-(We could also do the wrapping in <code>main</code> and leave <code>cat</code> mostly alone, except
-for changing the type of the argument; consider that an exercise.)
-The <code>if</code> at the top of <code>cat</code> sets it all up: If the <code>rot13</code> flag is true, wrap the <code>reader</code>
-we received into a <code>rotate13</code> and proceed.  Note that the interface variables
-are values, not pointers: the argument is of type <code>reader</code>, not <code>*reader</code>,
-even though under the covers it holds a pointer to a <code>struct</code>.
-<p>
-Here it is in action:
-<p>
-<pre>
-$ echo abcdefghijklmnopqrstuvwxyz | ./cat
-abcdefghijklmnopqrstuvwxyz
-$ echo abcdefghijklmnopqrstuvwxyz | ./cat --rot13
-nopqrstuvwxyzabcdefghijklm
-$
-</pre>
-<p>
-Fans of dependency injection may take cheer from how easily interfaces
-allow us to substitute the implementation of a file descriptor.
-<p>
-Interfaces are a distinctive feature of Go.  An interface is implemented by a
-type if the type implements all the methods declared in the interface.
-This means
-that a type may implement an arbitrary number of different interfaces.
-There is no type hierarchy; things can be much more <i>ad hoc</i>,
-as we saw with <code>rot13</code>.  The type <code>file.File</code> implements <code>reader</code>; it could also
-implement a <code>writer</code>, or any other interface built from its methods that
-fits the current situation. Consider the <i>empty interface</i>
-<p>
-<pre>
-type Empty interface {}
-</pre>
-<p>
-<i>Every</i> type implements the empty interface, which makes it
-useful for things like containers.
-<p>
-<h2>Sorting</h2>
-<p>
-Interfaces provide a simple form of polymorphism.  They completely
-separate the definition of what an object does from how it does it, allowing
-distinct implementations to be represented at different times by the
-same interface variable.
-<p>
-As an example, consider this simple sort algorithm taken from <code>progs/sort.go</code>:
-<p>
-{{code "progs/sort.go" `/func.Sort/` `/^}/`}}
-<p>
-The code needs only three methods, which we wrap into sort's <code>Interface</code>:
-<p>
-{{code "progs/sort.go" `/interface/` `/^}/`}}
-<p>
-We can apply <code>Sort</code> to any type that implements <code>Len</code>, <code>Less</code>, and <code>Swap</code>.
-The <code>sort</code> package includes the necessary methods to allow sorting of
-arrays of integers, strings, etc.; here's the code for arrays of <code>int</code>
-<p>
-{{code "progs/sort.go" `/type.*IntSlice/` `/Swap/`}}
-<p>
-Here we see methods defined for non-<code>struct</code> types.  You can define methods
-for any type you define and name in your package.
-<p>
-And now a routine to test it out, from <code>progs/sortmain.go</code>.  This
-uses a function in the <code>sort</code> package, omitted here for brevity,
-to test that the result is sorted.
-<p>
-{{code "progs/sortmain.go" `/func.ints/` `/^}/`}}
-<p>
-If we have a new type we want to be able to sort, all we need to do is
-to implement the three methods for that type, like this:
-<p>
-{{code "progs/sortmain.go" `/type.day/` `/Swap/`}}
-<p>
-<p>
-<h2>Printing</h2>
-<p>
-The examples of formatted printing so far have been modest.  In this section
-we'll talk about how formatted I/O can be done well in Go.
-<p>
-We've seen simple uses of the package <code>fmt</code>, which
-implements <code>Printf</code>, <code>Fprintf</code>, and so on.
-Within the <code>fmt</code> package, <code>Printf</code> is declared with this signature:
-<p>
-<pre>
-Printf(format string, v ...interface{}) (n int, errno error)
-</pre>
-<p>
-The token <code>...</code> introduces a variable-length argument list that in C would
-be handled using the <code>stdarg.h</code> macros.
-In Go, variadic functions are passed a slice of the arguments of the
-specified type.  In <code>Printf</code>'s case, the declaration says <code>...interface{}</code>
-so the actual type is a slice of empty interface values, <code>[]interface{}</code>.
-<code>Printf</code> can examine the arguments by iterating over the slice
-and, for each element, using a type switch or the reflection library
-to interpret the value.
-It's off topic here but such run-time type analysis
-helps explain some of the nice properties of Go's <code>Printf</code>,
-due to the ability of <code>Printf</code> to discover the type of its arguments
-dynamically.
-<p>
-For example, in C each format must correspond to the type of its
-argument.  It's easier in many cases in Go.  Instead of <code>%llud</code> you
-can just say <code>%d</code>; <code>Printf</code> knows the size and signedness of the
-integer and can do the right thing for you.  The snippet
-<p>
-{{code "progs/print.go" 10 11}}
-<p>
-prints
-<p>
-<pre>
-18446744073709551615 -1
-</pre>
-<p>
-In fact, if you're lazy the format <code>%v</code> will print, in a simple
-appropriate style, any value, even an array or structure.  The output of
-<p>
-{{code "progs/print.go" 14 20}}
-<p>
-is
-<p>
-<pre>
-18446744073709551615 {77 Sunset Strip} [1 2 3 4]
-</pre>
-<p>
-You can drop the formatting altogether if you use <code>Print</code> or <code>Println</code>
-instead of <code>Printf</code>.  Those routines do fully automatic formatting.
-The <code>Print</code> function just prints its elements out using the equivalent
-of <code>%v</code> while <code>Println</code> inserts spaces between arguments
-and adds a newline.  The output of each of these two lines is identical
-to that of the <code>Printf</code> call above.
-<p>
-{{code "progs/print.go" 21 22}}
-<p>
-If you have your own type you'd like <code>Printf</code> or <code>Print</code> to format,
-just give it a <code>String</code> method that returns a string.  The print
-routines will examine the value to inquire whether it implements
-the method and if so, use it rather than some other formatting.
-Here's a simple example.
-<p>
-{{code "progs/print_string.go" 9 "$"}}
-<p>
-Since <code>*testType</code> has a <code>String</code> method, the
-default formatter for that type will use it and produce the output
-<p>
-<pre>
-77 Sunset Strip
-</pre>
-<p>
-Observe that the <code>String</code> method calls <code>Sprint</code> (the obvious Go
-variant that returns a string) to do its formatting; special formatters
-can use the <code>fmt</code> library recursively.
-<p>
-Another feature of <code>Printf</code> is that the format <code>%T</code> will print a string
-representation of the type of a value, which can be handy when debugging
-polymorphic code.
-<p>
-It's possible to write full custom print formats with flags and precisions
-and such, but that's getting a little off the main thread so we'll leave it
-as an exploration exercise.
-<p>
-You might ask, though, how <code>Printf</code> can tell whether a type implements
-the <code>String</code> method.  Actually what it does is ask if the value can
-be converted to an interface variable that implements the method.
-Schematically, given a value <code>v</code>, it does this:
-<p>
-<p>
-<pre>
-type Stringer interface {
-    String() string
-}
-</pre>
-<p>
-<pre>
-s, ok := v.(Stringer)  // Test whether v implements "String()"
-if ok {
-    result = s.String()
-} else {
-    result = defaultOutput(v)
-}
-</pre>
-<p>
-The code uses a ``type assertion'' (<code>v.(Stringer)</code>) to test if the value stored in
-<code>v</code> satisfies the <code>Stringer</code> interface; if it does, <code>s</code>
-will become an interface variable implementing the method and <code>ok</code> will
-be <code>true</code>.  We then use the interface variable to call the method.
-(The ''comma, ok'' pattern is a Go idiom used to test the success of
-operations such as type conversion, map update, communications, and so on,
-although this is the only appearance in this tutorial.)
-If the value does not satisfy the interface, <code>ok</code> will be false.
-<p>
-In this snippet the name <code>Stringer</code> follows the convention that we add ''[e]r''
-to interfaces describing simple method sets like this.
-<p>
-A related interface is that defined by the <code>error</code> builtin type, which is just
-<p>
-<pre>
-type error interface {
-    Error() string
-}
-</pre>
-<p>
-Other than the method name (<code>Error</code> vs. <code>String</code>), this looks like
-a <code>Stringer</code>; the different name guarantees that types that implement <code>Stringer</code>
-don't accidentally satisfy the <code>error</code> interface.
-Naturally, <code>Printf</code> and its relatives recognize the <code>error</code> interface,
-just as they do <code>Stringer</code>,
-so it's trivial to print an error as a string.
-<p>
-One last wrinkle.  To complete the suite, besides <code>Printf</code> etc. and <code>Sprintf</code>
-etc., there are also <code>Fprintf</code> etc.  Unlike in C, <code>Fprintf</code>'s first argument is
-not a file.  Instead, it is a variable of type <code>io.Writer</code>, which is an
-interface type defined in the <code>io</code> library:
-<p>
-<pre>
-type Writer interface {
-    Write(p []byte) (n int, err error)
-}
-</pre>
-<p>
-(This interface is another conventional name, this time for <code>Write</code>; there are also
-<code>io.Reader</code>, <code>io.ReadWriter</code>, and so on.)
-Thus you can call <code>Fprintf</code> on any type that implements a standard <code>Write</code>
-method, not just files but also network channels, buffers, whatever
-you want.
-<p>
-<h2>Prime numbers</h2>
-<p>
-Now we come to processes and communication—concurrent programming.
-It's a big subject so to be brief we assume some familiarity with the topic.
-<p>
-A classic program in the style is a prime sieve.
-(The sieve of Eratosthenes is computationally more efficient than
-the algorithm presented here, but we are more interested in concurrency than
-algorithmics at the moment.)
-It works by taking a stream of all the natural numbers and introducing
-a sequence of filters, one for each prime, to winnow the multiples of
-that prime.  At each step we have a sequence of filters of the primes
-so far, and the next number to pop out is the next prime, which triggers
-the creation of the next filter in the chain.
-<p>
-Here's a flow diagram; each box represents a filter element whose
-creation is triggered by the first number that flowed from the
-elements before it.
-<p>
-<br>
-<p>
-     <img src='sieve.gif'>
-<p>
-<br>
-<p>
-To create a stream of integers, we use a Go <i>channel</i>, which,
-borrowing from CSP's descendants, represents a communications
-channel that can connect two concurrent computations.
-In Go, channel variables are references to a run-time object that
-coordinates the communication; as with maps and slices, use
-<code>make</code> to create a new channel.
-<p>
-Here is the first function in <code>progs/sieve.go</code>:
-<p>
-{{code "progs/sieve.go" `/Send/` `/^}/`}}
-<p>
-The <code>generate</code> function sends the sequence 2, 3, 4, 5, ... to its
-argument channel, <code>ch</code>, using the binary communications operator <code><-</code>.
-Channel operations block, so if there's no recipient for the value on <code>ch</code>,
-the send operation will wait until one becomes available.
-<p>
-The <code>filter</code> function has three arguments: an input channel, an output
-channel, and a prime number.  It copies values from the input to the
-output, discarding anything divisible by the prime.  The unary communications
-operator <code><-</code> (receive) retrieves the next value on the channel.
-<p>
-{{code "progs/sieve.go" `/Copy.the/` `/^}/`}}
-<p>
-The generator and filters execute concurrently.  Go has
-its own model of process/threads/light-weight processes/coroutines,
-so to avoid notational confusion we call concurrently executing
-computations in Go <i>goroutines</i>.  To start a goroutine,
-invoke the function, prefixing the call with the keyword <code>go</code>;
-this starts the function running in parallel with the current
-computation but in the same address space:
-<p>
-<pre>
-go sum(hugeArray) // calculate sum in the background
-</pre>
-<p>
-If you want to know when the calculation is done, pass a channel
-on which it can report back:
-<p>
-<pre>
-ch := make(chan int)
-go sum(hugeArray, ch)
-// ... do something else for a while
-result := <-ch  // wait for, and retrieve, result
-</pre>
-<p>
-Back to our prime sieve.  Here's how the sieve pipeline is stitched
-together:
-<p>
-{{code "progs/sieve.go" `/func.main/` `/^}/`}}
-<p>
-The first line of <code>main</code> creates the initial channel to pass to <code>generate</code>, which it
-then starts up.  As each prime pops out of the channel, a new <code>filter</code>
-is added to the pipeline and <i>its</i> output becomes the new value
-of <code>ch</code>.
-<p>
-The sieve program can be tweaked to use a pattern common
-in this style of programming.  Here is a variant version
-of <code>generate</code>, from <code>progs/sieve1.go</code>:
-<p>
-{{code "progs/sieve1.go" `/func.generate/` `/^}/`}}
-<p>
-This version does all the setup internally. It creates the output
-channel, launches a goroutine running a function literal, and
-returns the channel to the caller.  It is a factory for concurrent
-execution, starting the goroutine and returning its connection.
-<p>
-The function literal notation used in the <code>go</code> statement allows us to construct an
-anonymous function and invoke it on the spot. Notice that the local
-variable <code>ch</code> is available to the function literal and lives on even
-after <code>generate</code> returns.
-<p>
-The same change can be made to <code>filter</code>:
-<p>
-{{code "progs/sieve1.go" `/func.filter/` `/^}/`}}
-<p>
-The <code>sieve</code> function's main loop becomes simpler and clearer as a
-result, and while we're at it let's turn it into a factory too:
-<p>
-{{code "progs/sieve1.go" `/func.sieve/` `/^}/`}}
-<p>
-Now <code>main</code>'s interface to the prime sieve is a channel of primes:
-<p>
-{{code "progs/sieve1.go" `/func.main/` `/^}/`}}
-<p>
-<h2>Multiplexing</h2>
-<p>
-With channels, it's possible to serve multiple independent client goroutines without
-writing an explicit multiplexer.  The trick is to send the server a channel in the message,
-which it will then use to reply to the original sender.
-A realistic client-server program is a lot of code, so here is a very simple substitute
-to illustrate the idea.  It starts by defining a <code>request</code> type, which embeds a channel
-that will be used for the reply.
-<p>
-{{code "progs/server.go" `/type.request/` `/^}/`}}
-<p>
-The server will be trivial: it will do simple binary operations on integers.  Here's the
-code that invokes the operation and responds to the request:
-<p>
-{{code "progs/server.go" `/type.binOp/` `/^}/`}}
-<p>
-The type declaration makes <code>binOp</code> represent a function taking two integers and
-returning a third.
-<p>
-The <code>server</code> routine loops forever, receiving requests and, to avoid blocking due to
-a long-running operation, starting a goroutine to do the actual work.
-<p>
-{{code "progs/server.go" `/func.server/` `/^}/`}}
-<p>
-There's a new feature in the signature of <code>server</code>: the type of the
-<code>service</code> channel specifies the direction of communication.
-A channel of plain <code>chan</code> type can be used both for sending and receiving.
-However, the type used when declaring a channel can be decorated with an arrow to
-indicate that the channel can be used only to send (<code>chan<-</code>) or to
-receive (<code><-chan</code>) data.
-The arrow points towards or away from the <code>chan</code> to indicate whether data flows into or out of
-the channel.
-In the <code>server</code> function, <code>service <-chan *request</code> is a "receive only" channel
-that the function can use only to <em>read</em> new requests.
-<p>
-We instantiate a server in a familiar way, starting it and returning a channel
-connected to it:
-<p>
-{{code "progs/server.go" `/func.startServer/` `/^}/`}}
-<p>
-The returned channel is send only, even though the channel was created bidirectionally.
-The read end is passed to <code>server</code>, while the send end is returned
-to the caller of <code>startServer</code>, so the two halves of the channel
-are distinguished, just as we did in <code>startServer</code>.
-<p>
-Bidirectional channels can be assigned to unidirectional channels but not the
-other way around, so if you annotate your channel directions when you declare
-them, such as in function signatures, the type system can help you set up and
-use channels correctly.
-Note that it's pointless to <code>make</code> unidirectional channels, since you can't
-use them to communicate. Their purpose is served by variables assigned from bidirectional channels
-to distinguish the input and output halves.
-<p>
-Here's a simple test.  It starts a server with an addition operator and sends out
-<code>N</code> requests without waiting for the replies.  Only after all the requests are sent
-does it check the results.
-<p>
-{{code "progs/server.go" `/func.main/` `/^}/`}}
-<p>
-One annoyance with this program is that it doesn't shut down the server cleanly; when <code>main</code> returns
-there are a number of lingering goroutines blocked on communication.  To solve this,
-we can provide a second, <code>quit</code> channel to the server:
-<p>
-{{code "progs/server1.go" `/func.startServer/` `/^}/`}}
-<p>
-It passes the quit channel to the <code>server</code> function, which uses it like this:
-<p>
-{{code "progs/server1.go" `/func.server/` `/^}/`}}
-<p>
-Inside <code>server</code>, the <code>select</code> statement chooses which of the multiple communications
-listed by its cases can proceed.  If all are blocked, it waits until one can proceed; if
-multiple can proceed, it chooses one at random.  In this instance, the <code>select</code> allows
-the server to honor requests until it receives a quit message, at which point it
-returns, terminating its execution.
-<p>
-<p>
-All that's left is to strobe the <code>quit</code> channel
-at the end of main:
-<p>
-{{code "progs/server1.go" `/adder,.quit/`}}
-...
-{{code "progs/server1.go" `/quit....true/`}}
-<p>
-There's a lot more to Go programming and concurrent programming in general but this
-quick tour should give you some of the basics.
diff --git a/doc/help.html b/doc/help.html
new file mode 100644
index 0000000..2efda4e
--- /dev/null
+++ b/doc/help.html
@@ -0,0 +1,36 @@
+<!--{
+	"Title": "Getting Help",
+	"Path": "/help/"
+}-->
+
+<p>
+Need help with Go? Try these resources.
+</p>
+
+<div id="manual-nav"></div>
+
+<h3 id="go_faq"><a href="/doc/go_faq.html">Frequently Asked Questions (FAQ)</a></h3>
+<p>Answers to common questions about Go.</p>
+
+<h3 id="wiki"><a href="http://code.google.com/p/go-wiki/wiki">Go Language Community Wiki</a></h3>
+<p>A wiki maintained by the Go community.</p>
+
+<h3 id="mailinglist"><a href="http://groups.google.com/group/golang-nuts">Go Nuts Mailing List</a></h3>
+<p>
+Search the <a href="http://groups.google.com/group/golang-nuts">golang-nuts</a>
+archives and consult the <a href="/doc/go_faq.html">FAQ</a> and
+<a href="http://code.google.com/p/go-wiki/wiki">wiki</a> before posting.
+</p>
+
+<h3 id="irc"><a href="irc:irc.freenode.net/go-nuts">Go IRC Channel</a></h3>
+<p>Get live support at <b>#go-nuts</b> on <b>irc.freenode.net</b>, the official
+Go IRC channel.</p>
+
+<h3 id="twitter"><a href="http://twitter.com/go_nuts">@go_nuts at Twitter</a></h3>
+<p>The Go project's official Twitter account.</p>
+<p>Tweeting your about problem with the <code>#golang</code> hashtag usually
+generates some helpful responses.</p>
+
+<h3 id="plus"><a href="https://plus.google.com/101406623878176903605/posts">The Go Programming Language at Google+</a></h3>
+<p>The Go project's Google+ page.</p>
+
diff --git a/doc/install-source.html b/doc/install-source.html
index e3d0627..5a17844 100644
--- a/doc/install-source.html
+++ b/doc/install-source.html
@@ -1,25 +1,35 @@
 <!--{
 	"Title": "Installing Go from source",
-	"Path": "/install/source/"
+	"Path": "/doc/install/source"
 }-->
 
 <h2 id="introduction">Introduction</h2>
 
-<p>Go is an open source project, distributed under a
+<p>
+Go is an open source project, distributed under a
 <a href="/LICENSE">BSD-style license</a>.
 This document explains how to check out the sources,
 build them on your own machine, and run them.
 </p>
 
+<p>
+Most users don't need to do this, and will instead install
+from precompiled binary packages as described in
+<a href="/doc/install">Getting Started</a>,
+a much simpler process.
+If you want to help develop what goes into those precompiled
+packages, though, read on.
+</p>
+
 <div class="detail">
 
 <p>
 There are two official Go compiler tool chains.
 This document focuses on the <code>gc</code> Go
 compiler and tools (<code>6g</code>, <code>8g</code> etc.).
-For information on how to use <code>gccgo</code>, a more traditional
+For information on how to work on <code>gccgo</code>, a more traditional
 compiler using the GCC back end, see
-<a href="/install/gccgo/">Setting up and using gccgo</a>.
+<a href="/doc/install/gccgo">Setting up and using gccgo</a>.
 </p>
 
 <p>
@@ -33,7 +43,7 @@ architectures.
 	<code>amd64</code> (a.k.a. <code>x86-64</code>); <code>6g,6l,6c,6a</code>
 </dt>
 <dd>
-	The most mature implementation. The compiler has an effective
+	A mature implementation. The compiler has an effective
 	optimizer (registerizer) and generates good code (although
 	<code>gccgo</code> can do noticeably better sometimes).
 </dd>
@@ -47,7 +57,8 @@ architectures.
 	<code>arm</code> (a.k.a. <code>ARM</code>); <code>5g,5l,5c,5a</code>
 </dt>
 <dd>
-	Supports only Linux binaries. Less tested than the other ports.
+	Supports only Linux binaries. Less widely used than the other ports and therefore
+	not as thoroughly tested.
 </dd>
 </dl>
 
@@ -113,7 +124,7 @@ You might try this first:
 <p>
 If that fails, try installing manually from the
 <a href="http://mercurial.selenic.com/wiki/Download">Mercurial Download</a>
-page.</p>
+page.
 </p>
 
 <p>
@@ -136,7 +147,6 @@ if necessary.
 
 <h2 id="fetch">Fetch the repository</h2>
 
-<p>
 <p>Go will install to a directory named <code>go</code>.
 Change to the directory that will be its parent
 and make sure the <code>go</code> directory does not exist.
@@ -222,60 +232,32 @@ If you see the "hello, world" message then Go is installed correctly.
 </p>
 
 
-<h2 id="next">What's next</h2>
-
-<p>
-Start by taking <a href="http://code.google.com/p/go-tour/">A Tour of Go</a>
-or reading the <a href="/doc/go_tutorial.html">Go Tutorial</a>.
-</p>
-
-<p>
-For more detail about the process of building and testing Go programs
-read <a href="/doc/code.html">How to Write Go Code</a>.
-</p>
-
-<p>
-Build a web application by following the <a href="/doc/codelab/wiki/">Wiki
-Codelab</a>.
-</p>
-
-<p>
-Read <a href="/doc/effective_go.html">Effective Go</a> to learn about writing
-idiomatic Go code.
-</p>
-
-<p>
-For the full story, consult Go's extensive 
-<a href="/doc/">documentation</a>.
-</p>
-
-
 <h2 id="community">Community resources</h2>
 
 <p>
-For real-time help, there may be users or developers on
-<code>#go-nuts</code> on the <a href="http://freenode.net/">Freenode</a> IRC server.
-</p>
-
-<p>
-The official mailing list for discussion of the Go language is
-<a href="http://groups.google.com/group/golang-nuts">Go Nuts</a>.
+The usual community resources such as
+<code>#go-nuts</code> on the <a href="http://freenode.net/">Freenode</a> IRC server
+and the
+<a href="http://groups.google.com/group/golang-nuts">Go Nuts</a>
+mailing list have active developers that can help you with problems
+with your installation or your development work.
+For those who wish to keep up to date,
+there is another mailing list, <a href="http://groups.google.com/group/golang-checkins">golang-checkins</a>,
+that receives a message summarizing each checkin to the Go repository.
 </p>
 
 <p>
 Bugs can be reported using the <a href="http://code.google.com/p/go/issues/list">Go issue tracker</a>.
 </p>
 
-<p>
-For those who wish to keep up with development,
-there is another mailing list, <a href="http://groups.google.com/group/golang-checkins">golang-checkins</a>,
-that receives a message summarizing each checkin to the Go repository.
-</p>
-
 
 <h2 id="releases">Keeping up with releases</h2>
 
 <p>
+XXX TODO XXX
+</p>
+
+<p>
 The Go project maintains two stable tags in its Mercurial repository:
 <code>release</code> and <code>weekly</code>.
 The <code>weekly</code> tag is updated about once a week, and should be used by
@@ -312,7 +294,7 @@ To use the <code>weekly</code> tag run <code>hg update weekly</code> instead.
 
 <p>
 The Go compilation environment can be customized by environment variables.
-<i>None are required by the build</i>, but you may wish to set them
+<i>None is required by the build</i>, but you may wish to set some
 to override the defaults.
 </p>
 
@@ -322,11 +304,14 @@ to override the defaults.
 </dt>
 <dd>
 	<p>
+	XXX FONT IS WRONG IN THESE ENTRIES XXX
+	XXX I NEED SOME SPAN THING XXX
 	The root of the Go tree, often <code>$HOME/go</code>.
-	This defaults to the parent of the directory where <code>all.bash</code> is run.
-	If you choose not to set <code>$GOROOT</code>, you must
-	run <code>gomake</code> instead of <code>make</code> or <code>gmake</code>
-	when developing Go programs using the conventional makefiles.
+	Its value is built into the tree when it is compiled, and
+	defaults to the parent of the directory where <code>all.bash</code> was run.
+	There is no need to set this unless you want to switch between multiple
+	local copies of the repository.
+	</p>
 </dd>
 
 <dt>
@@ -335,11 +320,12 @@ to override the defaults.
 <dd>
 	<p>
 	The value assumed by installed binaries and scripts when
-	<code>$GOROOT</code> is not set.
-	It defaults to the value used for <code>$GOROOT</code>.
+	<code>$GOROOT</code> is not set explicitly.
+	It defaults to the value of <code>$GOROOT</code>.
 	If you want to build the Go tree in one location
 	but move it elsewhere after the build, set 
 	<code>$GOROOT_FINAL</code> to the eventual location.
+	</p>
 </dd>
 
 <dt>
@@ -407,7 +393,6 @@ to override the defaults.
 	<td></td><td><code>windows</code></td> <td><code>amd64</code></td>
 	</tr>
 	</table>
-	<p>
 </dd>
 
 <dt>
@@ -432,7 +417,8 @@ to override the defaults.
 </dt>
 <dd>
 	<p>
-	The location where binaries will be installed.
+	The location where binaries from the main repository will be installed.
+	XXX THIS MAY CHANGE TO BE AN OVERRIDE EVEN FOR GOPATH ENTRIES XXX
 	The default is <code>$GOROOT/bin</code>.
 	After installing, you will want to arrange to add this
 	directory to your <code>$PATH</code>, so you can use the tools.
@@ -473,3 +459,8 @@ export GOROOT=$HOME/go
 export GOARCH=amd64
 export GOOS=linux
 </pre>
+
+<p>
+although, to reiterate, none of these variables needs to be set to build,
+install, and develop the Go tree.
+</p>
diff --git a/doc/install.html b/doc/install.html
index 95bfaa7..4f2bb1c 100644
--- a/doc/install.html
+++ b/doc/install.html
@@ -1,6 +1,6 @@
 <!--{
 	"Title": "Getting Started",
-	"Path":  "/install/"
+	"Path":  "/doc/install"
 }-->
 
 <h2 id="introduction">Introduction</h2>
@@ -19,9 +19,9 @@ compiler.
 
 <p>
 For information about installing the <code>gc</code> compiler from source, see
-<a href="/install/source/">Installing Go from source</a>.
+<a href="/doc/install/source">Installing Go from source</a>.
 For information about installing <code>gccgo</code>, see
-<a href="/install/gccgo/">Setting up and using gccgo</a>.
+<a href="/doc/install/gccgo">Setting up and using gccgo</a>.
 </p>
 
 <h2 id="download">Obtaining the Go tools</h2>
@@ -43,8 +43,8 @@ x86 processor architectures.
 <p>
 If a binary distribution is not available for your
 OS/arch combination you may want to try
-<a href="/install/source/">installing from source</a> or
-<a href="/install/gccgo/">installing gccgo instead of gc</a>.
+<a href="/doc/install/source">installing from source</a> or
+<a href="/doc/install/gccgo">installing gccgo instead of gc</a>.
 </p>
 
 <h2 id="install">Installing the Go tools</h2>
@@ -69,15 +69,25 @@ export PATH=$PATH:$GOROOT/bin
 <h3 id="freebsd_linux">FreeBSD and Linux</h3>
 
 <p>
+On FreeBSD and Linux, if you are upgrading from an older version of Go you must
+first remove the existing version from <code>/usr/local/go</code>:
+</p>
+
+<pre>
+rm -r /usr/local/go
+</pre>
+
+<p>
 Extract the archive into <code>/usr/local</code>, creating a Go tree in
-<code>/usr/local/go</code> (typically this must be run as root or through
-<code>sudo</code>):
+<code>/usr/local/go</code>:
 </p>
 
 <pre>
-tar -C /usr/local go.release.go1.tar.gz
+tar -C /usr/local -xzf go.release.go1.tar.gz
 </pre>
 
+<p>(Typically these commands must be run as root or through <code>sudo</code>.)</p>
+
 <p>
 Add <code>/usr/local/go/bin</code> to the <code>PATH</code> environment
 variable. You can do this by adding this line to your <code>/etc/profile</code>
@@ -153,8 +163,8 @@ read <a href="/doc/code.html">How to Write Go Code</a>.
 </p>
 
 <p>
-Build a web application by following the <a href="/doc/codelab/wiki/">Wiki
-Codelab</a>.
+Build a web application by following the <a href="/doc/articles/wiki/">Wiki
+Tutorial</a>.
 </p>
 
 <p>
diff --git a/doc/makehtml b/doc/makehtml
index 8a02913..f6f601e 100755
--- a/doc/makehtml
+++ b/doc/makehtml
@@ -5,7 +5,7 @@
 
 set -e
 
-TMPL=${1:-go_tutorial.tmpl}                        # input file
+TMPL=${1:-effective_go.tmpl}                        # input file
 HTML=$(dirname $TMPL)/$(basename $TMPL .tmpl).html # output file
 
 if ! test -w $HTML
diff --git a/doc/progs/cat.go b/doc/progs/cat.go
deleted file mode 100644
index 79ad015..0000000
--- a/doc/progs/cat.go
+++ /dev/null
@@ -1,47 +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 main
-
-import (
-	"./file"
-	"flag"
-	"fmt"
-	"os"
-)
-
-func cat(f *file.File) {
-	const NBUF = 512
-	var buf [NBUF]byte
-	for {
-		switch nr, er := f.Read(buf[:]); true {
-		case nr < 0:
-			fmt.Fprintf(os.Stderr, "cat: error reading from %s: %s\n", f, er)
-			os.Exit(1)
-		case nr == 0: // EOF
-			return
-		case nr > 0:
-			if nw, ew := file.Stdout.Write(buf[0:nr]); nw != nr {
-				fmt.Fprintf(os.Stderr, "cat: error writing from %s: %s\n", f, ew)
-				os.Exit(1)
-			}
-		}
-	}
-}
-
-func main() {
-	flag.Parse() // Scans the arg list and sets up flags
-	if flag.NArg() == 0 {
-		cat(file.Stdin)
-	}
-	for i := 0; i < flag.NArg(); i++ {
-		f, err := file.Open(flag.Arg(i))
-		if f == nil {
-			fmt.Fprintf(os.Stderr, "cat: can't open %s: error %s\n", flag.Arg(i), err)
-			os.Exit(1)
-		}
-		cat(f)
-		f.Close()
-	}
-}
diff --git a/doc/progs/cat_rot13.go b/doc/progs/cat_rot13.go
deleted file mode 100644
index c8584ed..0000000
--- a/doc/progs/cat_rot13.go
+++ /dev/null
@@ -1,91 +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 main
-
-import (
-	"./file"
-	"flag"
-	"fmt"
-	"os"
-)
-
-var rot13Flag = flag.Bool("rot13", false, "rot13 the input")
-
-func rot13(b byte) byte {
-	if 'a' <= b && b <= 'z' {
-		b = 'a' + ((b-'a')+13)%26
-	}
-	if 'A' <= b && b <= 'Z' {
-		b = 'A' + ((b-'A')+13)%26
-	}
-	return b
-}
-
-type reader interface {
-	Read(b []byte) (ret int, err error)
-	String() string
-}
-
-type rotate13 struct {
-	source reader
-}
-
-func newRotate13(source reader) *rotate13 {
-	return &rotate13{source}
-}
-
-func (r13 *rotate13) Read(b []byte) (ret int, err error) {
-	r, e := r13.source.Read(b)
-	for i := 0; i < r; i++ {
-		b[i] = rot13(b[i])
-	}
-	return r, e
-}
-
-func (r13 *rotate13) String() string {
-	return r13.source.String()
-}
-
-// end of rotate13 implementation OMIT
-
-func cat(r reader) {
-	const NBUF = 512
-	var buf [NBUF]byte
-
-	if *rot13Flag {
-		r = newRotate13(r)
-	}
-	for {
-		switch nr, er := r.Read(buf[:]); {
-		case nr < 0:
-			fmt.Fprintf(os.Stderr, "cat: error reading from %s: %s\n", r, er)
-			os.Exit(1)
-		case nr == 0: // EOF
-			return
-		case nr > 0:
-			nw, ew := file.Stdout.Write(buf[0:nr])
-			if nw != nr {
-				fmt.Fprintf(os.Stderr, "cat: error writing from %s: %s\n", r, ew)
-				os.Exit(1)
-			}
-		}
-	}
-}
-
-func main() {
-	flag.Parse() // Scans the arg list and sets up flags
-	if flag.NArg() == 0 {
-		cat(file.Stdin)
-	}
-	for i := 0; i < flag.NArg(); i++ {
-		f, err := file.Open(flag.Arg(i))
-		if f == nil {
-			fmt.Fprintf(os.Stderr, "cat: can't open %s: error %s\n", flag.Arg(i), err)
-			os.Exit(1)
-		}
-		cat(f)
-		f.Close()
-	}
-}
diff --git a/doc/progs/echo.go b/doc/progs/echo.go
deleted file mode 100644
index 432e808..0000000
--- a/doc/progs/echo.go
+++ /dev/null
@@ -1,32 +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 main
-
-import (
-	"flag" // command line option parser
-	"os"
-)
-
-var omitNewline = flag.Bool("n", false, "don't print final newline")
-
-const (
-	Space   = " "
-	Newline = "\n"
-)
-
-func main() {
-	flag.Parse() // Scans the arg list and sets up flags
-	var s string = ""
-	for i := 0; i < flag.NArg(); i++ {
-		if i > 0 {
-			s += Space
-		}
-		s += flag.Arg(i)
-	}
-	if !*omitNewline {
-		s += Newline
-	}
-	os.Stdout.WriteString(s)
-}
diff --git a/doc/progs/error.go b/doc/progs/error.go
index ffa7ec1..f85a527 100644
--- a/doc/progs/error.go
+++ b/doc/progs/error.go
@@ -102,7 +102,10 @@ func decodeError(dec *json.Decoder, val struct{}) error { // OMIT
 	return nil
 }
 
-func findLine(os.FileInfo, int64) (int, int)
+func findLine(os.FileInfo, int64) (int, int) {
+	// place holder; no need to run
+	return 0, 0
+}
 
 func netError(err error) { // OMIT
 	for { // OMIT
diff --git a/doc/progs/file.go b/doc/progs/file.go
deleted file mode 100644
index 75f0f20..0000000
--- a/doc/progs/file.go
+++ /dev/null
@@ -1,77 +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 file
-
-import (
-	"os"
-	"syscall"
-)
-
-type File struct {
-	fd   int    // file descriptor number
-	name string // file name at Open time
-}
-
-func newFile(fd int, name string) *File {
-	if fd < 0 {
-		return nil
-	}
-	return &File{fd, name}
-}
-
-var (
-	Stdin  = newFile(syscall.Stdin, "/dev/stdin")
-	Stdout = newFile(syscall.Stdout, "/dev/stdout")
-	Stderr = newFile(syscall.Stderr, "/dev/stderr")
-)
-
-func OpenFile(name string, mode int, perm uint32) (file *File, err error) {
-	r, err := syscall.Open(name, mode, perm)
-	return newFile(r, name), err
-}
-
-const (
-	O_RDONLY = syscall.O_RDONLY
-	O_RDWR   = syscall.O_RDWR
-	O_CREATE = syscall.O_CREAT
-	O_TRUNC  = syscall.O_TRUNC
-)
-
-func Open(name string) (file *File, err error) {
-	return OpenFile(name, O_RDONLY, 0)
-}
-
-func Create(name string) (file *File, err error) {
-	return OpenFile(name, O_RDWR|O_CREATE|O_TRUNC, 0666)
-}
-
-func (file *File) Close() error {
-	if file == nil {
-		return os.ErrInvalid
-	}
-	err := syscall.Close(file.fd)
-	file.fd = -1 // so it can't be closed again
-	return err
-}
-
-func (file *File) Read(b []byte) (ret int, err error) {
-	if file == nil {
-		return -1, os.ErrInvalid
-	}
-	r, err := syscall.Read(file.fd, b)
-	return int(r), err
-}
-
-func (file *File) Write(b []byte) (ret int, err error) {
-	if file == nil {
-		return -1, os.ErrInvalid
-	}
-	r, err := syscall.Write(file.fd, b)
-	return int(r), err
-}
-
-func (file *File) String() string {
-	return file.name
-}
diff --git a/doc/progs/file_windows.go b/doc/progs/file_windows.go
deleted file mode 100644
index 8b79ee9..0000000
--- a/doc/progs/file_windows.go
+++ /dev/null
@@ -1,77 +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 file
-
-import (
-	"os"
-	"syscall"
-)
-
-type File struct {
-	fd   syscall.Handle // file descriptor number
-	name string         // file name at Open time
-}
-
-func newFile(fd syscall.Handle, name string) *File {
-	if fd == ^syscall.Handle(0) {
-		return nil
-	}
-	return &File{fd, name}
-}
-
-var (
-	Stdin  = newFile(syscall.Stdin, "/dev/stdin")
-	Stdout = newFile(syscall.Stdout, "/dev/stdout")
-	Stderr = newFile(syscall.Stderr, "/dev/stderr")
-)
-
-func OpenFile(name string, mode int, perm uint32) (file *File, err error) {
-	r, err := syscall.Open(name, mode, perm)
-	return newFile(r, name), err
-}
-
-const (
-	O_RDONLY = syscall.O_RDONLY
-	O_RDWR   = syscall.O_RDWR
-	O_CREATE = syscall.O_CREAT
-	O_TRUNC  = syscall.O_TRUNC
-)
-
-func Open(name string) (file *File, err error) {
-	return OpenFile(name, O_RDONLY, 0)
-}
-
-func Create(name string) (file *File, err error) {
-	return OpenFile(name, O_RDWR|O_CREATE|O_TRUNC, 0666)
-}
-
-func (file *File) Close() error {
-	if file == nil {
-		return os.ErrInvalid
-	}
-	err := syscall.Close(file.fd)
-	file.fd = syscall.InvalidHandle // so it can't be closed again
-	return err
-}
-
-func (file *File) Read(b []byte) (ret int, err error) {
-	if file == nil {
-		return -1, os.ErrInvalid
-	}
-	r, err := syscall.Read(file.fd, b)
-	return int(r), err
-}
-
-func (file *File) Write(b []byte) (ret int, err error) {
-	if file == nil {
-		return -1, os.ErrInvalid
-	}
-	r, err := syscall.Write(file.fd, b)
-	return int(r), err
-}
-
-func (file *File) String() string {
-	return file.name
-}
diff --git a/doc/progs/go1.go b/doc/progs/go1.go
index 1507d5b..50fd934 100644
--- a/doc/progs/go1.go
+++ b/doc/progs/go1.go
@@ -35,6 +35,11 @@ func main() {
 
 var timeout = flag.Duration("timeout", 30*time.Second, "how long to wait for completion")
 
+func init() {
+	// canonicalize the logging
+	log.SetFlags(0)
+}
+
 func mapDelete() {
 	m := map[string]int{"7": 7, "23": 23}
 	k := "7"
@@ -177,7 +182,7 @@ func sleepUntil(wakeup time.Time) {
 		return
 	}
 	delta := wakeup.Sub(now) // A Duration.
-	log.Printf("Sleeping for %.3fs", delta.Seconds())
+	fmt.Printf("Sleeping for %.3fs\n", delta.Seconds())
 	time.Sleep(delta)
 }
 
diff --git a/doc/progs/interface.go b/doc/progs/interface.go
new file mode 100644
index 0000000..9114540
--- /dev/null
+++ b/doc/progs/interface.go
@@ -0,0 +1,56 @@
+package main
+
+import (
+	"bufio"
+	"bytes"
+	"io"
+	"os"
+)
+
+type MyInt int
+
+var i int
+var j MyInt
+
+// STOP OMIT
+
+// Reader is the interface that wraps the basic Read method.
+type Reader interface {
+	Read(p []byte) (n int, err error)
+}
+
+// Writer is the interface that wraps the basic Write method.
+type Writer interface {
+	Write(p []byte) (n int, err error)
+}
+
+// STOP OMIT
+
+func readers() { // OMIT
+	var r io.Reader
+	r = os.Stdin
+	r = bufio.NewReader(r)
+	r = new(bytes.Buffer)
+	// and so on
+	// STOP OMIT
+}
+
+func typeAssertions() (interface{}, error) { // OMIT
+	var r io.Reader
+	tty, err := os.OpenFile("/dev/tty", os.O_RDWR, 0)
+	if err != nil {
+		return nil, err
+	}
+	r = tty
+	// STOP OMIT
+	var w io.Writer
+	w = r.(io.Writer)
+	// STOP OMIT
+	var empty interface{}
+	empty = w
+	// STOP OMIT
+	return empty, err
+}
+
+func main() {
+}
diff --git a/doc/progs/interface2.go b/doc/progs/interface2.go
new file mode 100644
index 0000000..e2716cf
--- /dev/null
+++ b/doc/progs/interface2.go
@@ -0,0 +1,112 @@
+package main
+
+import (
+	"fmt"
+	"reflect"
+)
+
+func main() {
+	var x float64 = 3.4
+	fmt.Println("type:", reflect.TypeOf(x))
+	// STOP OMIT
+	// TODO(proppy): test output OMIT
+}
+
+// STOP main OMIT
+
+func f1() {
+	// START f1 OMIT
+	var x float64 = 3.4
+	v := reflect.ValueOf(x)
+	fmt.Println("type:", v.Type())
+	fmt.Println("kind is float64:", v.Kind() == reflect.Float64)
+	fmt.Println("value:", v.Float())
+	// STOP OMIT
+}
+
+func f2() {
+	// START f2 OMIT
+	var x uint8 = 'x'
+	v := reflect.ValueOf(x)
+	fmt.Println("type:", v.Type())                            // uint8.
+	fmt.Println("kind is uint8: ", v.Kind() == reflect.Uint8) // true.
+	x = uint8(v.Uint())                                       // v.Uint returns a uint64.
+	// STOP OMIT
+}
+
+func f3() {
+	// START f3 OMIT
+	type MyInt int
+	var x MyInt = 7
+	v := reflect.ValueOf(x)
+	// START f3b OMIT
+	y := v.Interface().(float64) // y will have type float64.
+	fmt.Println(y)
+	// START f3c OMIT
+	fmt.Println(v.Interface())
+	// START f3d OMIT
+	fmt.Printf("value is %7.1e\n", v.Interface())
+	// STOP OMIT
+}
+
+func f4() {
+	// START f4 OMIT
+	var x float64 = 3.4
+	v := reflect.ValueOf(x)
+	v.SetFloat(7.1) // Error: will panic.
+	// STOP OMIT
+}
+
+func f5() {
+	// START f5 OMIT
+	var x float64 = 3.4
+	v := reflect.ValueOf(x)
+	fmt.Println("settability of v:", v.CanSet())
+	// STOP OMIT
+}
+
+func f6() {
+	// START f6 OMIT
+	var x float64 = 3.4
+	v := reflect.ValueOf(x)
+	// START f6b OMIT
+	v.SetFloat(7.1)
+	// STOP OMIT
+}
+
+func f7() {
+	// START f7 OMIT
+	var x float64 = 3.4
+	p := reflect.ValueOf(&x) // Note: take the address of x.
+	fmt.Println("type of p:", p.Type())
+	fmt.Println("settability of p:", p.CanSet())
+	// START f7b OMIT
+	v := p.Elem()
+	fmt.Println("settability of v:", v.CanSet())
+	// START f7c OMIT
+	v.SetFloat(7.1)
+	fmt.Println(v.Interface())
+	fmt.Println(x)
+	// STOP OMIT
+}
+
+func f8() {
+	// START f8 OMIT
+	type T struct {
+		A int
+		B string
+	}
+	t := T{23, "skidoo"}
+	s := reflect.ValueOf(&t).Elem()
+	typeOfT := s.Type()
+	for i := 0; i < s.NumField(); i++ {
+		f := s.Field(i)
+		fmt.Printf("%d: %s %s = %v\n", i,
+			typeOfT.Field(i).Name, f.Type(), f.Interface())
+	}
+	// START f8b OMIT
+	s.Field(0).SetInt(77)
+	s.Field(1).SetString("Sunset Strip")
+	fmt.Println("t is now", t)
+	// STOP OMIT
+}
diff --git a/doc/progs/run b/doc/progs/run
index 5a2b786..e3d5c12 100755
--- a/doc/progs/run
+++ b/doc/progs/run
@@ -5,121 +5,49 @@
 
 set -e
 
-eval $(gomake --no-print-directory -f ../../src/Make.inc go-env)
-
-if [ -z "$O" ]; then
-	echo 'missing $O - maybe no Make.$GOARCH?' 1>&2
-	exit 1
-fi
-
-rm -f *.$O
-
-if [ "$GOOS" = "windows" ];then
-	$GC -o file.$O file_windows.go
-else
-	$GC file.go
-fi
-
 defer_panic_recover="
-	defer.go 
-	defer2.go 
+	defer
+	defer2
 "
 
 effective_go="
-	eff_bytesize.go
-	eff_qr.go 
-	eff_sequence.go
+	eff_bytesize
+	eff_qr
+	eff_sequence
 "
 
 error_handling="
-	error.go
-	error2.go
-	error3.go
-	error4.go
+	error
+	error2
+	error3
+	error4
 "
 
-go_tutorial="
-	cat.go 
-	cat_rot13.go 
-	echo.go 
-	helloworld.go 
-	helloworld3.go 
-	print.go 
-	print_string.go 
-	server.go 
-	server1.go 
-	sieve.go 
-	sieve1.go 
-	sort.go 
-	sortmain.go 
-	strings.go 
-	sum.go 
-"
+all=$(echo $defer_panic_recover  $effective_go $error_handling slices go1)
 
-for i in \
-	$defer_panic_recover \
-	$effective_go \
-	$error_handling \
-	$go_tutorial \
-	slices.go \
-	go1.go \
-; do
-	$GC $i
+for i in $all; do
+	go build $i.go
 done
 
 # Write to temporary file to avoid mingw bash bug.
 TMPFILE="/tmp/gotest3.$USER"
 
 function testit {
-	$LD $1.$O
-	./$O.out $2 2>&1 >"$TMPFILE" || true
+	./$1 >"$TMPFILE" 2>&1 || true
 	x=$(echo $(cat "$TMPFILE")) # extra echo canonicalizes
-	if [ "$x" != "$3" ]
+	if ! echo "$x" | grep "$2" > /dev/null
 	then
-		echo $1 failed: '"'$x'"' is not '"'$3'"'
+		echo $1 failed: '"'$x'"' is not '"'$2'"'
 	fi
 }
 
-function testitpipe {
-	$LD $1.$O
-	./$O.out | $2 2>&1 >"$TMPFILE" || true
-	x=$(echo $(cat "$TMPFILE")) # extra echo canonicalizes
-	if [ "$x" != "$3" ]
-	then
-		echo $1 failed: '"'$x'"' is not '"'$3'"'
-	fi
-}
-
-
-testit helloworld "" "Hello, world; or Καλημέρα κόσμε; or こんにちは 世界"
-testit helloworld3 "" "hello, world can't open file; err=no such file or directory"
-testit echo "hello, world" "hello, world"
-testit sum "" "6"
-testit strings "" ""
-testit defer "" "0 3210 2"
-testit defer2 "" "Calling g. Printing in g 0 Printing in g 1 Printing in g 2 Printing in g 3 Panicking! Defer in g 3 Defer in g 2 Defer in g 1 Defer in g 0 Recovered in f 4 Returned normally from f."
-
-alphabet=abcdefghijklmnopqrstuvwxyz
-rot13=nopqrstuvwxyzabcdefghijklm
-echo $alphabet | testit cat "" $alphabet
-echo $alphabet | testit cat_rot13 "--rot13" $rot13
-echo $rot13 | testit cat_rot13 "--rot13" $alphabet
-
-testit sortmain "" "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
-
-testit print "" "18446744073709551615 -1 18446744073709551615 {77 Sunset Strip} [1 2 3 4] 18446744073709551615 {77 Sunset Strip} [1 2 3 4] 18446744073709551615 {77 Sunset Strip} [1 2 3 4]"
-testit print_string "" "77 Sunset Strip"
-
-testitpipe sieve "sed 10q" "2 3 5 7 11 13 17 19 23 29"
-testitpipe sieve "sed 10q" "2 3 5 7 11 13 17 19 23 29"
 
-# server hangs; don't run it, just compile it
-$GC server.go
-testit server1 "" ""
+testit defer '^0 3210 2$'
+testit defer2 '^Calling g. Printing in g 0 Printing in g 1 Printing in g 2 Printing in g 3 Panicking! Defer in g 3 Defer in g 2 Defer in g 1 Defer in g 0 Recovered in f 4 Returned normally from f.$'
 
-testit eff_bytesize "" "1.00YB 9.09TB"
-testit eff_sequence "" "[-1 2 6 16 44]"
+testit eff_bytesize '^1.00YB 9.09TB$'
+testit eff_sequence '^\[-1 2 6 16 44\]$'
 
-testit go1 "" "Christmas is a holiday: true"
+testit go1 '^Christmas is a holiday: true Sleeping for 0.123s.*go1.go already exists$'
 
-rm -f $O.out $O.out.exe *.$O "$TMPFILE"
+rm -f $all "$TMPFILE"
diff --git a/doc/progs/sieve.go b/doc/progs/sieve.go
deleted file mode 100644
index b315309..0000000
--- a/doc/progs/sieve.go
+++ /dev/null
@@ -1,38 +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 main
-
-import "fmt"
-
-// Send the sequence 2, 3, 4, ... to channel 'ch'.
-func generate(ch chan int) {
-	for i := 2; ; i++ {
-		ch <- i // Send 'i' to channel 'ch'.
-	}
-}
-
-// Copy the values from channel 'in' to channel 'out',
-// removing those divisible by 'prime'.
-func filter(in, out chan int, prime int) {
-	for {
-		i := <-in // Receive value of new variable 'i' from 'in'.
-		if i%prime != 0 {
-			out <- i // Send 'i' to channel 'out'.
-		}
-	}
-}
-
-// The prime sieve: Daisy-chain filter processes together.
-func main() {
-	ch := make(chan int)       // Create a new channel.
-	go generate(ch)            // Start generate() as a goroutine.
-	for i := 0; i < 100; i++ { // Print the first hundred primes.
-		prime := <-ch
-		fmt.Println(prime)
-		ch1 := make(chan int)
-		go filter(ch, ch1, prime)
-		ch = ch1
-	}
-}
diff --git a/doc/progs/sieve1.go b/doc/progs/sieve1.go
deleted file mode 100644
index e1411a3..0000000
--- a/doc/progs/sieve1.go
+++ /dev/null
@@ -1,51 +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 main
-
-import "fmt"
-
-// Send the sequence 2, 3, 4, ... to returned channel 
-func generate() chan int {
-	ch := make(chan int)
-	go func() {
-		for i := 2; ; i++ {
-			ch <- i
-		}
-	}()
-	return ch
-}
-
-// Filter out input values divisible by 'prime', send rest to returned channel
-func filter(in chan int, prime int) chan int {
-	out := make(chan int)
-	go func() {
-		for {
-			if i := <-in; i%prime != 0 {
-				out <- i
-			}
-		}
-	}()
-	return out
-}
-
-func sieve() chan int {
-	out := make(chan int)
-	go func() {
-		ch := generate()
-		for {
-			prime := <-ch
-			out <- prime
-			ch = filter(ch, prime)
-		}
-	}()
-	return out
-}
-
-func main() {
-	primes := sieve()
-	for i := 0; i < 100; i++ { // Print the first hundred primes.
-		fmt.Println(<-primes)
-	}
-}
diff --git a/doc/progs/slices.go b/doc/progs/slices.go
index 72fb4b7..8e44010 100644
--- a/doc/progs/slices.go
+++ b/doc/progs/slices.go
@@ -57,3 +57,7 @@ func CopyDigits(filename string) []byte {
 }
 
 // STOP OMIT
+
+func main() {
+	// place holder; no need to run
+}
diff --git a/doc/progs/sortmain.go b/doc/progs/sortmain.go
deleted file mode 100644
index 1bc3355..0000000
--- a/doc/progs/sortmain.go
+++ /dev/null
@@ -1,68 +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 main
-
-import (
-	"./sort"
-	"fmt"
-)
-
-func ints() {
-	data := []int{74, 59, 238, -784, 9845, 959, 905, 0, 0, 42, 7586, -5467984, 7586}
-	a := sort.IntSlice(data)
-	sort.Sort(a)
-	if !sort.IsSorted(a) {
-		panic("fail")
-	}
-}
-
-func strings() {
-	data := []string{"monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"}
-	a := sort.StringSlice(data)
-	sort.Sort(a)
-	if !sort.IsSorted(a) {
-		panic("fail")
-	}
-}
-
-type day struct {
-	num       int
-	shortName string
-	longName  string
-}
-
-type dayArray struct {
-	data []*day
-}
-
-func (p *dayArray) Len() int           { return len(p.data) }
-func (p *dayArray) Less(i, j int) bool { return p.data[i].num < p.data[j].num }
-func (p *dayArray) Swap(i, j int)      { p.data[i], p.data[j] = p.data[j], p.data[i] }
-
-func days() {
-	Sunday := day{0, "SUN", "Sunday"}
-	Monday := day{1, "MON", "Monday"}
-	Tuesday := day{2, "TUE", "Tuesday"}
-	Wednesday := day{3, "WED", "Wednesday"}
-	Thursday := day{4, "THU", "Thursday"}
-	Friday := day{5, "FRI", "Friday"}
-	Saturday := day{6, "SAT", "Saturday"}
-	data := []*day{&Tuesday, &Thursday, &Wednesday, &Sunday, &Monday, &Friday, &Saturday}
-	a := dayArray{data}
-	sort.Sort(&a)
-	if !sort.IsSorted(&a) {
-		panic("fail")
-	}
-	for _, d := range data {
-		fmt.Printf("%s ", d.longName)
-	}
-	fmt.Printf("\n")
-}
-
-func main() {
-	ints()
-	strings()
-	days()
-}
diff --git a/doc/reference-cmd.html b/doc/reference-cmd.html
new file mode 100644
index 0000000..3665e3c
--- /dev/null
+++ b/doc/reference-cmd.html
@@ -0,0 +1,84 @@
+<!--{
+	"Title": "Command Documentation",
+	"Path":  "/ref/cmd"
+}-->
+
+<p>
+Click on the links for more documentation and usage messages.
+</p>
+
+<table class="dir">
+<tr>
+<th>Name</th>
+<th>    </th>
+<th>Synopsis</th>
+</tr>
+
+<tr>
+<td><a href="/cmd/go/">go</a></td>
+<td>    </td>
+<td>
+Go is a tool for managing Go source code.
+<br>
+Besides compiling and running Go programs, the go command is also used to
+invoke the other commands listed below. See the command docs for usage
+details.
+<br><br>
+</td>
+</tr>
+
+<tr>
+<td><a href="/cmd/cgo/">cgo</a></td>
+<td>    </td>
+<td>Cgo enables the creation of Go packages that call C code.</td>
+</tr>
+
+<tr>
+<td><a href="/cmd/cov/">cov</a></td>
+<td>    </td>
+<td>Cov is a rudimentary code coverage tool.</td>
+</tr>
+
+<tr>
+<td><a href="/cmd/fix/">fix</a></td>
+<td>    </td>
+<td>Fix finds Go programs that use old features of the language and libraries
+and rewrites them to use newer ones.</td>
+</tr>
+
+<tr>
+<td><a href="/cmd/godoc/">godoc</a></td>
+<td>    </td>
+<td>Godoc extracts and generates documentation for Go programs.</td>
+</tr>
+
+<tr>
+<td><a href="/cmd/gofmt/">gofmt</a></td>
+<td>    </td>
+<td>Gofmt formats Go programs.</td>
+</tr>
+
+<tr>
+<td><a href="/cmd/prof/">prof</a></td>
+<td>    </td>
+<td>Prof is a rudimentary real-time profiler.</td>
+</tr>
+
+<tr>
+<td><a href="/cmd/vet/">vet</a></td>
+<td>    </td>
+<td>Vet examines Go source code and reports suspicious constructs, such as Printf calls whose arguments do not align with the format string.</td>
+</tr>
+
+<tr>
+<td><a href="/cmd/yacc/">yacc</a></td>
+<td>    </td>
+<td>Yacc is a version of yacc for Go.</td>
+</tr>
+
+</table>
+
+<p>
+This is an abridged list. See the <a href="/cmd/">full command reference</a>
+for documentation of the compilers and more.
+</p>
diff --git a/doc/reference.html b/doc/reference.html
index 71812bf..12a6ef9 100644
--- a/doc/reference.html
+++ b/doc/reference.html
@@ -1,23 +1,25 @@
 <!--{
-	"Title": "References"
+	"Title": "References",
+	"Path":  "/ref/"
 }-->
 
 <img src="/doc/gopher/ref.png" align="right"/>
-<p>Keep these under your pillow.</p>
+
+<p>Good bedtime reading.</p>
 
 <div>
 
 <h3 id="pkg"><a href="/pkg/">Package Documentation</a></h3>
 <p>
-The built-in documentation for the Go standard library.
+The documentation for the Go standard library.
 </p>
 
-<h3 id="cmd"><a href="/cmd/">Command Documentation</a></h3>
+<h3 id="cmd"><a href="/ref/cmd">Command Documentation</a></h3>
 <p>
-The built-in documentation for the Go tools.
+The documentation for the Go tools.
 </p>
 
-<h3 id="spec"><a href="go_spec.html">Language Specification</a></h3>
+<h3 id="spec"><a href="/ref/spec">Language Specification</a></h3>
 <p>
 The official Go Language specification. 
 </p>
@@ -28,19 +30,30 @@ The documentation for
 <a href="http://code.google.com/appengine/">Google App Engine</a>'s Go runtime.
 </p>
 
-<h3 id="release"><a href="devel/release.html">Release History</a></h3>
-<p>A summary of the changes between Go releases.</p>
-
-<h3 id="go_mem"><a href="go_mem.html">The Go Memory Model</a></h3>
+<h3 id="go_mem"><a href="/ref/mem">The Go Memory Model</a></h3>
 <p>
 A document that specifies the conditions under which reads of a variable in
 one goroutine can be guaranteed to observe values produced by writes to the
 same variable in a different goroutine.
 </p>
 
-<h3 id="debugging_with_gdb"><a href="debugging_with_gdb.html">Debugging Go Code with GDB</a></h3>
+<h3 id="debugging_with_gdb"><a href="/ref/gdb">Debugging Go Code with GDB</a></h3>
 <p>
 Using GDB to debug Go programs.
 </p>
 
+<h3 id="articles">Articles</h2>
+
+<ul>
+<li><a href="http://blog.golang.org/2011/03/c-go-cgo.html">C? Go? Cgo!</a> - linking against C code with <a href="/cmd/cgo/">cgo</a>.</li>
+<li><a href="/doc/articles/defer_panic_recover.html">Defer, Panic, and Recover</a></li>
+<li><a href="/doc/articles/slices_usage_and_internals.html">Go Slices: usage and internals</a></li>
+<li><a href="http://blog.golang.org/2011/03/godoc-documenting-go-code.html">Godoc: documenting Go code</a> - writing good documentation for <a href="/cmd/godoc/">godoc</a>.</li>
+<li><a href="http://blog.golang.org/2011/06/profiling-go-programs.html">Profiling Go Programs</a></li>
+</ul>
+
+<p>
+See the <a href=/doc/#articles">documentation page</a> for more articles.
+</p>
+
 </div>
diff --git a/doc/root.html b/doc/root.html
index 6884fba..2029d4c 100644
--- a/doc/root.html
+++ b/doc/root.html
@@ -2,26 +2,7 @@
 	"Path": "/"
 }-->
 
-<div id="left" class="aboutcol">
-
-<div id="about">
-Go is an open source programming environment that makes it easy to build
-simple, reliable, and efficient software.
-</div>
-
-<div id="gopher"></div>
-
-<a href="/install/" id="start">
-<div class="big">Download Go</div>
-<div class="desc">
-Binary distributions available for<br>
-Linux, Mac OS X, Windows, and more.
-</div>
-</a>
-
-</div>
-
-<div id="right" class="learncol">
+<div class="left">
 
 <div id="learn">
 <div class="rootHeading">Try Go</div>
@@ -49,9 +30,28 @@ Hello, 世界
 
 </div>
 
+<div class="right">
+
+<div id="about">
+Go is an open source programming environment that makes it easy to build
+simple, reliable, and efficient software.
+</div>
+
+<div id="gopher"></div>
+
+<a href="/install/" id="start">
+<div class="big">Download Go</div>
+<div class="desc">
+Binary distributions available for<br>
+Linux, Mac OS X, Windows, and more.
+</div>
+</a>
+
+</div>
+
 <div style="clear: both"></div>
 
-<div id="left">
+<div class="left">
 
 <div id="video">
 <div class="rootHeading">Featured video</div>
@@ -61,7 +61,7 @@ Hello, 世界
 
 </div>
 
-<div id="right">
+<div class="right">
 
 <div id="blog">
 <div class="rootHeading">Featured articles</div>
diff --git a/doc/style.css b/doc/style.css
index c387705..b180a61 100644
--- a/doc/style.css
+++ b/doc/style.css
@@ -3,7 +3,8 @@ body {
 	font-family: Helvetica, Arial, sans-serif;
 	font-size: 16px;
 }
-pre, code {
+pre,
+code {
 	font-family: Menlo, monospace;
 	font-size: 14px;
 }
@@ -13,6 +14,16 @@ pre {
 pre .comment {
 	color: #375EAB;
 }
+pre .highlight,
+pre .highlight-comment,
+pre .selection-highlight,
+pre .selection-highlight-comment {
+    background: #FFFF00;
+}
+pre .selection,
+pre .selection-comment {
+    background: #FF9632;
+}
 pre .ln {
 	color: #999;
 }
@@ -23,7 +34,10 @@ a {
 	color: #375EAB;
 	text-decoration: none;
 }
-p, pre, ul, ol {
+p,
+pre,
+ul,
+ol {
 	margin: 20px;
 }
 pre {
@@ -35,7 +49,11 @@ pre {
 	border-radius: 5px;
 }
 
-h1, h2, h3, h4, .rootHeading {
+h1,
+h2,
+h3,
+h4,
+.rootHeading {
 	margin: 20px 0;
 	padding: 0;
 	color: #375EAB;
@@ -52,7 +70,8 @@ h2 {
 h3 {
 	font-size: 18px;
 }
-h3, h4 {
+h3,
+h4 {
 	margin: 20px 5px;
 }
 h4 {
@@ -63,7 +82,10 @@ h4 {
 	margin: 0;
 }
 
-h1 a, h2 a, h3 a, h4 a {
+h1 a,
+h2 a,
+h3 a,
+h4 a {
 	text-decoration: underline;
 }
 
@@ -73,10 +95,11 @@ dl {
 dd {
 	margin: 2px 20px;
 }
-dl, dd {
+dl,
+dd {
 	font-size: 14px;
 }
-#nav table td {
+div#nav table td {
 	vertical-align: top;
 }
 
@@ -88,50 +111,54 @@ table.dir td {
 	vertical-align: top;
 }
 
-#heading {
+.alert {
+	color: #AA0000;
+}
+
+div#heading {
 	float: left;
 	margin: 0 0 10px 0;
-	padding: 16px 0;
-	font-size: 26px;
+	padding: 21px 0;
+	font-size: 20px;
 	font-weight: normal;
 }
-#heading a {
+div#heading a {
 	color: #222;
 	text-decoration: none;
 }
 
-#topbar {
+div#topbar {
 	background: #E0EBF5;
 }
 
 body {
 	text-align: center;
 }
-#page,
-#topbar .container {
+div#page,
+div#topbar .container {
 	clear: both;
 	text-align: left;
 	margin-left: auto;
 	margin-right: auto;
 	width: 900px;
 }
-#plusone {
+div#plusone {
 	float: right;
 }
-#plusoneRoot {
+div#plusoneRoot {
 	float: right;
 }
 
-#copyright {
+div#copyright {
 	color: #666;
 	font-size: 14px;
 	margin: 40px 0;
 }
 
-#menu > a,
-#menu > input,
-#learn .buttons a,
-#blog .read a {
+div#menu > a,
+div#menu > input,
+div#learn .buttons a,
+div#blog .read a {
 	padding: 10px;
 
 	text-decoration: none;
@@ -141,74 +168,75 @@ body {
 	-moz-border-radius: 5px;
 	border-radius: 5px;
 }
-#menu > a,
-#menu > input {
+div#menu > a,
+div#menu > input {
 	border: 1px solid #375EAB;
 }
-#menu > a {
+div#menu > a {
 	color: white;
 	background: #375EAB;
 }
-#start,
-#learn .buttons a,
-#blog .read a {
+a#start,
+div#learn .buttons a,
+div#blog .read a {
 	color: #222;
 	border: 1px solid #375EAB;
 	background: #E0EBF5;
 }
 
-#menu {
+div#menu {
 	padding: 10px 0;
 	text-align: right;
 }
-#menu > a {
+div#menu > a {
 	margin-right: 5px;
 	margin-bottom: 10px;
 
 	padding: 10px;
 }
-#menu > input {
+div#menu > input {
 	position: relative;
 	top: 1px;
-	width: 100px;
+	width: 60px;
 	background: white;
 	color: #222;
 }
-#menu > input.inactive {
+div#menu > input.inactive {
 	color: #999;
 }
 
-#left {
+div.left {
 	float: left;
 }
-#right {
+div.right {
 	float: right;
 }
-#left, #right {
+div.left,
+div.right {
 	width: 415px;
 }
 
-#learn,
-#about {
+div#learn,
+div#about {
 	padding-top: 20px;
 }
-#learn h2,
-#about {
+div#learn h2,
+div#about {
 	margin: 0;
 }
-#about {
+div#about {
 	font-size: 20px;
 }
 
-#about {
+div#about {
 	height: 96px;
 }
-#gopher {
+div#gopher {
 	background: url(/doc/gopher/frontpage.png) no-repeat;
 	background-position: center top;
 	height: 155px;
 }
-#start {
+a#start {
 	display: block;
 	padding: 10px;
 
@@ -219,23 +247,24 @@ body {
 	-moz-border-radius: 5px;
 	border-radius: 5px;
 }
-#start .big {
+a#start .big {
 	font-weight: bold;
 	font-size: 20px;
 }
-#start .desc {
+a#start .desc {
 	font-size: 14px;
 	font-weight: normal;
 	margin-top: 5px;
 }
 
-#learn pre, #learn textarea {
+div#learn pre,
+div#learn textarea {
 	padding: 0;
 	margin: 0;
 	font-family: Menlo, monospace;
 	font-size: 14px;
 }
-#learn .input {
+div#learn .input {
 	padding: 10px;
 	margin-top: 10px;
 	height: 150px;
@@ -247,14 +276,14 @@ body {
 	border-top-left-radius: 5px;
 	border-top-right-radius: 5px;
 }
-#learn .input textarea {
+div#learn .input textarea {
 	width: 100%;
 	height: 100%;
 	border: none;
 	outline: none;
 	resize: none;
 }
-#learn .output {
+div#learn .output {
 	border-top: none !important;
 
 	padding: 10px;
@@ -268,58 +297,65 @@ body {
 	border-bottom-right-radius: 5px;
 	border-bottom-left-radius: 5px;
 }
-#learn .output pre {
+div#learn .output pre {
 	padding: 0;
 
 	-webkit-border-radius: 0;
 	-moz-border-radius: 0;
 	border-radius: 0;
 }
-#learn .input,
-#learn .input textarea,
-#learn .output,
-#learn .output pre {
+div#learn .input,
+div#learn .input textarea,
+div#learn .output,
+div#learn .output pre {
 	background: #FFFFD8;
 }
-#learn .input,
-#learn .output {
+div#learn .input,
+div#learn .output {
 	border: 1px solid #375EAB;
 }
-#learn .buttons {
+div#learn .buttons {
 	padding: 20px 0 10px 0;
 	text-align: right;
 }
-#learn .buttons a {
+div#learn .buttons a {
 	height: 16px;
 	margin-left: 5px;
 
 	padding: 10px;
 }
-#learn .buttons .tour {
+div#learn .buttons .tour {
 	float: right;
 }
-#learn .buttons .tour a {
+div#learn .buttons .tour a {
 	margin-right: 0;
 	font-weight: bold;
 }
 
-#blog, #video {
+div#blog,
+div#video {
 	margin-top: 40px;
 }
-#blog > div, #blog > a, #video > div, #video > a, #blog > h2, #video > h2 {
+div#blog > a,
+div#blog > div,
+div#blog > h2,
+div#video > a,
+div#video > div,
+div#video > h2 {
 	margin-bottom: 10px;
 }
-#blog .title, #video .title {
+div#blog .title,
+div#video .title {
 	color: #222;
 	text-decoration: none;
 	display: block;
 	font-size: 20px;
 }
-#blog .when {
+div#blog .when {
 	color: #666;
 	font-size: 14px;
 }
-#blog .read {
+div#blog .read {
 	text-align: right;
 }
 
diff --git a/doc/talks/go_talk-20100323.html b/doc/talks/go_talk-20100323.html
index 3143b07..7330dd2 100644
--- a/doc/talks/go_talk-20100323.html
+++ b/doc/talks/go_talk-20100323.html
@@ -380,7 +380,7 @@ containing other data structures as continuous blocks of memory."
 	<h2>And more:</h2>
 	<ul>
 		<li>I haven't talked about the type system, interfaces, slices, closures, selects, ...</li>
-		<li>Tutorial, documentation, mailing list, source code all online</li>
+		<li>Documentation, mailing list, source code all online</li>
 	</ul>
 </div>
 
diff --git a/lib/godoc/godoc.html b/lib/godoc/godoc.html
index 380a391..09a2cc4 100644
--- a/lib/godoc/godoc.html
+++ b/lib/godoc/godoc.html
@@ -20,10 +20,11 @@
 <form method="GET" action="/search">
 <div id="heading"><a href="/">The Go Programming Language</a></div>
 <div id="menu">
-<a href="/doc/">Learn</a>
-<a href="/install/">Install</a>
-<a href="/project/">Project</a>
-<a href="/doc/reference.html">Reference</a>
+<a href="/doc/">Documents</a>
+<a href="/ref/">References</a>
+<a href="/pkg/">Packages</a>
+<a href="/project/">The Project</a>
+<a href="/help/">Help</a>
 <input type="text" id="search" name="q" class="inactive" value="Search">
 </div>
 </form>
diff --git a/lib/godoc/package.html b/lib/godoc/package.html
index 01043b0..fdebbf5 100644
--- a/lib/godoc/package.html
+++ b/lib/godoc/package.html
@@ -12,6 +12,9 @@
 			<dl>
 			<dd><a href="#overview">Overview</a></dd>
 			<dd><a href="#index">Index</a></dd>
+			{{if $.Examples}}
+				<dd><a href="#examples">Examples</a></dd>
+			{{end}}
 			{{if $.Dirs}}
 				<dd><a href="#subdirectories">Subdirectories</a></dd>
 			{{end}}
@@ -54,7 +57,7 @@
 		</dl>
 
 		{{if $.Examples}}
-			<h4>Examples</h4>
+			<h4 id="examples">Examples</h4>
 			<dl>
 			{{range $.Examples}}
 			<dd><a class="exampleLink" href="#example_{{.Name}}">{{example_name .Name}}</a></dd>
@@ -76,22 +79,22 @@
 		{{with .Consts}}
 			<h2 id="constants">Constants</h2>
 			{{range .}}
-				{{comment_html .Doc}}
 				<pre>{{node_html .Decl $.FSet}}</pre>
+				{{comment_html .Doc}}
 			{{end}}
 		{{end}}
 		{{with .Vars}}
 			<h2 id="variables">Variables</h2>
 			{{range .}}
-				{{comment_html .Doc}}
 				<pre>{{node_html .Decl $.FSet}}</pre>
+				{{comment_html .Doc}}
 			{{end}}
 		{{end}}
 		{{range .Funcs}}
 			{{/* Name is a string - no need for FSet */}}
 			{{$name_html := html .Name}}
 			<h2 id="{{$name_html}}">func <a href="/{{posLink_url .Decl $.FSet}}">{{$name_html}}</a></h2>
-			<p><code>{{node_html .Decl $.FSet}}</code></p>
+			<pre>{{node_html .Decl $.FSet}}</pre>
 			{{comment_html .Doc}}
 			{{example_html .Name $.Examples $.FSet}}
 		{{end}}
@@ -99,28 +102,33 @@
 			{{$tname := .Name}}
 			{{$tname_html := html .Name}}
 			<h2 id="{{$tname_html}}">type <a href="/{{posLink_url .Decl $.FSet}}">{{$tname_html}}</a></h2>
-			{{comment_html .Doc}}
 			<pre>{{node_html .Decl $.FSet}}</pre>
+			{{comment_html .Doc}}
+
 			{{range .Consts}}
-				{{comment_html .Doc}}
 				<pre>{{node_html .Decl $.FSet}}</pre>
+				{{comment_html .Doc}}
 			{{end}}
+
 			{{range .Vars}}
-				{{comment_html .Doc}}
 				<pre>{{node_html .Decl $.FSet}}</pre>
+				{{comment_html .Doc}}
 			{{end}}
+
 			{{example_html $tname $.Examples $.FSet}}
+
 			{{range .Funcs}}
 				{{$name_html := html .Name}}
 				<h3 id="{{$name_html}}">func <a href="/{{posLink_url .Decl $.FSet}}">{{$name_html}}</a></h3>
-				<p><code>{{node_html .Decl $.FSet}}</code></p>
+				<pre>{{node_html .Decl $.FSet}}</pre>
 				{{comment_html .Doc}}
 				{{example_html .Name $.Examples $.FSet}}
 			{{end}}
+
 			{{range .Methods}}
 				{{$name_html := html .Name}}
 				<h3 id="{{$tname_html}}.{{$name_html}}">func ({{html .Recv}}) <a href="/{{posLink_url .Decl $.FSet}}">{{$name_html}}</a></h3>
-				<p><code>{{node_html .Decl $.FSet}}</code></p>
+				<pre>{{node_html .Decl $.FSet}}</pre>
 				{{comment_html .Doc}}
 				{{$name := printf "%s_%s" $tname .Name}}
 				{{example_html $name $.Examples $.FSet}}
@@ -155,28 +163,34 @@
 
 {{with .Dirs}}
 	{{/* DirList entries are numbers and strings - no need for FSet */}}
-	<h2 id="subdirectories">Subdirectories</h2>
+	{{if $.PDoc}}<h2 id="subdirectories">Subdirectories</h2>{{end}}
 	<table class="dir">
 	<tr>
 	<th>Name</th>
 	<th>    </th>
 	<th style="text-align: left; width: auto">Synopsis</th>
 	</tr>
-	<tr>
-	<td><a href="..">..</a></td>
-	</tr>
+	{{if not $.DirFlat}}
+		<tr>
+		<td><a href="..">..</a></td>
+		</tr>
+	{{end}}
 	{{range .List}}
-	<tr>
-		<td>
 		{{if $.DirFlat}}
-			<a href="{{html .Path}}">{{html .Path}}</a>
+			{{if .HasPkg}}
+				<tr>
+				<td><a href="{{html .Path}}">{{html .Path}}</a></td>
+				<td>    </td>
+				<td style="width: auto">{{html .Synopsis}}</td>
+				</tr>
+			{{end}}
 		{{else}}
-			{{repeat `     ` .Depth}}<a href="{{html .Path}}">{{html .Name}}</a>
+			<tr>
+			<td>{{repeat `     ` .Depth}}<a href="{{html .Path}}">{{html .Name}}</a></td>
+			<td>    </td>
+			<td style="width: auto">{{html .Synopsis}}</td>
+			</tr>
 		{{end}}
-		</td>
-		<td>    </td>
-		<td style="width: auto">{{html .Synopsis}}</td>
-	</tr>
 	{{end}}
 	</table>
 {{end}}
diff --git a/lib/godoc/package.txt b/lib/godoc/package.txt
index d88cda7..3f3c396 100644
--- a/lib/godoc/package.txt
+++ b/lib/godoc/package.txt
@@ -76,8 +76,8 @@ OTHER PACKAGES
 
 */}}{{with .Dirs}}
 SUBDIRECTORIES
-{{if $.DirFlat}}{{range .List}}
-	{{.Path}}{{end}}
+{{if $.DirFlat}}{{range .List}}{{if .HasPkg}}
+	{{.Path}}{{end}}{{end}}
 {{else}}{{range .List}}
 	{{repeat `. ` .Depth}}{{.Name}}{{end}}
 {{end}}{{end}}
diff --git a/misc/bash/go b/misc/bash/go
index caced15..f5d79e4 100644
--- a/misc/bash/go
+++ b/misc/bash/go
@@ -4,3 +4,247 @@ complete -f -X '!*.8' 8l
 complete -f -X '!*.6' 6l
 complete -f -X '!*.5' 5l
 complete -f -X '!*.go' 8g 6g 5g gofmt gccgo
+
+_go_importpath()
+{
+  echo "$(compgen -W "$(go list all) all std" -- "$1")"
+}
+
+_go()
+{
+  # TODO: Only allow flags before other arguments. run already does
+  # this.
+
+  local cur=`_get_cword`
+  local prev="${COMP_WORDS[COMP_CWORD-1]}"
+
+  local cmd="${COMP_WORDS[1]}"
+
+  local cmds="build clean doc fix fmt get
+    install list run test tool version vet"
+  local addhelp="gopath importpath remote
+    testflag testfunc"
+  local other="help"
+
+  if [ "$COMP_CWORD" == 1 ]; then
+    for opt in $cmds; do
+      if [[ "$opt" == "$cmd" ]]; then
+        COMPREPLY=("$opt")
+        return
+      fi
+    done
+  fi
+
+  case "$cmd" in
+    'build')
+      case "$prev" in
+        '-o')
+          _filedir
+          ;;
+        '-p')
+          ;;
+        *)
+          if [[ "$cur" == -* ]]; then
+            COMPREPLY=($(compgen -W "-a -n -o -p -v -x" -- "$cur"))
+          else
+            local found=0
+            for ((i=0; i < ${#COMP_WORDS[@]}; i++)); do
+              case "$i" in
+                0|1|"$COMP_CWORD")
+                  continue
+                  ;;
+              esac
+              local opt="${COMP_WORDS[i]}"
+              if [[ "$opt" != -* ]]; then
+                if [[ "$opt" == *.go && -f "$opt" ]]; then
+                  found=1
+                  break
+                else
+                  found=2
+                  break
+                fi
+              fi
+            done
+            case "$found" in
+              0)
+                _filedir go
+                COMPREPLY+=(`_go_importpath "$cur"`)
+                ;;
+              1)
+                _filedir go
+                ;;
+              2)
+                COMPREPLY=(`_go_importpath "$cur"`)
+                ;;
+            esac
+          fi
+          ;;
+      esac
+      ;;
+    'clean')
+      if [[ "$cur" == -* ]]; then
+        COMPREPLY=($(compgen -W "-i -r -n -x" -- "$cur"))
+      else
+        COMPREPLY=(`_go_importpath "$cur"`)
+      fi
+      ;;
+    'doc')
+      COMPREPLY=(`_go_importpath "$cur"`)
+      ;;
+    'fix')
+      COMPREPLY=(`_go_importpath "$cur"`)
+      ;;
+    'fmt')
+      COMPREPLY=(`_go_importpath "$cur"`)
+      ;;
+    'get')
+      case "$prev" in
+        '-p')
+          ;;
+        *)
+          if [[ "$cur" == -* ]]; then
+            COMPREPLY=($(compgen -W "-a -d -fix -n -p -u -v -x" -- "$cur"))
+          else
+            COMPREPLY=(`_go_importpath "$cur"`)
+          fi
+          ;;
+      esac
+      ;;
+    'install')
+      case "$prev" in
+        '-p')
+          ;;
+        *)
+          if [[ "$cur" == -* ]]; then
+            COMPREPLY=($(compgen -W "-a -n -p -v -x" -- "$cur"))
+          else
+            COMPREPLY=(`_go_importpath "$cur"`)
+          fi
+          ;;
+      esac
+      ;;
+    'list')
+      case "$prev" in
+        '-f')
+          ;;
+        *)
+          if [[ "$cur" == -* ]]; then
+            COMPREPLY=($(compgen -W "-e -f -json" -- "$cur"))
+          else
+            COMPREPLY=(`_go_importpath "$cur"`)
+          fi
+          ;;
+      esac
+      ;;
+    'run')
+      if [[ "$cur" == -* && "$prev" != *.go ]]; then
+        COMPREPLY=($(compgen -W "-a -n -x" -- "$cur"))
+      else
+        _filedir
+      fi
+      ;;
+    'test') # TODO: Support for testflags.
+      case "$prev" in
+        '-file')
+          _filedir go
+          ;;
+        '-p')
+          ;;
+        *)
+          if [[ "$cur" == -* ]]; then
+            COMPREPLY=($(compgen -W "-c -file -i -p -x" -- "$cur"))
+          else
+            COMPREPLY=(`_go_importpath "$cur"`)
+          fi
+          ;;
+        esac
+      ;;
+    'tool')
+      if [ "$COMP_CWORD" == 2 ]; then
+        COMPREPLY=($(compgen -W "$(go tool)" -- "$cur"))
+      else
+        case "${COMP_WORDS[2]}" in
+          [568]a) # TODO: Implement something.
+            #_go_tool_568a
+            ;;
+          [568]c) # TODO: Implement something.
+            #_go_tool_568c
+            ;;
+          [568]g) # TODO: Implement something.
+            #_go_tool_568g
+            ;;
+          [568]l) # TODO: Implement something.
+            #_go_tool_568l
+            ;;
+          'api') # TODO: Implement something.
+            #_go_tool_api
+            ;;
+          'cgo') # TODO: Implement something.
+            #_go_tool_cgo
+            ;;
+          'cov') # TODO: Implement something.
+            #_go_tool_cov
+            ;;
+          'dist') # TODO: Implement something.
+            #_go_tool_dist
+            ;;
+          'ebnflint') # TODO: Implement something.
+            #_go_tool_ebnflint
+            ;;
+          'fix') # TODO: Implement something.
+            #_go_tool_fix
+            ;;
+          'gotype') # TODO: Implement something.
+            #_go_tool_gotype
+            ;;
+          'nm') # TODO: Implement something.
+            #_go_tool_nm
+            ;;
+          'pack') # TODO: Implement something.
+            #_go_tool_pack
+            ;;
+          'pprof') # TODO: Implement something.
+            #_go_tool_pprof
+            ;;
+          'prof') # TODO: Implement something.
+            #_go_tool_prof
+            ;;
+          'vet') # TODO: Implement something.
+            #_go_tool_vet
+            ;;
+          'yacc') # TODO: Implement something.
+            #_go_tool_yacc
+            ;;
+        esac
+        if [[ "$cur" == -* ]]; then
+          COMPREPLY=($(compgen -W "${COMPREPLY[*]} -h" -- "$cur"))
+        fi
+      fi
+      ;;
+    'version')
+      ;;
+    'vet')
+      if [[ "$cur" == -* ]]; then
+        :
+      else
+        COMPREPLY=(`_go_importpath "$cur"`)
+      fi
+      ;;
+    'help')
+      if [ "$COMP_CWORD" == 2 ]; then
+        COMPREPLY=($(compgen -W "$cmds $addhelp" -- "$cur"))
+      fi
+      ;;
+    *)
+      if [ "$COMP_CWORD" == 1 ]; then
+        COMPREPLY=($(compgen -W "$cmds $other" -- "$cur"))
+      else
+        _filedir
+      fi
+      ;;
+  esac
+}
+
+complete $filenames -F _go go
+
+# vim:ts=2 sw=2 et syn=sh
diff --git a/misc/benchcmp b/misc/benchcmp
index 24382b2..015e7d2 100755
--- a/misc/benchcmp
+++ b/misc/benchcmp
@@ -7,7 +7,7 @@ case "$1" in
 -*)	
 	echo 'usage: benchcmp old.txt new.txt' >&2
 	echo >&2
-	echo 'Each input file should be gotest -bench output.' >&2
+	echo 'Each input file should be go test -test.run=NONE -test.bench=. > [old,new].txt' >&2
 	echo 'Benchcmp compares the first and last for each benchmark.' >&2
 	exit 2
 esac
diff --git a/misc/dashboard/app/app.yaml b/misc/dashboard/app/app.yaml
index 6e19db0..47b7d82 100644
--- a/misc/dashboard/app/app.yaml
+++ b/misc/dashboard/app/app.yaml
@@ -13,8 +13,8 @@ handlers:
   static_dir: static
 - url: /log/.+
   script: _go_app
-- url: /(|commit|packages|result|tag|todo)
+- url: /(|commit|install|packages|result|tag|todo)
   script: _go_app
-- url: /(init|buildtest|key|_ah/queue/go/delay)
+- url: /(init|buildtest|key|_ah/queue/go/delay|install/cron)
   script: _go_app
   login: admin
diff --git a/misc/dashboard/app/build/build.go b/misc/dashboard/app/build/build.go
index c49fa8b..a7b0832 100644
--- a/misc/dashboard/app/build/build.go
+++ b/misc/dashboard/app/build/build.go
@@ -12,6 +12,7 @@ import (
 	"fmt"
 	"io"
 	"io/ioutil"
+	"strconv"
 	"strings"
 	"time"
 
@@ -27,6 +28,10 @@ type Package struct {
 	Name    string
 	Path    string // (empty for the main Go tree)
 	NextNum int    // Num of the next head Commit
+
+	Installs         int      // All-time total install count
+	InstallsByDay    []string `datastore:",noindex"` // "yyyy-mm-dd,n"
+	InstallsThisWeek int      // Rolling weekly count
 }
 
 func (p *Package) String() string {
@@ -41,6 +46,53 @@ func (p *Package) Key(c appengine.Context) *datastore.Key {
 	return datastore.NewKey(c, "Package", key, 0, nil)
 }
 
+const day = time.Hour * 24
+
+// IncrementInstalls increments the total install count and today's install count.
+// Daily install counts for dates older than 30 days are discarded.
+func (p *Package) IncrementInstalls() {
+	c := p.dayCounts()
+	s := []string{}
+	now := time.Now()
+	for i := 0; i < 30; i++ {
+		d := now.Add(-day * time.Duration(i)).Format("2006-01-02")
+		n := c[d]
+		if i == 0 {
+			n++ // increment today's count
+		}
+		if n > 0 { // no need to store zeroes in the datastore
+			s = append(s, fmt.Sprintf("%s,%d", d, n))
+		}
+	}
+	p.InstallsByDay = s
+	p.Installs++
+	p.UpdateInstallsThisWeek()
+}
+
+// UpdateInstallsThisWeek updates the package's InstallsThisWeek field using data
+// from the InstallsByDay list.
+func (p *Package) UpdateInstallsThisWeek() {
+	c := p.dayCounts()
+	n := 0
+	now := time.Now()
+	for i := 0; i < 7; i++ {
+		d := now.Add(-day * time.Duration(i)).Format("2006-01-02")
+		n += c[d]
+	}
+	p.InstallsThisWeek = n
+}
+
+// dayCounts explodes InstallsByDay into a map of dates to install counts.
+func (p *Package) dayCounts() map[string]int {
+	c := make(map[string]int)
+	for _, d := range p.InstallsByDay {
+		p := strings.SplitN(d, ",", 2)
+		n, _ := strconv.Atoi(p[1])
+		c[p[0]] = n
+	}
+	return c
+}
+
 // LastCommit returns the most recent Commit for this Package.
 func (p *Package) LastCommit(c appengine.Context) (*Commit, error) {
 	var commits []*Commit
diff --git a/misc/dashboard/app/build/pkg.go b/misc/dashboard/app/build/pkg.go
new file mode 100644
index 0000000..076fafe
--- /dev/null
+++ b/misc/dashboard/app/build/pkg.go
@@ -0,0 +1,201 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package build
+
+import (
+	"net/http"
+	"regexp"
+	"strings"
+
+	"appengine"
+	"appengine/datastore"
+	"appengine/delay"
+	"appengine/urlfetch"
+)
+
+func init() {
+	http.HandleFunc("/install", installHandler)
+	http.HandleFunc("/install/cron", installCronHandler)
+}
+
+// installHandler serves requests from the go tool to increment the install
+// count for a given package.
+func installHandler(w http.ResponseWriter, r *http.Request) {
+	installLater.Call(appengine.NewContext(r), r.FormValue("packagePath"))
+}
+
+// installCronHandler starts a task to update the weekly install counts for
+// every external package.
+func installCronHandler(w http.ResponseWriter, r *http.Request) {
+	c := appengine.NewContext(r)
+	q := datastore.NewQuery("Package").Filter("Kind=", "external").KeysOnly()
+	for t := q.Run(c); ; {
+		key, err := t.Next(nil)
+		if err == datastore.Done {
+			break
+		} else if err != nil {
+			c.Errorf("%v", err)
+			return
+		}
+		updateWeeklyLater.Call(c, key)
+	}
+}
+
+var (
+	installLater      = delay.Func("install", install)
+	updateWeeklyLater = delay.Func("updateWeekly", updateWeekly)
+)
+
+// install validates the provided package path, increments its install count,
+// and creates the Package record if it doesn't exist.
+func install(c appengine.Context, path string) {
+	if !validPath(c, path) {
+		return
+	}
+	tx := func(c appengine.Context) error {
+		p := &Package{Path: path, Kind: "external"}
+		err := datastore.Get(c, p.Key(c), p)
+		if err != nil && err != datastore.ErrNoSuchEntity {
+			return err
+		}
+		p.IncrementInstalls()
+		_, err = datastore.Put(c, p.Key(c), p)
+		return err
+	}
+	if err := datastore.RunInTransaction(c, tx, nil); err != nil {
+		c.Errorf("install(%q): %v", path, err)
+	}
+}
+
+// updateWeekly updates the weekly count for the specified Package.
+func updateWeekly(c appengine.Context, key *datastore.Key) {
+	tx := func(c appengine.Context) error {
+		p := new(Package)
+		if err := datastore.Get(c, key, p); err != nil {
+			return err
+		}
+		p.UpdateInstallsThisWeek()
+		_, err := datastore.Put(c, key, p)
+		return err
+	}
+	if err := datastore.RunInTransaction(c, tx, nil); err != nil {
+		c.Errorf("updateWeekly: %v", err)
+	}
+}
+
+// validPath validates the specified import path by matching it against the
+// vcsPath regexen and validating its existence by making an HTTP GET request
+// to the remote repository.
+func validPath(c appengine.Context, path string) bool {
+	for _, p := range vcsPaths {
+		if !strings.HasPrefix(path, p.prefix) {
+			continue
+		}
+		m := p.regexp.FindStringSubmatch(path)
+		if m == nil {
+			continue
+		}
+		if p.check == nil {
+			// no check function, so just say OK
+			return true
+		}
+		match := make(map[string]string)
+		for i, name := range p.regexp.SubexpNames() {
+			if name != "" {
+				match[name] = m[i]
+			}
+		}
+		return p.check(c, match)
+	}
+	c.Debugf("validPath(%q): matching vcsPath not found", path)
+	return false
+}
+
+// A vcsPath describes how to convert an import path into a version control
+// system and repository name.
+//
+// This is a cut down and modified version of the data structure from
+// $GOROOT/src/cmd/go/vcs.go.
+type vcsPath struct {
+	prefix string // prefix this description applies to
+	re     string // pattern for import path
+
+	// check should perform an HTTP request to validate the import path
+	check func(c appengine.Context, match map[string]string) bool
+
+	regexp *regexp.Regexp // cached compiled form of re
+}
+
+// vcsPaths lists the known vcs paths.
+//
+// This is a cut down version of the data from $GOROOT/src/cmd/go/vcs.go.
+var vcsPaths = []*vcsPath{
+	// Google Code - new syntax
+	{
+		prefix: "code.google.com/",
+		re:     `^(?P<root>code\.google\.com/p/(?P<project>[a-z0-9\-]+)(\.(?P<subrepo>[a-z0-9\-]+))?)(/[A-Za-z0-9_.\-]+)*$`,
+		check:  googleCodeVCS,
+	},
+
+	// Github
+	{
+		prefix: "github.com/",
+		re:     `^(?P<root>github\.com/[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+)(/[A-Za-z0-9_.\-]+)*$`,
+		check:  checkRoot,
+	},
+
+	// Bitbucket
+	{
+		prefix: "bitbucket.org/",
+		re:     `^(?P<root>bitbucket\.org/(?P<bitname>[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+))(/[A-Za-z0-9_.\-]+)*$`,
+		check:  checkRoot,
+	},
+
+	// Launchpad
+	{
+		prefix: "launchpad.net/",
+		re:     `^(?P<root>launchpad\.net/((?P<project>[A-Za-z0-9_.\-]+)(?P<series>/[A-Za-z0-9_.\-]+)?|~[A-Za-z0-9_.\-]+/(\+junk|[A-Za-z0-9_.\-]+)/[A-Za-z0-9_.\-]+))(/[A-Za-z0-9_.\-]+)*$`,
+		// TODO(adg): write check function for Launchpad
+	},
+}
+
+func init() {
+	// Compile the regular expressions.
+	for i := range vcsPaths {
+		vcsPaths[i].regexp = regexp.MustCompile(vcsPaths[i].re)
+	}
+}
+
+// googleCodeVCS performs an HTTP GET to verify that a Google Code project
+// (and, optionally, a sub-repository) exists.
+func googleCodeVCS(c appengine.Context, match map[string]string) bool {
+	u := "https://code.google.com/p/" + match["project"]
+	if match["subrepo"] != "" {
+		u += "/source/checkout?repo=" + match["subrepo"]
+	}
+	return checkURL(c, u)
+}
+
+// checkRoot performs an HTTP GET to verify that a specific repository root
+// exists (for github and bitbucket both).
+func checkRoot(c appengine.Context, match map[string]string) bool {
+	return checkURL(c, "https://"+match["root"])
+}
+
+// checkURL performs an HTTP GET to the specified URL and returns whether the
+// remote server returned a 2xx response.
+func checkURL(c appengine.Context, u string) bool {
+	client := urlfetch.Client(c)
+	resp, err := client.Get(u)
+	if err != nil {
+		c.Errorf("checkURL(%q): %v", u, err)
+		return false
+	}
+	if resp.StatusCode/100 != 2 {
+		c.Debugf("checkURL(%q): HTTP status: %s", u, resp.Status)
+		return false
+	}
+	return true
+}
diff --git a/misc/dashboard/app/build/ui.html b/misc/dashboard/app/build/ui.html
index 742268f..5b5f4eb 100644
--- a/misc/dashboard/app/build/ui.html
+++ b/misc/dashboard/app/build/ui.html
@@ -118,7 +118,7 @@
           </td>
         {{end}}
         <td class="user" title="{{.User}}">{{shortUser .User}}</td>
-        <td class="time">{{.Time.Time.Format "Mon 02 Jan 15:04"}}</td>
+        <td class="time">{{.Time.Format "Mon 02 Jan 15:04"}}</td>
         <td class="desc" title="{{.Desc}}">{{shortDesc .Desc}}</td>
       </tr>
     {{end}}
@@ -197,7 +197,7 @@
         {{end}}
         {{with $pkg.Commit}}
           <td class="user" title="{{.User}}">{{shortUser .User}}</td>
-          <td class="time">{{.Time.Time.Format "Mon 02 Jan 15:04"}}</td>
+          <td class="time">{{.Time.Format "Mon 02 Jan 15:04"}}</td>
           <td class="desc" title="{{.Desc}}">{{shortDesc .Desc}}</td>
         {{end}}
       </tr>
diff --git a/misc/dashboard/app/cron.yaml b/misc/dashboard/app/cron.yaml
new file mode 100644
index 0000000..b54c24c
--- /dev/null
+++ b/misc/dashboard/app/cron.yaml
@@ -0,0 +1,4 @@
+cron:
+- description: update rolling package install counts
+  url: /install/cron
+  schedule: every 24 hours
diff --git a/misc/dashboard/builder/http.go b/misc/dashboard/builder/http.go
index 3f3bc41..f5a1fcf 100644
--- a/misc/dashboard/builder/http.go
+++ b/misc/dashboard/builder/http.go
@@ -169,7 +169,7 @@ func postCommit(key, pkg string, l *HgLog) error {
 		"PackagePath": pkg,
 		"Hash":        l.Hash,
 		"ParentHash":  l.Parent,
-		"Time":        t.Unix() * 1e6, // in microseconds, yuck!
+		"Time":        t.Format(time.RFC3339),
 		"User":        l.Author,
 		"Desc":        l.Desc,
 	}, nil)
diff --git a/misc/dist/README b/misc/dist/README
deleted file mode 100644
index 06136c4..0000000
--- a/misc/dist/README
+++ /dev/null
@@ -1,4 +0,0 @@
-This directory contains the binary distribution packaging scripts for the
-supported GOOSes.
-
-To build a package, run $GOOS/dist.bash.
diff --git a/misc/dist/bindist.go b/misc/dist/bindist.go
new file mode 100644
index 0000000..f307d9b
--- /dev/null
+++ b/misc/dist/bindist.go
@@ -0,0 +1,304 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This is a tool for packaging binary releases.
+// It supports FreeBSD, Linux, and OS X.
+package main
+
+import (
+	"bytes"
+	"encoding/base64"
+	"errors"
+	"flag"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"log"
+	"mime/multipart"
+	"net/http"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"strings"
+)
+
+var (
+	tag  = flag.String("tag", "weekly", "mercurial tag to check out")
+	repo = flag.String("repo", "https://code.google.com/p/go", "repo URL")
+
+	username, password string // for Google Code upload
+)
+
+const (
+	packageMaker = "/Applications/Utilities/PackageMaker.app/Contents/MacOS/PackageMaker"
+	uploadURL    = "https://go.googlecode.com/files"
+)
+
+var cleanFiles = []string{
+	".hg",
+	".hgtags",
+	".hgignore",
+	"VERSION.cache",
+}
+
+func main() {
+	flag.Usage = func() {
+		fmt.Fprintf(os.Stderr, "usage: %s [flags] targets...\n", os.Args[0])
+		flag.PrintDefaults()
+		os.Exit(2)
+	}
+	flag.Parse()
+	if flag.NArg() == 0 {
+		flag.Usage()
+	}
+	readCredentials()
+	for _, targ := range flag.Args() {
+		p := strings.SplitN(targ, "-", 2)
+		if len(p) != 2 {
+			log.Println("Ignoring unrecognized target:", targ)
+			continue
+		}
+		b := Build{OS: p[0], Arch: p[1]}
+		if err := b.Do(); err != nil {
+			log.Printf("%s: %v", targ, err)
+		}
+	}
+}
+
+type Build struct {
+	OS   string
+	Arch string
+	root string
+}
+
+func (b *Build) Do() error {
+	work, err := ioutil.TempDir("", "bindist")
+	if err != nil {
+		return err
+	}
+	defer os.RemoveAll(work)
+	b.root = filepath.Join(work, "go")
+
+	// Clone Go distribution and update to tag.
+	_, err = b.run(work, "hg", "clone", "-q", *repo, b.root)
+	if err != nil {
+		return err
+	}
+	_, err = b.run(b.root, "hg", "update", *tag)
+	if err != nil {
+		return err
+	}
+
+	// Build.
+	_, err = b.run(filepath.Join(work, "go/src"), "bash", "make.bash")
+	if err != nil {
+		return err
+	}
+
+	// Get version string.
+	version, err := b.run("", filepath.Join(b.root, "bin/go"), "version")
+	if err != nil {
+		return err
+	}
+	v := bytes.SplitN(version, []byte(" "), 4)
+	version = bytes.Join(v[2:], []byte(" "))
+
+	// Write VERSION file.
+	err = ioutil.WriteFile(filepath.Join(b.root, "VERSION"), version, 0644)
+	if err != nil {
+		return err
+	}
+
+	// Clean goroot.
+	for _, name := range cleanFiles {
+		err = os.RemoveAll(filepath.Join(b.root, name))
+		if err != nil {
+			return err
+		}
+	}
+
+	// Create packages.
+	targ := fmt.Sprintf("go.%s.%s-%s", v[2], b.OS, b.Arch)
+	switch b.OS {
+	case "linux", "freebsd":
+		// build tarball
+		targ += ".tar.gz"
+		_, err = b.run("", "tar", "czf", targ, "-C", work, "go")
+	case "darwin":
+		// arrange work so it's laid out as the dest filesystem
+		etc := filepath.Join(b.root, "misc/dist/darwin/etc")
+		_, err = b.run(work, "cp", "-r", etc, ".")
+		if err != nil {
+			return err
+		}
+		localDir := filepath.Join(work, "usr/local")
+		err = os.MkdirAll(localDir, 0744)
+		if err != nil {
+			return err
+		}
+		_, err = b.run(work, "mv", "go", localDir)
+		if err != nil {
+			return err
+		}
+		// build package
+		pm := packageMaker
+		if !exists(pm) {
+			pm = "/Developer" + pm
+			if !exists(pm) {
+				return errors.New("couldn't find PackageMaker")
+			}
+		}
+		targ += ".pkg"
+		scripts := filepath.Join(work, "usr/local/go/misc/dist/darwin/scripts")
+		_, err = b.run("", pm, "-v",
+			"-r", work,
+			"-o", targ,
+			"--scripts", scripts,
+			"--id", "com.googlecode.go",
+			"--title", "Go",
+			"--version", "1.0",
+			"--target", "10.5")
+	}
+	if err == nil && password != "" {
+		err = b.upload(string(v[2]), targ)
+	}
+	return err
+}
+
+func (b *Build) run(dir, name string, args ...string) ([]byte, error) {
+	buf := new(bytes.Buffer)
+	cmd := exec.Command(name, args...)
+	cmd.Stdout = buf
+	cmd.Stderr = buf
+	cmd.Dir = dir
+	cmd.Env = b.env()
+	if err := cmd.Run(); err != nil {
+		fmt.Fprintf(os.Stderr, "%s", buf.Bytes())
+		return nil, fmt.Errorf("%s %s: %v", name, strings.Join(args, " "), err)
+	}
+	return buf.Bytes(), nil
+}
+
+var cleanEnv = []string{
+	"GOARCH",
+	"GOBIN",
+	"GOHOSTARCH",
+	"GOHOSTOS",
+	"GOOS",
+	"GOROOT",
+	"GOROOT_FINAL",
+}
+
+func (b *Build) env() []string {
+	env := os.Environ()
+	for i := 0; i < len(env); i++ {
+		for _, c := range cleanEnv {
+			if strings.HasPrefix(env[i], c+"=") {
+				env = append(env[:i], env[i+1:]...)
+			}
+		}
+	}
+	env = append(env,
+		"GOARCH="+b.Arch,
+		"GOHOSTARCH="+b.Arch,
+		"GOHOSTOS="+b.OS,
+		"GOOS="+b.OS,
+		"GOROOT="+b.root,
+		"GOROOT_FINAL=/usr/local/go",
+	)
+	return env
+}
+
+func (b *Build) upload(version string, filename string) error {
+	// Prepare upload metadata.
+	labels := []string{"Arch-" + b.Arch}
+	os_, arch := b.OS, b.Arch
+	switch b.Arch {
+	case "386":
+		arch = "32-bit"
+	case "amd64":
+		arch = "64-bit"
+	}
+	switch b.OS {
+	case "linux":
+		os_ = "Linux"
+		labels = append(labels, "Type-Archive", "OpSys-Linux")
+	case "freebsd":
+		os_ = "FreeBSD"
+		labels = append(labels, "Type-Archive", "OpSys-FreeBSD")
+	case "darwin":
+		os_ = "Mac OS X"
+		labels = append(labels, "Type-Installer", "OpSys-OSX")
+	}
+	summary := fmt.Sprintf("Go %s %s (%s)", version, os_, arch)
+
+	// Open file to upload.
+	f, err := os.Open(filename)
+	if err != nil {
+		return err
+	}
+	defer f.Close()
+
+	// Prepare multipart payload.
+	body := new(bytes.Buffer)
+	w := multipart.NewWriter(body)
+	if err := w.WriteField("summary", summary); err != nil {
+		return err
+	}
+	for _, l := range labels {
+		if err := w.WriteField("label", l); err != nil {
+			return err
+		}
+	}
+	fw, err := w.CreateFormFile("filename", filename)
+	if err != nil {
+		return err
+	}
+	if _, err = io.Copy(fw, f); err != nil {
+		return err
+	}
+	if err := w.Close(); err != nil {
+		return err
+	}
+
+	// Send the file to Google Code.
+	req, err := http.NewRequest("POST", uploadURL, body)
+	if err != nil {
+		return err
+	}
+	token := fmt.Sprintf("%s:%s", username, password)
+	token = base64.StdEncoding.EncodeToString([]byte(token))
+	req.Header.Set("Authorization", "Basic "+token)
+	req.Header.Set("Content-type", w.FormDataContentType())
+
+	resp, err := http.DefaultTransport.RoundTrip(req)
+	if err != nil {
+		return err
+	}
+	if resp.StatusCode/100 != 2 {
+		fmt.Fprintln(os.Stderr, "upload failed")
+		defer resp.Body.Close()
+		io.Copy(os.Stderr, resp.Body)
+		return fmt.Errorf("upload: %s", resp.Status)
+	}
+	return nil
+}
+
+func exists(path string) bool {
+	_, err := os.Stat(path)
+	return err == nil
+}
+
+func readCredentials() {
+	name := filepath.Join(os.Getenv("HOME"), ".gobuildkey")
+	c, err := ioutil.ReadFile(name)
+	if err != nil {
+		log.Println("readCredentials:", err)
+		return
+	}
+	v := bytes.Split(c, []byte("\n"))
+	if len(v) >= 3 {
+		username, password = string(v[1]), string(v[2])
+	}
+}
diff --git a/misc/dist/darwin/README b/misc/dist/darwin/README
deleted file mode 100644
index 25aeb8c..0000000
--- a/misc/dist/darwin/README
+++ /dev/null
@@ -1,3 +0,0 @@
-Use dist.bash to construct a package file (Go.pkg) for installation on OS X.
-
-This script depends on PackageMaker (Developer Tools).
diff --git a/misc/dist/darwin/dist.bash b/misc/dist/darwin/dist.bash
deleted file mode 100755
index adade2e..0000000
--- a/misc/dist/darwin/dist.bash
+++ /dev/null
@@ -1,69 +0,0 @@
-#!/bin/bash
-# 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.
-
-set -e
-
-if ! test -f ../../../src/all.bash; then
-	echo >&2 "dist.bash must be run from $GOROOT/misc/dist/darwin"
-	exit 1
-fi
-
-echo >&2 "Locating PackageMaker..."
-PM=/Applications/Utilities/PackageMaker.app/Contents/MacOS/PackageMaker
-if [ ! -x $PM ]; then
-	PM=/Developer$PM
-	if [ ! -x $PM ]; then
-		echo >&2 "could not find PackageMaker; aborting"
-		exit 1
-	fi
-fi
-echo >&2 "  Found: $PM"
-
-BUILD=/tmp/go.build.tmp
-ROOT=`hg root`
-export GOROOT=$BUILD/root/usr/local/go
-export GOROOT_FINAL=/usr/local/go
-
-echo >&2 "Removing old images"
-rm -f *.pkg *.dmg
-
-echo >&2 "Preparing temporary directory"
-rm -rf $BUILD
-mkdir -p $BUILD
-trap "rm -rf $BUILD" 0
-
-echo >&2 "Copying go source distribution"
-mkdir -p $BUILD/root/usr/local
-cp -r $ROOT $GOROOT
-cp -r etc $BUILD/root/etc
-
-pushd $GOROOT > /dev/null
-
-echo >&2 "Detecting version..."
-pushd src > /dev/null
-./make.bash --dist-tool > /dev/null
-../bin/tool/dist version > /dev/null
-popd > /dev/null
-mv VERSION.cache VERSION
-VERSION="$(cat VERSION | awk '{ print $1 }')"
-echo >&2 "  Version: $VERSION"
-
-echo >&2 "Pruning Mercurial metadata"
-rm -rf .hg .hgignore .hgtags
-
-echo >&2 "Building Go"
-pushd src
-./all.bash 2>&1 | sed "s/^/  /" >&2
-popd > /dev/null
-
-popd > /dev/null
-
-echo >&2 "Building package"
-$PM -v -r $BUILD/root -o "go.darwin.$VERSION.pkg" \
-	--scripts scripts \
-	--id com.googlecode.go \
-	--title Go \
-	--version "0.1" \
-	--target "10.5"
diff --git a/misc/dist/linux/dist.bash b/misc/dist/linux/dist.bash
deleted file mode 100755
index 9270782..0000000
--- a/misc/dist/linux/dist.bash
+++ /dev/null
@@ -1,55 +0,0 @@
-#!/usr/bin/env bash
-# Copyright 2012 The Go Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the LICENSE file.
-
-set -e
-
-TAG=$1
-if [ "$TAG" == "" ]; then
-	echo >&2 'usage: dist.bash <tag>'
-	exit 2
-fi
-
-GOOS=${GOOS:-linux}
-GOARCH=${GOARCH:-amd64}
-
-ROOT=/tmp/godist.linux.$GOARCH
-rm -rf $ROOT
-mkdir -p $ROOT
-pushd $ROOT>/dev/null
-
-# clone Go distribution
-echo "Preparing new GOROOT"
-hg clone -q https://code.google.com/p/go go
-pushd go > /dev/null
-hg update $TAG
-
-# get version
-pushd src > /dev/null
-echo "Building dist tool to get VERSION"
-./make.bash --dist-tool 2>&1 | sed 's/^/  /' >&2
-../bin/tool/dist version > ../VERSION
-popd > /dev/null
-VERSION="$(cat VERSION | awk '{ print $1 }')"
-echo "  Version: $VERSION"
-
-# remove mercurial stuff
-rm -rf .hg*
-
-# build Go
-echo "Building Go"
-unset GOROOT
-export GOOS
-export GOARCH
-export GOROOT_FINAL=/usr/local/go
-pushd src > /dev/null
-./all.bash 2>&1 | sed 's/^/  /' >&2
-popd > /dev/null
-popd > /dev/null
-
-# tar it up
-DEST=go.$VERSION.$GOOS-$GOARCH.tar.gz
-echo "Writing tarball: $ROOT/$DEST"
-tar czf $DEST go
-popd > /dev/null
diff --git a/misc/pprof b/misc/pprof
index 777a45c..2fe5650 100755
--- a/misc/pprof
+++ b/misc/pprof
@@ -1,7 +1,7 @@
 #! /usr/bin/env perl
 
 # This is a copy of http://google-perftools.googlecode.com/svn/trunk/src/pprof
-# with local modifications to handle generation of SVG images and 
+# with local modifications to handle generation of SVG images and
 # the Go-style pprof paths.  These modifications will probably filter
 # back into the official source before long.
 # It's convenient to have a copy here because we need just the one
@@ -9,11 +9,11 @@
 
 # Copyright (c) 1998-2007, Google Inc.
 # All rights reserved.
-# 
+#
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions are
 # met:
-# 
+#
 #     * Redistributions of source code must retain the above copyright
 # notice, this list of conditions and the following disclaimer.
 #     * Redistributions in binary form must reproduce the above
@@ -23,7 +23,7 @@
 #     * Neither the name of Google Inc. nor the names of its
 # contributors may be used to endorse or promote products derived from
 # this software without specific prior written permission.
-# 
+#
 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -1234,6 +1234,13 @@ sub Disassemble {
   my $cmd = sprintf("$objdump -C -d -l --no-show-raw-insn " .
                     "--start-address=0x$start_addr " .
                     "--stop-address=0x$end_addr $prog");
+
+  if (system("$objdump --help >/dev/null 2>&1") != 0) {
+    # objdump must not exist.  Fall back to go tool objdump.
+    $objdump = "go tool objdump";
+    $cmd = "$objdump $prog 0x$start_addr 0x$end_addr";
+  }
+
   open(OBJDUMP, "$cmd |") || error("$objdump: $!\n");
   my @result = ();
   my $filename = "";
@@ -1305,10 +1312,10 @@ sub PrintListing {
   my $cumulative = shift;
   my $list_opts = shift;
   my $html = shift;
-  
+
   my $output = \*STDOUT;
   my $fname = "";
-  
+
 
   if ($html) {
     # Arrange to write the output to a temporary file
@@ -1323,7 +1330,7 @@ sub PrintListing {
     printf $output ("<div class=\"legend\">%s<br>Total: %s %s</div>\n",
                     $main::prog, Unparse($total), Units());
   }
- 
+
   my $listed = 0;
   foreach my $lib (@{$libs}) {
     my $symbol_table = GetProcedureBoundaries($lib->[0], $list_opts);
@@ -2221,7 +2228,7 @@ function handleMouseWheel(evt) {
 		z = 0.1;
 	if(z > 10.0)
 		z = 10.0;
-		
+
 	var g = svgDoc.getElementById("viewport");
 
 	var p = getEventPoint(evt);
@@ -4391,6 +4398,12 @@ sub MapToSymbols {
     $cmd = "$addr2line --demangle -f -C -e $image";
   }
 
+  if (system("$addr2line --help >/dev/null 2>&1") != 0) {
+    # addr2line must not exist.  Fall back to go tool addr2line.
+    $addr2line = "go tool addr2line";
+    $cmd = "$addr2line $image";
+  }
+
   # If "addr2line" isn't installed on the system at all, just use
   # nm to get what info we can (function names, but not line numbers).
   if (system("$addr2line --help >/dev/null 2>&1") != 0) {
@@ -4434,7 +4447,7 @@ sub MapToSymbols {
   if ($debug) {
     print("----\n");
     system("cat $main::tmpfile_sym");
-    print("----\n");
+    print("---- $cmd\n");
     system("$cmd <$main::tmpfile_sym");
     print("----\n");
   }
@@ -4544,7 +4557,7 @@ sub ShortFunctionName {
 # Trim overly long symbols found in disassembler output
 sub CleanDisassembly {
   my $d = shift;
-  while ($d =~ s/(?<!\.)\([^()%]*\)(\s*const)?//g) { } # Argument types, not (%rax)
+  while ($d =~ s/(?<!\.)\([^()%A-Z]*\)(\s*const)?//g) { } # Argument types, not (%rax)
   while ($d =~ s/(\w+)<[^<>]*>/$1/g)  { }       # Remove template arguments
   return $d;
 }
@@ -4625,7 +4638,7 @@ sub ConfigureTool {
     my $dirname = $`;    # this is everything up to and including the last slash
     if (-x "$dirname$tool") {
       $path = "$dirname$tool";
-    } else { 
+    } else {
       $path = $tool;
     }
   }
diff --git a/misc/xcode/3/README b/misc/xcode/3/README
new file mode 100644
index 0000000..c4cb915
--- /dev/null
+++ b/misc/xcode/3/README
@@ -0,0 +1,3 @@
+This directory contains files for Go syntax highlighting in Xcode 3.x.
+See the comments go.pbfilespec and go.xclangspec for installation
+instructions.
diff --git a/misc/xcode/go.pbfilespec b/misc/xcode/3/go.pbfilespec
similarity index 100%
rename from misc/xcode/go.pbfilespec
rename to misc/xcode/3/go.pbfilespec
diff --git a/misc/xcode/go.xclangspec b/misc/xcode/3/go.xclangspec
similarity index 100%
rename from misc/xcode/go.xclangspec
rename to misc/xcode/3/go.xclangspec
diff --git a/misc/zsh/go b/misc/zsh/go
index f17763d..23afa96 100644
--- a/misc/zsh/go
+++ b/misc/zsh/go
@@ -12,3 +12,140 @@ compctl -g "*.go" gofmt
 
 # gccgo
 compctl -g "*.go" gccgo
+
+# go tool
+__go_tool_complete() {
+  typeset -a commands build_flags
+  commands+=(
+    'build[compile packages and dependencies]'
+    'clean[remove object files]'
+    'doc[run godoc on package sources]'
+    'fix[run go tool fix on packages]'
+    'fmt[run gofmt on package sources]'
+    'get[download and install packages and dependencies]'
+    'help[display help]'
+    'install[compile and install packages and dependencies]'
+    'list[list packages]'
+    'run[compile and run Go program]'
+    'test[test packages]'
+    'tool[run specified go tool]'
+    'version[print Go version]'
+    'vet[run go tool vet on packages]'
+  )
+  if (( CURRENT == 2 )); then
+    # explain go commands
+    _values 'go tool commands' ${commands[@]}
+    return
+  fi
+  build_flags=(
+    '-a[force reinstallation of packages that are already up-to-date]'
+    '-n[print the commands but do not run them]'
+    "-p[number of parallel builds]:number"
+    '-x[print the commands]'
+    "-work[print temporary directory name and keep it]"
+    "-gcflags[flags for 5g/6g/8g]:flags"
+    "-ldflags[flags for 5l/6l/8l]:flags"
+    "-gccgoflags[flags for gccgo]:flags"
+  )
+  __go_list() {
+      local expl importpaths
+      declare -a importpaths
+      importpaths=($(go list ${words[$CURRENT]}... 2>/dev/null))
+      _wanted importpaths expl 'import paths' compadd "$@" - "${importpaths[@]}"
+  }
+  case ${words[2]} in
+  clean|doc)
+      _arguments -s -w : '*:importpaths:__go_list'
+      ;;
+  fix|fmt|list|vet)
+      _alternative ':importpaths:__go_list' ':files:_path_files -g "*.go"'
+      ;;
+  install)
+      _arguments -s -w : ${build_flags[@]} \
+        "-v[show package names]" \
+	'*:importpaths:__go_list'
+      ;;
+  get)
+      _arguments -s -w : \
+        ${build_flags[@]}
+      ;;
+  build)
+      _arguments -s -w : \
+        ${build_flags[@]} \
+        "-v[show package names]" \
+        "-o[output file]:file:_files" \
+        "*:args:{ _alternative ':importpaths:__go_list' ':files:_path_files -g \"*.go\"' }"
+      ;;
+  test)
+      _arguments -s -w : \
+        ${build_flags[@]} \
+        "-c[do not run, compile the test binary]" \
+        "-i[do not run, install dependencies]" \
+        "-v[print test output]" \
+        "-x[print the commands]" \
+        "-short[use short mode]" \
+        "-parallel[number of parallel tests]:number" \
+        "-cpu[values of GOMAXPROCS to use]:number list" \
+        "-run[run tests and examples matching regexp]:regexp" \
+        "-bench[run benchmarks matching regexp]:regexp" \
+        "-benchtime[run each benchmark during n seconds]:duration" \
+        "-timeout[kill test after that duration]:duration" \
+        "-cpuprofile[write CPU profile to file]:file:_files" \
+        "-memprofile[write heap profile to file]:file:_files" \
+        "-memprofilerate[set heap profiling rate]:number" \
+        "*:args:{ _alternative ':importpaths:__go_list' ':files:_path_files -g \"*.go\"' }"
+      ;;
+  help)
+      _values "${commands[@]}" \
+        'gopath[GOPATH environment variable]' \
+        'importpath[description of import paths]' \
+        'remote[remote import path syntax]' \
+        'testflag[description of testing flags]' \
+        'testfunc[description of testing functions]'
+      ;;
+  run)
+      _arguments -s -w : \
+          ${build_flags[@]} \
+          '*:file:_path_files -g "*.go"'
+      ;;
+  tool)
+      if (( CURRENT == 3 )); then
+          _values "go tool" $(go tool)
+          return
+      fi
+      case ${words[3]} in
+      [568]g)
+          _arguments -s -w : \
+              '-I[search for packages in DIR]:includes:_path_files -/' \
+              '-L[show full path in file:line prints]' \
+              '-S[print the assembly language]' \
+              '-V[print the compiler version]' \
+              '-e[no limit on number of errors printed]' \
+              '-h[panic on an error]' \
+              '-l[disable inlining]' \
+              '-m[print optimization decisions]' \
+              '-o[file specify output file]:file' \
+              '-p[assumed import path for this code]:importpath' \
+              '-u[disable package unsafe]' \
+              "*:file:_files -g '*.go'"
+          ;;
+      [568]l)
+          local O=${words[3]%l}
+          _arguments -s -w : \
+              '-o[file specify output file]:file' \
+              '-L[search for packages in DIR]:includes:_path_files -/' \
+              "*:file:_files -g '*.[ao$O]'"
+          ;;
+      dist)
+          _values "dist tool" banner bootstrap clean env install version
+          ;;
+      *)
+          # use files by default
+          _files
+          ;;
+      esac
+      ;;
+  esac
+}
+
+compdef __go_tool_complete go
diff --git a/src/cmd/5g/doc.go b/src/cmd/5g/doc.go
index e86013b..5a4a772 100644
--- a/src/cmd/5g/doc.go
+++ b/src/cmd/5g/doc.go
@@ -9,7 +9,5 @@ The $GOARCH for these tools is arm.
 
 It reads .go files and outputs .5 files. The flags are documented in ../gc/doc.go.
 
-There is no instruction optimizer, so the -N flag is a no-op.
-
 */
 package documentation
diff --git a/src/cmd/6a/lex.c b/src/cmd/6a/lex.c
index 1a8e5ad..e013bec 100644
--- a/src/cmd/6a/lex.c
+++ b/src/cmd/6a/lex.c
@@ -396,6 +396,7 @@ struct
 	"IMULB",	LTYPEI,	AIMULB,
 	"IMULL",	LTYPEI,	AIMULL,
 	"IMULQ",	LTYPEI,	AIMULQ,
+	"IMUL3Q",	LTYPEX,	AIMUL3Q,
 	"IMULW",	LTYPEI,	AIMULW,
 	"INB",		LTYPE0,	AINB,
 	"INL",		LTYPE0,	AINL,
diff --git a/src/cmd/6l/6.out.h b/src/cmd/6l/6.out.h
index 559cdc7..8499159 100644
--- a/src/cmd/6l/6.out.h
+++ b/src/cmd/6l/6.out.h
@@ -735,6 +735,7 @@ enum	as
 	AMODE,
 	ACRC32B,
 	ACRC32Q,
+	AIMUL3Q,
 
 	ALAST
 };
diff --git a/src/cmd/6l/optab.c b/src/cmd/6l/optab.c
index 2308e0d..5746ded 100644
--- a/src/cmd/6l/optab.c
+++ b/src/cmd/6l/optab.c
@@ -267,6 +267,11 @@ uchar	yimul[] =
 	Yml,	Yrl,	Zm_r,	2,
 	0
 };
+uchar	yimul3[] =
+{
+	Yml,	Yrl,	Zibm_r,	1,
+	0
+};
 uchar	ybyte[] =
 {
 	Yi64,	Ynone,	Zbyte,	1,
@@ -772,6 +777,7 @@ Optab optab[] =
 	{ AIMULL,	yimul,	Px, 0xf7,(05),0x6b,0x69,Pm,0xaf },
 	{ AIMULQ,	yimul,	Pw, 0xf7,(05),0x6b,0x69,Pm,0xaf },
 	{ AIMULW,	yimul,	Pe, 0xf7,(05),0x6b,0x69,Pm,0xaf },
+	{ AIMUL3Q,	yimul3,	Pw, 0x6b },
 	{ AINB,		yin,	Pb, 0xe4,0xec },
 	{ AINCB,	yincb,	Pb, 0xfe,(00) },
 	{ AINCL,	yincl,	Px, 0xff,(00) },
diff --git a/src/cmd/8g/doc.go b/src/cmd/8g/doc.go
index 2d9ff9a..6d678ea 100644
--- a/src/cmd/8g/doc.go
+++ b/src/cmd/8g/doc.go
@@ -9,7 +9,5 @@ The $GOARCH for these tools is 386.
 
 It reads .go files and outputs .8 files. The flags are documented in ../gc/doc.go.
 
-There is no instruction optimizer, so the -N flag is a no-op.
-
 */
 package documentation
diff --git a/src/cmd/addr2line/main.c b/src/cmd/addr2line/main.c
new file mode 100644
index 0000000..6b2fe5d
--- /dev/null
+++ b/src/cmd/addr2line/main.c
@@ -0,0 +1,68 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+ * addr2line simulation - only enough to make pprof work on Macs
+ */
+
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include <mach.h>
+
+void
+usage(void)
+{
+	fprint(2, "usage: addr2line binary\n");
+	fprint(2, "reads addresses from standard input and writes two lines for each:\n");
+	fprint(2, "\tfunction name\n");
+	fprint(2, "\tfile:line\n");
+	exits("usage");
+}
+
+void
+main(int argc, char **argv)
+{
+	int fd;
+	char *p;
+	uvlong pc;
+	Symbol s;
+	Fhdr fhdr;
+	Biobuf bin, bout;
+	char file[1024];
+
+	ARGBEGIN{
+	default:
+		usage();
+	}ARGEND
+
+	if(argc != 1)
+		usage();
+
+	fd = open(argv[0], OREAD);
+	if(fd < 0)
+		sysfatal("open %s: %r", argv[0]);
+	if(crackhdr(fd, &fhdr) <= 0)
+		sysfatal("crackhdr: %r");
+	machbytype(fhdr.type);
+	if(syminit(fd, &fhdr) <= 0)
+		sysfatal("syminit: %r");
+
+	Binit(&bin, 0, OREAD);
+	Binit(&bout, 1, OWRITE);
+	for(;;) {
+		p = Brdline(&bin, '\n');
+		if(p == nil)
+			break;
+		p[Blinelen(&bin)-1] = '\0';
+		pc = strtoull(p, 0, 16);
+		if(!findsym(pc, CTEXT, &s))
+			s.name = "??";
+		if(!fileline(file, sizeof file, pc))
+			strcpy(file, "??:0");
+		Bprint(&bout, "%s\n%s\n", s.name, file);
+	}
+	Bflush(&bout);
+	exits(0);
+}
diff --git a/src/cmd/api/goapi.go b/src/cmd/api/goapi.go
index ee0f923..fe9c862 100644
--- a/src/cmd/api/goapi.go
+++ b/src/cmd/api/goapi.go
@@ -74,16 +74,10 @@ func main() {
 		pkgs = strings.Fields(string(stds))
 	}
 
-	tree, _, err := build.FindTree("os") // some known package
-	if err != nil {
-		log.Fatalf("failed to find tree: %v", err)
-	}
-
 	var featureCtx = make(map[string]map[string]bool) // feature -> context name -> true
 	for _, context := range contexts {
 		w := NewWalker()
 		w.context = context
-		w.tree = tree
 
 		for _, pkg := range pkgs {
 			w.wantedPkg[pkg] = true
@@ -95,7 +89,7 @@ func main() {
 				strings.HasPrefix(pkg, "old/") {
 				continue
 			}
-			if !tree.HasSrc(pkg) {
+			if fi, err := os.Stat(filepath.Join(w.root, pkg)); err != nil || !fi.IsDir() {
 				log.Fatalf("no source in tree for package %q", pkg)
 			}
 			w.WalkPackage(pkg)
@@ -165,7 +159,7 @@ type pkgSymbol struct {
 
 type Walker struct {
 	context         *build.Context
-	tree            *build.Tree
+	root            string
 	fset            *token.FileSet
 	scope           []string
 	features        map[string]bool // set
@@ -191,6 +185,7 @@ func NewWalker() *Walker {
 		selectorFullPkg: make(map[string]string),
 		wantedPkg:       make(map[string]bool),
 		prevConstType:   make(map[pkgSymbol]string),
+		root:            filepath.Join(build.Default.GOROOT, "src/pkg"),
 	}
 }
 
@@ -252,15 +247,13 @@ func (w *Walker) WalkPackage(name string) {
 	defer func() {
 		w.packageState[name] = loaded
 	}()
-	dir := filepath.Join(w.tree.SrcDir(), filepath.FromSlash(name))
+	dir := filepath.Join(w.root, filepath.FromSlash(name))
 
-	var info *build.DirInfo
-	var err error
-	if ctx := w.context; ctx != nil {
-		info, err = ctx.ScanDir(dir)
-	} else {
-		info, err = build.ScanDir(dir)
+	ctxt := w.context
+	if ctxt == nil {
+		ctxt = &build.Default
 	}
+	info, err := ctxt.ImportDir(dir, 0)
 	if err != nil {
 		if strings.Contains(err.Error(), "no Go source files") {
 			return
diff --git a/src/cmd/api/goapi_test.go b/src/cmd/api/goapi_test.go
index dbbec46..c7cc601 100644
--- a/src/cmd/api/goapi_test.go
+++ b/src/cmd/api/goapi_test.go
@@ -7,7 +7,6 @@ package main
 import (
 	"flag"
 	"fmt"
-	"go/build"
 	"io/ioutil"
 	"os"
 	"path/filepath"
@@ -36,7 +35,7 @@ func TestGolden(t *testing.T) {
 		w := NewWalker()
 		w.wantedPkg[fi.Name()] = true
 
-		w.tree = &build.Tree{Path: "testdata", Goroot: true}
+		w.root = "testdata/src/pkg"
 		goldenFile := filepath.Join("testdata", "src", "pkg", fi.Name(), "golden.txt")
 		w.WalkPackage(fi.Name())
 
diff --git a/src/cmd/cc/cc.h b/src/cmd/cc/cc.h
index f463236..4c527a2 100644
--- a/src/cmd/cc/cc.h
+++ b/src/cmd/cc/cc.h
@@ -517,8 +517,8 @@ EXTERN	int	thechar;
 EXTERN	char*	thestring;
 EXTERN	Type*	thisfn;
 EXTERN	int32	thunk;
-EXTERN	Type*	types[NTYPE];
-EXTERN	Type*	fntypes[NTYPE];
+EXTERN	Type*	types[NALLTYPES];
+EXTERN	Type*	fntypes[NALLTYPES];
 EXTERN	Node*	initlist;
 EXTERN	Term	term[NTERM];
 EXTERN	int	nterm;
diff --git a/src/cmd/cc/com64.c b/src/cmd/cc/com64.c
index fb7a3f7..f46fedc 100644
--- a/src/cmd/cc/com64.c
+++ b/src/cmd/cc/com64.c
@@ -96,7 +96,7 @@ Node*	nodmmv;
 
 Node*	nodvasop;
 
-char	etconv[NTYPE];	/* for _vasop */
+char	etconv[NALLTYPES];	/* for _vasop */
 Init	initetconv[] =
 {
 	TCHAR,		1,	0,
diff --git a/src/cmd/cc/funct.c b/src/cmd/cc/funct.c
index 99477b2..0571519 100644
--- a/src/cmd/cc/funct.c
+++ b/src/cmd/cc/funct.c
@@ -46,7 +46,7 @@ struct	Gtab
 };
 
 Ftab	ftabinit[OEND];
-Gtab	gtabinit[NTYPE];
+Gtab	gtabinit[NALLTYPES];
 
 int
 isfunct(Node *n)
@@ -350,7 +350,7 @@ bad:
 	diag(Z, "dclfunct bad %T %s\n", t, s->name);
 }
 
-Gtab	gtabinit[NTYPE] =
+Gtab	gtabinit[NALLTYPES] =
 {
 	TCHAR,		"c",
 	TUCHAR,		"uc",
diff --git a/src/cmd/cc/sub.c b/src/cmd/cc/sub.c
index e5992e2..72d671b 100644
--- a/src/cmd/cc/sub.c
+++ b/src/cmd/cc/sub.c
@@ -156,7 +156,10 @@ typ(int et, Type *d)
 	t->link = d;
 	t->down = T;
 	t->sym = S;
-	t->width = ewidth[et];
+	if(et < NTYPE)
+		t->width = ewidth[et];
+	else
+		t->width = -1; // for TDOT or TOLD in prototype
 	t->offset = 0;
 	t->shift = 0;
 	t->nbits = 0;
@@ -1535,92 +1538,92 @@ uchar	logrel[12] =
 	OEQ, ONE, OLS, OLS, OLO, OLO, OHS, OHS, OHI, OHI,
 };
 
-uchar	typei[NTYPE];
+uchar	typei[NALLTYPES];
 int	typeiinit[] =
 {
 	TCHAR, TUCHAR, TSHORT, TUSHORT, TINT, TUINT, TLONG, TULONG, TVLONG, TUVLONG, -1,
 };
-uchar	typeu[NTYPE];
+uchar	typeu[NALLTYPES];
 int	typeuinit[] =
 {
 	TUCHAR, TUSHORT, TUINT, TULONG, TUVLONG, TIND, -1,
 };
 
-uchar	typesuv[NTYPE];
+uchar	typesuv[NALLTYPES];
 int	typesuvinit[] =
 {
 	TVLONG, TUVLONG, TSTRUCT, TUNION, -1,
 };
 
-uchar	typeilp[NTYPE];
+uchar	typeilp[NALLTYPES];
 int	typeilpinit[] =
 {
 	TINT, TUINT, TLONG, TULONG, TIND, -1
 };
 
-uchar	typechl[NTYPE];
-uchar	typechlv[NTYPE];
-uchar	typechlvp[NTYPE];
+uchar	typechl[NALLTYPES];
+uchar	typechlv[NALLTYPES];
+uchar	typechlvp[NALLTYPES];
 int	typechlinit[] =
 {
 	TCHAR, TUCHAR, TSHORT, TUSHORT, TINT, TUINT, TLONG, TULONG, -1,
 };
 
-uchar	typechlp[NTYPE];
+uchar	typechlp[NALLTYPES];
 int	typechlpinit[] =
 {
 	TCHAR, TUCHAR, TSHORT, TUSHORT, TINT, TUINT, TLONG, TULONG, TIND, -1,
 };
 
-uchar	typechlpfd[NTYPE];
+uchar	typechlpfd[NALLTYPES];
 int	typechlpfdinit[] =
 {
 	TCHAR, TUCHAR, TSHORT, TUSHORT, TINT, TUINT, TLONG, TULONG, TFLOAT, TDOUBLE, TIND, -1,
 };
 
-uchar	typec[NTYPE];
+uchar	typec[NALLTYPES];
 int	typecinit[] =
 {
 	TCHAR, TUCHAR, -1
 };
 
-uchar	typeh[NTYPE];
+uchar	typeh[NALLTYPES];
 int	typehinit[] =
 {
 	TSHORT, TUSHORT, -1,
 };
 
-uchar	typeil[NTYPE];
+uchar	typeil[NALLTYPES];
 int	typeilinit[] =
 {
 	TINT, TUINT, TLONG, TULONG, -1,
 };
 
-uchar	typev[NTYPE];
+uchar	typev[NALLTYPES];
 int	typevinit[] =
 {
 	TVLONG,	TUVLONG, -1,
 };
 
-uchar	typefd[NTYPE];
+uchar	typefd[NALLTYPES];
 int	typefdinit[] =
 {
 	TFLOAT, TDOUBLE, -1,
 };
 
-uchar	typeaf[NTYPE];
+uchar	typeaf[NALLTYPES];
 int	typeafinit[] =
 {
 	TFUNC, TARRAY, -1,
 };
 
-uchar	typesu[NTYPE];
+uchar	typesu[NALLTYPES];
 int	typesuinit[] =
 {
 	TSTRUCT, TUNION, -1,
 };
 
-int32	tasign[NTYPE];
+int32	tasign[NALLTYPES];
 Init	tasigninit[] =
 {
 	TCHAR,		BNUMBER,	0,
@@ -1641,7 +1644,7 @@ Init	tasigninit[] =
 	-1,		0,		0,
 };
 
-int32	tasadd[NTYPE];
+int32	tasadd[NALLTYPES];
 Init	tasaddinit[] =
 {
 	TCHAR,		BNUMBER,	0,
@@ -1660,7 +1663,7 @@ Init	tasaddinit[] =
 	-1,		0,		0,
 };
 
-int32	tcast[NTYPE];
+int32	tcast[NALLTYPES];
 Init	tcastinit[] =
 {
 	TCHAR,		BNUMBER|BIND|BVOID,	0,
@@ -1682,7 +1685,7 @@ Init	tcastinit[] =
 	-1,		0,			0,
 };
 
-int32	tadd[NTYPE];
+int32	tadd[NALLTYPES];
 Init	taddinit[] =
 {
 	TCHAR,		BNUMBER|BIND,	0,
@@ -1701,7 +1704,7 @@ Init	taddinit[] =
 	-1,		0,		0,
 };
 
-int32	tsub[NTYPE];
+int32	tsub[NALLTYPES];
 Init	tsubinit[] =
 {
 	TCHAR,		BNUMBER,	0,
@@ -1720,7 +1723,7 @@ Init	tsubinit[] =
 	-1,		0,		0,
 };
 
-int32	tmul[NTYPE];
+int32	tmul[NALLTYPES];
 Init	tmulinit[] =
 {
 	TCHAR,		BNUMBER,	0,
@@ -1738,7 +1741,7 @@ Init	tmulinit[] =
 	-1,		0,		0,
 };
 
-int32	tand[NTYPE];
+int32	tand[NALLTYPES];
 Init	tandinit[] =
 {
 	TCHAR,		BINTEGER,	0,
@@ -1754,7 +1757,7 @@ Init	tandinit[] =
 	-1,		0,		0,
 };
 
-int32	trel[NTYPE];
+int32	trel[NALLTYPES];
 Init	trelinit[] =
 {
 	TCHAR,		BNUMBER,	0,
diff --git a/src/cmd/cgo/doc.go b/src/cmd/cgo/doc.go
index 83f1ba4..f6a14ae 100644
--- a/src/cmd/cgo/doc.go
+++ b/src/cmd/cgo/doc.go
@@ -6,7 +6,8 @@
 
 Cgo enables the creation of Go packages that call C code.
 
-Usage: go tool cgo [compiler options] file.go
+Usage:
+	go tool cgo [compiler options] file.go
 
 The compiler options are passed through uninterpreted when
 invoking gcc to compile the C parts of the package.
diff --git a/src/cmd/cgo/util.go b/src/cmd/cgo/util.go
index cd7cde2..a0f2166 100644
--- a/src/cmd/cgo/util.go
+++ b/src/cmd/cgo/util.go
@@ -36,7 +36,6 @@ func run(stdin []byte, argv []string) (stdout, stderr []byte, ok bool) {
 	if err != nil {
 		fatalf("%s", err)
 	}
-	defer p.Release()
 	r0.Close()
 	w1.Close()
 	w2.Close()
diff --git a/src/cmd/cov/doc.go b/src/cmd/cov/doc.go
index edeb915..a5fc003 100644
--- a/src/cmd/cov/doc.go
+++ b/src/cmd/cov/doc.go
@@ -6,12 +6,14 @@
 
 Cov is a rudimentary code coverage tool.
 
+Usage:
+	go tool cov [-lsv] [-g substring] [-m minlines] [6.out args]
+
 Given a command to run, it runs the command while tracking which
 sections of code have been executed.  When the command finishes,
 cov prints the line numbers of sections of code in the binary that
 were not executed.   With no arguments it assumes the command "6.out".
 
-Usage: go tool cov [-lsv] [-g substring] [-m minlines] [6.out args]
 
 The options are:
 
diff --git a/src/cmd/dist/build.c b/src/cmd/dist/build.c
index 1b68883..a40853f 100644
--- a/src/cmd/dist/build.c
+++ b/src/cmd/dist/build.c
@@ -59,7 +59,7 @@ int
 find(char *p, char **l, int n)
 {
 	int i;
-	
+
 	for(i=0; i<n; i++)
 		if(streq(p, l[i]))
 			return i;
@@ -73,7 +73,7 @@ init(void)
 	char *p;
 	int i;
 	Buf b;
-	
+
 	binit(&b);
 
 	xgetenv(&b, "GOROOT");
@@ -126,7 +126,7 @@ init(void)
 	xsetenv("GOROOT", goroot);
 	xsetenv("GOARCH", goarch);
 	xsetenv("GOOS", goos);
-	
+
 	// Make the environment more predictable.
 	xsetenv("LANG", "C");
 	xsetenv("LANGUAGE", "en_US.UTF8");
@@ -170,13 +170,13 @@ findgoversion(void)
 	int i, nrev;
 	Buf b, path, bmore, branch;
 	Vec tags;
-	
+
 	binit(&b);
 	binit(&path);
 	binit(&bmore);
 	binit(&branch);
 	vinit(&tags);
-	
+
 	// The $GOROOT/VERSION file takes priority, for distributions
 	// without the Mercurial repo.
 	bpathf(&path, "%s/VERSION", goroot);
@@ -232,14 +232,14 @@ findgoversion(void)
 		bprintf(&b, "branch.%s", bstr(&branch));
 		tag = btake(&b);
 	}
-	
+
 	if(rev[0]) {
 		// Tag is before the revision we're building.
 		// Add extra information.
 		run(&bmore, goroot, CheckExit, "hg", "log", "--template", " +{node|short}", "-r", rev, nil);
 		chomp(&bmore);
 	}
-	
+
 	bprintf(&b, "%s", tag);
 	if(bmore.len > 0)
 		bwriteb(&b, &bmore);
@@ -249,14 +249,14 @@ findgoversion(void)
 
 done:
 	p = btake(&b);
-	
-	
+
+
 	bfree(&b);
 	bfree(&path);
 	bfree(&bmore);
 	bfree(&branch);
 	vfree(&tags);
-	
+
 	return p;
 }
 
@@ -325,7 +325,7 @@ setup(void)
 			xremoveall(p);
 		xmkdirall(p);
 	}
-	
+
 	// Create object directory.
 	// We keep it in pkg/ so that all the generated binaries
 	// are in one tree.  If pkg/obj/libgc.a exists, it is a dreg from
@@ -393,7 +393,7 @@ static char *proto_gccargs[] = {
 static Vec gccargs;
 
 // deptab lists changes to the default dependencies for a given prefix.
-// deps ending in /* read the whole directory; deps beginning with - 
+// deps ending in /* read the whole directory; deps beginning with -
 // exclude files with that prefix.
 static struct {
 	char *prefix;  // prefix of target
@@ -539,7 +539,7 @@ install(char *dir)
 	Buf b, b1, path;
 	Vec compile, files, link, go, missing, clean, lib, extra;
 	Time ttarg, t;
-	int i, j, k, n, doclean;
+	int i, j, k, n, doclean, targ;
 
 	if(vflag) {
 		if(!streq(goos, gohostos) || !streq(goarch, gohostarch))
@@ -559,7 +559,7 @@ install(char *dir)
 	vinit(&clean);
 	vinit(&lib);
 	vinit(&extra);
-	
+
 	// path = full path to dir.
 	bpathf(&path, "%s/src/%s", goroot, dir);
 	name = lastelem(dir);
@@ -586,7 +586,7 @@ install(char *dir)
 		splitfields(&gccargs, bstr(&b));
 		for(i=0; i<nelem(proto_gccargs); i++)
 			vadd(&gccargs, proto_gccargs[i]);
-		if(xstrstr(gccargs.p[0], "clang") != nil) {
+		if(xstrstr(bstr(&b), "clang") != nil) {
 			vadd(&gccargs, "-Wno-dangling-else");
 			vadd(&gccargs, "-Wno-unused-value");
 		}
@@ -599,9 +599,9 @@ install(char *dir)
 	exe = "";
 	if(streq(gohostos, "windows"))
 		exe = ".exe";
-	
+
 	// Start final link command line.
-	// Note: code below knows that link.p[2] is the target.
+	// Note: code below knows that link.p[targ] is the target.
 	if(islib) {
 		// C library.
 		vadd(&link, "ar");
@@ -609,6 +609,7 @@ install(char *dir)
 		prefix = "";
 		if(!hasprefix(name, "lib"))
 			prefix = "lib";
+		targ = link.len;
 		vadd(&link, bpathf(&b, "%s/pkg/obj/%s_%s/%s%s.a", goroot, gohostos, gohostarch, prefix, name));
 	} else if(ispkg) {
 		// Go library (package).
@@ -617,6 +618,7 @@ install(char *dir)
 		p = bprintf(&b, "%s/pkg/%s_%s/%s", goroot, goos, goarch, dir+4);
 		*xstrrchr(p, '/') = '\0';
 		xmkdirall(p);
+		targ = link.len;
 		vadd(&link, bpathf(&b, "%s/pkg/%s_%s/%s.a", goroot, goos, goarch, dir+4));
 	} else if(streq(dir, "cmd/go") || streq(dir, "cmd/cgo")) {
 		// Go command.
@@ -625,21 +627,20 @@ install(char *dir)
 		elem = name;
 		if(streq(elem, "go"))
 			elem = "go_bootstrap";
+		targ = link.len;
 		vadd(&link, bpathf(&b, "%s/%s%s", tooldir, elem, exe));
 	} else {
-		// C command.
-		// Use gccargs, but ensure that link.p[2] is output file,
-		// as noted above.
-		vadd(&link, gccargs.p[0]);
+		// C command. Use gccargs.
+		vcopy(&link, gccargs.p, gccargs.len);
 		vadd(&link, "-o");
+		targ = link.len;
 		vadd(&link, bpathf(&b, "%s/%s%s", tooldir, name, exe));
-		vcopy(&link, gccargs.p+1, gccargs.len-1);
 		if(streq(gohostarch, "amd64"))
 			vadd(&link, "-m64");
 		else if(streq(gohostarch, "386"))
 			vadd(&link, "-m32");
 	}
-	ttarg = mtime(link.p[2]);
+	ttarg = mtime(link.p[targ]);
 
 	// Gather files that are sources for this target.
 	// Everything in that directory, and any target-specific
@@ -695,13 +696,13 @@ install(char *dir)
 					}
 					files.len = n;
 					continue;
-				}				
+				}
 				vadd(&files, p);
 			}
 		}
 	}
 	vuniq(&files);
-	
+
 	// Convert to absolute paths.
 	for(i=0; i<files.len; i++) {
 		if(!isabs(files.p[i])) {
@@ -739,11 +740,11 @@ install(char *dir)
 		files.p[n++] = files.p[i];
 	}
 	files.len = n;
-	
+
 	for(i=0; i<lib.len && !stale; i++)
 		if(mtime(lib.p[i]) > ttarg)
 			stale = 1;
-		
+
 	if(!stale)
 		goto out;
 
@@ -791,9 +792,9 @@ install(char *dir)
 		copy(bpathf(&b, "%s/zasm_GOOS_GOARCH.h", workdir),
 			bpathf(&b1, "%s/zasm_%s_%s.h", bstr(&path), goos, goarch), 0);
 	}
-	
+
 	// Generate .c files from .goc files.
-	if(streq(dir, "pkg/runtime")) {		
+	if(streq(dir, "pkg/runtime")) {
 		for(i=0; i<files.len; i++) {
 			p = files.p[i];
 			if(!hassuffix(p, ".goc"))
@@ -807,7 +808,7 @@ install(char *dir)
 		}
 		vuniq(&files);
 	}
-	
+
 	if((!streq(goos, gohostos) || !streq(goarch, gohostarch)) && isgo) {
 		// We've generated the right files; the go command can do the build.
 		if(vflag > 1)
@@ -832,13 +833,13 @@ install(char *dir)
 				vadd(&compile, "-m32");
 			if(streq(dir, "lib9"))
 				vadd(&compile, "-DPLAN9PORT");
-	
+
 			vadd(&compile, "-I");
 			vadd(&compile, bpathf(&b, "%s/include", goroot));
-			
+
 			vadd(&compile, "-I");
 			vadd(&compile, bstr(&path));
-	
+
 			// lib9/goos.c gets the default constants hard-coded.
 			if(streq(name, "goos.c")) {
 				vadd(&compile, bprintf(&b, "-DGOOS=\"%s\"", goos));
@@ -848,7 +849,7 @@ install(char *dir)
 				vadd(&compile, bprintf(&b, "-DGOROOT=\"%s\"", bstr(&b1)));
 				vadd(&compile, bprintf(&b, "-DGOVERSION=\"%s\"", goversion));
 			}
-	
+
 			// gc/lex.c records the GOEXPERIMENT setting used during the build.
 			if(streq(name, "lex.c")) {
 				xgetenv(&b, "GOEXPERIMENT");
@@ -866,7 +867,7 @@ install(char *dir)
 			vadd(&compile, workdir);
 			vadd(&compile, bprintf(&b, "-DGOOS_%s", goos));
 			vadd(&compile, bprintf(&b, "-DGOARCH_%s", goarch));
-		}	
+		}
 
 		bpathf(&b, "%s/%s", workdir, lastelem(files.p[i]));
 		doclean = 1;
@@ -892,7 +893,7 @@ install(char *dir)
 			vadd(&clean, bstr(&b));
 	}
 	bgwait();
-	
+
 	if(isgo) {
 		// The last loop was compiling individual files.
 		// Hand the Go files to the compiler en masse.
@@ -904,16 +905,16 @@ install(char *dir)
 		vadd(&compile, bstr(&b));
 		vadd(&clean, bstr(&b));
 		vadd(&link, bstr(&b));
-		
+
 		vadd(&compile, "-p");
 		if(hasprefix(dir, "pkg/"))
 			vadd(&compile, dir+4);
 		else
 			vadd(&compile, "main");
-		
+
 		if(streq(dir, "pkg/runtime"))
 			vadd(&compile, "-+");
-		
+
 		vcopy(&compile, go.p, go.len);
 
 		runv(nil, bstr(&path), CheckExit, &compile);
@@ -926,7 +927,7 @@ install(char *dir)
 	}
 
 	// Remove target before writing it.
-	xremove(link.p[2]);
+	xremove(link.p[targ]);
 
 	runv(nil, nil, CheckExit, &link);
 
@@ -979,7 +980,7 @@ shouldbuild(char *file, char *dir)
 	int i, j, ret;
 	Buf b;
 	Vec lines, fields;
-	
+
 	// Check file name for GOOS or GOARCH.
 	name = lastelem(file);
 	for(i=0; i<nelem(okgoos); i++)
@@ -988,11 +989,11 @@ shouldbuild(char *file, char *dir)
 	for(i=0; i<nelem(okgoarch); i++)
 		if(contains(name, okgoarch[i]) && !streq(okgoarch[i], goarch))
 			return 0;
-	
+
 	// Omit test files.
 	if(contains(name, "_test"))
 		return 0;
-	
+
 	// cmd/go/doc.go has a giant /* */ comment before
 	// it gets to the important detail that it is not part of
 	// package main.  We don't parse those comments,
@@ -1045,7 +1046,7 @@ out:
 	bfree(&b);
 	vfree(&lines);
 	vfree(&fields);
-	
+
 	return ret;
 }
 
@@ -1054,7 +1055,7 @@ static void
 copy(char *dst, char *src, int exec)
 {
 	Buf b;
-	
+
 	if(vflag > 1)
 		xprintf("cp %s %s\n", src, dst);
 
@@ -1069,11 +1070,13 @@ static char *buildorder[] = {
 	"lib9",
 	"libbio",
 	"libmach",
-	
+
 	"misc/pprof",
 
+	"cmd/addr2line",
 	"cmd/cov",
 	"cmd/nm",
+	"cmd/objdump",
 	"cmd/pack",
 	"cmd/prof",
 
@@ -1121,12 +1124,12 @@ static char *buildorder[] = {
 	"pkg/go/scanner",
 	"pkg/go/ast",
 	"pkg/go/parser",
-	"pkg/go/build",
 	"pkg/os/exec",
 	"pkg/net/url",
 	"pkg/text/template/parse",
 	"pkg/text/template",
 	"pkg/go/doc",
+	"pkg/go/build",
 	"cmd/go",
 };
 
@@ -1146,11 +1149,13 @@ static char *cleantab[] = {
 	"cmd/8c",
 	"cmd/8g",
 	"cmd/8l",
+	"cmd/addr2line",
 	"cmd/cc",
 	"cmd/cov",
 	"cmd/gc",
 	"cmd/go",
 	"cmd/nm",
+	"cmd/objdump",
 	"cmd/pack",
 	"cmd/prof",
 	"lib9",
@@ -1203,11 +1208,11 @@ clean(void)
 	int i, j, k;
 	Buf b, path;
 	Vec dir;
-	
+
 	binit(&b);
 	binit(&path);
 	vinit(&dir);
-	
+
 	for(i=0; i<nelem(cleantab); i++) {
 		bpathf(&path, "%s/src/%s", goroot, cleantab[i]);
 		xreaddir(&dir, bstr(&path));
@@ -1226,7 +1231,7 @@ clean(void)
 	if(rebuildall) {
 		// Remove object tree.
 		xremoveall(bpathf(&b, "%s/pkg/obj/%s_%s", goroot, gohostos, gohostarch));
-	
+
 		// Remove installed packages and tools.
 		xremoveall(bpathf(&b, "%s/pkg/%s_%s", goroot, gohostos, gohostarch));
 		xremoveall(bpathf(&b, "%s/pkg/%s_%s", goroot, goos, goarch));
@@ -1293,7 +1298,7 @@ cmdenv(int argc, char **argv)
 
 	if(argc > 0)
 		usage();
-	
+
 	xprintf(format, "GOROOT", goroot);
 	xprintf(format, "GOBIN", gobin);
 	xprintf(format, "GOARCH", goarch);
@@ -1345,7 +1350,7 @@ cmdbootstrap(int argc, char **argv)
 		clean();
 	goversion = findgoversion();
 	setup();
-	
+
 	// For the main bootstrap, building for host os/arch.
 	oldgoos = goos;
 	oldgoarch = goarch;
@@ -1355,7 +1360,7 @@ cmdbootstrap(int argc, char **argv)
 	gochar = gohostchar;
 	xsetenv("GOARCH", goarch);
 	xsetenv("GOOS", goos);
-	
+
 	for(i=0; i<nelem(buildorder); i++) {
 		install(bprintf(&b, buildorder[i], gohostchar));
 		if(!streq(oldgochar, gohostchar) && xstrstr(buildorder[i], "%s"))
@@ -1380,7 +1385,7 @@ defaulttarg(void)
 {
 	char *p;
 	Buf pwd, src, real_src;
-	
+
 	binit(&pwd);
 	binit(&src);
 	binit(&real_src);
@@ -1403,7 +1408,7 @@ defaulttarg(void)
 	bfree(&pwd);
 	bfree(&src);
 	bfree(&real_src);
-	
+
 	return p;
 }
 
@@ -1420,7 +1425,7 @@ cmdinstall(int argc, char **argv)
 	default:
 		usage();
 	}ARGEND
-	
+
 	if(argc == 0)
 		install(defaulttarg());
 
@@ -1468,7 +1473,7 @@ cmdbanner(int argc, char **argv)
 	binit(&b);
 	binit(&b1);
 	binit(&search);
-	
+
 	xprintf("\n");
 	xprintf("---\n");
 	xprintf("Installed Go for %s/%s in %s\n", goos, goarch, goroot);
@@ -1486,10 +1491,10 @@ cmdbanner(int argc, char **argv)
 
 	if(streq(gohostos, "darwin")) {
 		xprintf("\n"
-			"On OS X the debuggers must be installed setgrp procmod.\n"
+			"On OS X the debuggers must be installed setgid procmod.\n"
 			"Read and run ./sudo.bash to install the debuggers.\n");
 	}
-	
+
 	if(!streq(goroot_final, goroot)) {
 		xprintf("\n"
 			"The binaries expect %s to be copied or moved to %s\n",
diff --git a/src/cmd/dist/unix.c b/src/cmd/dist/unix.c
index 76622a4..e6d82e1 100644
--- a/src/cmd/dist/unix.c
+++ b/src/cmd/dist/unix.c
@@ -641,6 +641,9 @@ main(int argc, char **argv)
 	Buf b;
 	struct utsname u;
 
+	setvbuf(stdout, nil, _IOLBF, 0);
+	setvbuf(stderr, nil, _IOLBF, 0);
+
 	binit(&b);
 	
 	slash = "/";
diff --git a/src/cmd/fix/go1rename.go b/src/cmd/fix/go1rename.go
index 2995880..4b66672 100644
--- a/src/cmd/fix/go1rename.go
+++ b/src/cmd/fix/go1rename.go
@@ -39,6 +39,12 @@ var go1renameReplace = []rename{
 		New:       "cipher.Block",
 	},
 	{
+		OldImport: "encoding/json",
+		NewImport: "",
+		Old:       "json.MarshalForHTML",
+		New:       "json.Marshal",
+	},
+	{
 		OldImport: "net/url",
 		NewImport: "",
 		Old:       "url.ParseWithReference",
diff --git a/src/cmd/fix/go1rename_test.go b/src/cmd/fix/go1rename_test.go
index 02eaea6..481ebea 100644
--- a/src/cmd/fix/go1rename_test.go
+++ b/src/cmd/fix/go1rename_test.go
@@ -16,6 +16,7 @@ var go1renameTests = []testCase{
 import (
 	"crypto/aes"
 	"crypto/des"
+	"encoding/json"
 	"net/url"
 	"os"
 	"runtime"
@@ -25,6 +26,7 @@ var (
 	_ *aes.Cipher
 	_ *des.Cipher
 	_ *des.TripleDESCipher
+	_ = json.MarshalForHTML
 	_ = aes.New()
 	_ = url.Parse
 	_ = url.ParseWithReference
@@ -39,6 +41,7 @@ var (
 import (
 	"crypto/aes"
 	"crypto/cipher"
+	"encoding/json"
 	"net/url"
 	"runtime"
 	"syscall"
@@ -48,6 +51,7 @@ var (
 	_ cipher.Block
 	_ cipher.Block
 	_ cipher.Block
+	_ = json.Marshal
 	_ = aes.New()
 	_ = url.Parse
 	_ = url.Parse
diff --git a/src/cmd/gc/doc.go b/src/cmd/gc/doc.go
index c704011..5a2977e 100644
--- a/src/cmd/gc/doc.go
+++ b/src/cmd/gc/doc.go
@@ -38,6 +38,8 @@ Flags:
 	-p path
 		assume that path is the eventual import path for this code,
 		and diagnose any attempt to import a package that depends on it.
+	-D path
+		treat a relative import as relative to path
 	-L
 		show entire file path when printing line numbers in errors
 	-I dir1 -I dir2
diff --git a/src/cmd/gc/esc.c b/src/cmd/gc/esc.c
index 7e20457..2614b5f 100644
--- a/src/cmd/gc/esc.c
+++ b/src/cmd/gc/esc.c
@@ -59,7 +59,7 @@ static int	dstcount, edgecount;	// diagnostic
 static NodeList*	noesc;	// list of possible non-escaping nodes, for printing
 
 void
-escapes(void)
+escapes(NodeList *all)
 {
 	NodeList *l;
 
@@ -70,9 +70,10 @@ escapes(void)
 	theSink.escloopdepth = -1;
 
 	safetag = strlit("noescape");
+	noesc = nil;
 
-	// flow-analyze top level functions
-	for(l=xtop; l; l=l->next)
+	// flow-analyze functions
+	for(l=all; l; l=l->next)
 		if(l->n->op == ODCLFUNC || l->n->op == OCLOSURE)
 			escfunc(l->n);
 
@@ -84,7 +85,7 @@ escapes(void)
 		escflood(l->n);
 
 	// for all top level functions, tag the typenodes corresponding to the param nodes
-	for(l=xtop; l; l=l->next)
+	for(l=all; l; l=l->next)
 		if(l->n->op == ODCLFUNC)
 			esctag(l->n);
 
diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h
index fcbea2c..753360e 100644
--- a/src/cmd/gc/go.h
+++ b/src/cmd/gc/go.h
@@ -772,6 +772,7 @@ extern	char*	runtimeimport;
 extern	char*	unsafeimport;
 EXTERN	char*	myimportpath;
 EXTERN	Idir*	idirs;
+EXTERN	char*	localimport;
 
 EXTERN	Type*	types[NTYPE];
 EXTERN	Type*	idealstring;
@@ -955,7 +956,7 @@ NodeList*	variter(NodeList *vl, Node *t, NodeList *el);
 /*
  *	esc.c
  */
-void	escapes(void);
+void	escapes(NodeList*);
 
 /*
  *	export.c
@@ -1171,6 +1172,7 @@ Type*	getthisx(Type *t);
 int	implements(Type *t, Type *iface, Type **missing, Type **have, int *ptr);
 void	importdot(Pkg *opkg, Node *pack);
 int	is64(Type *t);
+int	isbadimport(Strlit *s);
 int	isblank(Node *n);
 int	isblanksym(Sym *s);
 int	isfixedarray(Type *t);
diff --git a/src/cmd/gc/go.y b/src/cmd/gc/go.y
index 91f9392..f950587 100644
--- a/src/cmd/gc/go.y
+++ b/src/cmd/gc/go.y
@@ -205,7 +205,15 @@ import_stmt:
 		my->lastlineno = $1;
 		my->block = 1;	// at top level
 	}
-
+|	import_here import_there
+	{
+		// When an invalid import path is passed to importfile,
+		// it calls yyerror and then sets up a fake import with
+		// no package statement. This allows us to test more
+		// than one invalid import statement in a single file.
+		if(nerrors == 0)
+			fatal("phase error in import");
+	}
 
 import_stmt_list:
 	import_stmt
diff --git a/src/cmd/gc/lex.c b/src/cmd/gc/lex.c
index e880b2f..96786b5 100644
--- a/src/cmd/gc/lex.c
+++ b/src/cmd/gc/lex.c
@@ -148,6 +148,7 @@ usage(void)
 	// -y print declarations in cannedimports (used with -d)
 	// -% print non-static initializers
 	// -+ indicate that the runtime is being compiled
+	print("  -D PATH interpret local imports relative to this import path\n");
 	print("  -I DIR search for packages in DIR\n");
 	print("  -L show full path in file:line prints\n");
 	print("  -N disable optimizations\n");
@@ -186,7 +187,7 @@ int
 main(int argc, char *argv[])
 {
 	int i, c;
-	NodeList *l;
+	NodeList *l, *batch;
 	char *p;
 
 #ifdef	SIGBUS	
@@ -238,14 +239,18 @@ main(int argc, char *argv[])
 		myimportpath = EARGF(usage());
 		break;
 
-	case 'I':
-		addidir(EARGF(usage()));
-		break;
-	
 	case 'u':
 		safemode = 1;
 		break;
 
+	case 'D':
+		localimport = EARGF(usage());
+		break;
+
+	case 'I':
+		addidir(EARGF(usage()));
+		break;
+	
 	case 'V':
 		p = expstring();
 		if(strcmp(p, "X:none") == 0)
@@ -390,7 +395,7 @@ main(int argc, char *argv[])
 
 	// Phase 5: escape analysis.
 	if(!debug['N'])
-		escapes();
+		escapes(xtop);
 
 	// Phase 6: Compile top level functions.
 	for(l=xtop; l; l=l->next)
@@ -401,14 +406,17 @@ main(int argc, char *argv[])
 		fninit(xtop);
 
 	// Phase 6b: Compile all closures.
+	// Can generate more closures, so run in batches.
 	while(closures) {
-		l = closures;
+		batch = closures;
 		closures = nil;
-		for(; l; l=l->next) {
-			if (debug['l'])
+		if(debug['l'])
+			for(l=batch; l; l=l->next)
 				inlcalls(l->n);
+		if(!debug['N'])
+			escapes(batch);
+		for(l=batch; l; l=l->next)
 			funccompile(l->n, 1);
-		}
 	}
 
 	// Phase 7: check external declarations.
@@ -513,8 +521,12 @@ islocalname(Strlit *name)
 	   	return 1;
 	if(name->len >= 2 && strncmp(name->s, "./", 2) == 0)
 		return 1;
+	if(name->len == 1 && strncmp(name->s, ".", 1) == 0)
+		return 1;
 	if(name->len >= 3 && strncmp(name->s, "../", 3) == 0)
 		return 1;
+	if(name->len == 2 && strncmp(name->s, "..", 2) == 0)
+		return 1;
 	return 0;
 }
 
@@ -570,6 +582,13 @@ findpkg(Strlit *name)
 	return 0;
 }
 
+static void
+fakeimport(void)
+{
+	importpkg = mkpkg(strlit("fake"));
+	cannedimports("fake.6", "$$\n");
+}
+
 void
 importfile(Val *f, int line)
 {
@@ -578,7 +597,7 @@ importfile(Val *f, int line)
 	int32 c;
 	int len;
 	Strlit *path;
-	char *cleanbuf;
+	char *cleanbuf, *prefix;
 
 	USED(line);
 
@@ -586,17 +605,19 @@ importfile(Val *f, int line)
 
 	if(f->ctype != CTSTR) {
 		yyerror("import statement not a string");
+		fakeimport();
 		return;
 	}
 
-	if(strlen(f->u.sval->s) != f->u.sval->len) {
-		yyerror("import path contains NUL");
-		errorexit();
+	if(f->u.sval->len == 0) {
+		yyerror("import path is empty");
+		fakeimport();
+		return;
 	}
-	
-	if(strchr(f->u.sval->s, '\\')) {
-		yyerror("import path contains backslash; use slash");
-		errorexit();
+
+	if(isbadimport(f->u.sval)) {
+		fakeimport();
+		return;
 	}
 
 	// The package name main is no longer reserved,
@@ -625,8 +646,16 @@ importfile(Val *f, int line)
 	
 	path = f->u.sval;
 	if(islocalname(path)) {
-		cleanbuf = mal(strlen(pathname) + strlen(path->s) + 2);
-		strcpy(cleanbuf, pathname);
+		if(path->s[0] == '/') {
+			yyerror("import path cannot be absolute path");
+			fakeimport();
+			return;
+		}
+		prefix = pathname;
+		if(localimport != nil)
+			prefix = localimport;
+		cleanbuf = mal(strlen(prefix) + strlen(path->s) + 2);
+		strcpy(cleanbuf, prefix);
 		strcat(cleanbuf, "/");
 		strcat(cleanbuf, path->s);
 		cleanname(cleanbuf);
diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c
index 12ac6fc..6eb7734 100644
--- a/src/cmd/gc/subr.c
+++ b/src/cmd/gc/subr.c
@@ -3559,11 +3559,9 @@ mkpkg(Strlit *path)
 {
 	Pkg *p;
 	int h;
-	
-	if(strlen(path->s) != path->len) {
-		yyerror("import path contains NUL byte");
+
+	if(isbadimport(path))
 		errorexit();
-	}
 	
 	h = stringhash(path->s) & (nelem(phash)-1);
 	for(p=phash[h]; p; p=p->link)
@@ -3612,3 +3610,41 @@ addinit(Node **np, NodeList *init)
 	n->ninit = concat(init, n->ninit);
 	n->ullman = UINF;
 }
+
+int
+isbadimport(Strlit *path)
+{
+	char *s;
+	Rune r;
+
+	if(strlen(path->s) != path->len) {
+		yyerror("import path contains NUL");
+		return 1;
+	}
+
+	s = path->s;
+	while(*s) {
+		s += chartorune(&r, s);
+		if(r == Runeerror) {
+			yyerror("import path contains invalid UTF-8 sequence");
+			return 1;
+		}
+		if(r < 0x20 || r == 0x7f) {
+			yyerror("import path contains control character");
+			return 1;
+		}
+		if(r == '\\') {
+			yyerror("import path contains backslash; use slash");
+			return 1;
+		}
+		if(isspacerune(r)) {
+			yyerror("import path contains space character");
+			return 1;
+		}
+		if(utfrune("!\"#$%&'()*,:;<=>?[]^`{|}~", r)) {
+			yyerror("import path contains invalid character '%C'", r);
+			return 1;
+		}
+	}
+	return 0;
+}
diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c
index 9bd0a69..74298e1 100644
--- a/src/cmd/gc/walk.c
+++ b/src/cmd/gc/walk.c
@@ -1017,6 +1017,7 @@ walkexpr(Node **np, NodeList **init)
 			r = nod(n->etype, nod(OLEN, n->left, N), nod(OLEN, n->right, N));
 			typecheck(&r, Erv);
 			walkexpr(&r, init);
+			r->type = n->type;
 			n = r;
 			goto ret;
 		}
@@ -1029,6 +1030,7 @@ walkexpr(Node **np, NodeList **init)
 			r = nod(n->etype, nod(OLEN, n->left->left, N), nodintconst(0));
 			typecheck(&r, Erv);
 			walkexpr(&r, init);
+			r->type = n->type;
 			n = r;
 			goto ret;
 		}
diff --git a/src/cmd/gc/y.tab.c b/src/cmd/gc/y.tab.c
index 84fe945..97bf233 100644
--- a/src/cmd/gc/y.tab.c
+++ b/src/cmd/gc/y.tab.c
@@ -1,10 +1,8 @@
+/* A Bison parser, made by GNU Bison 2.5.  */
 
-/* A Bison parser, made by GNU Bison 2.4.1.  */
-
-/* Skeleton implementation for Bison's Yacc-like parsers in C
+/* Bison implementation for Yacc-like parsers in C
    
-      Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
-   Free Software Foundation, Inc.
+      Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
    
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -46,7 +44,7 @@
 #define YYBISON 1
 
 /* Bison version.  */
-#define YYBISON_VERSION "2.4.1"
+#define YYBISON_VERSION "2.5"
 
 /* Skeleton name.  */
 #define YYSKELETON_NAME "yacc.c"
@@ -67,7 +65,7 @@
 
 /* Copy the first part of user declarations.  */
 
-/* Line 189 of yacc.c  */
+/* Line 268 of yacc.c  */
 #line 20 "go.y"
 
 #include <u.h>
@@ -78,8 +76,8 @@
 static void fixlbrace(int);
 
 
-/* Line 189 of yacc.c  */
-#line 83 "y.tab.c"
+/* Line 268 of yacc.c  */
+#line 81 "y.tab.c"
 
 /* Enabling traces.  */
 #ifndef YYDEBUG
@@ -215,7 +213,7 @@ static void fixlbrace(int);
 typedef union YYSTYPE
 {
 
-/* Line 214 of yacc.c  */
+/* Line 293 of yacc.c  */
 #line 28 "go.y"
 
 	Node*		node;
@@ -227,8 +225,8 @@ typedef union YYSTYPE
 
 
 
-/* Line 214 of yacc.c  */
-#line 232 "y.tab.c"
+/* Line 293 of yacc.c  */
+#line 230 "y.tab.c"
 } YYSTYPE;
 # define YYSTYPE_IS_TRIVIAL 1
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
@@ -239,8 +237,8 @@ typedef union YYSTYPE
 /* Copy the second part of user declarations.  */
 
 
-/* Line 264 of yacc.c  */
-#line 244 "y.tab.c"
+/* Line 343 of yacc.c  */
+#line 242 "y.tab.c"
 
 #ifdef short
 # undef short
@@ -290,7 +288,7 @@ typedef short int yytype_int16;
 #define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
 
 #ifndef YY_
-# if YYENABLE_NLS
+# if defined YYENABLE_NLS && YYENABLE_NLS
 #  if ENABLE_NLS
 #   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
 #   define YY_(msgid) dgettext ("bison-runtime", msgid)
@@ -343,11 +341,11 @@ YYID (yyi)
 #    define alloca _alloca
 #   else
 #    define YYSTACK_ALLOC alloca
-#    if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+#    if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 #     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-#     ifndef _STDLIB_H
-#      define _STDLIB_H 1
+#     ifndef EXIT_SUCCESS
+#      define EXIT_SUCCESS 0
 #     endif
 #    endif
 #   endif
@@ -370,24 +368,24 @@ YYID (yyi)
 #  ifndef YYSTACK_ALLOC_MAXIMUM
 #   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
 #  endif
-#  if (defined __cplusplus && ! defined _STDLIB_H \
+#  if (defined __cplusplus && ! defined EXIT_SUCCESS \
        && ! ((defined YYMALLOC || defined malloc) \
 	     && (defined YYFREE || defined free)))
 #   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-#   ifndef _STDLIB_H
-#    define _STDLIB_H 1
+#   ifndef EXIT_SUCCESS
+#    define EXIT_SUCCESS 0
 #   endif
 #  endif
 #  ifndef YYMALLOC
 #   define YYMALLOC malloc
-#   if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+#   if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
 #   endif
 #  endif
 #  ifndef YYFREE
 #   define YYFREE free
-#   if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+#   if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 void free (void *); /* INFRINGES ON USER NAME SPACE */
 #   endif
@@ -416,23 +414,7 @@ union yyalloc
      ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
       + YYSTACK_GAP_MAXIMUM)
 
-/* Copy COUNT objects from FROM to TO.  The source and destination do
-   not overlap.  */
-# ifndef YYCOPY
-#  if defined __GNUC__ && 1 < __GNUC__
-#   define YYCOPY(To, From, Count) \
-      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
-#  else
-#   define YYCOPY(To, From, Count)		\
-      do					\
-	{					\
-	  YYSIZE_T yyi;				\
-	  for (yyi = 0; yyi < (Count); yyi++)	\
-	    (To)[yyi] = (From)[yyi];		\
-	}					\
-      while (YYID (0))
-#  endif
-# endif
+# define YYCOPY_NEEDED 1
 
 /* Relocate STACK from its old location to the new one.  The
    local variables YYSIZE and YYSTACKSIZE give the old and new number of
@@ -452,19 +434,39 @@ union yyalloc
 
 #endif
 
+#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
+/* Copy COUNT objects from FROM to TO.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if defined __GNUC__ && 1 < __GNUC__
+#   define YYCOPY(To, From, Count) \
+      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+#  else
+#   define YYCOPY(To, From, Count)		\
+      do					\
+	{					\
+	  YYSIZE_T yyi;				\
+	  for (yyi = 0; yyi < (Count); yyi++)	\
+	    (To)[yyi] = (From)[yyi];		\
+	}					\
+      while (YYID (0))
+#  endif
+# endif
+#endif /* !YYCOPY_NEEDED */
+
 /* YYFINAL -- State number of the termination state.  */
 #define YYFINAL  4
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   2157
+#define YYLAST   2131
 
 /* YYNTOKENS -- Number of terminals.  */
 #define YYNTOKENS  76
 /* YYNNTS -- Number of nonterminals.  */
 #define YYNNTS  138
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  343
+#define YYNRULES  344
 /* YYNRULES -- Number of states.  */
-#define YYNSTATES  652
+#define YYNSTATES  653
 
 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
 #define YYUNDEFTOK  2
@@ -515,40 +517,40 @@ static const yytype_uint8 yytranslate[] =
 static const yytype_uint16 yyprhs[] =
 {
        0,     0,     3,     8,     9,    13,    14,    18,    19,    23,
-      26,    32,    36,    40,    42,    46,    48,    51,    54,    59,
-      60,    62,    63,    68,    69,    71,    73,    75,    77,    80,
-      86,    90,    93,    99,   107,   111,   114,   120,   124,   126,
-     129,   134,   138,   143,   147,   149,   152,   154,   156,   159,
-     161,   165,   169,   173,   176,   179,   183,   189,   195,   198,
-     199,   204,   205,   209,   210,   213,   214,   219,   224,   229,
-     235,   237,   239,   242,   243,   247,   249,   253,   254,   255,
-     256,   264,   265,   268,   271,   272,   273,   281,   282,   288,
-     290,   294,   298,   302,   306,   310,   314,   318,   322,   326,
-     330,   334,   338,   342,   346,   350,   354,   358,   362,   366,
-     370,   372,   375,   378,   381,   384,   387,   390,   393,   396,
-     400,   406,   413,   415,   417,   421,   427,   433,   438,   445,
-     447,   452,   458,   464,   472,   474,   475,   479,   481,   486,
-     488,   492,   494,   496,   498,   500,   502,   504,   506,   507,
-     509,   511,   513,   515,   520,   522,   524,   526,   529,   531,
-     533,   535,   537,   539,   543,   545,   547,   549,   552,   554,
-     556,   558,   560,   564,   566,   568,   570,   572,   574,   576,
-     578,   580,   582,   586,   591,   596,   599,   603,   609,   611,
-     613,   616,   620,   626,   630,   636,   640,   644,   650,   659,
-     665,   674,   680,   681,   685,   686,   688,   692,   694,   699,
-     702,   703,   707,   709,   713,   715,   719,   721,   725,   727,
-     731,   733,   737,   741,   744,   749,   753,   759,   765,   767,
-     771,   773,   776,   778,   782,   787,   789,   792,   795,   797,
-     799,   803,   804,   807,   808,   810,   812,   814,   816,   818,
-     820,   822,   824,   826,   827,   832,   834,   837,   840,   843,
-     846,   849,   852,   854,   858,   860,   864,   866,   870,   872,
-     876,   878,   882,   884,   886,   890,   894,   895,   898,   899,
-     901,   902,   904,   905,   907,   908,   910,   911,   913,   914,
-     916,   917,   919,   920,   922,   923,   925,   930,   935,   941,
-     948,   953,   958,   960,   962,   964,   966,   968,   970,   972,
-     974,   976,   980,   985,   991,   996,  1001,  1004,  1007,  1012,
-    1016,  1020,  1026,  1030,  1035,  1039,  1045,  1047,  1048,  1050,
-    1054,  1056,  1058,  1061,  1063,  1065,  1071,  1072,  1075,  1077,
-    1081,  1083,  1087,  1089
+      26,    32,    36,    40,    43,    45,    49,    51,    54,    57,
+      62,    63,    65,    66,    71,    72,    74,    76,    78,    80,
+      83,    89,    93,    96,   102,   110,   114,   117,   123,   127,
+     129,   132,   137,   141,   146,   150,   152,   155,   157,   159,
+     162,   164,   168,   172,   176,   179,   182,   186,   192,   198,
+     201,   202,   207,   208,   212,   213,   216,   217,   222,   227,
+     232,   238,   240,   242,   245,   246,   250,   252,   256,   257,
+     258,   259,   267,   268,   271,   274,   275,   276,   284,   285,
+     291,   293,   297,   301,   305,   309,   313,   317,   321,   325,
+     329,   333,   337,   341,   345,   349,   353,   357,   361,   365,
+     369,   373,   375,   378,   381,   384,   387,   390,   393,   396,
+     399,   403,   409,   416,   418,   420,   424,   430,   436,   441,
+     448,   450,   455,   461,   467,   475,   477,   478,   482,   484,
+     489,   491,   495,   497,   499,   501,   503,   505,   507,   509,
+     510,   512,   514,   516,   518,   523,   525,   527,   529,   532,
+     534,   536,   538,   540,   542,   546,   548,   550,   552,   555,
+     557,   559,   561,   563,   567,   569,   571,   573,   575,   577,
+     579,   581,   583,   585,   589,   594,   599,   602,   606,   612,
+     614,   616,   619,   623,   629,   633,   639,   643,   647,   653,
+     662,   668,   677,   683,   684,   688,   689,   691,   695,   697,
+     702,   705,   706,   710,   712,   716,   718,   722,   724,   728,
+     730,   734,   736,   740,   744,   747,   752,   756,   762,   768,
+     770,   774,   776,   779,   781,   785,   790,   792,   795,   798,
+     800,   802,   806,   807,   810,   811,   813,   815,   817,   819,
+     821,   823,   825,   827,   829,   830,   835,   837,   840,   843,
+     846,   849,   852,   855,   857,   861,   863,   867,   869,   873,
+     875,   879,   881,   885,   887,   889,   893,   897,   898,   901,
+     902,   904,   905,   907,   908,   910,   911,   913,   914,   916,
+     917,   919,   920,   922,   923,   925,   926,   928,   933,   938,
+     944,   951,   956,   961,   963,   965,   967,   969,   971,   973,
+     975,   977,   979,   983,   988,   994,   999,  1004,  1007,  1010,
+    1015,  1019,  1023,  1029,  1033,  1038,  1042,  1048,  1050,  1051,
+    1053,  1057,  1059,  1061,  1064,  1066,  1068,  1074,  1075,  1078,
+    1080,  1084,  1086,  1090,  1092
 };
 
 /* YYRHS -- A `-1'-separated list of the rules' RHS.  */
@@ -558,152 +560,152 @@ static const yytype_int16 yyrhs[] =
      137,    62,    -1,    -1,    80,    86,    88,    -1,    -1,    81,
       82,    62,    -1,    21,    83,    -1,    21,    59,    84,   186,
       60,    -1,    21,    59,    60,    -1,    85,    86,    88,    -1,
-      83,    -1,    84,    62,    83,    -1,     3,    -1,   137,     3,
-      -1,    63,     3,    -1,    25,    24,    87,    62,    -1,    -1,
-      24,    -1,    -1,    89,   210,    64,    64,    -1,    -1,    91,
-      -1,   154,    -1,   177,    -1,     1,    -1,    32,    93,    -1,
-      32,    59,   163,   186,    60,    -1,    32,    59,    60,    -1,
-      92,    94,    -1,    92,    59,    94,   186,    60,    -1,    92,
-      59,    94,    62,   164,   186,    60,    -1,    92,    59,    60,
-      -1,    31,    97,    -1,    31,    59,   165,   186,    60,    -1,
-      31,    59,    60,    -1,     9,    -1,   181,   142,    -1,   181,
-     142,    65,   182,    -1,   181,    65,   182,    -1,   181,   142,
-      65,   182,    -1,   181,    65,   182,    -1,    94,    -1,   181,
-     142,    -1,   181,    -1,   137,    -1,    96,   142,    -1,   123,
-      -1,   123,     4,   123,    -1,   182,    65,   182,    -1,   182,
-       8,   182,    -1,   123,    42,    -1,   123,    37,    -1,     6,
-     183,    66,    -1,     6,   183,    65,   123,    66,    -1,     6,
-     183,     8,   123,    66,    -1,    12,    66,    -1,    -1,    67,
-     101,   179,    68,    -1,    -1,    99,   103,   179,    -1,    -1,
-     104,   102,    -1,    -1,    35,   106,   179,    68,    -1,   182,
-      65,    26,   123,    -1,   182,     8,    26,   123,    -1,   190,
-      62,   190,    62,   190,    -1,   190,    -1,   107,    -1,   108,
-     105,    -1,    -1,    16,   111,   109,    -1,   190,    -1,   190,
-      62,   190,    -1,    -1,    -1,    -1,    20,   114,   112,   115,
-     105,   116,   117,    -1,    -1,    14,   113,    -1,    14,   100,
-      -1,    -1,    -1,    30,   119,   112,   120,    35,   104,    68,
-      -1,    -1,    28,   122,    35,   104,    68,    -1,   124,    -1,
-     123,    47,   123,    -1,   123,    33,   123,    -1,   123,    38,
-     123,    -1,   123,    46,   123,    -1,   123,    45,   123,    -1,
-     123,    43,   123,    -1,   123,    39,   123,    -1,   123,    40,
-     123,    -1,   123,    49,   123,    -1,   123,    50,   123,    -1,
-     123,    51,   123,    -1,   123,    52,   123,    -1,   123,    53,
-     123,    -1,   123,    54,   123,    -1,   123,    55,   123,    -1,
-     123,    56,   123,    -1,   123,    34,   123,    -1,   123,    44,
-     123,    -1,   123,    48,   123,    -1,   123,    36,   123,    -1,
-     130,    -1,    53,   124,    -1,    56,   124,    -1,    49,   124,
-      -1,    50,   124,    -1,    69,   124,    -1,    70,   124,    -1,
-      52,   124,    -1,    36,   124,    -1,   130,    59,    60,    -1,
-     130,    59,   183,   187,    60,    -1,   130,    59,   183,    11,
-     187,    60,    -1,     3,    -1,   139,    -1,   130,    63,   137,
-      -1,   130,    63,    59,   131,    60,    -1,   130,    63,    59,
-      31,    60,    -1,   130,    71,   123,    72,    -1,   130,    71,
-     188,    66,   188,    72,    -1,   125,    -1,   145,    59,   123,
-      60,    -1,   146,   133,   127,   185,    68,    -1,   126,    67,
-     127,   185,    68,    -1,    59,   131,    60,    67,   127,   185,
-      68,    -1,   161,    -1,    -1,   123,    66,   129,    -1,   123,
-      -1,    67,   127,   185,    68,    -1,   126,    -1,    59,   131,
-      60,    -1,   123,    -1,   143,    -1,   142,    -1,    35,    -1,
-      67,    -1,   137,    -1,   137,    -1,    -1,   134,    -1,    24,
-      -1,   138,    -1,    73,    -1,    74,     3,    63,    24,    -1,
-     137,    -1,   134,    -1,    11,    -1,    11,   142,    -1,   151,
-      -1,   157,    -1,   149,    -1,   150,    -1,   148,    -1,    59,
-     142,    60,    -1,   151,    -1,   157,    -1,   149,    -1,    53,
-     143,    -1,   157,    -1,   149,    -1,   150,    -1,   148,    -1,
-      59,   142,    60,    -1,   157,    -1,   149,    -1,   149,    -1,
-     151,    -1,   157,    -1,   149,    -1,   150,    -1,   148,    -1,
-     139,    -1,   139,    63,   137,    -1,    71,   188,    72,   142,
-      -1,    71,    11,    72,   142,    -1,     7,   144,    -1,     7,
-      36,   142,    -1,    23,    71,   142,    72,   142,    -1,   152,
-      -1,   153,    -1,    53,   142,    -1,    36,     7,   142,    -1,
-      29,   133,   166,   186,    68,    -1,    29,   133,    68,    -1,
-      22,   133,   167,   186,    68,    -1,    22,   133,    68,    -1,
-      17,   155,   158,    -1,   137,    59,   175,    60,   159,    -1,
-      59,   175,    60,   137,    59,   175,    60,   159,    -1,   196,
-      59,   191,    60,   206,    -1,    59,   211,    60,   137,    59,
-     191,    60,   206,    -1,    17,    59,   175,    60,   159,    -1,
-      -1,    67,   179,    68,    -1,    -1,   147,    -1,    59,   175,
-      60,    -1,   157,    -1,   160,   133,   179,    68,    -1,   160,
-       1,    -1,    -1,   162,    90,    62,    -1,    93,    -1,   163,
-      62,    93,    -1,    95,    -1,   164,    62,    95,    -1,    97,
-      -1,   165,    62,    97,    -1,   168,    -1,   166,    62,   168,
-      -1,   171,    -1,   167,    62,   171,    -1,   180,   142,   194,
-      -1,   170,   194,    -1,    59,   170,    60,   194,    -1,    53,
-     170,   194,    -1,    59,    53,   170,    60,   194,    -1,    53,
-      59,   170,    60,   194,    -1,    24,    -1,    24,    63,   137,
-      -1,   169,    -1,   134,   172,    -1,   169,    -1,    59,   169,
-      60,    -1,    59,   175,    60,   159,    -1,   132,    -1,   137,
-     132,    -1,   137,   141,    -1,   141,    -1,   173,    -1,   174,
-      75,   173,    -1,    -1,   174,   187,    -1,    -1,   100,    -1,
-      91,    -1,   177,    -1,     1,    -1,    98,    -1,   110,    -1,
-     118,    -1,   121,    -1,   113,    -1,    -1,   140,    66,   178,
-     176,    -1,    15,    -1,     5,   136,    -1,    10,   136,    -1,
-      18,   125,    -1,    13,   125,    -1,    19,   134,    -1,    27,
-     189,    -1,   176,    -1,   179,    62,   176,    -1,   134,    -1,
-     180,    75,   134,    -1,   135,    -1,   181,    75,   135,    -1,
-     123,    -1,   182,    75,   123,    -1,   131,    -1,   183,    75,
-     131,    -1,   128,    -1,   129,    -1,   184,    75,   128,    -1,
-     184,    75,   129,    -1,    -1,   184,   187,    -1,    -1,    62,
-      -1,    -1,    75,    -1,    -1,   123,    -1,    -1,   182,    -1,
-      -1,    98,    -1,    -1,   211,    -1,    -1,   212,    -1,    -1,
-     213,    -1,    -1,     3,    -1,    21,    24,     3,    62,    -1,
-      32,   196,   198,    62,    -1,     9,   196,    65,   209,    62,
-      -1,     9,   196,   198,    65,   209,    62,    -1,    31,   197,
-     198,    62,    -1,    17,   156,   158,    62,    -1,   138,    -1,
-     196,    -1,   200,    -1,   201,    -1,   202,    -1,   200,    -1,
-     202,    -1,   138,    -1,    24,    -1,    71,    72,   198,    -1,
-      71,     3,    72,   198,    -1,    23,    71,   198,    72,   198,
-      -1,    29,    67,   192,    68,    -1,    22,    67,   193,    68,
-      -1,    53,   198,    -1,     7,   199,    -1,     7,    59,   201,
-      60,    -1,     7,    36,   198,    -1,    36,     7,   198,    -1,
-      17,    59,   191,    60,   206,    -1,   137,   198,   194,    -1,
-     137,    11,   198,   194,    -1,   137,   198,   194,    -1,   137,
-      59,   191,    60,   206,    -1,   198,    -1,    -1,   207,    -1,
-      59,   191,    60,    -1,   198,    -1,     3,    -1,    50,     3,
-      -1,   137,    -1,   208,    -1,    59,   208,    49,   208,    60,
-      -1,    -1,   210,   195,    -1,   203,    -1,   211,    75,   203,
-      -1,   204,    -1,   212,    62,   204,    -1,   205,    -1,   213,
-      62,   205,    -1
+      85,    88,    -1,    83,    -1,    84,    62,    83,    -1,     3,
+      -1,   137,     3,    -1,    63,     3,    -1,    25,    24,    87,
+      62,    -1,    -1,    24,    -1,    -1,    89,   210,    64,    64,
+      -1,    -1,    91,    -1,   154,    -1,   177,    -1,     1,    -1,
+      32,    93,    -1,    32,    59,   163,   186,    60,    -1,    32,
+      59,    60,    -1,    92,    94,    -1,    92,    59,    94,   186,
+      60,    -1,    92,    59,    94,    62,   164,   186,    60,    -1,
+      92,    59,    60,    -1,    31,    97,    -1,    31,    59,   165,
+     186,    60,    -1,    31,    59,    60,    -1,     9,    -1,   181,
+     142,    -1,   181,   142,    65,   182,    -1,   181,    65,   182,
+      -1,   181,   142,    65,   182,    -1,   181,    65,   182,    -1,
+      94,    -1,   181,   142,    -1,   181,    -1,   137,    -1,    96,
+     142,    -1,   123,    -1,   123,     4,   123,    -1,   182,    65,
+     182,    -1,   182,     8,   182,    -1,   123,    42,    -1,   123,
+      37,    -1,     6,   183,    66,    -1,     6,   183,    65,   123,
+      66,    -1,     6,   183,     8,   123,    66,    -1,    12,    66,
+      -1,    -1,    67,   101,   179,    68,    -1,    -1,    99,   103,
+     179,    -1,    -1,   104,   102,    -1,    -1,    35,   106,   179,
+      68,    -1,   182,    65,    26,   123,    -1,   182,     8,    26,
+     123,    -1,   190,    62,   190,    62,   190,    -1,   190,    -1,
+     107,    -1,   108,   105,    -1,    -1,    16,   111,   109,    -1,
+     190,    -1,   190,    62,   190,    -1,    -1,    -1,    -1,    20,
+     114,   112,   115,   105,   116,   117,    -1,    -1,    14,   113,
+      -1,    14,   100,    -1,    -1,    -1,    30,   119,   112,   120,
+      35,   104,    68,    -1,    -1,    28,   122,    35,   104,    68,
+      -1,   124,    -1,   123,    47,   123,    -1,   123,    33,   123,
+      -1,   123,    38,   123,    -1,   123,    46,   123,    -1,   123,
+      45,   123,    -1,   123,    43,   123,    -1,   123,    39,   123,
+      -1,   123,    40,   123,    -1,   123,    49,   123,    -1,   123,
+      50,   123,    -1,   123,    51,   123,    -1,   123,    52,   123,
+      -1,   123,    53,   123,    -1,   123,    54,   123,    -1,   123,
+      55,   123,    -1,   123,    56,   123,    -1,   123,    34,   123,
+      -1,   123,    44,   123,    -1,   123,    48,   123,    -1,   123,
+      36,   123,    -1,   130,    -1,    53,   124,    -1,    56,   124,
+      -1,    49,   124,    -1,    50,   124,    -1,    69,   124,    -1,
+      70,   124,    -1,    52,   124,    -1,    36,   124,    -1,   130,
+      59,    60,    -1,   130,    59,   183,   187,    60,    -1,   130,
+      59,   183,    11,   187,    60,    -1,     3,    -1,   139,    -1,
+     130,    63,   137,    -1,   130,    63,    59,   131,    60,    -1,
+     130,    63,    59,    31,    60,    -1,   130,    71,   123,    72,
+      -1,   130,    71,   188,    66,   188,    72,    -1,   125,    -1,
+     145,    59,   123,    60,    -1,   146,   133,   127,   185,    68,
+      -1,   126,    67,   127,   185,    68,    -1,    59,   131,    60,
+      67,   127,   185,    68,    -1,   161,    -1,    -1,   123,    66,
+     129,    -1,   123,    -1,    67,   127,   185,    68,    -1,   126,
+      -1,    59,   131,    60,    -1,   123,    -1,   143,    -1,   142,
+      -1,    35,    -1,    67,    -1,   137,    -1,   137,    -1,    -1,
+     134,    -1,    24,    -1,   138,    -1,    73,    -1,    74,     3,
+      63,    24,    -1,   137,    -1,   134,    -1,    11,    -1,    11,
+     142,    -1,   151,    -1,   157,    -1,   149,    -1,   150,    -1,
+     148,    -1,    59,   142,    60,    -1,   151,    -1,   157,    -1,
+     149,    -1,    53,   143,    -1,   157,    -1,   149,    -1,   150,
+      -1,   148,    -1,    59,   142,    60,    -1,   157,    -1,   149,
+      -1,   149,    -1,   151,    -1,   157,    -1,   149,    -1,   150,
+      -1,   148,    -1,   139,    -1,   139,    63,   137,    -1,    71,
+     188,    72,   142,    -1,    71,    11,    72,   142,    -1,     7,
+     144,    -1,     7,    36,   142,    -1,    23,    71,   142,    72,
+     142,    -1,   152,    -1,   153,    -1,    53,   142,    -1,    36,
+       7,   142,    -1,    29,   133,   166,   186,    68,    -1,    29,
+     133,    68,    -1,    22,   133,   167,   186,    68,    -1,    22,
+     133,    68,    -1,    17,   155,   158,    -1,   137,    59,   175,
+      60,   159,    -1,    59,   175,    60,   137,    59,   175,    60,
+     159,    -1,   196,    59,   191,    60,   206,    -1,    59,   211,
+      60,   137,    59,   191,    60,   206,    -1,    17,    59,   175,
+      60,   159,    -1,    -1,    67,   179,    68,    -1,    -1,   147,
+      -1,    59,   175,    60,    -1,   157,    -1,   160,   133,   179,
+      68,    -1,   160,     1,    -1,    -1,   162,    90,    62,    -1,
+      93,    -1,   163,    62,    93,    -1,    95,    -1,   164,    62,
+      95,    -1,    97,    -1,   165,    62,    97,    -1,   168,    -1,
+     166,    62,   168,    -1,   171,    -1,   167,    62,   171,    -1,
+     180,   142,   194,    -1,   170,   194,    -1,    59,   170,    60,
+     194,    -1,    53,   170,   194,    -1,    59,    53,   170,    60,
+     194,    -1,    53,    59,   170,    60,   194,    -1,    24,    -1,
+      24,    63,   137,    -1,   169,    -1,   134,   172,    -1,   169,
+      -1,    59,   169,    60,    -1,    59,   175,    60,   159,    -1,
+     132,    -1,   137,   132,    -1,   137,   141,    -1,   141,    -1,
+     173,    -1,   174,    75,   173,    -1,    -1,   174,   187,    -1,
+      -1,   100,    -1,    91,    -1,   177,    -1,     1,    -1,    98,
+      -1,   110,    -1,   118,    -1,   121,    -1,   113,    -1,    -1,
+     140,    66,   178,   176,    -1,    15,    -1,     5,   136,    -1,
+      10,   136,    -1,    18,   125,    -1,    13,   125,    -1,    19,
+     134,    -1,    27,   189,    -1,   176,    -1,   179,    62,   176,
+      -1,   134,    -1,   180,    75,   134,    -1,   135,    -1,   181,
+      75,   135,    -1,   123,    -1,   182,    75,   123,    -1,   131,
+      -1,   183,    75,   131,    -1,   128,    -1,   129,    -1,   184,
+      75,   128,    -1,   184,    75,   129,    -1,    -1,   184,   187,
+      -1,    -1,    62,    -1,    -1,    75,    -1,    -1,   123,    -1,
+      -1,   182,    -1,    -1,    98,    -1,    -1,   211,    -1,    -1,
+     212,    -1,    -1,   213,    -1,    -1,     3,    -1,    21,    24,
+       3,    62,    -1,    32,   196,   198,    62,    -1,     9,   196,
+      65,   209,    62,    -1,     9,   196,   198,    65,   209,    62,
+      -1,    31,   197,   198,    62,    -1,    17,   156,   158,    62,
+      -1,   138,    -1,   196,    -1,   200,    -1,   201,    -1,   202,
+      -1,   200,    -1,   202,    -1,   138,    -1,    24,    -1,    71,
+      72,   198,    -1,    71,     3,    72,   198,    -1,    23,    71,
+     198,    72,   198,    -1,    29,    67,   192,    68,    -1,    22,
+      67,   193,    68,    -1,    53,   198,    -1,     7,   199,    -1,
+       7,    59,   201,    60,    -1,     7,    36,   198,    -1,    36,
+       7,   198,    -1,    17,    59,   191,    60,   206,    -1,   137,
+     198,   194,    -1,   137,    11,   198,   194,    -1,   137,   198,
+     194,    -1,   137,    59,   191,    60,   206,    -1,   198,    -1,
+      -1,   207,    -1,    59,   191,    60,    -1,   198,    -1,     3,
+      -1,    50,     3,    -1,   137,    -1,   208,    -1,    59,   208,
+      49,   208,    60,    -1,    -1,   210,   195,    -1,   203,    -1,
+     211,    75,   203,    -1,   204,    -1,   212,    62,   204,    -1,
+     205,    -1,   213,    62,   205,    -1
 };
 
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
        0,   124,   124,   133,   140,   151,   151,   166,   167,   170,
-     171,   172,   175,   211,   212,   215,   222,   229,   238,   251,
-     252,   259,   259,   272,   276,   277,   281,   286,   292,   296,
-     300,   304,   310,   316,   322,   327,   331,   335,   341,   347,
-     351,   355,   361,   365,   371,   372,   376,   382,   391,   397,
-     401,   406,   418,   434,   439,   446,   466,   484,   493,   512,
-     511,   523,   522,   553,   556,   563,   562,   573,   579,   588,
-     599,   605,   608,   616,   615,   626,   632,   644,   648,   653,
-     643,   665,   668,   672,   679,   683,   678,   701,   700,   716,
-     717,   721,   725,   729,   733,   737,   741,   745,   749,   753,
-     757,   761,   765,   769,   773,   777,   781,   785,   789,   794,
-     800,   801,   805,   816,   820,   824,   828,   833,   837,   847,
-     851,   856,   864,   868,   869,   880,   884,   888,   892,   896,
-     897,   903,   910,   916,   923,   926,   933,   939,   940,   947,
-     948,   966,   967,   970,   973,   977,   988,   997,  1003,  1006,
-    1009,  1016,  1017,  1023,  1032,  1040,  1052,  1057,  1063,  1064,
-    1065,  1066,  1067,  1068,  1074,  1075,  1076,  1077,  1083,  1084,
-    1085,  1086,  1087,  1093,  1094,  1097,  1100,  1101,  1102,  1103,
-    1104,  1107,  1108,  1121,  1125,  1130,  1135,  1140,  1144,  1145,
-    1148,  1154,  1161,  1167,  1174,  1180,  1191,  1202,  1231,  1270,
-    1293,  1310,  1319,  1322,  1330,  1334,  1338,  1345,  1351,  1356,
-    1368,  1371,  1379,  1380,  1386,  1387,  1393,  1397,  1403,  1404,
-    1410,  1414,  1420,  1443,  1448,  1454,  1460,  1467,  1476,  1485,
-    1500,  1506,  1511,  1515,  1522,  1535,  1536,  1542,  1548,  1551,
-    1555,  1561,  1564,  1573,  1576,  1577,  1581,  1582,  1588,  1589,
-    1590,  1591,  1592,  1594,  1593,  1608,  1613,  1617,  1621,  1625,
-    1629,  1634,  1653,  1659,  1667,  1671,  1677,  1681,  1687,  1691,
-    1697,  1701,  1710,  1714,  1718,  1722,  1728,  1731,  1739,  1740,
-    1742,  1743,  1746,  1749,  1752,  1755,  1758,  1761,  1764,  1767,
-    1770,  1773,  1776,  1779,  1782,  1785,  1791,  1795,  1799,  1803,
-    1807,  1811,  1829,  1836,  1847,  1848,  1849,  1852,  1853,  1856,
-    1860,  1870,  1874,  1878,  1882,  1886,  1890,  1894,  1900,  1906,
-    1914,  1922,  1928,  1935,  1951,  1969,  1973,  1979,  1982,  1985,
-    1989,  1999,  2003,  2018,  2026,  2027,  2037,  2038,  2041,  2045,
-    2051,  2055,  2061,  2065
+     171,   172,   175,   208,   219,   220,   223,   230,   237,   246,
+     259,   260,   267,   267,   280,   284,   285,   289,   294,   300,
+     304,   308,   312,   318,   324,   330,   335,   339,   343,   349,
+     355,   359,   363,   369,   373,   379,   380,   384,   390,   399,
+     405,   409,   414,   426,   442,   447,   454,   474,   492,   501,
+     520,   519,   531,   530,   561,   564,   571,   570,   581,   587,
+     596,   607,   613,   616,   624,   623,   634,   640,   652,   656,
+     661,   651,   673,   676,   680,   687,   691,   686,   709,   708,
+     724,   725,   729,   733,   737,   741,   745,   749,   753,   757,
+     761,   765,   769,   773,   777,   781,   785,   789,   793,   797,
+     802,   808,   809,   813,   824,   828,   832,   836,   841,   845,
+     855,   859,   864,   872,   876,   877,   888,   892,   896,   900,
+     904,   905,   911,   918,   924,   931,   934,   941,   947,   948,
+     955,   956,   974,   975,   978,   981,   985,   996,  1005,  1011,
+    1014,  1017,  1024,  1025,  1031,  1040,  1048,  1060,  1065,  1071,
+    1072,  1073,  1074,  1075,  1076,  1082,  1083,  1084,  1085,  1091,
+    1092,  1093,  1094,  1095,  1101,  1102,  1105,  1108,  1109,  1110,
+    1111,  1112,  1115,  1116,  1129,  1133,  1138,  1143,  1148,  1152,
+    1153,  1156,  1162,  1169,  1175,  1182,  1188,  1199,  1210,  1239,
+    1278,  1301,  1318,  1327,  1330,  1338,  1342,  1346,  1353,  1359,
+    1364,  1376,  1379,  1387,  1388,  1394,  1395,  1401,  1405,  1411,
+    1412,  1418,  1422,  1428,  1451,  1456,  1462,  1468,  1475,  1484,
+    1493,  1508,  1514,  1519,  1523,  1530,  1543,  1544,  1550,  1556,
+    1559,  1563,  1569,  1572,  1581,  1584,  1585,  1589,  1590,  1596,
+    1597,  1598,  1599,  1600,  1602,  1601,  1616,  1621,  1625,  1629,
+    1633,  1637,  1642,  1661,  1667,  1675,  1679,  1685,  1689,  1695,
+    1699,  1705,  1709,  1718,  1722,  1726,  1730,  1736,  1739,  1747,
+    1748,  1750,  1751,  1754,  1757,  1760,  1763,  1766,  1769,  1772,
+    1775,  1778,  1781,  1784,  1787,  1790,  1793,  1799,  1803,  1807,
+    1811,  1815,  1819,  1837,  1844,  1855,  1856,  1857,  1860,  1861,
+    1864,  1868,  1878,  1882,  1886,  1890,  1894,  1898,  1902,  1908,
+    1914,  1922,  1930,  1936,  1943,  1959,  1977,  1981,  1987,  1990,
+    1993,  1997,  2007,  2011,  2026,  2034,  2035,  2045,  2046,  2049,
+    2053,  2059,  2063,  2069,  2073
 };
 #endif
 
@@ -775,709 +777,710 @@ static const yytype_uint16 yytoknum[] =
 static const yytype_uint8 yyr1[] =
 {
        0,    76,    77,    78,    78,    80,    79,    81,    81,    82,
-      82,    82,    83,    84,    84,    85,    85,    85,    86,    87,
-      87,    89,    88,    90,    90,    90,    90,    90,    91,    91,
-      91,    91,    91,    91,    91,    91,    91,    91,    92,    93,
-      93,    93,    94,    94,    95,    95,    95,    96,    97,    98,
-      98,    98,    98,    98,    98,    99,    99,    99,    99,   101,
-     100,   103,   102,   104,   104,   106,   105,   107,   107,   108,
-     108,   108,   109,   111,   110,   112,   112,   114,   115,   116,
-     113,   117,   117,   117,   119,   120,   118,   122,   121,   123,
+      82,    82,    83,    83,    84,    84,    85,    85,    85,    86,
+      87,    87,    89,    88,    90,    90,    90,    90,    90,    91,
+      91,    91,    91,    91,    91,    91,    91,    91,    91,    92,
+      93,    93,    93,    94,    94,    95,    95,    95,    96,    97,
+      98,    98,    98,    98,    98,    98,    99,    99,    99,    99,
+     101,   100,   103,   102,   104,   104,   106,   105,   107,   107,
+     108,   108,   108,   109,   111,   110,   112,   112,   114,   115,
+     116,   113,   117,   117,   117,   119,   120,   118,   122,   121,
      123,   123,   123,   123,   123,   123,   123,   123,   123,   123,
      123,   123,   123,   123,   123,   123,   123,   123,   123,   123,
-     124,   124,   124,   124,   124,   124,   124,   124,   124,   125,
-     125,   125,   126,   126,   126,   126,   126,   126,   126,   126,
-     126,   126,   126,   126,   126,   127,   128,   129,   129,   130,
-     130,   131,   131,   132,   133,   133,   134,   135,   136,   136,
-     137,   137,   137,   138,   139,   140,   141,   141,   142,   142,
-     142,   142,   142,   142,   143,   143,   143,   143,   144,   144,
-     144,   144,   144,   145,   145,   146,   147,   147,   147,   147,
-     147,   148,   148,   149,   149,   149,   149,   149,   149,   149,
-     150,   151,   152,   152,   153,   153,   154,   155,   155,   156,
-     156,   157,   158,   158,   159,   159,   159,   160,   161,   161,
-     162,   162,   163,   163,   164,   164,   165,   165,   166,   166,
-     167,   167,   168,   168,   168,   168,   168,   168,   169,   169,
-     170,   171,   171,   171,   172,   173,   173,   173,   173,   174,
-     174,   175,   175,   176,   176,   176,   176,   176,   177,   177,
-     177,   177,   177,   178,   177,   177,   177,   177,   177,   177,
-     177,   177,   179,   179,   180,   180,   181,   181,   182,   182,
-     183,   183,   184,   184,   184,   184,   185,   185,   186,   186,
-     187,   187,   188,   188,   189,   189,   190,   190,   191,   191,
-     192,   192,   193,   193,   194,   194,   195,   195,   195,   195,
-     195,   195,   196,   197,   198,   198,   198,   199,   199,   200,
+     123,   124,   124,   124,   124,   124,   124,   124,   124,   124,
+     125,   125,   125,   126,   126,   126,   126,   126,   126,   126,
+     126,   126,   126,   126,   126,   126,   127,   128,   129,   129,
+     130,   130,   131,   131,   132,   133,   133,   134,   135,   136,
+     136,   137,   137,   137,   138,   139,   140,   141,   141,   142,
+     142,   142,   142,   142,   142,   143,   143,   143,   143,   144,
+     144,   144,   144,   144,   145,   145,   146,   147,   147,   147,
+     147,   147,   148,   148,   149,   149,   149,   149,   149,   149,
+     149,   150,   151,   152,   152,   153,   153,   154,   155,   155,
+     156,   156,   157,   158,   158,   159,   159,   159,   160,   161,
+     161,   162,   162,   163,   163,   164,   164,   165,   165,   166,
+     166,   167,   167,   168,   168,   168,   168,   168,   168,   169,
+     169,   170,   171,   171,   171,   172,   173,   173,   173,   173,
+     174,   174,   175,   175,   176,   176,   176,   176,   176,   177,
+     177,   177,   177,   177,   178,   177,   177,   177,   177,   177,
+     177,   177,   177,   179,   179,   180,   180,   181,   181,   182,
+     182,   183,   183,   184,   184,   184,   184,   185,   185,   186,
+     186,   187,   187,   188,   188,   189,   189,   190,   190,   191,
+     191,   192,   192,   193,   193,   194,   194,   195,   195,   195,
+     195,   195,   195,   196,   197,   198,   198,   198,   199,   199,
      200,   200,   200,   200,   200,   200,   200,   200,   200,   200,
-     201,   202,   203,   203,   204,   205,   205,   206,   206,   207,
-     207,   208,   208,   208,   209,   209,   210,   210,   211,   211,
-     212,   212,   213,   213
+     200,   201,   202,   203,   203,   204,   205,   205,   206,   206,
+     207,   207,   208,   208,   208,   209,   209,   210,   210,   211,
+     211,   212,   212,   213,   213
 };
 
 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
 static const yytype_uint8 yyr2[] =
 {
        0,     2,     4,     0,     3,     0,     3,     0,     3,     2,
-       5,     3,     3,     1,     3,     1,     2,     2,     4,     0,
-       1,     0,     4,     0,     1,     1,     1,     1,     2,     5,
-       3,     2,     5,     7,     3,     2,     5,     3,     1,     2,
-       4,     3,     4,     3,     1,     2,     1,     1,     2,     1,
-       3,     3,     3,     2,     2,     3,     5,     5,     2,     0,
-       4,     0,     3,     0,     2,     0,     4,     4,     4,     5,
-       1,     1,     2,     0,     3,     1,     3,     0,     0,     0,
-       7,     0,     2,     2,     0,     0,     7,     0,     5,     1,
+       5,     3,     3,     2,     1,     3,     1,     2,     2,     4,
+       0,     1,     0,     4,     0,     1,     1,     1,     1,     2,
+       5,     3,     2,     5,     7,     3,     2,     5,     3,     1,
+       2,     4,     3,     4,     3,     1,     2,     1,     1,     2,
+       1,     3,     3,     3,     2,     2,     3,     5,     5,     2,
+       0,     4,     0,     3,     0,     2,     0,     4,     4,     4,
+       5,     1,     1,     2,     0,     3,     1,     3,     0,     0,
+       0,     7,     0,     2,     2,     0,     0,     7,     0,     5,
+       1,     3,     3,     3,     3,     3,     3,     3,     3,     3,
        3,     3,     3,     3,     3,     3,     3,     3,     3,     3,
-       3,     3,     3,     3,     3,     3,     3,     3,     3,     3,
-       1,     2,     2,     2,     2,     2,     2,     2,     2,     3,
-       5,     6,     1,     1,     3,     5,     5,     4,     6,     1,
-       4,     5,     5,     7,     1,     0,     3,     1,     4,     1,
-       3,     1,     1,     1,     1,     1,     1,     1,     0,     1,
-       1,     1,     1,     4,     1,     1,     1,     2,     1,     1,
-       1,     1,     1,     3,     1,     1,     1,     2,     1,     1,
-       1,     1,     3,     1,     1,     1,     1,     1,     1,     1,
-       1,     1,     3,     4,     4,     2,     3,     5,     1,     1,
-       2,     3,     5,     3,     5,     3,     3,     5,     8,     5,
-       8,     5,     0,     3,     0,     1,     3,     1,     4,     2,
-       0,     3,     1,     3,     1,     3,     1,     3,     1,     3,
-       1,     3,     3,     2,     4,     3,     5,     5,     1,     3,
-       1,     2,     1,     3,     4,     1,     2,     2,     1,     1,
-       3,     0,     2,     0,     1,     1,     1,     1,     1,     1,
-       1,     1,     1,     0,     4,     1,     2,     2,     2,     2,
-       2,     2,     1,     3,     1,     3,     1,     3,     1,     3,
-       1,     3,     1,     1,     3,     3,     0,     2,     0,     1,
-       0,     1,     0,     1,     0,     1,     0,     1,     0,     1,
-       0,     1,     0,     1,     0,     1,     4,     4,     5,     6,
-       4,     4,     1,     1,     1,     1,     1,     1,     1,     1,
-       1,     3,     4,     5,     4,     4,     2,     2,     4,     3,
-       3,     5,     3,     4,     3,     5,     1,     0,     1,     3,
-       1,     1,     2,     1,     1,     5,     0,     2,     1,     3,
-       1,     3,     1,     3
+       3,     1,     2,     2,     2,     2,     2,     2,     2,     2,
+       3,     5,     6,     1,     1,     3,     5,     5,     4,     6,
+       1,     4,     5,     5,     7,     1,     0,     3,     1,     4,
+       1,     3,     1,     1,     1,     1,     1,     1,     1,     0,
+       1,     1,     1,     1,     4,     1,     1,     1,     2,     1,
+       1,     1,     1,     1,     3,     1,     1,     1,     2,     1,
+       1,     1,     1,     3,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     3,     4,     4,     2,     3,     5,     1,
+       1,     2,     3,     5,     3,     5,     3,     3,     5,     8,
+       5,     8,     5,     0,     3,     0,     1,     3,     1,     4,
+       2,     0,     3,     1,     3,     1,     3,     1,     3,     1,
+       3,     1,     3,     3,     2,     4,     3,     5,     5,     1,
+       3,     1,     2,     1,     3,     4,     1,     2,     2,     1,
+       1,     3,     0,     2,     0,     1,     1,     1,     1,     1,
+       1,     1,     1,     1,     0,     4,     1,     2,     2,     2,
+       2,     2,     2,     1,     3,     1,     3,     1,     3,     1,
+       3,     1,     3,     1,     1,     3,     3,     0,     2,     0,
+       1,     0,     1,     0,     1,     0,     1,     0,     1,     0,
+       1,     0,     1,     0,     1,     0,     1,     4,     4,     5,
+       6,     4,     4,     1,     1,     1,     1,     1,     1,     1,
+       1,     1,     3,     4,     5,     4,     4,     2,     2,     4,
+       3,     3,     5,     3,     4,     3,     5,     1,     0,     1,
+       3,     1,     1,     2,     1,     1,     5,     0,     2,     1,
+       3,     1,     3,     1,     3
 };
 
-/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
-   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
+/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
+   Performed when YYTABLE doesn't specify something else to do.  Zero
    means the default is an error.  */
 static const yytype_uint16 yydefact[] =
 {
-       5,     0,     3,     0,     1,     0,     7,     0,    21,   150,
-     152,     0,     0,   151,   210,    19,     6,   336,     0,     4,
-       0,     0,     0,    20,     0,     0,     0,    15,     0,     0,
-       9,     0,     0,     8,    27,   122,   148,     0,    38,   148,
-       0,   255,    73,     0,     0,     0,    77,     0,     0,   284,
-      87,     0,    84,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,   282,     0,    24,     0,   248,   249,
-     252,   250,   251,    49,    89,   129,   139,   110,   155,   154,
-     123,     0,     0,     0,   175,   188,   189,    25,   207,     0,
-     134,    26,     0,    18,     0,     0,     0,     0,     0,     0,
-     337,   153,    11,    13,   278,    17,    21,    16,   149,   256,
-     146,     0,     0,     0,     0,   154,   181,   185,   171,   169,
-     170,   168,   257,   129,     0,   286,   241,     0,   202,   129,
-     260,   286,   144,   145,     0,     0,   268,   285,   261,     0,
-       0,   286,     0,     0,    35,    47,     0,    28,   266,   147,
-       0,   118,   113,   114,   117,   111,   112,     0,     0,   141,
-       0,   142,   166,   164,   165,   115,   116,     0,   283,     0,
-     211,     0,    31,     0,     0,     0,     0,     0,    54,     0,
-       0,     0,    53,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,   135,     0,     0,
-     282,   253,     0,   135,   209,     0,     0,     0,     0,   302,
-       0,     0,   202,     0,     0,   303,     0,     0,    22,   279,
-       0,    12,   241,     0,     0,   186,   162,   160,   161,   158,
-     159,   190,     0,     0,   287,    71,     0,    74,     0,    70,
-     156,   235,   154,   238,   143,   239,   280,     0,   241,     0,
-     196,    78,    75,   150,     0,   195,     0,   278,   232,   220,
-       0,    63,     0,     0,   193,   264,   278,   218,   230,   294,
-       0,    85,    37,   216,   278,    48,    30,   212,   278,     0,
-       0,    39,     0,   167,   140,     0,     0,    34,   278,     0,
-       0,    50,    91,   106,   109,    92,    96,    97,    95,   107,
-      94,    93,    90,   108,    98,    99,   100,   101,   102,   103,
-     104,   105,   276,   119,   270,   280,     0,   124,   283,     0,
-       0,     0,   276,   247,    59,   245,   244,   262,   246,     0,
-      52,    51,   269,     0,     0,     0,     0,   310,     0,     0,
-       0,     0,     0,   309,     0,   304,   305,   306,     0,   338,
-       0,     0,   288,     0,     0,     0,    14,    10,     0,     0,
-       0,   172,   182,    65,    72,     0,     0,   286,   157,   236,
-     237,   281,   242,   204,     0,     0,     0,   286,     0,   228,
-       0,   241,   231,   279,     0,     0,     0,     0,   294,     0,
-       0,   279,     0,   295,   223,     0,   294,     0,   279,     0,
-     279,     0,    41,   267,     0,     0,     0,   191,   162,   160,
-     161,   159,   135,   184,   183,   279,     0,    43,     0,   135,
-     137,   272,   273,   280,     0,   280,   281,     0,     0,     0,
-     127,   282,   254,   130,     0,     0,     0,   208,     0,     0,
-     317,   307,   308,   288,   292,     0,   290,     0,   316,   331,
-       0,     0,   333,   334,     0,     0,     0,     0,     0,   294,
-       0,     0,   301,     0,   289,   296,   300,   297,   204,   163,
-       0,     0,     0,     0,   240,   241,   154,   205,   180,   178,
-     179,   176,   177,   201,   204,   203,    79,    76,   229,   233,
-       0,   221,   194,   187,     0,     0,    88,    61,    64,     0,
-     225,     0,   294,   219,   192,   265,   222,    63,   217,    36,
-     213,    29,    40,     0,   276,    44,   214,   278,    46,    32,
-      42,   276,     0,   281,   277,   132,   281,     0,   271,   120,
-     126,   125,     0,   131,     0,   263,   319,     0,     0,   310,
-       0,   309,     0,   326,   342,   293,     0,     0,     0,   340,
-     291,   320,   332,     0,   298,     0,   311,     0,   294,   322,
-       0,   339,   327,     0,    68,    67,   286,     0,   241,   197,
-      81,   204,     0,    58,     0,   294,   294,   224,     0,   163,
-       0,   279,     0,    45,     0,   137,   136,   274,   275,   121,
-     128,    60,   318,   327,   288,   315,     0,     0,   294,   314,
-       0,     0,   312,   299,   323,   288,   288,   330,   199,   328,
-      66,    69,   206,     0,     0,    80,   234,     0,     0,    55,
-       0,    62,   227,   226,    86,   133,   215,    33,   138,   321,
-       0,   343,   313,   324,   341,     0,     0,     0,   204,    83,
-      82,     0,     0,   327,   335,   327,   329,   198,    57,    56,
-     325,   200
+       5,     0,     3,     0,     1,     0,     7,     0,    22,   151,
+     153,     0,     0,   152,   211,    20,     6,   337,     0,     4,
+       0,     0,     0,    21,     0,     0,     0,    16,     0,     0,
+       9,    22,     0,     8,    28,   123,   149,     0,    39,   149,
+       0,   256,    74,     0,     0,     0,    78,     0,     0,   285,
+      88,     0,    85,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,   283,     0,    25,     0,   249,   250,
+     253,   251,   252,    50,    90,   130,   140,   111,   156,   155,
+     124,     0,     0,     0,   176,   189,   190,    26,   208,     0,
+     135,    27,     0,    19,     0,     0,     0,     0,     0,     0,
+     338,   154,    11,    14,   279,    18,    22,    13,    17,   150,
+     257,   147,     0,     0,     0,     0,   155,   182,   186,   172,
+     170,   171,   169,   258,   130,     0,   287,   242,     0,   203,
+     130,   261,   287,   145,   146,     0,     0,   269,   286,   262,
+       0,     0,   287,     0,     0,    36,    48,     0,    29,   267,
+     148,     0,   119,   114,   115,   118,   112,   113,     0,     0,
+     142,     0,   143,   167,   165,   166,   116,   117,     0,   284,
+       0,   212,     0,    32,     0,     0,     0,     0,     0,    55,
+       0,     0,     0,    54,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,   136,     0,
+       0,   283,   254,     0,   136,   210,     0,     0,     0,     0,
+     303,     0,     0,   203,     0,     0,   304,     0,     0,    23,
+     280,     0,    12,   242,     0,     0,   187,   163,   161,   162,
+     159,   160,   191,     0,     0,   288,    72,     0,    75,     0,
+      71,   157,   236,   155,   239,   144,   240,   281,     0,   242,
+       0,   197,    79,    76,   151,     0,   196,     0,   279,   233,
+     221,     0,    64,     0,     0,   194,   265,   279,   219,   231,
+     295,     0,    86,    38,   217,   279,    49,    31,   213,   279,
+       0,     0,    40,     0,   168,   141,     0,     0,    35,   279,
+       0,     0,    51,    92,   107,   110,    93,    97,    98,    96,
+     108,    95,    94,    91,   109,    99,   100,   101,   102,   103,
+     104,   105,   106,   277,   120,   271,   281,     0,   125,   284,
+       0,     0,     0,   277,   248,    60,   246,   245,   263,   247,
+       0,    53,    52,   270,     0,     0,     0,     0,   311,     0,
+       0,     0,     0,     0,   310,     0,   305,   306,   307,     0,
+     339,     0,     0,   289,     0,     0,     0,    15,    10,     0,
+       0,     0,   173,   183,    66,    73,     0,     0,   287,   158,
+     237,   238,   282,   243,   205,     0,     0,     0,   287,     0,
+     229,     0,   242,   232,   280,     0,     0,     0,     0,   295,
+       0,     0,   280,     0,   296,   224,     0,   295,     0,   280,
+       0,   280,     0,    42,   268,     0,     0,     0,   192,   163,
+     161,   162,   160,   136,   185,   184,   280,     0,    44,     0,
+     136,   138,   273,   274,   281,     0,   281,   282,     0,     0,
+       0,   128,   283,   255,   131,     0,     0,     0,   209,     0,
+       0,   318,   308,   309,   289,   293,     0,   291,     0,   317,
+     332,     0,     0,   334,   335,     0,     0,     0,     0,     0,
+     295,     0,     0,   302,     0,   290,   297,   301,   298,   205,
+     164,     0,     0,     0,     0,   241,   242,   155,   206,   181,
+     179,   180,   177,   178,   202,   205,   204,    80,    77,   230,
+     234,     0,   222,   195,   188,     0,     0,    89,    62,    65,
+       0,   226,     0,   295,   220,   193,   266,   223,    64,   218,
+      37,   214,    30,    41,     0,   277,    45,   215,   279,    47,
+      33,    43,   277,     0,   282,   278,   133,   282,     0,   272,
+     121,   127,   126,     0,   132,     0,   264,   320,     0,     0,
+     311,     0,   310,     0,   327,   343,   294,     0,     0,     0,
+     341,   292,   321,   333,     0,   299,     0,   312,     0,   295,
+     323,     0,   340,   328,     0,    69,    68,   287,     0,   242,
+     198,    82,   205,     0,    59,     0,   295,   295,   225,     0,
+     164,     0,   280,     0,    46,     0,   138,   137,   275,   276,
+     122,   129,    61,   319,   328,   289,   316,     0,     0,   295,
+     315,     0,     0,   313,   300,   324,   289,   289,   331,   200,
+     329,    67,    70,   207,     0,     0,    81,   235,     0,     0,
+      56,     0,    63,   228,   227,    87,   134,   216,    34,   139,
+     322,     0,   344,   314,   325,   342,     0,     0,     0,   205,
+      84,    83,     0,     0,   328,   336,   328,   330,   199,    58,
+      57,   326,   201
 };
 
 /* YYDEFGOTO[NTERM-NUM].  */
 static const yytype_int16 yydefgoto[] =
 {
       -1,     1,     6,     2,     3,    14,    21,    30,   104,    31,
-       8,    24,    16,    17,    65,   325,    67,   147,   515,   516,
-     143,   144,    68,   497,   326,   435,   498,   574,   386,   364,
-     470,   235,   236,   237,    69,   125,   251,    70,   131,   376,
-     570,   615,    71,   141,   397,    72,   139,    73,    74,    75,
-      76,   312,   421,   422,    77,   314,   241,   134,    78,   148,
-     109,   115,    13,    80,    81,   243,   244,   161,   117,    82,
-      83,   477,   226,    84,   228,   229,    85,    86,    87,   128,
-     212,    88,   250,   483,    89,    90,    22,   278,   517,   274,
-     266,   257,   267,   268,   269,   259,   382,   245,   246,   247,
-     327,   328,   320,   329,   270,   150,    92,   315,   423,   424,
-     220,   372,   169,   138,   252,   463,   548,   542,   394,   100,
-     210,   216,   607,   440,   345,   346,   347,   349,   549,   544,
-     608,   609,   453,   454,    25,   464,   550,   545
+       8,    24,    16,    17,    65,   326,    67,   148,   516,   517,
+     144,   145,    68,   498,   327,   436,   499,   575,   387,   365,
+     471,   236,   237,   238,    69,   126,   252,    70,   132,   377,
+     571,   616,    71,   142,   398,    72,   140,    73,    74,    75,
+      76,   313,   422,   423,    77,   315,   242,   135,    78,   149,
+     110,   116,    13,    80,    81,   244,   245,   162,   118,    82,
+      83,   478,   227,    84,   229,   230,    85,    86,    87,   129,
+     213,    88,   251,   484,    89,    90,    22,   279,   518,   275,
+     267,   258,   268,   269,   270,   260,   383,   246,   247,   248,
+     328,   329,   321,   330,   271,   151,    92,   316,   424,   425,
+     221,   373,   170,   139,   253,   464,   549,   543,   395,   100,
+     211,   217,   608,   441,   346,   347,   348,   350,   550,   545,
+     609,   610,   454,   455,    25,   465,   551,   546
 };
 
 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
    STATE-NUM.  */
-#define YYPACT_NINF -516
+#define YYPACT_NINF -551
 static const yytype_int16 yypact[] =
 {
-    -516,    69,    27,    75,  -516,   161,  -516,   125,  -516,  -516,
-    -516,   164,   113,  -516,   156,   166,  -516,  -516,   142,  -516,
-      44,   145,  1036,  -516,   165,   275,   206,  -516,   139,   243,
-    -516,    75,   244,  -516,  -516,  -516,   161,    60,  -516,   161,
-     771,  -516,  -516,   150,   771,   161,  -516,   137,   177,  1473,
-    -516,   137,  -516,   434,   474,  1473,  1473,  1473,  1473,  1473,
-    1473,  1528,  1473,  1473,   710,   192,  -516,   486,  -516,  -516,
-    -516,  -516,  -516,   847,  -516,  -516,   190,   174,  -516,   200,
-    -516,   211,   223,   137,   238,  -516,  -516,  -516,   241,   186,
-    -516,  -516,    45,  -516,   224,    11,   279,   224,   224,   240,
-    -516,  -516,  -516,  -516,   252,  -516,  -516,  -516,  -516,  -516,
-    -516,   246,  1736,  1736,  1736,  -516,   255,  -516,  -516,  -516,
-    -516,  -516,  -516,    33,   174,  1473,  1697,   263,   265,   219,
-    -516,  1473,  -516,  -516,   347,  1736,  2030,   259,  -516,   302,
-     423,  1473,   228,  1736,  -516,  -516,   331,  -516,  -516,  -516,
-    1638,  -516,  -516,  -516,  -516,  -516,  -516,  1583,  1528,  2030,
-     278,  -516,    31,  -516,   183,  -516,  -516,   288,  2030,   292,
-    -516,   334,  -516,  1663,  1473,  1473,  1473,  1473,  -516,  1473,
-    1473,  1473,  -516,  1473,  1473,  1473,  1473,  1473,  1473,  1473,
-    1473,  1473,  1473,  1473,  1473,  1473,  1473,  -516,   934,   529,
-    1473,  -516,  1473,  -516,  -516,  1195,  1473,  1473,  1473,  -516,
-     782,   161,   265,   285,   364,  -516,  1264,  1264,  -516,   216,
-     290,  -516,  1697,   363,  1736,  -516,  -516,  -516,  -516,  -516,
-    -516,  -516,   312,   161,  -516,  -516,   340,  -516,    79,   323,
-    1736,  -516,  1697,  -516,  -516,  -516,   326,   327,  1697,  1195,
-    -516,  -516,   336,    85,   379,  -516,   354,   355,  -516,  -516,
-     353,  -516,    50,   112,  -516,  -516,   365,  -516,  -516,   426,
-    1671,  -516,  -516,  -516,   372,  -516,  -516,  -516,   378,  1473,
-     161,   361,  1740,  -516,   387,  1736,  1736,  -516,   397,  1473,
-     380,  2030,  2101,  -516,  2054,   616,   616,   616,   616,  -516,
-     616,   616,  2078,  -516,   585,   585,   585,   585,  -516,  -516,
-    -516,  -516,  1253,  -516,  -516,    40,  1308,  -516,  1903,   396,
-    1121,  2005,  1253,  -516,  -516,  -516,  -516,  -516,  -516,    29,
-     259,   259,  2030,  1811,   407,   400,   406,  -516,   401,   473,
-    1264,    52,    34,  -516,   418,  -516,  -516,  -516,   925,  -516,
-      19,   422,   161,   424,   428,   430,  -516,  -516,   435,  1736,
-     445,  -516,  -516,  -516,  -516,  1363,  1418,  1473,  -516,  -516,
-    -516,  1697,  -516,  1768,   452,   127,   340,  1473,   161,   425,
-     454,  1697,  -516,   554,   448,  1736,   102,   379,   426,   379,
-     457,   477,   455,  -516,  -516,   161,   426,   485,   161,   466,
-     161,   468,   259,  -516,  1473,  1779,  1736,  -516,   260,   274,
-     276,   310,  -516,  -516,  -516,   161,   469,   259,  1473,  -516,
-    1933,  -516,  -516,   464,   475,   467,  1528,   481,   484,   489,
-    -516,  1473,  -516,  -516,   478,  1195,  1121,  -516,  1264,   518,
-    -516,  -516,  -516,   161,  1837,  1264,   161,  1264,  -516,  -516,
-     552,   307,  -516,  -516,   495,   490,  1264,    52,  1264,   426,
-     161,   161,  -516,   498,   491,  -516,  -516,  -516,  1768,  -516,
-    1195,  1473,  1473,   506,  -516,  1697,   511,  -516,  -516,  -516,
-    -516,  -516,  -516,  -516,  1768,  -516,  -516,  -516,  -516,  -516,
-     505,  -516,  -516,  -516,  1528,   508,  -516,  -516,  -516,   512,
-    -516,   515,   426,  -516,  -516,  -516,  -516,  -516,  -516,  -516,
-    -516,  -516,   259,   517,  1253,  -516,  -516,   509,  1663,  -516,
-     259,  1253,  1253,  1253,  -516,  -516,  -516,   519,  -516,  -516,
-    -516,  -516,   510,  -516,   202,  -516,  -516,   520,   523,   525,
-     526,   528,   522,  -516,  -516,   532,   527,  1264,   536,  -516,
-     535,  -516,  -516,   567,  -516,  1264,  -516,   555,   426,  -516,
-     559,  -516,  1864,   231,  2030,  2030,  1473,   563,  1697,  -516,
-     611,  1768,    57,  -516,  1121,   426,   426,  -516,   226,   383,
-     558,   161,   571,   380,   564,  2030,  -516,  -516,  -516,  -516,
-    -516,  -516,  -516,  1864,   161,  -516,  1837,  1264,   426,  -516,
-     161,   307,  -516,  -516,  -516,   161,   161,  -516,  -516,  -516,
-    -516,  -516,  -516,   575,    26,  -516,  -516,  1473,  1473,  -516,
-    1528,   574,  -516,  -516,  -516,  -516,  -516,  -516,  -516,  -516,
-     577,  -516,  -516,  -516,  -516,   582,   583,   586,  1768,  -516,
-    -516,  1957,  1981,  1864,  -516,  1864,  -516,  -516,  -516,  -516,
-    -516,  -516
+    -551,    46,    48,   121,  -551,    58,  -551,   135,  -551,  -551,
+    -551,    65,    72,  -551,   147,   156,  -551,  -551,   112,  -551,
+      50,   134,   904,  -551,   162,   463,   209,  -551,    54,   237,
+    -551,   121,   245,  -551,  -551,  -551,    58,  1666,  -551,    58,
+     288,  -551,  -551,    34,   288,    58,  -551,    36,   184,  1467,
+    -551,    36,  -551,   316,   462,  1467,  1467,  1467,  1467,  1467,
+    1467,  1522,  1467,  1467,   965,   198,  -551,   506,  -551,  -551,
+    -551,  -551,  -551,   796,  -551,  -551,   195,     1,  -551,   199,
+    -551,   207,   216,    36,   221,  -551,  -551,  -551,   226,    53,
+    -551,  -551,   108,  -551,   214,   110,   269,   214,   214,   233,
+    -551,  -551,  -551,  -551,   238,  -551,  -551,  -551,  -551,  -551,
+    -551,  -551,   242,  1691,  1691,  1691,  -551,   240,  -551,  -551,
+    -551,  -551,  -551,  -551,   154,     1,  1467,  1658,   247,   246,
+     290,  -551,  1467,  -551,  -551,   419,  1691,  2004,   229,  -551,
+     272,   333,  1467,   258,  1691,  -551,  -551,   485,  -551,  -551,
+    -551,   656,  -551,  -551,  -551,  -551,  -551,  -551,  1577,  1522,
+    2004,   255,  -551,    10,  -551,    51,  -551,  -551,   251,  2004,
+     256,  -551,   508,  -551,  1632,  1467,  1467,  1467,  1467,  -551,
+    1467,  1467,  1467,  -551,  1467,  1467,  1467,  1467,  1467,  1467,
+    1467,  1467,  1467,  1467,  1467,  1467,  1467,  1467,  -551,  1192,
+     552,  1467,  -551,  1467,  -551,  -551,  1134,  1467,  1467,  1467,
+    -551,  1203,    58,   246,   260,   332,  -551,  1838,  1838,  -551,
+      76,   282,  -551,  1658,   344,  1691,  -551,  -551,  -551,  -551,
+    -551,  -551,  -551,   293,    58,  -551,  -551,   328,  -551,   178,
+     303,  1691,  -551,  1658,  -551,  -551,  -551,   295,   308,  1658,
+    1134,  -551,  -551,   309,   271,   364,  -551,   334,   337,  -551,
+    -551,   330,  -551,    11,    66,  -551,  -551,   342,  -551,  -551,
+     397,   664,  -551,  -551,  -551,   351,  -551,  -551,  -551,   352,
+    1467,    58,   343,  1719,  -551,   349,  1691,  1691,  -551,   356,
+    1467,   357,  2004,  2075,  -551,  2028,   692,   692,   692,   692,
+    -551,   692,   692,  2052,  -551,   593,   593,   593,   593,  -551,
+    -551,  -551,  -551,  1247,  -551,  -551,    22,  1302,  -551,  1877,
+     355,  1060,  1979,  1247,  -551,  -551,  -551,  -551,  -551,  -551,
+      86,   229,   229,  2004,  1777,   367,   361,   359,  -551,   366,
+     427,  1838,    52,    29,  -551,   370,  -551,  -551,  -551,   784,
+    -551,   118,   379,    58,   396,   400,   401,  -551,  -551,   404,
+    1691,   409,  -551,  -551,  -551,  -551,  1357,  1412,  1467,  -551,
+    -551,  -551,  1658,  -551,  1744,   414,   109,   328,  1467,    58,
+     416,   423,  1658,  -551,   561,   417,  1691,    44,   364,   397,
+     364,   428,   451,   421,  -551,  -551,    58,   397,   456,    58,
+     436,    58,   438,   229,  -551,  1467,  1752,  1691,  -551,    24,
+     171,   287,   338,  -551,  -551,  -551,    58,   439,   229,  1467,
+    -551,  1907,  -551,  -551,   425,   435,   430,  1522,   446,   448,
+     453,  -551,  1467,  -551,  -551,   443,  1134,  1060,  -551,  1838,
+     479,  -551,  -551,  -551,    58,  1805,  1838,    58,  1838,  -551,
+    -551,   514,   161,  -551,  -551,   460,   454,  1838,    52,  1838,
+     397,    58,    58,  -551,   458,   459,  -551,  -551,  -551,  1744,
+    -551,  1134,  1467,  1467,   467,  -551,  1658,   472,  -551,  -551,
+    -551,  -551,  -551,  -551,  -551,  1744,  -551,  -551,  -551,  -551,
+    -551,   477,  -551,  -551,  -551,  1522,   474,  -551,  -551,  -551,
+     482,  -551,   500,   397,  -551,  -551,  -551,  -551,  -551,  -551,
+    -551,  -551,  -551,   229,   501,  1247,  -551,  -551,   505,  1632,
+    -551,   229,  1247,  1247,  1247,  -551,  -551,  -551,   503,  -551,
+    -551,  -551,  -551,   511,  -551,   137,  -551,  -551,   518,   528,
+     532,   534,   535,   530,  -551,  -551,   537,   533,  1838,   536,
+    -551,   538,  -551,  -551,   560,  -551,  1838,  -551,   551,   397,
+    -551,   557,  -551,  1830,   151,  2004,  2004,  1467,   558,  1658,
+    -551,   605,  1744,   125,  -551,  1060,   397,   397,  -551,    75,
+     360,   554,    58,   563,   357,   556,  2004,  -551,  -551,  -551,
+    -551,  -551,  -551,  -551,  1830,    58,  -551,  1805,  1838,   397,
+    -551,    58,   161,  -551,  -551,  -551,    58,    58,  -551,  -551,
+    -551,  -551,  -551,  -551,   570,    78,  -551,  -551,  1467,  1467,
+    -551,  1522,   569,  -551,  -551,  -551,  -551,  -551,  -551,  -551,
+    -551,   576,  -551,  -551,  -551,  -551,   578,   582,   584,  1744,
+    -551,  -551,  1931,  1955,  1830,  -551,  1830,  -551,  -551,  -551,
+    -551,  -551,  -551
 };
 
 /* YYPGOTO[NTERM-NUM].  */
 static const yytype_int16 yypgoto[] =
 {
-    -516,  -516,  -516,  -516,  -516,  -516,  -516,    -4,  -516,  -516,
-     618,  -516,   541,  -516,  -516,   629,  -516,  -137,   -25,    71,
-    -516,  -139,  -109,  -516,    39,  -516,  -516,  -516,   149,   281,
-    -516,  -516,  -516,  -516,  -516,  -516,   521,    47,  -516,  -516,
-    -516,  -516,  -516,  -516,  -516,  -516,  -516,   503,     1,   272,
-    -516,  -190,   136,  -450,   277,   -47,   431,     3,     5,   394,
-     636,    -5,   405,   239,  -516,   443,   249,   542,  -516,  -516,
-    -516,  -516,   -33,    38,   -31,    10,  -516,  -516,  -516,  -516,
-    -516,    43,   492,  -459,  -516,  -516,  -516,  -516,  -516,  -516,
-    -516,  -516,   311,  -127,  -227,   325,  -516,   335,  -516,  -220,
-    -293,   690,  -516,  -244,  -516,   -66,    67,   221,  -516,  -311,
-    -245,  -285,  -192,  -516,  -106,  -423,  -516,  -516,  -378,  -516,
-     377,  -516,   376,  -516,   385,   280,   389,   264,   120,   130,
-    -515,  -516,  -425,   271,  -516,   524,  -516,  -516
+    -551,  -551,  -551,  -551,  -551,  -551,  -551,    -6,  -551,  -551,
+     608,  -551,   -11,  -551,  -551,   623,  -551,  -134,   -25,    68,
+    -551,  -135,  -121,  -551,    39,  -551,  -551,  -551,   145,   278,
+    -551,  -551,  -551,  -551,  -551,  -551,   515,    41,  -551,  -551,
+    -551,  -551,  -551,  -551,  -551,  -551,  -551,   579,   493,    45,
+    -551,  -192,   138,  -246,   192,   -47,   415,   200,   -20,   380,
+     626,    -5,   449,   346,  -551,   426,    95,   509,  -551,  -551,
+    -551,  -551,   -33,    38,   -31,   -18,  -551,  -551,  -551,  -551,
+    -551,    43,   457,  -467,  -551,  -551,  -551,  -551,  -551,  -551,
+    -551,  -551,   280,  -126,  -227,   292,  -551,   302,  -551,  -220,
+    -297,   662,  -551,  -248,  -551,   -66,    18,   194,  -551,  -295,
+    -228,  -289,  -191,  -551,  -119,  -403,  -551,  -551,  -305,  -551,
+     -32,  -551,   127,  -551,   362,   250,   363,   232,    90,    98,
+    -550,  -551,  -426,   241,  -551,   486,  -551,  -551
 };
 
 /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
    positive, shift that token.  If negative, reduce the rule which
-   number is the opposite.  If zero, do what YYDEFACT says.
-   If YYTABLE_NINF, syntax error.  */
-#define YYTABLE_NINF -269
+   number is the opposite.  If YYTABLE_NINF, syntax error.  */
+#define YYTABLE_NINF -270
 static const yytype_int16 yytable[] =
 {
-      12,   173,   358,   273,   118,   375,   120,   258,   319,   277,
-     500,   434,   384,   322,   160,    32,   234,    79,   506,   239,
-     538,   392,   234,    32,   103,   569,   553,   432,   374,   399,
-     427,   110,   234,   401,   110,   388,   390,   455,   127,  -259,
-     110,   108,   172,   416,   108,  -259,    46,    27,   145,   149,
-     130,   425,     5,   206,   140,   449,   151,   152,   153,   154,
-     155,   156,   149,   165,   166,   617,  -175,    37,     9,     4,
-     211,   163,   586,   588,   379,   119,     9,   111,   629,   460,
-     121,   559,    47,    48,     9,    11,   203,   365,  -228,    51,
-    -174,   436,   205,   324,   461,  -259,   112,   437,  -175,   162,
-       7,  -259,   450,    28,   164,   173,   456,    29,   494,   387,
-     207,   451,   616,   113,   495,   426,   137,    10,    11,   114,
-     208,   242,   618,   619,   577,    10,    11,   380,   650,   110,
-     651,    64,   620,    10,    11,   110,   379,   145,   524,   256,
-     527,   149,    27,   535,   366,   265,   288,  -228,   378,    15,
-     227,   227,   227,  -228,   208,   230,   230,   230,   151,   155,
-     499,   490,   501,     9,   227,   389,   149,    18,   163,   230,
-     496,   630,   132,   227,     9,    19,   635,    20,   230,   647,
-     604,   227,   636,   637,  -207,     9,   230,   204,   227,   436,
-      23,   534,   238,   230,   317,   485,   162,   622,   623,   102,
-      79,   164,    29,   580,   133,    26,   348,    33,   163,   126,
-     584,   227,    10,    11,    32,   356,   230,   242,  -207,    27,
-     633,   132,   514,    10,    11,  -258,   563,    93,   362,   521,
-     101,  -258,   494,   198,    10,    11,   162,   199,   495,   532,
-       9,   164,  -173,   242,    79,   200,   105,   107,   135,   408,
-    -207,   410,     9,   133,   170,   567,   258,   197,   234,   508,
-     227,   473,   227,   510,   436,   230,  -146,   230,   234,   429,
-     591,   487,   582,   330,   331,   149,   116,   201,   227,    29,
-     227,  -258,   202,   230,    94,   230,   227,  -258,   272,    10,
-      11,   230,    95,   436,   624,  -171,    96,  -174,    11,   610,
-    -173,    10,    11,   214,   218,   222,    97,    98,   227,  -169,
-     449,  -170,   123,   230,   219,    79,   129,   124,   233,  -171,
-     409,   124,   248,   227,   227,   411,   163,  -171,   230,   230,
-     621,     9,   249,  -169,   208,  -170,   452,   261,   284,    99,
-     478,  -169,   480,  -170,   352,  -168,   402,   348,   613,   518,
-     357,   116,   116,   116,   162,     9,   417,   450,     9,   164,
-     285,   225,   231,   232,   286,   116,   242,   353,   476,  -168,
-     359,   253,   361,   488,   116,   363,   242,  -168,   110,   528,
-      10,    11,   116,   481,   260,   367,   110,   373,   256,   116,
-     110,   276,   275,   145,   287,   149,   265,   227,   377,   281,
-     505,   371,   230,   379,    10,    11,   254,    10,    11,   227,
-     149,   479,   116,   381,   230,   255,   482,   383,  -172,   227,
-      10,    11,   290,   227,   230,   385,   404,   391,   230,   393,
-      79,    79,   330,   331,   398,   478,   163,   480,   348,   540,
-     400,   547,  -172,   227,   227,   418,   452,   253,   230,   230,
-    -172,   478,   452,   480,   412,   560,   348,   234,     9,   415,
-     611,   116,   431,   116,   162,    79,   443,   444,   446,   164,
-     242,   512,   213,   360,   215,   217,   262,   445,   481,   116,
-     447,   116,   263,   457,   462,   520,   465,   116,   378,   368,
-     466,   264,   467,   142,   481,   468,    10,    11,     9,   209,
-     209,   253,   209,   209,   163,   469,   479,    10,    11,   116,
-       9,   482,   484,   227,   489,   518,   492,   502,   230,   396,
-     507,   116,   479,   504,   116,   116,   509,   482,   511,   519,
-     262,   407,   162,   146,   413,   414,   263,   164,   478,   523,
-     480,   529,   526,   525,   530,   171,   533,    10,    11,   531,
-      10,    11,   136,     9,   339,   552,   227,   554,   562,    10,
-      11,   230,   555,   242,   159,   571,   461,   168,   566,    79,
-     568,   581,   575,   528,   573,   576,   149,   579,   253,   589,
-     592,   481,   590,   593,  -150,   594,   344,  -151,   316,   348,
-     595,   540,   354,   355,   596,   547,   452,   600,   116,   597,
-     348,   348,    10,    11,   599,   478,   227,   480,   407,   479,
-     116,   230,   116,   254,   482,   343,   601,   603,   605,   176,
-     116,   343,   343,   612,   116,   614,   625,    10,    11,   184,
-     163,   627,   628,   188,   493,   638,   436,   643,   193,   194,
-     195,   196,   644,   645,   116,   116,   646,   221,   481,   106,
-     176,    66,   626,   639,   225,   513,   578,   486,   162,   587,
-     184,   640,   271,   164,   188,   189,   190,   191,   192,   193,
-     194,   195,   196,   369,   403,   122,   479,   291,   292,   293,
-     294,   482,   295,   296,   297,   370,   298,   299,   300,   301,
-     302,   303,   304,   305,   306,   307,   308,   309,   310,   311,
-     283,   159,   503,   318,   351,   321,   474,   116,   491,   136,
-     136,   332,    91,    35,   116,   572,   448,    37,   441,   537,
-     634,   167,   442,   116,   459,   561,   631,   111,   557,     0,
-       0,     0,    47,    48,     9,   350,     0,     0,   343,    51,
-       0,     0,     0,     0,     0,   343,    55,     0,     0,     0,
-       0,     0,     0,   343,     0,     0,     0,   116,     0,    56,
-      57,     0,    58,    59,     0,     0,    60,   583,     0,    61,
-       0,     0,     0,     0,    35,     0,     0,     0,    37,    62,
-      63,    64,   136,    10,    11,     0,     0,     0,   111,   333,
-       0,     0,   136,    47,    48,     9,     0,     0,     0,   334,
-      51,     0,     0,     0,   335,   336,   337,   116,     0,     0,
-     116,   338,     0,     0,   536,   420,     0,     0,   339,   159,
-     543,   546,     0,   551,     0,   420,     0,     0,     0,     0,
-      61,     0,   556,     0,   558,   340,     0,     0,     0,     0,
-       0,     0,    64,   343,    10,    11,     0,   341,     0,   541,
-     343,   174,   343,   342,     0,  -268,    11,     0,     0,     0,
-       0,   343,     0,   343,     0,     0,     0,     0,   136,   136,
-       0,     0,     0,     0,     0,     0,     0,   116,     0,     0,
-     175,   176,     0,   177,   178,   179,   180,   181,     0,   182,
-     183,   184,   185,   186,   187,   188,   189,   190,   191,   192,
-     193,   194,   195,   196,     0,     0,     0,   136,     0,     0,
-       0,     0,  -268,     0,     0,     0,     0,     0,     0,     0,
-       0,   136,  -268,   598,     0,     0,     0,     0,     0,   159,
-       0,   602,   333,     0,   168,     0,   458,    35,     0,     0,
-       0,    37,   334,     0,     0,     0,     0,   335,   336,   337,
-       0,   111,   343,     0,   338,     0,    47,    48,     9,     0,
-     343,   339,     0,    51,     0,     0,     0,   343,     0,     0,
-     157,     0,   543,   632,   564,   565,     0,     0,   340,     0,
-       0,     0,     0,    56,    57,     0,    58,   158,     0,     0,
-      60,     0,     0,    61,   313,     0,   342,   159,   343,    11,
-       0,   541,   343,    62,    63,    64,     0,    10,    11,     0,
-       0,     0,     0,     0,     0,     0,     0,   420,     0,     0,
-       0,     0,     0,     0,   420,   585,   420,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,    -2,    34,     0,    35,
-       0,    36,     0,    37,     0,    38,    39,     0,   343,    40,
-     343,    41,    42,    43,    44,    45,    46,     0,    47,    48,
-       9,     0,     0,    49,    50,    51,    52,    53,    54,     0,
-       0,     0,    55,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,    56,    57,     0,    58,    59,
-       0,     0,    60,     0,     0,    61,     0,     0,   -23,     0,
-       0,     0,     0,     0,     0,    62,    63,    64,     0,    10,
-      11,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-     641,   642,   323,   159,    35,     0,    36,  -243,    37,     0,
-      38,    39,     0,  -243,    40,     0,    41,    42,   111,    44,
-      45,    46,     0,    47,    48,     9,     0,     0,    49,    50,
-      51,    52,    53,    54,     0,     0,     0,    55,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-      56,    57,     0,    58,    59,     0,     0,    60,     0,     0,
-      61,     0,     0,  -243,     0,     0,     0,     0,   324,  -243,
-      62,    63,    64,     0,    10,    11,   323,     0,    35,     0,
-      36,     0,    37,     0,    38,    39,     0,     0,    40,     0,
-      41,    42,   111,    44,    45,    46,     0,    47,    48,     9,
-       0,     0,    49,    50,    51,    52,    53,    54,     0,     0,
-       0,    55,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,    56,    57,     0,    58,    59,     0,
-       0,    60,     0,     0,    61,     0,    35,  -243,     0,     0,
-      37,     0,   324,  -243,    62,    63,    64,     0,    10,    11,
-     111,   333,     0,     0,     0,    47,    48,     9,     0,     0,
-       0,   334,    51,     0,     0,     0,   335,   336,   337,    55,
-       0,     0,     0,   338,     0,     0,     0,     0,     0,     0,
-     339,     0,    56,    57,     0,    58,    59,     0,     0,    60,
-       0,    35,    61,     0,     0,    37,     0,   340,     0,     0,
-     419,     0,    62,    63,    64,   111,    10,    11,     0,     0,
-      47,    48,     9,     0,     0,   342,     0,    51,    11,   428,
-       0,     0,     0,     0,   157,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,    56,    57,     0,
-      58,   158,     0,     0,    60,     0,    35,    61,     0,     0,
-      37,     0,     0,     0,     0,     0,     0,    62,    63,    64,
-     111,    10,    11,     0,     0,    47,    48,     9,     0,   471,
-       0,     0,    51,     0,     0,     0,     0,     0,     0,    55,
+      12,   174,   376,   359,   119,   235,   121,   240,   274,   259,
+     320,   235,   323,   278,   161,    32,   109,    79,   570,   109,
+     107,   235,   103,    32,   433,   131,   554,   428,   435,   375,
+     385,   111,   456,   426,   111,   380,   389,   391,   128,   393,
+     111,   539,   173,   164,   630,  -176,     4,   400,   146,   150,
+     495,   402,  -208,    27,   205,   450,   496,    27,     9,  -172,
+     199,   417,   150,   214,   200,   216,   218,   138,    18,  -175,
+     388,   133,   201,     5,     9,   120,     9,  -176,     9,    27,
+     122,   495,     9,  -172,   501,   124,  -208,   496,   133,   130,
+     380,  -172,   507,   127,   651,   222,   652,   427,    46,   163,
+       9,   457,   451,   134,   165,   617,   174,    10,    11,    28,
+    -174,   452,   497,    29,   102,   257,   207,    29,  -208,   390,
+     134,   266,   243,    10,    11,    10,    11,    10,    11,   381,
+     111,    10,    11,   618,    19,   525,   111,   528,   146,    29,
+     536,   164,   150,   625,   239,   325,     7,   289,   437,    10,
+      11,   228,   228,   228,   438,   560,   231,   231,   231,    15,
+    -260,   500,   491,   502,   450,   228,  -260,   150,    20,   212,
+     231,   437,   648,   208,   228,    26,   636,   486,   461,   231,
+      23,   164,   228,   209,    11,     9,   366,   231,   535,   228,
+     619,   620,   631,   462,   231,   318,    33,   163,   578,   437,
+     621,    79,   165,   637,   638,   592,  -170,   349,   226,   232,
+     233,   451,   228,   437,   357,    32,  -260,   231,   243,   611,
+     581,   515,  -260,   564,    93,   331,   332,   585,   522,   363,
+    -170,   261,   125,   101,    10,    11,   125,   163,  -170,   276,
+     105,   533,   165,   367,   243,    79,   282,   235,   108,   474,
+     409,   141,   411,   209,   605,   136,   568,   235,   259,   488,
+     171,   228,   198,   228,   509,  -147,   231,   511,   231,   291,
+     430,   623,   624,   202,  -229,   203,   150,   587,   589,   228,
+    -175,   228,     9,   204,   231,  -174,   231,   228,    11,   206,
+     583,    35,   231,   215,   634,    37,  -259,   219,   403,   164,
+     220,   223,  -259,   234,   209,   112,   249,   262,   418,   228,
+      47,    48,     9,   250,   231,   285,    79,    51,   273,   353,
+     361,   410,  -171,   286,   228,   228,   412,   622,   287,   231,
+     231,    10,    11,  -229,   379,   354,   369,   453,   345,  -229,
+       9,   479,   358,   481,   355,   356,  -171,    61,   349,   614,
+     519,   360,  -259,   362,  -171,   163,   482,   254,  -259,    64,
+     165,    10,    11,   364,   257,   368,   397,   243,   374,   477,
+     372,   378,   266,  -169,   489,   143,   506,   243,   408,   111,
+     529,   414,   415,   117,   331,   332,   263,   111,   380,    10,
+      11,   111,   264,   382,   146,  -173,   150,  -169,   228,   384,
+     394,   265,   386,   231,   392,  -169,    10,    11,   405,   164,
+     228,   150,   480,   399,   401,   231,   413,   483,   416,  -173,
+     228,   432,   419,   513,   228,   231,   444,  -173,   445,   231,
+     446,    79,    79,   447,   448,   458,   479,   521,   481,   349,
+     541,   463,   548,   254,   228,   228,   235,   453,   612,   231,
+     231,   482,   479,   453,   481,   408,   561,   349,   466,   117,
+     117,   117,   467,   468,   469,   163,    79,   482,   449,   470,
+     165,   243,    94,   117,   485,   254,   460,   164,   255,   379,
+      95,   494,   117,   490,    96,   493,     9,   256,   503,   505,
+     117,   508,    10,    11,    97,    98,   510,   117,   512,   520,
+     524,   226,   514,   526,   263,   527,   530,   480,   531,     9,
+     264,   534,   483,   532,   228,   340,   519,   553,   563,   231,
+     117,   147,   555,   480,    10,    11,   556,    99,   483,   567,
+       9,   569,     9,   163,   462,    10,    11,   572,   165,   479,
+     574,   481,   576,   210,   210,   277,   210,   210,   152,   153,
+     154,   155,   156,   157,   482,   166,   167,   228,    10,    11,
+     577,   580,   231,   590,   243,   172,   537,   582,   288,   117,
+      79,   117,   544,   547,   529,   552,     9,   150,   593,    10,
+      11,    10,    11,   591,   557,   254,   559,   117,   594,   117,
+     349,  -151,   541,   595,  -152,   117,   548,   453,   596,   597,
+     601,   349,   349,   164,   600,   598,   479,   228,   481,   602,
+     480,   317,   231,   604,   584,   483,   606,   117,   613,   615,
+     255,   482,   626,   628,   629,    10,    11,   177,   137,   117,
+     639,   437,   117,   117,    10,    11,   644,   185,   645,   106,
+     160,   189,   646,   169,   647,    66,   194,   195,   196,   197,
+     627,   152,   156,   579,   640,   487,   641,   272,   370,   163,
+     344,   404,   588,    37,   165,   123,   344,   344,   284,   371,
+     352,    37,   504,   112,   475,   599,   492,   480,    47,    48,
+       9,   112,   483,   603,    91,    51,    47,    48,     9,   573,
+     538,   635,   224,    51,   562,   632,   442,   443,   351,   558,
+     224,     0,     0,     0,     0,     0,   117,     0,     0,   114,
+       0,     0,     0,     0,     0,   225,     0,   114,   117,     0,
+     117,   280,     0,   225,   544,   633,   177,    64,   117,    10,
+      11,   281,   117,     0,     0,    64,   185,    10,    11,   396,
+     189,   190,   191,   192,   193,   194,   195,   196,   197,     0,
+       0,     0,   117,   117,   292,   293,   294,   295,     0,   296,
+     297,   298,     0,   299,   300,   301,   302,   303,   304,   305,
+     306,   307,   308,   309,   310,   311,   312,     0,   160,     0,
+     319,     0,   322,   344,     0,     0,   137,   137,   333,     0,
+     344,   334,     0,     0,     0,   459,     0,     0,   344,     0,
+     175,   335,     0,     0,  -269,     0,   336,   337,   338,     0,
+       0,     0,     0,   339,     0,   117,     0,     0,     0,     0,
+     340,     0,   117,     0,     0,     0,     0,     0,     0,   176,
+     177,   117,   178,   179,   180,   181,   182,   341,   183,   184,
+     185,   186,   187,   188,   189,   190,   191,   192,   193,   194,
+     195,   196,   197,     0,     0,   343,     0,     0,    11,   137,
+       0,  -269,     0,     0,     0,   117,     0,     0,     0,   137,
+       0,  -269,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,   344,     0,
+       0,     0,   421,     0,   542,   344,   160,   344,     0,     0,
+       0,     0,   421,     0,    -2,    34,   344,    35,   344,    36,
+       0,    37,     0,    38,    39,   117,     0,    40,   117,    41,
+      42,    43,    44,    45,    46,     0,    47,    48,     9,     0,
+       0,    49,    50,    51,    52,    53,    54,     0,     0,     0,
+      55,     0,     0,     0,     0,   137,   137,     0,     0,     0,
+       0,     0,     0,    56,    57,     0,    58,    59,     0,     0,
+      60,     0,     0,    61,     0,     0,   -24,     0,    35,     0,
+       0,     0,    37,    62,    63,    64,   168,    10,    11,     0,
+       0,     0,   112,     0,   137,   117,     0,    47,    48,     9,
+       0,     0,     0,     0,    51,     0,     0,   344,   137,     0,
+       0,    55,     0,     0,     0,   344,   160,     0,     0,     0,
+       0,   169,   344,     0,    56,    57,     0,    58,    59,     0,
+       0,    60,     0,     0,    61,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,    62,    63,    64,     0,    10,    11,
+       0,     0,     0,   344,     0,     0,   542,   344,     0,     0,
+       0,   565,   566,     0,     0,     0,     0,     0,     0,     0,
+       0,   324,     0,    35,     0,    36,  -244,    37,     0,    38,
+      39,     0,  -244,    40,   160,    41,    42,   112,    44,    45,
+      46,     0,    47,    48,     9,     0,     0,    49,    50,    51,
+      52,    53,    54,   344,   421,   344,    55,     0,     0,     0,
+       0,   421,   586,   421,     0,     0,     0,     0,     0,    56,
+      57,     0,    58,    59,     0,     0,    60,     0,     0,    61,
+       0,     0,  -244,     0,     0,     0,     0,   325,  -244,    62,
+      63,    64,     0,    10,    11,   324,     0,    35,     0,    36,
+       0,    37,     0,    38,    39,     0,     0,    40,     0,    41,
+      42,   112,    44,    45,    46,     0,    47,    48,     9,     0,
+       0,    49,    50,    51,    52,    53,    54,     0,     0,     0,
+      55,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,    56,    57,     0,    58,    59,     0,     0,
+      60,     0,     0,    61,     0,    35,  -244,   642,   643,    37,
+     160,   325,  -244,    62,    63,    64,     0,    10,    11,   112,
+     334,     0,     0,     0,    47,    48,     9,     0,     0,     0,
+     335,    51,     0,     0,     0,   336,   337,   338,   158,     0,
+       0,     0,   339,     0,     0,     0,     0,     0,     0,   340,
+       0,    56,    57,     0,    58,   159,     0,     0,    60,     0,
+      35,    61,   314,     0,    37,     0,   341,     0,     0,     0,
+       0,    62,    63,    64,   112,    10,    11,     0,   342,    47,
+      48,     9,     0,     0,   343,     0,    51,    11,     0,     0,
+       0,     0,     0,    55,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,    56,    57,     0,    58,
+      59,     0,     0,    60,     0,    35,    61,     0,     0,    37,
+       0,     0,     0,     0,   420,     0,    62,    63,    64,   112,
+      10,    11,     0,     0,    47,    48,     9,     0,     0,     0,
+       0,    51,     0,   429,     0,     0,     0,     0,   158,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,    56,    57,     0,    58,    59,     0,     0,    60,
-       0,    35,    61,     0,     0,    37,     0,     0,     0,     0,
-       0,     0,    62,    63,    64,   111,    10,    11,     0,     0,
-      47,    48,     9,     0,   472,     0,     0,    51,     0,     0,
-       0,     0,     0,     0,    55,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,    56,    57,     0,
-      58,    59,     0,     0,    60,     0,    35,    61,     0,     0,
-      37,     0,     0,     0,     0,     0,     0,    62,    63,    64,
-     111,    10,    11,     0,     0,    47,    48,     9,     0,     0,
-       0,     0,    51,     0,     0,     0,     0,     0,     0,    55,
+       0,    56,    57,     0,    58,   159,     0,     0,    60,     0,
+      35,    61,     0,     0,    37,     0,     0,     0,     0,     0,
+       0,    62,    63,    64,   112,    10,    11,     0,     0,    47,
+      48,     9,     0,   472,     0,     0,    51,     0,     0,     0,
+       0,     0,     0,    55,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,    56,    57,     0,    58,
+      59,     0,     0,    60,     0,    35,    61,     0,     0,    37,
+       0,     0,     0,     0,     0,     0,    62,    63,    64,   112,
+      10,    11,     0,     0,    47,    48,     9,     0,   473,     0,
+       0,    51,     0,     0,     0,     0,     0,     0,    55,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,    56,    57,     0,    58,    59,     0,     0,    60,
-       0,    35,    61,     0,     0,    37,     0,     0,     0,     0,
-       0,     0,    62,    63,    64,   111,    10,    11,     0,     0,
-      47,    48,     9,     0,     0,     0,     0,    51,     0,     0,
-       0,     0,     0,     0,   157,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,    56,    57,     0,
-      58,   158,     0,     0,    60,     0,    35,    61,     0,     0,
-     282,     0,     0,     0,     0,     0,     0,    62,    63,    64,
-     111,    10,    11,     0,     0,    47,    48,     9,     0,     0,
-       0,     0,    51,     0,     0,     0,     0,     0,     0,    55,
+       0,    56,    57,     0,    58,    59,     0,     0,    60,     0,
+      35,    61,     0,     0,    37,     0,     0,     0,     0,     0,
+       0,    62,    63,    64,   112,    10,    11,     0,     0,    47,
+      48,     9,     0,     0,     0,     0,    51,     0,     0,     0,
+       0,     0,     0,    55,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,    56,    57,     0,    58,
+      59,     0,     0,    60,     0,    35,    61,     0,     0,    37,
+       0,     0,     0,     0,     0,     0,    62,    63,    64,   112,
+      10,    11,     0,     0,    47,    48,     9,     0,     0,     0,
+       0,    51,     0,     0,     0,     0,     0,     0,   158,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,    56,    57,     0,    58,    59,     0,     0,    60,
-       0,     0,    61,     0,     0,    37,     0,     0,     0,     0,
-       0,     0,    62,    63,    64,   111,    10,    11,     0,     0,
-      47,    48,     9,     0,     0,     0,     0,    51,     0,     0,
-      37,     0,     0,     0,   223,     0,     0,     0,    37,     0,
-     111,     0,     0,     0,     0,    47,    48,     9,   111,     0,
-       0,   113,    51,    47,    48,     9,     0,   224,     0,   223,
-      51,     0,     0,   279,    37,     0,     0,   223,   240,    64,
-       0,    10,    11,   280,   111,     0,   113,     0,     0,    47,
-      48,     9,   224,     0,   113,     0,    51,     0,   289,     0,
-     224,     0,     0,   223,    64,     0,    10,    11,   280,     0,
-       0,     0,    64,    37,    10,    11,   395,    37,     0,     0,
-     113,     0,     0,   111,     0,     0,   224,   111,    47,    48,
-       9,     0,    47,    48,     9,    51,     0,     0,    64,    51,
-      10,    11,   223,     0,     0,    37,   405,     0,     0,     0,
-       0,     0,     0,     0,     0,   111,   282,     0,     0,   113,
-      47,    48,     9,   113,     0,   224,   111,    51,     0,   406,
-       0,    47,    48,     9,   223,     0,     0,    64,    51,    10,
-      11,    64,     0,    10,    11,   223,     0,     0,   333,     0,
-       0,   113,     0,     0,     0,     0,     0,   475,   334,     0,
-       0,     0,   113,   335,   336,   337,     0,     0,   224,    64,
-     338,    10,    11,     0,   333,     0,     0,   438,     0,     0,
-      64,     0,    10,    11,   334,     0,     0,     0,     0,   335,
-     336,   539,     0,     0,   340,     0,   338,     0,     0,     0,
-     439,   333,     0,   339,     0,     0,     0,     0,     0,     0,
-       0,   334,   342,     0,     0,    11,   335,   336,   337,     0,
-     340,     0,     0,   338,     0,     0,     0,     0,     0,     0,
-     339,     0,     0,     0,     0,     0,     0,     0,   342,     0,
-      10,    11,     0,     0,     0,     0,     0,   340,     0,     0,
-       0,     0,     0,   606,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,   342,   175,   176,    11,   177,
-       0,   179,   180,   181,     0,     0,   183,   184,   185,   186,
-     187,   188,   189,   190,   191,   192,   193,   194,   195,   196,
-       0,     0,     0,     0,     0,     0,   175,   176,     0,   177,
-       0,   179,   180,   181,     0,   430,   183,   184,   185,   186,
-     187,   188,   189,   190,   191,   192,   193,   194,   195,   196,
-     175,   176,     0,   177,     0,   179,   180,   181,     0,   522,
-     183,   184,   185,   186,   187,   188,   189,   190,   191,   192,
-     193,   194,   195,   196,   175,   176,     0,   177,     0,   179,
-     180,   181,     0,   648,   183,   184,   185,   186,   187,   188,
-     189,   190,   191,   192,   193,   194,   195,   196,   175,   176,
-       0,   177,     0,   179,   180,   181,     0,   649,   183,   184,
-     185,   186,   187,   188,   189,   190,   191,   192,   193,   194,
-     195,   196,     0,   175,   176,   433,   177,     0,   179,   180,
-     181,     0,     0,   183,   184,   185,   186,   187,   188,   189,
-     190,   191,   192,   193,   194,   195,   196,   175,   176,     0,
-       0,     0,   179,   180,   181,     0,     0,   183,   184,   185,
+       0,    56,    57,     0,    58,   159,     0,     0,    60,     0,
+      35,    61,     0,     0,   283,     0,     0,     0,     0,     0,
+       0,    62,    63,    64,   112,    10,    11,     0,     0,    47,
+      48,     9,     0,     0,     0,     0,    51,     0,     0,     0,
+       0,     0,     0,    55,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,    56,    57,     0,    58,
+      59,     0,     0,    60,     0,     0,    61,     0,     0,    37,
+       0,     0,     0,     0,     0,     0,    62,    63,    64,   112,
+      10,    11,     0,     0,    47,    48,     9,     0,     0,     0,
+       0,    51,     0,     0,     0,    37,     0,     0,   224,   241,
+       0,     0,     0,    37,     0,   112,     0,     0,     0,     0,
+      47,    48,     9,   112,     0,   114,     0,    51,    47,    48,
+       9,   225,     0,     0,   224,    51,     0,   290,    37,     0,
+       0,     0,   113,    64,     0,    10,    11,   281,   112,     0,
+       0,   114,     0,    47,    48,     9,     0,   225,     0,   114,
+      51,     0,     0,     0,     0,   115,    37,   224,     0,    64,
+       0,    10,    11,     0,     0,     0,   112,    64,     0,    10,
+      11,    47,    48,     9,   114,     0,     0,     0,    51,     0,
+     225,    37,     0,     0,     0,   406,     0,     0,     0,   283,
+       0,   112,    64,     0,    10,    11,    47,    48,     9,   112,
+       0,     0,   114,    51,    47,    48,     9,     0,   407,     0,
+     224,    51,     0,     0,   334,     0,     0,     0,   224,     0,
+      64,     0,    10,    11,   335,     0,     0,   114,     0,   336,
+     337,   338,     0,   476,     0,   114,   339,     0,     0,     0,
+       0,   225,   334,   439,     0,    64,     0,    10,    11,     0,
+       0,     0,   335,    64,     0,    10,    11,   336,   337,   540,
+     341,     0,     0,     0,   339,     0,   440,   334,     0,     0,
+       0,   340,     0,     0,     0,   334,     0,   335,   343,     0,
+       0,    11,   336,   337,   338,   335,     0,     0,   341,   339,
+     336,   337,   338,     0,     0,     0,   340,   339,     0,     0,
+       0,     0,     0,     0,   340,     0,   343,     0,    10,    11,
+       0,     0,     0,   341,     0,     0,     0,     0,     0,   607,
+       0,   341,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,   343,     0,     0,    11,     0,     0,     0,     0,   343,
+     176,   177,    11,   178,     0,   180,   181,   182,     0,     0,
+     184,   185,   186,   187,   188,   189,   190,   191,   192,   193,
+     194,   195,   196,   197,     0,     0,     0,     0,     0,     0,
+     176,   177,     0,   178,     0,   180,   181,   182,     0,   431,
+     184,   185,   186,   187,   188,   189,   190,   191,   192,   193,
+     194,   195,   196,   197,   176,   177,     0,   178,     0,   180,
+     181,   182,     0,   523,   184,   185,   186,   187,   188,   189,
+     190,   191,   192,   193,   194,   195,   196,   197,   176,   177,
+       0,   178,     0,   180,   181,   182,     0,   649,   184,   185,
      186,   187,   188,   189,   190,   191,   192,   193,   194,   195,
-     196,   175,   176,     0,     0,     0,   179,   180,   181,     0,
-       0,   183,   184,   185,   186,     0,   188,   189,   190,   191,
-     192,   193,   194,   195,   196,   176,     0,     0,     0,   179,
-     180,   181,     0,     0,   183,   184,   185,   186,     0,   188,
-     189,   190,   191,   192,   193,   194,   195,   196
+     196,   197,   176,   177,     0,   178,     0,   180,   181,   182,
+       0,   650,   184,   185,   186,   187,   188,   189,   190,   191,
+     192,   193,   194,   195,   196,   197,     0,   176,   177,   434,
+     178,     0,   180,   181,   182,     0,     0,   184,   185,   186,
+     187,   188,   189,   190,   191,   192,   193,   194,   195,   196,
+     197,   176,   177,     0,     0,     0,   180,   181,   182,     0,
+       0,   184,   185,   186,   187,   188,   189,   190,   191,   192,
+     193,   194,   195,   196,   197,   176,   177,     0,     0,     0,
+     180,   181,   182,     0,     0,   184,   185,   186,   187,     0,
+     189,   190,   191,   192,   193,   194,   195,   196,   197,   177,
+       0,     0,     0,   180,   181,   182,     0,     0,   184,   185,
+     186,   187,     0,   189,   190,   191,   192,   193,   194,   195,
+     196,   197
 };
 
+#define yypact_value_is_default(yystate) \
+  ((yystate) == (-551))
+
+#define yytable_value_is_error(yytable_value) \
+  YYID (0)
+
 static const yytype_int16 yycheck[] =
 {
-       5,    67,   222,   142,    37,   249,    37,   134,   200,   146,
-     388,   322,   257,   203,    61,    20,   125,    22,   396,   125,
-     443,   266,   131,    28,    28,   484,   451,   320,   248,   274,
-     315,    36,   141,   278,    39,   262,   263,     3,    43,     6,
-      45,    36,    67,   288,    39,    12,    20,     3,    53,    54,
-      45,    11,    25,     8,    51,     3,    55,    56,    57,    58,
-      59,    60,    67,    62,    63,     8,    35,     7,    24,     0,
-      59,    61,   522,   523,    24,    37,    24,    17,   593,    60,
-      37,   459,    22,    23,    24,    74,    83,     8,     3,    29,
-      59,    62,    89,    67,    75,    62,    36,    68,    67,    61,
-      25,    68,    50,    59,    61,   171,    72,    63,     6,    59,
-      65,    59,   571,    53,    12,    75,    49,    73,    74,    59,
-      75,   126,    65,    66,   502,    73,    74,   254,   643,   134,
-     645,    71,    75,    73,    74,   140,    24,   142,   423,   134,
-     425,   146,     3,   436,    65,   140,   171,    62,    63,    24,
-     112,   113,   114,    68,    75,   112,   113,   114,   157,   158,
-     387,   381,   389,    24,   126,    53,   171,     3,   158,   126,
-      68,   594,    35,   135,    24,    62,   601,    21,   135,   638,
-     558,   143,   605,   606,     1,    24,   143,     1,   150,    62,
-      24,   435,   125,   150,   199,    68,   158,   575,   576,    60,
-     205,   158,    63,   514,    67,    63,   211,    62,   198,    59,
-     521,   173,    73,    74,   219,   219,   173,   222,    35,     3,
-     598,    35,   412,    73,    74,     6,   470,    62,   233,   419,
-      24,    12,     6,    59,    73,    74,   198,    63,    12,   431,
-      24,   198,    59,   248,   249,    71,     3,     3,    71,   282,
-      67,   282,    24,    67,    62,   475,   383,    67,   367,   398,
-     222,   367,   224,   400,    62,   222,    66,   224,   377,   316,
-      68,   377,   517,   206,   207,   280,    37,    66,   240,    63,
-     242,    62,    59,   240,     9,   242,   248,    68,    60,    73,
-      74,   248,    17,    62,    68,    35,    21,    59,    74,    68,
-      59,    73,    74,    24,    64,    59,    31,    32,   270,    35,
-       3,    35,    40,   270,    62,   320,    44,    40,    63,    59,
-     282,    44,    59,   285,   286,   282,   316,    67,   285,   286,
-     574,    24,    67,    59,    75,    59,   341,    35,    60,    64,
-     373,    67,   373,    67,    59,    35,   279,   352,   568,   415,
-      60,   112,   113,   114,   316,    24,   289,    50,    24,   316,
-      72,   112,   113,   114,    72,   126,   371,     3,   373,    59,
-       7,    24,    60,   378,   135,    35,   381,    67,   383,   426,
-      73,    74,   143,   373,   135,    62,   391,    60,   383,   150,
-     395,    60,   143,   398,    60,   400,   391,   359,    62,   150,
-     395,    75,   359,    24,    73,    74,    59,    73,    74,   371,
-     415,   373,   173,    59,   371,    68,   373,    62,    35,   381,
-      73,    74,   173,   385,   381,    72,    65,    62,   385,     3,
-     435,   436,   365,   366,    62,   468,   426,   468,   443,   444,
-      62,   446,    59,   405,   406,    65,   451,    24,   405,   406,
-      67,   484,   457,   484,    67,   460,   461,   566,    24,    62,
-     566,   222,    66,   224,   426,   470,    59,    67,    67,   426,
-     475,   404,    95,   224,    97,    98,    53,    71,   468,   240,
-       7,   242,    59,    65,    62,   418,    62,   248,    63,   240,
-      62,    68,    62,    59,   484,    60,    73,    74,    24,    94,
-      95,    24,    97,    98,   494,    60,   468,    73,    74,   270,
-      24,   468,    60,   475,    60,   581,    68,    60,   475,   270,
-      35,   282,   484,    68,   285,   286,    60,   484,    60,    60,
-      53,   282,   494,    59,   285,   286,    59,   494,   571,    75,
-     571,    60,    75,    68,    60,    59,    68,    73,    74,    60,
-      73,    74,    49,    24,    36,     3,   518,    62,    60,    73,
-      74,   518,    72,   568,    61,    60,    75,    64,    62,   574,
-      59,    62,    60,   620,    66,    60,   581,    60,    24,    60,
-      60,   571,    72,    60,    59,    59,   210,    59,    59,   594,
-      68,   596,   216,   217,    62,   600,   601,    62,   359,    72,
-     605,   606,    73,    74,    68,   638,   568,   638,   359,   571,
-     371,   568,   373,    59,   571,   210,    49,    62,    59,    34,
-     381,   216,   217,    60,   385,    14,    68,    73,    74,    44,
-     620,    60,    68,    48,   385,    60,    62,    60,    53,    54,
-      55,    56,    60,    60,   405,   406,    60,   106,   638,    31,
-      34,    22,   581,   614,   405,   406,   507,   376,   620,   523,
-      44,   614,   141,   620,    48,    49,    50,    51,    52,    53,
-      54,    55,    56,   242,   280,    39,   638,   174,   175,   176,
-     177,   638,   179,   180,   181,   242,   183,   184,   185,   186,
-     187,   188,   189,   190,   191,   192,   193,   194,   195,   196,
-     158,   198,   391,   200,   212,   202,   371,   468,   383,   206,
-     207,   208,    22,     3,   475,   494,   340,     7,   333,   439,
-     600,    11,   333,   484,   348,   461,   596,    17,   457,    -1,
-      -1,    -1,    22,    23,    24,   211,    -1,    -1,   333,    29,
-      -1,    -1,    -1,    -1,    -1,   340,    36,    -1,    -1,    -1,
-      -1,    -1,    -1,   348,    -1,    -1,    -1,   518,    -1,    49,
-      50,    -1,    52,    53,    -1,    -1,    56,   518,    -1,    59,
-      -1,    -1,    -1,    -1,     3,    -1,    -1,    -1,     7,    69,
-      70,    71,   279,    73,    74,    -1,    -1,    -1,    17,     7,
-      -1,    -1,   289,    22,    23,    24,    -1,    -1,    -1,    17,
-      29,    -1,    -1,    -1,    22,    23,    24,   568,    -1,    -1,
-     571,    29,    -1,    -1,   438,   312,    -1,    -1,    36,   316,
-     444,   445,    -1,   447,    -1,   322,    -1,    -1,    -1,    -1,
-      59,    -1,   456,    -1,   458,    53,    -1,    -1,    -1,    -1,
-      -1,    -1,    71,   438,    73,    74,    -1,    65,    -1,   444,
-     445,     4,   447,    71,    -1,     8,    74,    -1,    -1,    -1,
-      -1,   456,    -1,   458,    -1,    -1,    -1,    -1,   365,   366,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,   638,    -1,    -1,
-      33,    34,    -1,    36,    37,    38,    39,    40,    -1,    42,
-      43,    44,    45,    46,    47,    48,    49,    50,    51,    52,
-      53,    54,    55,    56,    -1,    -1,    -1,   404,    -1,    -1,
-      -1,    -1,    65,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,   418,    75,   547,    -1,    -1,    -1,    -1,    -1,   426,
-      -1,   555,     7,    -1,   431,    -1,    11,     3,    -1,    -1,
-      -1,     7,    17,    -1,    -1,    -1,    -1,    22,    23,    24,
-      -1,    17,   547,    -1,    29,    -1,    22,    23,    24,    -1,
-     555,    36,    -1,    29,    -1,    -1,    -1,   562,    -1,    -1,
-      36,    -1,   596,   597,   471,   472,    -1,    -1,    53,    -1,
+       5,    67,   250,   223,    37,   126,    37,   126,   143,   135,
+     201,   132,   204,   147,    61,    20,    36,    22,   485,    39,
+      31,   142,    28,    28,   321,    45,   452,   316,   323,   249,
+     258,    36,     3,    11,    39,    24,   263,   264,    43,   267,
+      45,   444,    67,    61,   594,    35,     0,   275,    53,    54,
+       6,   279,     1,     3,     1,     3,    12,     3,    24,    35,
+      59,   289,    67,    95,    63,    97,    98,    49,     3,    59,
+      59,    35,    71,    25,    24,    37,    24,    67,    24,     3,
+      37,     6,    24,    59,   389,    40,    35,    12,    35,    44,
+      24,    67,   397,    59,   644,   106,   646,    75,    20,    61,
+      24,    72,    50,    67,    61,   572,   172,    73,    74,    59,
+      59,    59,    68,    63,    60,   135,     8,    63,    67,    53,
+      67,   141,   127,    73,    74,    73,    74,    73,    74,   255,
+     135,    73,    74,     8,    62,   424,   141,   426,   143,    63,
+     437,   159,   147,    68,   126,    67,    25,   172,    62,    73,
+      74,   113,   114,   115,    68,   460,   113,   114,   115,    24,
+       6,   388,   382,   390,     3,   127,    12,   172,    21,    59,
+     127,    62,   639,    65,   136,    63,   602,    68,    60,   136,
+      24,   199,   144,    75,    74,    24,     8,   144,   436,   151,
+      65,    66,   595,    75,   151,   200,    62,   159,   503,    62,
+      75,   206,   159,   606,   607,    68,    35,   212,   113,   114,
+     115,    50,   174,    62,   220,   220,    62,   174,   223,    68,
+     515,   413,    68,   471,    62,   207,   208,   522,   420,   234,
+      59,   136,    40,    24,    73,    74,    44,   199,    67,   144,
+       3,   432,   199,    65,   249,   250,   151,   368,     3,   368,
+     283,    51,   283,    75,   559,    71,   476,   378,   384,   378,
+      62,   223,    67,   225,   399,    66,   223,   401,   225,   174,
+     317,   576,   577,    66,     3,    59,   281,   523,   524,   241,
+      59,   243,    24,    83,   241,    59,   243,   249,    74,    89,
+     518,     3,   249,    24,   599,     7,     6,    64,   280,   317,
+      62,    59,    12,    63,    75,    17,    59,    35,   290,   271,
+      22,    23,    24,    67,   271,    60,   321,    29,    60,    59,
+     225,   283,    35,    72,   286,   287,   283,   575,    72,   286,
+     287,    73,    74,    62,    63,     3,   241,   342,   211,    68,
+      24,   374,    60,   374,   217,   218,    59,    59,   353,   569,
+     416,     7,    62,    60,    67,   317,   374,    24,    68,    71,
+     317,    73,    74,    35,   384,    62,   271,   372,    60,   374,
+      75,    62,   392,    35,   379,    59,   396,   382,   283,   384,
+     427,   286,   287,    37,   366,   367,    53,   392,    24,    73,
+      74,   396,    59,    59,   399,    35,   401,    59,   360,    62,
+       3,    68,    72,   360,    62,    67,    73,    74,    65,   427,
+     372,   416,   374,    62,    62,   372,    67,   374,    62,    59,
+     382,    66,    65,   405,   386,   382,    59,    67,    67,   386,
+      71,   436,   437,    67,     7,    65,   469,   419,   469,   444,
+     445,    62,   447,    24,   406,   407,   567,   452,   567,   406,
+     407,   469,   485,   458,   485,   360,   461,   462,    62,   113,
+     114,   115,    62,    62,    60,   427,   471,   485,   341,    60,
+     427,   476,     9,   127,    60,    24,   349,   495,    59,    63,
+      17,   386,   136,    60,    21,    68,    24,    68,    60,    68,
+     144,    35,    73,    74,    31,    32,    60,   151,    60,    60,
+      75,   406,   407,    68,    53,    75,    60,   469,    60,    24,
+      59,    68,   469,    60,   476,    36,   582,     3,    60,   476,
+     174,    59,    62,   485,    73,    74,    72,    64,   485,    62,
+      24,    59,    24,   495,    75,    73,    74,    60,   495,   572,
+      66,   572,    60,    94,    95,    60,    97,    98,    55,    56,
+      57,    58,    59,    60,   572,    62,    63,   519,    73,    74,
+      60,    60,   519,    60,   569,    59,   439,    62,    60,   223,
+     575,   225,   445,   446,   621,   448,    24,   582,    60,    73,
+      74,    73,    74,    72,   457,    24,   459,   241,    60,   243,
+     595,    59,   597,    59,    59,   249,   601,   602,    68,    62,
+      62,   606,   607,   621,    68,    72,   639,   569,   639,    49,
+     572,    59,   569,    62,   519,   572,    59,   271,    60,    14,
+      59,   639,    68,    60,    68,    73,    74,    34,    49,   283,
+      60,    62,   286,   287,    73,    74,    60,    44,    60,    31,
+      61,    48,    60,    64,    60,    22,    53,    54,    55,    56,
+     582,   158,   159,   508,   615,   377,   615,   142,   243,   621,
+     211,   281,   524,     7,   621,    39,   217,   218,   159,   243,
+     213,     7,   392,    17,   372,   548,   384,   639,    22,    23,
+      24,    17,   639,   556,    22,    29,    22,    23,    24,   495,
+     440,   601,    36,    29,   462,   597,   334,   334,   212,   458,
+      36,    -1,    -1,    -1,    -1,    -1,   360,    -1,    -1,    53,
+      -1,    -1,    -1,    -1,    -1,    59,    -1,    53,   372,    -1,
+     374,    65,    -1,    59,   597,   598,    34,    71,   382,    73,
+      74,    75,   386,    -1,    -1,    71,    44,    73,    74,    75,
+      48,    49,    50,    51,    52,    53,    54,    55,    56,    -1,
+      -1,    -1,   406,   407,   175,   176,   177,   178,    -1,   180,
+     181,   182,    -1,   184,   185,   186,   187,   188,   189,   190,
+     191,   192,   193,   194,   195,   196,   197,    -1,   199,    -1,
+     201,    -1,   203,   334,    -1,    -1,   207,   208,   209,    -1,
+     341,     7,    -1,    -1,    -1,    11,    -1,    -1,   349,    -1,
+       4,    17,    -1,    -1,     8,    -1,    22,    23,    24,    -1,
+      -1,    -1,    -1,    29,    -1,   469,    -1,    -1,    -1,    -1,
+      36,    -1,   476,    -1,    -1,    -1,    -1,    -1,    -1,    33,
+      34,   485,    36,    37,    38,    39,    40,    53,    42,    43,
+      44,    45,    46,    47,    48,    49,    50,    51,    52,    53,
+      54,    55,    56,    -1,    -1,    71,    -1,    -1,    74,   280,
+      -1,    65,    -1,    -1,    -1,   519,    -1,    -1,    -1,   290,
+      -1,    75,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   439,    -1,
+      -1,    -1,   313,    -1,   445,   446,   317,   448,    -1,    -1,
+      -1,    -1,   323,    -1,     0,     1,   457,     3,   459,     5,
+      -1,     7,    -1,     9,    10,   569,    -1,    13,   572,    15,
+      16,    17,    18,    19,    20,    -1,    22,    23,    24,    -1,
+      -1,    27,    28,    29,    30,    31,    32,    -1,    -1,    -1,
+      36,    -1,    -1,    -1,    -1,   366,   367,    -1,    -1,    -1,
       -1,    -1,    -1,    49,    50,    -1,    52,    53,    -1,    -1,
-      56,    -1,    -1,    59,    60,    -1,    71,   494,   593,    74,
-      -1,   596,   597,    69,    70,    71,    -1,    73,    74,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,   514,    -1,    -1,
-      -1,    -1,    -1,    -1,   521,   522,   523,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,     0,     1,    -1,     3,
-      -1,     5,    -1,     7,    -1,     9,    10,    -1,   643,    13,
-     645,    15,    16,    17,    18,    19,    20,    -1,    22,    23,
-      24,    -1,    -1,    27,    28,    29,    30,    31,    32,    -1,
-      -1,    -1,    36,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    49,    50,    -1,    52,    53,
-      -1,    -1,    56,    -1,    -1,    59,    -1,    -1,    62,    -1,
-      -1,    -1,    -1,    -1,    -1,    69,    70,    71,    -1,    73,
-      74,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-     617,   618,     1,   620,     3,    -1,     5,     6,     7,    -1,
-       9,    10,    -1,    12,    13,    -1,    15,    16,    17,    18,
-      19,    20,    -1,    22,    23,    24,    -1,    -1,    27,    28,
-      29,    30,    31,    32,    -1,    -1,    -1,    36,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      49,    50,    -1,    52,    53,    -1,    -1,    56,    -1,    -1,
-      59,    -1,    -1,    62,    -1,    -1,    -1,    -1,    67,    68,
-      69,    70,    71,    -1,    73,    74,     1,    -1,     3,    -1,
-       5,    -1,     7,    -1,     9,    10,    -1,    -1,    13,    -1,
-      15,    16,    17,    18,    19,    20,    -1,    22,    23,    24,
-      -1,    -1,    27,    28,    29,    30,    31,    32,    -1,    -1,
-      -1,    36,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    49,    50,    -1,    52,    53,    -1,
-      -1,    56,    -1,    -1,    59,    -1,     3,    62,    -1,    -1,
-       7,    -1,    67,    68,    69,    70,    71,    -1,    73,    74,
-      17,     7,    -1,    -1,    -1,    22,    23,    24,    -1,    -1,
-      -1,    17,    29,    -1,    -1,    -1,    22,    23,    24,    36,
-      -1,    -1,    -1,    29,    -1,    -1,    -1,    -1,    -1,    -1,
-      36,    -1,    49,    50,    -1,    52,    53,    -1,    -1,    56,
-      -1,     3,    59,    -1,    -1,     7,    -1,    53,    -1,    -1,
-      67,    -1,    69,    70,    71,    17,    73,    74,    -1,    -1,
-      22,    23,    24,    -1,    -1,    71,    -1,    29,    74,    31,
-      -1,    -1,    -1,    -1,    36,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    49,    50,    -1,
-      52,    53,    -1,    -1,    56,    -1,     3,    59,    -1,    -1,
-       7,    -1,    -1,    -1,    -1,    -1,    -1,    69,    70,    71,
-      17,    73,    74,    -1,    -1,    22,    23,    24,    -1,    26,
+      56,    -1,    -1,    59,    -1,    -1,    62,    -1,     3,    -1,
+      -1,    -1,     7,    69,    70,    71,    11,    73,    74,    -1,
+      -1,    -1,    17,    -1,   405,   639,    -1,    22,    23,    24,
+      -1,    -1,    -1,    -1,    29,    -1,    -1,   548,   419,    -1,
+      -1,    36,    -1,    -1,    -1,   556,   427,    -1,    -1,    -1,
+      -1,   432,   563,    -1,    49,    50,    -1,    52,    53,    -1,
+      -1,    56,    -1,    -1,    59,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    69,    70,    71,    -1,    73,    74,
+      -1,    -1,    -1,   594,    -1,    -1,   597,   598,    -1,    -1,
+      -1,   472,   473,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,     1,    -1,     3,    -1,     5,     6,     7,    -1,     9,
+      10,    -1,    12,    13,   495,    15,    16,    17,    18,    19,
+      20,    -1,    22,    23,    24,    -1,    -1,    27,    28,    29,
+      30,    31,    32,   644,   515,   646,    36,    -1,    -1,    -1,
+      -1,   522,   523,   524,    -1,    -1,    -1,    -1,    -1,    49,
+      50,    -1,    52,    53,    -1,    -1,    56,    -1,    -1,    59,
+      -1,    -1,    62,    -1,    -1,    -1,    -1,    67,    68,    69,
+      70,    71,    -1,    73,    74,     1,    -1,     3,    -1,     5,
+      -1,     7,    -1,     9,    10,    -1,    -1,    13,    -1,    15,
+      16,    17,    18,    19,    20,    -1,    22,    23,    24,    -1,
+      -1,    27,    28,    29,    30,    31,    32,    -1,    -1,    -1,
+      36,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    49,    50,    -1,    52,    53,    -1,    -1,
+      56,    -1,    -1,    59,    -1,     3,    62,   618,   619,     7,
+     621,    67,    68,    69,    70,    71,    -1,    73,    74,    17,
+       7,    -1,    -1,    -1,    22,    23,    24,    -1,    -1,    -1,
+      17,    29,    -1,    -1,    -1,    22,    23,    24,    36,    -1,
       -1,    -1,    29,    -1,    -1,    -1,    -1,    -1,    -1,    36,
+      -1,    49,    50,    -1,    52,    53,    -1,    -1,    56,    -1,
+       3,    59,    60,    -1,     7,    -1,    53,    -1,    -1,    -1,
+      -1,    69,    70,    71,    17,    73,    74,    -1,    65,    22,
+      23,    24,    -1,    -1,    71,    -1,    29,    74,    -1,    -1,
+      -1,    -1,    -1,    36,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    49,    50,    -1,    52,
+      53,    -1,    -1,    56,    -1,     3,    59,    -1,    -1,     7,
+      -1,    -1,    -1,    -1,    67,    -1,    69,    70,    71,    17,
+      73,    74,    -1,    -1,    22,    23,    24,    -1,    -1,    -1,
+      -1,    29,    -1,    31,    -1,    -1,    -1,    -1,    36,    -1,
       -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    49,    50,    -1,    52,    53,    -1,    -1,    56,
-      -1,     3,    59,    -1,    -1,     7,    -1,    -1,    -1,    -1,
-      -1,    -1,    69,    70,    71,    17,    73,    74,    -1,    -1,
-      22,    23,    24,    -1,    26,    -1,    -1,    29,    -1,    -1,
-      -1,    -1,    -1,    -1,    36,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    49,    50,    -1,
-      52,    53,    -1,    -1,    56,    -1,     3,    59,    -1,    -1,
-       7,    -1,    -1,    -1,    -1,    -1,    -1,    69,    70,    71,
-      17,    73,    74,    -1,    -1,    22,    23,    24,    -1,    -1,
-      -1,    -1,    29,    -1,    -1,    -1,    -1,    -1,    -1,    36,
+      -1,    49,    50,    -1,    52,    53,    -1,    -1,    56,    -1,
+       3,    59,    -1,    -1,     7,    -1,    -1,    -1,    -1,    -1,
+      -1,    69,    70,    71,    17,    73,    74,    -1,    -1,    22,
+      23,    24,    -1,    26,    -1,    -1,    29,    -1,    -1,    -1,
+      -1,    -1,    -1,    36,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    49,    50,    -1,    52,
+      53,    -1,    -1,    56,    -1,     3,    59,    -1,    -1,     7,
+      -1,    -1,    -1,    -1,    -1,    -1,    69,    70,    71,    17,
+      73,    74,    -1,    -1,    22,    23,    24,    -1,    26,    -1,
+      -1,    29,    -1,    -1,    -1,    -1,    -1,    -1,    36,    -1,
       -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    49,    50,    -1,    52,    53,    -1,    -1,    56,
-      -1,     3,    59,    -1,    -1,     7,    -1,    -1,    -1,    -1,
-      -1,    -1,    69,    70,    71,    17,    73,    74,    -1,    -1,
-      22,    23,    24,    -1,    -1,    -1,    -1,    29,    -1,    -1,
-      -1,    -1,    -1,    -1,    36,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    49,    50,    -1,
-      52,    53,    -1,    -1,    56,    -1,     3,    59,    -1,    -1,
-       7,    -1,    -1,    -1,    -1,    -1,    -1,    69,    70,    71,
-      17,    73,    74,    -1,    -1,    22,    23,    24,    -1,    -1,
-      -1,    -1,    29,    -1,    -1,    -1,    -1,    -1,    -1,    36,
+      -1,    49,    50,    -1,    52,    53,    -1,    -1,    56,    -1,
+       3,    59,    -1,    -1,     7,    -1,    -1,    -1,    -1,    -1,
+      -1,    69,    70,    71,    17,    73,    74,    -1,    -1,    22,
+      23,    24,    -1,    -1,    -1,    -1,    29,    -1,    -1,    -1,
+      -1,    -1,    -1,    36,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    49,    50,    -1,    52,
+      53,    -1,    -1,    56,    -1,     3,    59,    -1,    -1,     7,
+      -1,    -1,    -1,    -1,    -1,    -1,    69,    70,    71,    17,
+      73,    74,    -1,    -1,    22,    23,    24,    -1,    -1,    -1,
+      -1,    29,    -1,    -1,    -1,    -1,    -1,    -1,    36,    -1,
       -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    49,    50,    -1,    52,    53,    -1,    -1,    56,
-      -1,    -1,    59,    -1,    -1,     7,    -1,    -1,    -1,    -1,
-      -1,    -1,    69,    70,    71,    17,    73,    74,    -1,    -1,
-      22,    23,    24,    -1,    -1,    -1,    -1,    29,    -1,    -1,
-       7,    -1,    -1,    -1,    36,    -1,    -1,    -1,     7,    -1,
-      17,    -1,    -1,    -1,    -1,    22,    23,    24,    17,    -1,
-      -1,    53,    29,    22,    23,    24,    -1,    59,    -1,    36,
-      29,    -1,    -1,    65,     7,    -1,    -1,    36,    11,    71,
-      -1,    73,    74,    75,    17,    -1,    53,    -1,    -1,    22,
-      23,    24,    59,    -1,    53,    -1,    29,    -1,    65,    -1,
-      59,    -1,    -1,    36,    71,    -1,    73,    74,    75,    -1,
-      -1,    -1,    71,     7,    73,    74,    75,     7,    -1,    -1,
-      53,    -1,    -1,    17,    -1,    -1,    59,    17,    22,    23,
-      24,    -1,    22,    23,    24,    29,    -1,    -1,    71,    29,
-      73,    74,    36,    -1,    -1,     7,    36,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    17,     7,    -1,    -1,    53,
-      22,    23,    24,    53,    -1,    59,    17,    29,    -1,    59,
-      -1,    22,    23,    24,    36,    -1,    -1,    71,    29,    73,
-      74,    71,    -1,    73,    74,    36,    -1,    -1,     7,    -1,
-      -1,    53,    -1,    -1,    -1,    -1,    -1,    59,    17,    -1,
-      -1,    -1,    53,    22,    23,    24,    -1,    -1,    59,    71,
-      29,    73,    74,    -1,     7,    -1,    -1,    36,    -1,    -1,
-      71,    -1,    73,    74,    17,    -1,    -1,    -1,    -1,    22,
-      23,    24,    -1,    -1,    53,    -1,    29,    -1,    -1,    -1,
-      59,     7,    -1,    36,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    17,    71,    -1,    -1,    74,    22,    23,    24,    -1,
-      53,    -1,    -1,    29,    -1,    -1,    -1,    -1,    -1,    -1,
-      36,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    71,    -1,
-      73,    74,    -1,    -1,    -1,    -1,    -1,    53,    -1,    -1,
-      -1,    -1,    -1,    59,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    71,    33,    34,    74,    36,
-      -1,    38,    39,    40,    -1,    -1,    43,    44,    45,    46,
-      47,    48,    49,    50,    51,    52,    53,    54,    55,    56,
-      -1,    -1,    -1,    -1,    -1,    -1,    33,    34,    -1,    36,
-      -1,    38,    39,    40,    -1,    72,    43,    44,    45,    46,
-      47,    48,    49,    50,    51,    52,    53,    54,    55,    56,
-      33,    34,    -1,    36,    -1,    38,    39,    40,    -1,    66,
+      -1,    49,    50,    -1,    52,    53,    -1,    -1,    56,    -1,
+       3,    59,    -1,    -1,     7,    -1,    -1,    -1,    -1,    -1,
+      -1,    69,    70,    71,    17,    73,    74,    -1,    -1,    22,
+      23,    24,    -1,    -1,    -1,    -1,    29,    -1,    -1,    -1,
+      -1,    -1,    -1,    36,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    49,    50,    -1,    52,
+      53,    -1,    -1,    56,    -1,    -1,    59,    -1,    -1,     7,
+      -1,    -1,    -1,    -1,    -1,    -1,    69,    70,    71,    17,
+      73,    74,    -1,    -1,    22,    23,    24,    -1,    -1,    -1,
+      -1,    29,    -1,    -1,    -1,     7,    -1,    -1,    36,    11,
+      -1,    -1,    -1,     7,    -1,    17,    -1,    -1,    -1,    -1,
+      22,    23,    24,    17,    -1,    53,    -1,    29,    22,    23,
+      24,    59,    -1,    -1,    36,    29,    -1,    65,     7,    -1,
+      -1,    -1,    36,    71,    -1,    73,    74,    75,    17,    -1,
+      -1,    53,    -1,    22,    23,    24,    -1,    59,    -1,    53,
+      29,    -1,    -1,    -1,    -1,    59,     7,    36,    -1,    71,
+      -1,    73,    74,    -1,    -1,    -1,    17,    71,    -1,    73,
+      74,    22,    23,    24,    53,    -1,    -1,    -1,    29,    -1,
+      59,     7,    -1,    -1,    -1,    36,    -1,    -1,    -1,     7,
+      -1,    17,    71,    -1,    73,    74,    22,    23,    24,    17,
+      -1,    -1,    53,    29,    22,    23,    24,    -1,    59,    -1,
+      36,    29,    -1,    -1,     7,    -1,    -1,    -1,    36,    -1,
+      71,    -1,    73,    74,    17,    -1,    -1,    53,    -1,    22,
+      23,    24,    -1,    59,    -1,    53,    29,    -1,    -1,    -1,
+      -1,    59,     7,    36,    -1,    71,    -1,    73,    74,    -1,
+      -1,    -1,    17,    71,    -1,    73,    74,    22,    23,    24,
+      53,    -1,    -1,    -1,    29,    -1,    59,     7,    -1,    -1,
+      -1,    36,    -1,    -1,    -1,     7,    -1,    17,    71,    -1,
+      -1,    74,    22,    23,    24,    17,    -1,    -1,    53,    29,
+      22,    23,    24,    -1,    -1,    -1,    36,    29,    -1,    -1,
+      -1,    -1,    -1,    -1,    36,    -1,    71,    -1,    73,    74,
+      -1,    -1,    -1,    53,    -1,    -1,    -1,    -1,    -1,    59,
+      -1,    53,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    71,    -1,    -1,    74,    -1,    -1,    -1,    -1,    71,
+      33,    34,    74,    36,    -1,    38,    39,    40,    -1,    -1,
+      43,    44,    45,    46,    47,    48,    49,    50,    51,    52,
+      53,    54,    55,    56,    -1,    -1,    -1,    -1,    -1,    -1,
+      33,    34,    -1,    36,    -1,    38,    39,    40,    -1,    72,
       43,    44,    45,    46,    47,    48,    49,    50,    51,    52,
       53,    54,    55,    56,    33,    34,    -1,    36,    -1,    38,
       39,    40,    -1,    66,    43,    44,    45,    46,    47,    48,
       49,    50,    51,    52,    53,    54,    55,    56,    33,    34,
       -1,    36,    -1,    38,    39,    40,    -1,    66,    43,    44,
       45,    46,    47,    48,    49,    50,    51,    52,    53,    54,
-      55,    56,    -1,    33,    34,    60,    36,    -1,    38,    39,
-      40,    -1,    -1,    43,    44,    45,    46,    47,    48,    49,
-      50,    51,    52,    53,    54,    55,    56,    33,    34,    -1,
-      -1,    -1,    38,    39,    40,    -1,    -1,    43,    44,    45,
+      55,    56,    33,    34,    -1,    36,    -1,    38,    39,    40,
+      -1,    66,    43,    44,    45,    46,    47,    48,    49,    50,
+      51,    52,    53,    54,    55,    56,    -1,    33,    34,    60,
+      36,    -1,    38,    39,    40,    -1,    -1,    43,    44,    45,
       46,    47,    48,    49,    50,    51,    52,    53,    54,    55,
       56,    33,    34,    -1,    -1,    -1,    38,    39,    40,    -1,
-      -1,    43,    44,    45,    46,    -1,    48,    49,    50,    51,
-      52,    53,    54,    55,    56,    34,    -1,    -1,    -1,    38,
-      39,    40,    -1,    -1,    43,    44,    45,    46,    -1,    48,
-      49,    50,    51,    52,    53,    54,    55,    56
+      -1,    43,    44,    45,    46,    47,    48,    49,    50,    51,
+      52,    53,    54,    55,    56,    33,    34,    -1,    -1,    -1,
+      38,    39,    40,    -1,    -1,    43,    44,    45,    46,    -1,
+      48,    49,    50,    51,    52,    53,    54,    55,    56,    34,
+      -1,    -1,    -1,    38,    39,    40,    -1,    -1,    43,    44,
+      45,    46,    -1,    48,    49,    50,    51,    52,    53,    54,
+      55,    56
 };
 
 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
@@ -1494,62 +1497,62 @@ static const yytype_uint8 yystos[] =
      113,   118,   121,   123,   124,   125,   126,   130,   134,   137,
      139,   140,   145,   146,   149,   152,   153,   154,   157,   160,
      161,   177,   182,    62,     9,    17,    21,    31,    32,    64,
-     195,    24,    60,    83,    84,     3,    86,     3,   134,   136,
-     137,    17,    36,    53,    59,   137,   139,   144,   148,   149,
-     150,   157,   136,   125,   130,   111,    59,   137,   155,   125,
-     134,   114,    35,    67,   133,    71,   123,   182,   189,   122,
-     133,   119,    59,    96,    97,   137,    59,    93,   135,   137,
-     181,   124,   124,   124,   124,   124,   124,    36,    53,   123,
-     131,   143,   149,   151,   157,   124,   124,    11,   123,   188,
-      62,    59,    94,   181,     4,    33,    34,    36,    37,    38,
-      39,    40,    42,    43,    44,    45,    46,    47,    48,    49,
-      50,    51,    52,    53,    54,    55,    56,    67,    59,    63,
-      71,    66,    59,   133,     1,   133,     8,    65,    75,   138,
-     196,    59,   156,   196,    24,   196,   197,   196,    64,    62,
-     186,    88,    59,    36,    59,   142,   148,   149,   150,   151,
-     157,   142,   142,    63,    98,   107,   108,   109,   182,   190,
-      11,   132,   137,   141,   142,   173,   174,   175,    59,    67,
-     158,   112,   190,    24,    59,    68,   134,   167,   169,   171,
-     142,    35,    53,    59,    68,   134,   166,   168,   169,   170,
-     180,   112,    60,    97,   165,   142,    60,    93,   163,    65,
-      75,   142,     7,   143,    60,    72,    72,    60,    94,    65,
-     142,   123,   123,   123,   123,   123,   123,   123,   123,   123,
+     195,    24,    60,    83,    84,     3,    86,    88,     3,   134,
+     136,   137,    17,    36,    53,    59,   137,   139,   144,   148,
+     149,   150,   157,   136,   125,   130,   111,    59,   137,   155,
+     125,   134,   114,    35,    67,   133,    71,   123,   182,   189,
+     122,   133,   119,    59,    96,    97,   137,    59,    93,   135,
+     137,   181,   124,   124,   124,   124,   124,   124,    36,    53,
+     123,   131,   143,   149,   151,   157,   124,   124,    11,   123,
+     188,    62,    59,    94,   181,     4,    33,    34,    36,    37,
+      38,    39,    40,    42,    43,    44,    45,    46,    47,    48,
+      49,    50,    51,    52,    53,    54,    55,    56,    67,    59,
+      63,    71,    66,    59,   133,     1,   133,     8,    65,    75,
+     138,   196,    59,   156,   196,    24,   196,   197,   196,    64,
+      62,   186,    88,    59,    36,    59,   142,   148,   149,   150,
+     151,   157,   142,   142,    63,    98,   107,   108,   109,   182,
+     190,    11,   132,   137,   141,   142,   173,   174,   175,    59,
+      67,   158,   112,   190,    24,    59,    68,   134,   167,   169,
+     171,   142,    35,    53,    59,    68,   134,   166,   168,   169,
+     170,   180,   112,    60,    97,   165,   142,    60,    93,   163,
+      65,    75,   142,     7,   143,    60,    72,    72,    60,    94,
+      65,   142,   123,   123,   123,   123,   123,   123,   123,   123,
      123,   123,   123,   123,   123,   123,   123,   123,   123,   123,
-     123,   123,   127,    60,   131,   183,    59,   137,   123,   188,
-     178,   123,   127,     1,    67,    91,   100,   176,   177,   179,
-     182,   182,   123,     7,    17,    22,    23,    24,    29,    36,
-      53,    65,    71,   138,   198,   200,   201,   202,   137,   203,
-     211,   158,    59,     3,   198,   198,    83,    60,   175,     7,
-     142,    60,   137,    35,   105,     8,    65,    62,   142,   132,
-     141,    75,   187,    60,   175,   179,   115,    62,    63,    24,
-     169,    59,   172,    62,   186,    72,   104,    59,   170,    53,
-     170,    62,   186,     3,   194,    75,   142,   120,    62,   186,
-      62,   186,   182,   135,    65,    36,    59,   142,   148,   149,
-     150,   157,    67,   142,   142,    62,   186,   182,    65,    67,
-     123,   128,   129,   184,   185,    11,    75,   187,    31,   131,
-      72,    66,   176,    60,   185,   101,    62,    68,    36,    59,
-     199,   200,   202,    59,    67,    71,    67,     7,   198,     3,
-      50,    59,   137,   208,   209,     3,    72,    65,    11,   198,
-      60,    75,    62,   191,   211,    62,    62,    62,    60,    60,
-     106,    26,    26,   190,   173,    59,   137,   147,   148,   149,
-     150,   151,   157,   159,    60,    68,   105,   190,   137,    60,
-     175,   171,    68,   142,     6,    12,    68,    99,   102,   170,
-     194,   170,    60,   168,    68,   134,   194,    35,    97,    60,
-      93,    60,   182,   142,   127,    94,    95,   164,   181,    60,
-     182,   127,    66,    75,   187,    68,    75,   187,   131,    60,
-      60,    60,   188,    68,   179,   176,   198,   201,   191,    24,
-     137,   138,   193,   198,   205,   213,   198,   137,   192,   204,
-     212,   198,     3,   208,    62,    72,   198,   209,   198,   194,
-     137,   203,    60,   179,   123,   123,    62,   175,    59,   159,
-     116,    60,   183,    66,   103,    60,    60,   194,   104,    60,
-     185,    62,   186,   142,   185,   123,   129,   128,   129,    60,
-      72,    68,    60,    60,    59,    68,    62,    72,   198,    68,
-      62,    49,   198,    62,   194,    59,    59,   198,   206,   207,
-      68,   190,    60,   175,    14,   117,   159,     8,    65,    66,
-      75,   179,   194,   194,    68,    68,    95,    60,    68,   206,
-     191,   205,   198,   194,   204,   208,   191,   191,    60,   100,
-     113,   123,   123,    60,    60,    60,    60,   159,    66,    66,
-     206,   206
+     123,   123,   123,   127,    60,   131,   183,    59,   137,   123,
+     188,   178,   123,   127,     1,    67,    91,   100,   176,   177,
+     179,   182,   182,   123,     7,    17,    22,    23,    24,    29,
+      36,    53,    65,    71,   138,   198,   200,   201,   202,   137,
+     203,   211,   158,    59,     3,   198,   198,    83,    60,   175,
+       7,   142,    60,   137,    35,   105,     8,    65,    62,   142,
+     132,   141,    75,   187,    60,   175,   179,   115,    62,    63,
+      24,   169,    59,   172,    62,   186,    72,   104,    59,   170,
+      53,   170,    62,   186,     3,   194,    75,   142,   120,    62,
+     186,    62,   186,   182,   135,    65,    36,    59,   142,   148,
+     149,   150,   157,    67,   142,   142,    62,   186,   182,    65,
+      67,   123,   128,   129,   184,   185,    11,    75,   187,    31,
+     131,    72,    66,   176,    60,   185,   101,    62,    68,    36,
+      59,   199,   200,   202,    59,    67,    71,    67,     7,   198,
+       3,    50,    59,   137,   208,   209,     3,    72,    65,    11,
+     198,    60,    75,    62,   191,   211,    62,    62,    62,    60,
+      60,   106,    26,    26,   190,   173,    59,   137,   147,   148,
+     149,   150,   151,   157,   159,    60,    68,   105,   190,   137,
+      60,   175,   171,    68,   142,     6,    12,    68,    99,   102,
+     170,   194,   170,    60,   168,    68,   134,   194,    35,    97,
+      60,    93,    60,   182,   142,   127,    94,    95,   164,   181,
+      60,   182,   127,    66,    75,   187,    68,    75,   187,   131,
+      60,    60,    60,   188,    68,   179,   176,   198,   201,   191,
+      24,   137,   138,   193,   198,   205,   213,   198,   137,   192,
+     204,   212,   198,     3,   208,    62,    72,   198,   209,   198,
+     194,   137,   203,    60,   179,   123,   123,    62,   175,    59,
+     159,   116,    60,   183,    66,   103,    60,    60,   194,   104,
+      60,   185,    62,   186,   142,   185,   123,   129,   128,   129,
+      60,    72,    68,    60,    60,    59,    68,    62,    72,   198,
+      68,    62,    49,   198,    62,   194,    59,    59,   198,   206,
+     207,    68,   190,    60,   175,    14,   117,   159,     8,    65,
+      66,    75,   179,   194,   194,    68,    68,    95,    60,    68,
+     206,   191,   205,   198,   194,   204,   208,   191,   191,    60,
+     100,   113,   123,   123,    60,    60,    60,    60,   159,    66,
+      66,   206,   206
 };
 
 #define yyerrok		(yyerrstatus = 0)
@@ -1564,9 +1567,18 @@ static const yytype_uint8 yystos[] =
 
 /* Like YYERROR except do call yyerror.  This remains here temporarily
    to ease the transition to the new meaning of YYERROR, for GCC.
-   Once GCC version 2 has supplanted version 1, this can go.  */
+   Once GCC version 2 has supplanted version 1, this can go.  However,
+   YYFAIL appears to be in use.  Nevertheless, it is formally deprecated
+   in Bison 2.4.2's NEWS entry, where a plan to phase it out is
+   discussed.  */
 
 #define YYFAIL		goto yyerrlab
+#if defined YYFAIL
+  /* This is here to suppress warnings from the GCC cpp's
+     -Wunused-macros.  Normally we don't worry about that warning, but
+     some users do, and we want to make it easy for users to remove
+     YYFAIL uses, which will produce warnings from Bison 2.5.  */
+#endif
 
 #define YYRECOVERING()  (!!yyerrstatus)
 
@@ -1576,7 +1588,6 @@ do								\
     {								\
       yychar = (Token);						\
       yylval = (Value);						\
-      yytoken = YYTRANSLATE (yychar);				\
       YYPOPSTACK (1);						\
       goto yybackup;						\
     }								\
@@ -1618,19 +1629,10 @@ while (YYID (0))
 #endif
 
 
-/* YY_LOCATION_PRINT -- Print the location on the stream.
-   This macro was not mandated originally: define only if we know
-   we won't break user code: when these are the locations we know.  */
+/* This macro is provided for backward compatibility. */
 
 #ifndef YY_LOCATION_PRINT
-# if YYLTYPE_IS_TRIVIAL
-#  define YY_LOCATION_PRINT(File, Loc)			\
-     fprintf (File, "%d.%d-%d.%d",			\
-	      (Loc).first_line, (Loc).first_column,	\
-	      (Loc).last_line,  (Loc).last_column)
-# else
-#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
-# endif
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
 #endif
 
 
@@ -1822,7 +1824,6 @@ int yydebug;
 # define YYMAXDEPTH 10000
 #endif
 
-
 
 #if YYERROR_VERBOSE
 
@@ -1925,115 +1926,142 @@ yytnamerr (char *yyres, const char *yystr)
 }
 # endif
 
-/* Copy into YYRESULT an error message about the unexpected token
-   YYCHAR while in state YYSTATE.  Return the number of bytes copied,
-   including the terminating null byte.  If YYRESULT is null, do not
-   copy anything; just return the number of bytes that would be
-   copied.  As a special case, return 0 if an ordinary "syntax error"
-   message will do.  Return YYSIZE_MAXIMUM if overflow occurs during
-   size calculation.  */
-static YYSIZE_T
-yysyntax_error (char *yyresult, int yystate, int yychar)
-{
-  int yyn = yypact[yystate];
+/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
+   about the unexpected token YYTOKEN for the state stack whose top is
+   YYSSP.
 
-  if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
-    return 0;
-  else
-    {
-      int yytype = YYTRANSLATE (yychar);
-      YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
-      YYSIZE_T yysize = yysize0;
-      YYSIZE_T yysize1;
-      int yysize_overflow = 0;
-      enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
-      char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
-      int yyx;
-
-# if 0
-      /* This is so xgettext sees the translatable formats that are
-	 constructed on the fly.  */
-      YY_("syntax error, unexpected %s");
-      YY_("syntax error, unexpected %s, expecting %s");
-      YY_("syntax error, unexpected %s, expecting %s or %s");
-      YY_("syntax error, unexpected %s, expecting %s or %s or %s");
-      YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
-# endif
-      char *yyfmt;
-      char const *yyf;
-      static char const yyunexpected[] = "syntax error, unexpected %s";
-      static char const yyexpecting[] = ", expecting %s";
-      static char const yyor[] = " or %s";
-      char yyformat[sizeof yyunexpected
-		    + sizeof yyexpecting - 1
-		    + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
-		       * (sizeof yyor - 1))];
-      char const *yyprefix = yyexpecting;
-
-      /* Start YYX at -YYN if negative to avoid negative indexes in
-	 YYCHECK.  */
-      int yyxbegin = yyn < 0 ? -yyn : 0;
-
-      /* Stay within bounds of both yycheck and yytname.  */
-      int yychecklim = YYLAST - yyn + 1;
-      int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
-      int yycount = 1;
-
-      yyarg[0] = yytname[yytype];
-      yyfmt = yystpcpy (yyformat, yyunexpected);
-
-      for (yyx = yyxbegin; yyx < yyxend; ++yyx)
-	if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
-	  {
-	    if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
-	      {
-		yycount = 1;
-		yysize = yysize0;
-		yyformat[sizeof yyunexpected - 1] = '\0';
-		break;
-	      }
-	    yyarg[yycount++] = yytname[yyx];
-	    yysize1 = yysize + yytnamerr (0, yytname[yyx]);
-	    yysize_overflow |= (yysize1 < yysize);
-	    yysize = yysize1;
-	    yyfmt = yystpcpy (yyfmt, yyprefix);
-	    yyprefix = yyor;
-	  }
+   Return 0 if *YYMSG was successfully written.  Return 1 if *YYMSG is
+   not large enough to hold the message.  In that case, also set
+   *YYMSG_ALLOC to the required number of bytes.  Return 2 if the
+   required number of bytes is too large to store.  */
+static int
+yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
+                yytype_int16 *yyssp, int yytoken)
+{
+  YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]);
+  YYSIZE_T yysize = yysize0;
+  YYSIZE_T yysize1;
+  enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+  /* Internationalized format string. */
+  const char *yyformat = 0;
+  /* Arguments of yyformat. */
+  char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+  /* Number of reported tokens (one for the "unexpected", one per
+     "expected"). */
+  int yycount = 0;
+
+  /* There are many possibilities here to consider:
+     - Assume YYFAIL is not used.  It's too flawed to consider.  See
+       <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html>
+       for details.  YYERROR is fine as it does not invoke this
+       function.
+     - If this state is a consistent state with a default action, then
+       the only way this function was invoked is if the default action
+       is an error action.  In that case, don't check for expected
+       tokens because there are none.
+     - The only way there can be no lookahead present (in yychar) is if
+       this state is a consistent state with a default action.  Thus,
+       detecting the absence of a lookahead is sufficient to determine
+       that there is no unexpected or expected token to report.  In that
+       case, just report a simple "syntax error".
+     - Don't assume there isn't a lookahead just because this state is a
+       consistent state with a default action.  There might have been a
+       previous inconsistent state, consistent state with a non-default
+       action, or user semantic action that manipulated yychar.
+     - Of course, the expected token list depends on states to have
+       correct lookahead information, and it depends on the parser not
+       to perform extra reductions after fetching a lookahead from the
+       scanner and before detecting a syntax error.  Thus, state merging
+       (from LALR or IELR) and default reductions corrupt the expected
+       token list.  However, the list is correct for canonical LR with
+       one exception: it will still contain any token that will not be
+       accepted due to an error action in a later state.
+  */
+  if (yytoken != YYEMPTY)
+    {
+      int yyn = yypact[*yyssp];
+      yyarg[yycount++] = yytname[yytoken];
+      if (!yypact_value_is_default (yyn))
+        {
+          /* Start YYX at -YYN if negative to avoid negative indexes in
+             YYCHECK.  In other words, skip the first -YYN actions for
+             this state because they are default actions.  */
+          int yyxbegin = yyn < 0 ? -yyn : 0;
+          /* Stay within bounds of both yycheck and yytname.  */
+          int yychecklim = YYLAST - yyn + 1;
+          int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+          int yyx;
+
+          for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+            if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
+                && !yytable_value_is_error (yytable[yyx + yyn]))
+              {
+                if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+                  {
+                    yycount = 1;
+                    yysize = yysize0;
+                    break;
+                  }
+                yyarg[yycount++] = yytname[yyx];
+                yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+                if (! (yysize <= yysize1
+                       && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+                  return 2;
+                yysize = yysize1;
+              }
+        }
+    }
 
-      yyf = YY_(yyformat);
-      yysize1 = yysize + yystrlen (yyf);
-      yysize_overflow |= (yysize1 < yysize);
-      yysize = yysize1;
+  switch (yycount)
+    {
+# define YYCASE_(N, S)                      \
+      case N:                               \
+        yyformat = S;                       \
+      break
+      YYCASE_(0, YY_("syntax error"));
+      YYCASE_(1, YY_("syntax error, unexpected %s"));
+      YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
+      YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
+      YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
+      YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
+# undef YYCASE_
+    }
 
-      if (yysize_overflow)
-	return YYSIZE_MAXIMUM;
+  yysize1 = yysize + yystrlen (yyformat);
+  if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+    return 2;
+  yysize = yysize1;
 
-      if (yyresult)
-	{
-	  /* Avoid sprintf, as that infringes on the user's name space.
-	     Don't have undefined behavior even if the translation
-	     produced a string with the wrong number of "%s"s.  */
-	  char *yyp = yyresult;
-	  int yyi = 0;
-	  while ((*yyp = *yyf) != '\0')
-	    {
-	      if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
-		{
-		  yyp += yytnamerr (yyp, yyarg[yyi++]);
-		  yyf += 2;
-		}
-	      else
-		{
-		  yyp++;
-		  yyf++;
-		}
-	    }
-	}
-      return yysize;
+  if (*yymsg_alloc < yysize)
+    {
+      *yymsg_alloc = 2 * yysize;
+      if (! (yysize <= *yymsg_alloc
+             && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
+        *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
+      return 1;
     }
+
+  /* Avoid sprintf, as that infringes on the user's name space.
+     Don't have undefined behavior even if the translation
+     produced a string with the wrong number of "%s"s.  */
+  {
+    char *yyp = *yymsg;
+    int yyi = 0;
+    while ((*yyp = *yyformat) != '\0')
+      if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
+        {
+          yyp += yytnamerr (yyp, yyarg[yyi++]);
+          yyformat += 2;
+        }
+      else
+        {
+          yyp++;
+          yyformat++;
+        }
+  }
+  return 0;
 }
 #endif /* YYERROR_VERBOSE */
-
 
 /*-----------------------------------------------.
 | Release the memory associated to this symbol.  |
@@ -2066,6 +2094,7 @@ yydestruct (yymsg, yytype, yyvaluep)
     }
 }
 
+
 /* Prevent warnings from -Wmissing-prototypes.  */
 #ifdef YYPARSE_PARAM
 #if defined __STDC__ || defined __cplusplus
@@ -2092,10 +2121,9 @@ YYSTYPE yylval;
 int yynerrs;
 
 
-
-/*-------------------------.
-| yyparse or yypush_parse.  |
-`-------------------------*/
+/*----------.
+| yyparse.  |
+`----------*/
 
 #ifdef YYPARSE_PARAM
 #if (defined __STDC__ || defined __C99__FUNC__ \
@@ -2119,8 +2147,6 @@ yyparse ()
 #endif
 #endif
 {
-
-
     /* Number of tokens to shift before error messages enabled.  */
     int yyerrstatus;
 
@@ -2274,7 +2300,7 @@ yybackup:
 
   /* First try to decide what to do without reference to lookahead token.  */
   yyn = yypact[yystate];
-  if (yyn == YYPACT_NINF)
+  if (yypact_value_is_default (yyn))
     goto yydefault;
 
   /* Not known => get a lookahead token if don't already have one.  */
@@ -2305,8 +2331,8 @@ yybackup:
   yyn = yytable[yyn];
   if (yyn <= 0)
     {
-      if (yyn == 0 || yyn == YYTABLE_NINF)
-	goto yyerrlab;
+      if (yytable_value_is_error (yyn))
+        goto yyerrlab;
       yyn = -yyn;
       goto yyreduce;
     }
@@ -2361,7 +2387,7 @@ yyreduce:
     {
         case 2:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 128 "go.y"
     {
 		xtop = concat(xtop, (yyvsp[(4) - (4)].list));
@@ -2370,7 +2396,7 @@ yyreduce:
 
   case 3:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 134 "go.y"
     {
 		prevlineno = lineno;
@@ -2382,7 +2408,7 @@ yyreduce:
 
   case 4:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 141 "go.y"
     {
 		mkpackage((yyvsp[(2) - (3)].sym)->name);
@@ -2391,7 +2417,7 @@ yyreduce:
 
   case 5:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 151 "go.y"
     {
 		importpkg = runtimepkg;
@@ -2406,7 +2432,7 @@ yyreduce:
 
   case 6:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 162 "go.y"
     {
 		importpkg = nil;
@@ -2415,7 +2441,7 @@ yyreduce:
 
   case 12:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 176 "go.y"
     {
 		Pkg *ipkg;
@@ -2451,10 +2477,24 @@ yyreduce:
 	}
     break;
 
-  case 15:
+  case 13:
 
-/* Line 1455 of yacc.c  */
-#line 216 "go.y"
+/* Line 1806 of yacc.c  */
+#line 209 "go.y"
+    {
+		// When an invalid import path is passed to importfile,
+		// it calls yyerror and then sets up a fake import with
+		// no package statement. This allows us to test more
+		// than one invalid import statement in a single file.
+		if(nerrors == 0)
+			fatal("phase error in import");
+	}
+    break;
+
+  case 16:
+
+/* Line 1806 of yacc.c  */
+#line 224 "go.y"
     {
 		// import with original name
 		(yyval.i) = parserline();
@@ -2463,10 +2503,10 @@ yyreduce:
 	}
     break;
 
-  case 16:
+  case 17:
 
-/* Line 1455 of yacc.c  */
-#line 223 "go.y"
+/* Line 1806 of yacc.c  */
+#line 231 "go.y"
     {
 		// import with given name
 		(yyval.i) = parserline();
@@ -2475,10 +2515,10 @@ yyreduce:
 	}
     break;
 
-  case 17:
+  case 18:
 
-/* Line 1455 of yacc.c  */
-#line 230 "go.y"
+/* Line 1806 of yacc.c  */
+#line 238 "go.y"
     {
 		// import into my name space
 		(yyval.i) = parserline();
@@ -2487,10 +2527,10 @@ yyreduce:
 	}
     break;
 
-  case 18:
+  case 19:
 
-/* Line 1455 of yacc.c  */
-#line 239 "go.y"
+/* Line 1806 of yacc.c  */
+#line 247 "go.y"
     {
 		if(importpkg->name == nil) {
 			importpkg->name = (yyvsp[(2) - (4)].sym)->name;
@@ -2504,104 +2544,104 @@ yyreduce:
 	}
     break;
 
-  case 20:
+  case 21:
 
-/* Line 1455 of yacc.c  */
-#line 253 "go.y"
+/* Line 1806 of yacc.c  */
+#line 261 "go.y"
     {
 		if(strcmp((yyvsp[(1) - (1)].sym)->name, "safe") == 0)
 			curio.importsafe = 1;
 	}
     break;
 
-  case 21:
+  case 22:
 
-/* Line 1455 of yacc.c  */
-#line 259 "go.y"
+/* Line 1806 of yacc.c  */
+#line 267 "go.y"
     {
 		defercheckwidth();
 	}
     break;
 
-  case 22:
+  case 23:
 
-/* Line 1455 of yacc.c  */
-#line 263 "go.y"
+/* Line 1806 of yacc.c  */
+#line 271 "go.y"
     {
 		resumecheckwidth();
 		unimportfile();
 	}
     break;
 
-  case 23:
+  case 24:
 
-/* Line 1455 of yacc.c  */
-#line 272 "go.y"
+/* Line 1806 of yacc.c  */
+#line 280 "go.y"
     {
 		yyerror("empty top-level declaration");
 		(yyval.list) = nil;
 	}
     break;
 
-  case 25:
+  case 26:
 
-/* Line 1455 of yacc.c  */
-#line 278 "go.y"
+/* Line 1806 of yacc.c  */
+#line 286 "go.y"
     {
 		(yyval.list) = list1((yyvsp[(1) - (1)].node));
 	}
     break;
 
-  case 26:
+  case 27:
 
-/* Line 1455 of yacc.c  */
-#line 282 "go.y"
+/* Line 1806 of yacc.c  */
+#line 290 "go.y"
     {
 		yyerror("non-declaration statement outside function body");
 		(yyval.list) = nil;
 	}
     break;
 
-  case 27:
+  case 28:
 
-/* Line 1455 of yacc.c  */
-#line 287 "go.y"
+/* Line 1806 of yacc.c  */
+#line 295 "go.y"
     {
 		(yyval.list) = nil;
 	}
     break;
 
-  case 28:
+  case 29:
 
-/* Line 1455 of yacc.c  */
-#line 293 "go.y"
+/* Line 1806 of yacc.c  */
+#line 301 "go.y"
     {
 		(yyval.list) = (yyvsp[(2) - (2)].list);
 	}
     break;
 
-  case 29:
+  case 30:
 
-/* Line 1455 of yacc.c  */
-#line 297 "go.y"
+/* Line 1806 of yacc.c  */
+#line 305 "go.y"
     {
 		(yyval.list) = (yyvsp[(3) - (5)].list);
 	}
     break;
 
-  case 30:
+  case 31:
 
-/* Line 1455 of yacc.c  */
-#line 301 "go.y"
+/* Line 1806 of yacc.c  */
+#line 309 "go.y"
     {
 		(yyval.list) = nil;
 	}
     break;
 
-  case 31:
+  case 32:
 
-/* Line 1455 of yacc.c  */
-#line 305 "go.y"
+/* Line 1806 of yacc.c  */
+#line 313 "go.y"
     {
 		(yyval.list) = (yyvsp[(2) - (2)].list);
 		iota = -100000;
@@ -2609,10 +2649,10 @@ yyreduce:
 	}
     break;
 
-  case 32:
+  case 33:
 
-/* Line 1455 of yacc.c  */
-#line 311 "go.y"
+/* Line 1806 of yacc.c  */
+#line 319 "go.y"
     {
 		(yyval.list) = (yyvsp[(3) - (5)].list);
 		iota = -100000;
@@ -2620,10 +2660,10 @@ yyreduce:
 	}
     break;
 
-  case 33:
+  case 34:
 
-/* Line 1455 of yacc.c  */
-#line 317 "go.y"
+/* Line 1806 of yacc.c  */
+#line 325 "go.y"
     {
 		(yyval.list) = concat((yyvsp[(3) - (7)].list), (yyvsp[(5) - (7)].list));
 		iota = -100000;
@@ -2631,119 +2671,119 @@ yyreduce:
 	}
     break;
 
-  case 34:
+  case 35:
 
-/* Line 1455 of yacc.c  */
-#line 323 "go.y"
+/* Line 1806 of yacc.c  */
+#line 331 "go.y"
     {
 		(yyval.list) = nil;
 		iota = -100000;
 	}
     break;
 
-  case 35:
+  case 36:
 
-/* Line 1455 of yacc.c  */
-#line 328 "go.y"
+/* Line 1806 of yacc.c  */
+#line 336 "go.y"
     {
 		(yyval.list) = list1((yyvsp[(2) - (2)].node));
 	}
     break;
 
-  case 36:
+  case 37:
 
-/* Line 1455 of yacc.c  */
-#line 332 "go.y"
+/* Line 1806 of yacc.c  */
+#line 340 "go.y"
     {
 		(yyval.list) = (yyvsp[(3) - (5)].list);
 	}
     break;
 
-  case 37:
+  case 38:
 
-/* Line 1455 of yacc.c  */
-#line 336 "go.y"
+/* Line 1806 of yacc.c  */
+#line 344 "go.y"
     {
 		(yyval.list) = nil;
 	}
     break;
 
-  case 38:
+  case 39:
 
-/* Line 1455 of yacc.c  */
-#line 342 "go.y"
+/* Line 1806 of yacc.c  */
+#line 350 "go.y"
     {
 		iota = 0;
 	}
     break;
 
-  case 39:
+  case 40:
 
-/* Line 1455 of yacc.c  */
-#line 348 "go.y"
+/* Line 1806 of yacc.c  */
+#line 356 "go.y"
     {
 		(yyval.list) = variter((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].node), nil);
 	}
     break;
 
-  case 40:
+  case 41:
 
-/* Line 1455 of yacc.c  */
-#line 352 "go.y"
+/* Line 1806 of yacc.c  */
+#line 360 "go.y"
     {
 		(yyval.list) = variter((yyvsp[(1) - (4)].list), (yyvsp[(2) - (4)].node), (yyvsp[(4) - (4)].list));
 	}
     break;
 
-  case 41:
+  case 42:
 
-/* Line 1455 of yacc.c  */
-#line 356 "go.y"
+/* Line 1806 of yacc.c  */
+#line 364 "go.y"
     {
 		(yyval.list) = variter((yyvsp[(1) - (3)].list), nil, (yyvsp[(3) - (3)].list));
 	}
     break;
 
-  case 42:
+  case 43:
 
-/* Line 1455 of yacc.c  */
-#line 362 "go.y"
+/* Line 1806 of yacc.c  */
+#line 370 "go.y"
     {
 		(yyval.list) = constiter((yyvsp[(1) - (4)].list), (yyvsp[(2) - (4)].node), (yyvsp[(4) - (4)].list));
 	}
     break;
 
-  case 43:
+  case 44:
 
-/* Line 1455 of yacc.c  */
-#line 366 "go.y"
+/* Line 1806 of yacc.c  */
+#line 374 "go.y"
     {
 		(yyval.list) = constiter((yyvsp[(1) - (3)].list), N, (yyvsp[(3) - (3)].list));
 	}
     break;
 
-  case 45:
+  case 46:
 
-/* Line 1455 of yacc.c  */
-#line 373 "go.y"
+/* Line 1806 of yacc.c  */
+#line 381 "go.y"
     {
 		(yyval.list) = constiter((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].node), nil);
 	}
     break;
 
-  case 46:
+  case 47:
 
-/* Line 1455 of yacc.c  */
-#line 377 "go.y"
+/* Line 1806 of yacc.c  */
+#line 385 "go.y"
     {
 		(yyval.list) = constiter((yyvsp[(1) - (1)].list), N, nil);
 	}
     break;
 
-  case 47:
+  case 48:
 
-/* Line 1455 of yacc.c  */
-#line 383 "go.y"
+/* Line 1806 of yacc.c  */
+#line 391 "go.y"
     {
 		// different from dclname because the name
 		// becomes visible right here, not at the end
@@ -2752,38 +2792,38 @@ yyreduce:
 	}
     break;
 
-  case 48:
+  case 49:
 
-/* Line 1455 of yacc.c  */
-#line 392 "go.y"
+/* Line 1806 of yacc.c  */
+#line 400 "go.y"
     {
 		(yyval.node) = typedcl1((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].node), 1);
 	}
     break;
 
-  case 49:
+  case 50:
 
-/* Line 1455 of yacc.c  */
-#line 398 "go.y"
+/* Line 1806 of yacc.c  */
+#line 406 "go.y"
     {
 		(yyval.node) = (yyvsp[(1) - (1)].node);
 	}
     break;
 
-  case 50:
+  case 51:
 
-/* Line 1455 of yacc.c  */
-#line 402 "go.y"
+/* Line 1806 of yacc.c  */
+#line 410 "go.y"
     {
 		(yyval.node) = nod(OASOP, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
 		(yyval.node)->etype = (yyvsp[(2) - (3)].i);			// rathole to pass opcode
 	}
     break;
 
-  case 51:
+  case 52:
 
-/* Line 1455 of yacc.c  */
-#line 407 "go.y"
+/* Line 1806 of yacc.c  */
+#line 415 "go.y"
     {
 		if((yyvsp[(1) - (3)].list)->next == nil && (yyvsp[(3) - (3)].list)->next == nil) {
 			// simple
@@ -2797,10 +2837,10 @@ yyreduce:
 	}
     break;
 
-  case 52:
+  case 53:
 
-/* Line 1455 of yacc.c  */
-#line 419 "go.y"
+/* Line 1806 of yacc.c  */
+#line 427 "go.y"
     {
 		if((yyvsp[(3) - (3)].list)->n->op == OTYPESW) {
 			(yyval.node) = nod(OTYPESW, N, (yyvsp[(3) - (3)].list)->n->right);
@@ -2818,30 +2858,30 @@ yyreduce:
 	}
     break;
 
-  case 53:
+  case 54:
 
-/* Line 1455 of yacc.c  */
-#line 435 "go.y"
+/* Line 1806 of yacc.c  */
+#line 443 "go.y"
     {
 		(yyval.node) = nod(OASOP, (yyvsp[(1) - (2)].node), nodintconst(1));
 		(yyval.node)->etype = OADD;
 	}
     break;
 
-  case 54:
+  case 55:
 
-/* Line 1455 of yacc.c  */
-#line 440 "go.y"
+/* Line 1806 of yacc.c  */
+#line 448 "go.y"
     {
 		(yyval.node) = nod(OASOP, (yyvsp[(1) - (2)].node), nodintconst(1));
 		(yyval.node)->etype = OSUB;
 	}
     break;
 
-  case 55:
+  case 56:
 
-/* Line 1455 of yacc.c  */
-#line 447 "go.y"
+/* Line 1806 of yacc.c  */
+#line 455 "go.y"
     {
 		Node *n, *nn;
 
@@ -2863,10 +2903,10 @@ yyreduce:
 	}
     break;
 
-  case 56:
+  case 57:
 
-/* Line 1455 of yacc.c  */
-#line 467 "go.y"
+/* Line 1806 of yacc.c  */
+#line 475 "go.y"
     {
 		Node *n;
 
@@ -2886,10 +2926,10 @@ yyreduce:
 	}
     break;
 
-  case 57:
+  case 58:
 
-/* Line 1455 of yacc.c  */
-#line 485 "go.y"
+/* Line 1806 of yacc.c  */
+#line 493 "go.y"
     {
 		// will be converted to OCASE
 		// right will point to next case
@@ -2900,10 +2940,10 @@ yyreduce:
 	}
     break;
 
-  case 58:
+  case 59:
 
-/* Line 1455 of yacc.c  */
-#line 494 "go.y"
+/* Line 1806 of yacc.c  */
+#line 502 "go.y"
     {
 		Node *n, *nn;
 
@@ -2921,29 +2961,29 @@ yyreduce:
 	}
     break;
 
-  case 59:
+  case 60:
 
-/* Line 1455 of yacc.c  */
-#line 512 "go.y"
+/* Line 1806 of yacc.c  */
+#line 520 "go.y"
     {
 		markdcl();
 	}
     break;
 
-  case 60:
+  case 61:
 
-/* Line 1455 of yacc.c  */
-#line 516 "go.y"
+/* Line 1806 of yacc.c  */
+#line 524 "go.y"
     {
 		(yyval.node) = liststmt((yyvsp[(3) - (4)].list));
 		popdcl();
 	}
     break;
 
-  case 61:
+  case 62:
 
-/* Line 1455 of yacc.c  */
-#line 523 "go.y"
+/* Line 1806 of yacc.c  */
+#line 531 "go.y"
     {
 		// If the last token read by the lexer was consumed
 		// as part of the case, clear it (parser has cleared yychar).
@@ -2955,10 +2995,10 @@ yyreduce:
 	}
     break;
 
-  case 62:
+  case 63:
 
-/* Line 1455 of yacc.c  */
-#line 533 "go.y"
+/* Line 1806 of yacc.c  */
+#line 541 "go.y"
     {
 		int last;
 
@@ -2979,47 +3019,47 @@ yyreduce:
 	}
     break;
 
-  case 63:
+  case 64:
 
-/* Line 1455 of yacc.c  */
-#line 553 "go.y"
+/* Line 1806 of yacc.c  */
+#line 561 "go.y"
     {
 		(yyval.list) = nil;
 	}
     break;
 
-  case 64:
+  case 65:
 
-/* Line 1455 of yacc.c  */
-#line 557 "go.y"
+/* Line 1806 of yacc.c  */
+#line 565 "go.y"
     {
 		(yyval.list) = list((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].node));
 	}
     break;
 
-  case 65:
+  case 66:
 
-/* Line 1455 of yacc.c  */
-#line 563 "go.y"
+/* Line 1806 of yacc.c  */
+#line 571 "go.y"
     {
 		markdcl();
 	}
     break;
 
-  case 66:
+  case 67:
 
-/* Line 1455 of yacc.c  */
-#line 567 "go.y"
+/* Line 1806 of yacc.c  */
+#line 575 "go.y"
     {
 		(yyval.list) = (yyvsp[(3) - (4)].list);
 		popdcl();
 	}
     break;
 
-  case 67:
+  case 68:
 
-/* Line 1455 of yacc.c  */
-#line 574 "go.y"
+/* Line 1806 of yacc.c  */
+#line 582 "go.y"
     {
 		(yyval.node) = nod(ORANGE, N, (yyvsp[(4) - (4)].node));
 		(yyval.node)->list = (yyvsp[(1) - (4)].list);
@@ -3027,10 +3067,10 @@ yyreduce:
 	}
     break;
 
-  case 68:
+  case 69:
 
-/* Line 1455 of yacc.c  */
-#line 580 "go.y"
+/* Line 1806 of yacc.c  */
+#line 588 "go.y"
     {
 		(yyval.node) = nod(ORANGE, N, (yyvsp[(4) - (4)].node));
 		(yyval.node)->list = (yyvsp[(1) - (4)].list);
@@ -3039,10 +3079,10 @@ yyreduce:
 	}
     break;
 
-  case 69:
+  case 70:
 
-/* Line 1455 of yacc.c  */
-#line 589 "go.y"
+/* Line 1806 of yacc.c  */
+#line 597 "go.y"
     {
 		// init ; test ; incr
 		if((yyvsp[(5) - (5)].node) != N && (yyvsp[(5) - (5)].node)->colas != 0)
@@ -3055,10 +3095,10 @@ yyreduce:
 	}
     break;
 
-  case 70:
+  case 71:
 
-/* Line 1455 of yacc.c  */
-#line 600 "go.y"
+/* Line 1806 of yacc.c  */
+#line 608 "go.y"
     {
 		// normal test
 		(yyval.node) = nod(OFOR, N, N);
@@ -3066,39 +3106,39 @@ yyreduce:
 	}
     break;
 
-  case 72:
+  case 73:
 
-/* Line 1455 of yacc.c  */
-#line 609 "go.y"
+/* Line 1806 of yacc.c  */
+#line 617 "go.y"
     {
 		(yyval.node) = (yyvsp[(1) - (2)].node);
 		(yyval.node)->nbody = concat((yyval.node)->nbody, (yyvsp[(2) - (2)].list));
 	}
     break;
 
-  case 73:
+  case 74:
 
-/* Line 1455 of yacc.c  */
-#line 616 "go.y"
+/* Line 1806 of yacc.c  */
+#line 624 "go.y"
     {
 		markdcl();
 	}
     break;
 
-  case 74:
+  case 75:
 
-/* Line 1455 of yacc.c  */
-#line 620 "go.y"
+/* Line 1806 of yacc.c  */
+#line 628 "go.y"
     {
 		(yyval.node) = (yyvsp[(3) - (3)].node);
 		popdcl();
 	}
     break;
 
-  case 75:
+  case 76:
 
-/* Line 1455 of yacc.c  */
-#line 627 "go.y"
+/* Line 1806 of yacc.c  */
+#line 635 "go.y"
     {
 		// test
 		(yyval.node) = nod(OIF, N, N);
@@ -3106,10 +3146,10 @@ yyreduce:
 	}
     break;
 
-  case 76:
+  case 77:
 
-/* Line 1455 of yacc.c  */
-#line 633 "go.y"
+/* Line 1806 of yacc.c  */
+#line 641 "go.y"
     {
 		// init ; test
 		(yyval.node) = nod(OIF, N, N);
@@ -3119,38 +3159,38 @@ yyreduce:
 	}
     break;
 
-  case 77:
+  case 78:
 
-/* Line 1455 of yacc.c  */
-#line 644 "go.y"
+/* Line 1806 of yacc.c  */
+#line 652 "go.y"
     {
 		markdcl();
 	}
     break;
 
-  case 78:
+  case 79:
 
-/* Line 1455 of yacc.c  */
-#line 648 "go.y"
+/* Line 1806 of yacc.c  */
+#line 656 "go.y"
     {
 		if((yyvsp[(3) - (3)].node)->ntest == N)
 			yyerror("missing condition in if statement");
 	}
     break;
 
-  case 79:
+  case 80:
 
-/* Line 1455 of yacc.c  */
-#line 653 "go.y"
+/* Line 1806 of yacc.c  */
+#line 661 "go.y"
     {
 		(yyvsp[(3) - (5)].node)->nbody = (yyvsp[(5) - (5)].list);
 	}
     break;
 
-  case 80:
+  case 81:
 
-/* Line 1455 of yacc.c  */
-#line 657 "go.y"
+/* Line 1806 of yacc.c  */
+#line 665 "go.y"
     {
 		popdcl();
 		(yyval.node) = (yyvsp[(3) - (7)].node);
@@ -3159,46 +3199,46 @@ yyreduce:
 	}
     break;
 
-  case 81:
+  case 82:
 
-/* Line 1455 of yacc.c  */
-#line 665 "go.y"
+/* Line 1806 of yacc.c  */
+#line 673 "go.y"
     {
 		(yyval.node) = N;
 	}
     break;
 
-  case 82:
+  case 83:
 
-/* Line 1455 of yacc.c  */
-#line 669 "go.y"
+/* Line 1806 of yacc.c  */
+#line 677 "go.y"
     {
 		(yyval.node) = (yyvsp[(2) - (2)].node);
 	}
     break;
 
-  case 83:
+  case 84:
 
-/* Line 1455 of yacc.c  */
-#line 673 "go.y"
+/* Line 1806 of yacc.c  */
+#line 681 "go.y"
     {
 		(yyval.node) = (yyvsp[(2) - (2)].node);
 	}
     break;
 
-  case 84:
+  case 85:
 
-/* Line 1455 of yacc.c  */
-#line 679 "go.y"
+/* Line 1806 of yacc.c  */
+#line 687 "go.y"
     {
 		markdcl();
 	}
     break;
 
-  case 85:
+  case 86:
 
-/* Line 1455 of yacc.c  */
-#line 683 "go.y"
+/* Line 1806 of yacc.c  */
+#line 691 "go.y"
     {
 		Node *n;
 		n = (yyvsp[(3) - (3)].node)->ntest;
@@ -3208,10 +3248,10 @@ yyreduce:
 	}
     break;
 
-  case 86:
+  case 87:
 
-/* Line 1455 of yacc.c  */
-#line 691 "go.y"
+/* Line 1806 of yacc.c  */
+#line 699 "go.y"
     {
 		(yyval.node) = (yyvsp[(3) - (7)].node);
 		(yyval.node)->op = OSWITCH;
@@ -3221,19 +3261,19 @@ yyreduce:
 	}
     break;
 
-  case 87:
+  case 88:
 
-/* Line 1455 of yacc.c  */
-#line 701 "go.y"
+/* Line 1806 of yacc.c  */
+#line 709 "go.y"
     {
 		typesw = nod(OXXX, typesw, N);
 	}
     break;
 
-  case 88:
+  case 89:
 
-/* Line 1455 of yacc.c  */
-#line 705 "go.y"
+/* Line 1806 of yacc.c  */
+#line 713 "go.y"
     {
 		(yyval.node) = nod(OSELECT, N, N);
 		(yyval.node)->lineno = typesw->lineno;
@@ -3242,199 +3282,199 @@ yyreduce:
 	}
     break;
 
-  case 90:
+  case 91:
 
-/* Line 1455 of yacc.c  */
-#line 718 "go.y"
+/* Line 1806 of yacc.c  */
+#line 726 "go.y"
     {
 		(yyval.node) = nod(OOROR, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 91:
+  case 92:
 
-/* Line 1455 of yacc.c  */
-#line 722 "go.y"
+/* Line 1806 of yacc.c  */
+#line 730 "go.y"
     {
 		(yyval.node) = nod(OANDAND, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 92:
+  case 93:
 
-/* Line 1455 of yacc.c  */
-#line 726 "go.y"
+/* Line 1806 of yacc.c  */
+#line 734 "go.y"
     {
 		(yyval.node) = nod(OEQ, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 93:
+  case 94:
 
-/* Line 1455 of yacc.c  */
-#line 730 "go.y"
+/* Line 1806 of yacc.c  */
+#line 738 "go.y"
     {
 		(yyval.node) = nod(ONE, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 94:
+  case 95:
 
-/* Line 1455 of yacc.c  */
-#line 734 "go.y"
+/* Line 1806 of yacc.c  */
+#line 742 "go.y"
     {
 		(yyval.node) = nod(OLT, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 95:
+  case 96:
 
-/* Line 1455 of yacc.c  */
-#line 738 "go.y"
+/* Line 1806 of yacc.c  */
+#line 746 "go.y"
     {
 		(yyval.node) = nod(OLE, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 96:
+  case 97:
 
-/* Line 1455 of yacc.c  */
-#line 742 "go.y"
+/* Line 1806 of yacc.c  */
+#line 750 "go.y"
     {
 		(yyval.node) = nod(OGE, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 97:
+  case 98:
 
-/* Line 1455 of yacc.c  */
-#line 746 "go.y"
+/* Line 1806 of yacc.c  */
+#line 754 "go.y"
     {
 		(yyval.node) = nod(OGT, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 98:
+  case 99:
 
-/* Line 1455 of yacc.c  */
-#line 750 "go.y"
+/* Line 1806 of yacc.c  */
+#line 758 "go.y"
     {
 		(yyval.node) = nod(OADD, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 99:
+  case 100:
 
-/* Line 1455 of yacc.c  */
-#line 754 "go.y"
+/* Line 1806 of yacc.c  */
+#line 762 "go.y"
     {
 		(yyval.node) = nod(OSUB, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 100:
+  case 101:
 
-/* Line 1455 of yacc.c  */
-#line 758 "go.y"
+/* Line 1806 of yacc.c  */
+#line 766 "go.y"
     {
 		(yyval.node) = nod(OOR, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 101:
+  case 102:
 
-/* Line 1455 of yacc.c  */
-#line 762 "go.y"
+/* Line 1806 of yacc.c  */
+#line 770 "go.y"
     {
 		(yyval.node) = nod(OXOR, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 102:
+  case 103:
 
-/* Line 1455 of yacc.c  */
-#line 766 "go.y"
+/* Line 1806 of yacc.c  */
+#line 774 "go.y"
     {
 		(yyval.node) = nod(OMUL, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 103:
+  case 104:
 
-/* Line 1455 of yacc.c  */
-#line 770 "go.y"
+/* Line 1806 of yacc.c  */
+#line 778 "go.y"
     {
 		(yyval.node) = nod(ODIV, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 104:
+  case 105:
 
-/* Line 1455 of yacc.c  */
-#line 774 "go.y"
+/* Line 1806 of yacc.c  */
+#line 782 "go.y"
     {
 		(yyval.node) = nod(OMOD, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 105:
+  case 106:
 
-/* Line 1455 of yacc.c  */
-#line 778 "go.y"
+/* Line 1806 of yacc.c  */
+#line 786 "go.y"
     {
 		(yyval.node) = nod(OAND, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 106:
+  case 107:
 
-/* Line 1455 of yacc.c  */
-#line 782 "go.y"
+/* Line 1806 of yacc.c  */
+#line 790 "go.y"
     {
 		(yyval.node) = nod(OANDNOT, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 107:
+  case 108:
 
-/* Line 1455 of yacc.c  */
-#line 786 "go.y"
+/* Line 1806 of yacc.c  */
+#line 794 "go.y"
     {
 		(yyval.node) = nod(OLSH, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 108:
+  case 109:
 
-/* Line 1455 of yacc.c  */
-#line 790 "go.y"
+/* Line 1806 of yacc.c  */
+#line 798 "go.y"
     {
 		(yyval.node) = nod(ORSH, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 109:
+  case 110:
 
-/* Line 1455 of yacc.c  */
-#line 795 "go.y"
+/* Line 1806 of yacc.c  */
+#line 803 "go.y"
     {
 		(yyval.node) = nod(OSEND, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 111:
+  case 112:
 
-/* Line 1455 of yacc.c  */
-#line 802 "go.y"
+/* Line 1806 of yacc.c  */
+#line 810 "go.y"
     {
 		(yyval.node) = nod(OIND, (yyvsp[(2) - (2)].node), N);
 	}
     break;
 
-  case 112:
+  case 113:
 
-/* Line 1455 of yacc.c  */
-#line 806 "go.y"
+/* Line 1806 of yacc.c  */
+#line 814 "go.y"
     {
 		if((yyvsp[(2) - (2)].node)->op == OCOMPLIT) {
 			// Special case for &T{...}: turn into (*T){...}.
@@ -3447,84 +3487,84 @@ yyreduce:
 	}
     break;
 
-  case 113:
+  case 114:
 
-/* Line 1455 of yacc.c  */
-#line 817 "go.y"
+/* Line 1806 of yacc.c  */
+#line 825 "go.y"
     {
 		(yyval.node) = nod(OPLUS, (yyvsp[(2) - (2)].node), N);
 	}
     break;
 
-  case 114:
+  case 115:
 
-/* Line 1455 of yacc.c  */
-#line 821 "go.y"
+/* Line 1806 of yacc.c  */
+#line 829 "go.y"
     {
 		(yyval.node) = nod(OMINUS, (yyvsp[(2) - (2)].node), N);
 	}
     break;
 
-  case 115:
+  case 116:
 
-/* Line 1455 of yacc.c  */
-#line 825 "go.y"
+/* Line 1806 of yacc.c  */
+#line 833 "go.y"
     {
 		(yyval.node) = nod(ONOT, (yyvsp[(2) - (2)].node), N);
 	}
     break;
 
-  case 116:
+  case 117:
 
-/* Line 1455 of yacc.c  */
-#line 829 "go.y"
+/* Line 1806 of yacc.c  */
+#line 837 "go.y"
     {
 		yyerror("the bitwise complement operator is ^");
 		(yyval.node) = nod(OCOM, (yyvsp[(2) - (2)].node), N);
 	}
     break;
 
-  case 117:
+  case 118:
 
-/* Line 1455 of yacc.c  */
-#line 834 "go.y"
+/* Line 1806 of yacc.c  */
+#line 842 "go.y"
     {
 		(yyval.node) = nod(OCOM, (yyvsp[(2) - (2)].node), N);
 	}
     break;
 
-  case 118:
+  case 119:
 
-/* Line 1455 of yacc.c  */
-#line 838 "go.y"
+/* Line 1806 of yacc.c  */
+#line 846 "go.y"
     {
 		(yyval.node) = nod(ORECV, (yyvsp[(2) - (2)].node), N);
 	}
     break;
 
-  case 119:
+  case 120:
 
-/* Line 1455 of yacc.c  */
-#line 848 "go.y"
+/* Line 1806 of yacc.c  */
+#line 856 "go.y"
     {
 		(yyval.node) = nod(OCALL, (yyvsp[(1) - (3)].node), N);
 	}
     break;
 
-  case 120:
+  case 121:
 
-/* Line 1455 of yacc.c  */
-#line 852 "go.y"
+/* Line 1806 of yacc.c  */
+#line 860 "go.y"
     {
 		(yyval.node) = nod(OCALL, (yyvsp[(1) - (5)].node), N);
 		(yyval.node)->list = (yyvsp[(3) - (5)].list);
 	}
     break;
 
-  case 121:
+  case 122:
 
-/* Line 1455 of yacc.c  */
-#line 857 "go.y"
+/* Line 1806 of yacc.c  */
+#line 865 "go.y"
     {
 		(yyval.node) = nod(OCALL, (yyvsp[(1) - (6)].node), N);
 		(yyval.node)->list = (yyvsp[(3) - (6)].list);
@@ -3532,19 +3572,19 @@ yyreduce:
 	}
     break;
 
-  case 122:
+  case 123:
 
-/* Line 1455 of yacc.c  */
-#line 865 "go.y"
+/* Line 1806 of yacc.c  */
+#line 873 "go.y"
     {
 		(yyval.node) = nodlit((yyvsp[(1) - (1)].val));
 	}
     break;
 
-  case 124:
+  case 125:
 
-/* Line 1455 of yacc.c  */
-#line 870 "go.y"
+/* Line 1806 of yacc.c  */
+#line 878 "go.y"
     {
 		if((yyvsp[(1) - (3)].node)->op == OPACK) {
 			Sym *s;
@@ -3557,46 +3597,46 @@ yyreduce:
 	}
     break;
 
-  case 125:
+  case 126:
 
-/* Line 1455 of yacc.c  */
-#line 881 "go.y"
+/* Line 1806 of yacc.c  */
+#line 889 "go.y"
     {
 		(yyval.node) = nod(ODOTTYPE, (yyvsp[(1) - (5)].node), (yyvsp[(4) - (5)].node));
 	}
     break;
 
-  case 126:
+  case 127:
 
-/* Line 1455 of yacc.c  */
-#line 885 "go.y"
+/* Line 1806 of yacc.c  */
+#line 893 "go.y"
     {
 		(yyval.node) = nod(OTYPESW, N, (yyvsp[(1) - (5)].node));
 	}
     break;
 
-  case 127:
+  case 128:
 
-/* Line 1455 of yacc.c  */
-#line 889 "go.y"
+/* Line 1806 of yacc.c  */
+#line 897 "go.y"
     {
 		(yyval.node) = nod(OINDEX, (yyvsp[(1) - (4)].node), (yyvsp[(3) - (4)].node));
 	}
     break;
 
-  case 128:
+  case 129:
 
-/* Line 1455 of yacc.c  */
-#line 893 "go.y"
+/* Line 1806 of yacc.c  */
+#line 901 "go.y"
     {
 		(yyval.node) = nod(OSLICE, (yyvsp[(1) - (6)].node), nod(OKEY, (yyvsp[(3) - (6)].node), (yyvsp[(5) - (6)].node)));
 	}
     break;
 
-  case 130:
+  case 131:
 
-/* Line 1455 of yacc.c  */
-#line 898 "go.y"
+/* Line 1806 of yacc.c  */
+#line 906 "go.y"
     {
 		// conversion
 		(yyval.node) = nod(OCALL, (yyvsp[(1) - (4)].node), N);
@@ -3604,10 +3644,10 @@ yyreduce:
 	}
     break;
 
-  case 131:
+  case 132:
 
-/* Line 1455 of yacc.c  */
-#line 904 "go.y"
+/* Line 1806 of yacc.c  */
+#line 912 "go.y"
     {
 		(yyval.node) = (yyvsp[(3) - (5)].node);
 		(yyval.node)->right = (yyvsp[(1) - (5)].node);
@@ -3616,10 +3656,10 @@ yyreduce:
 	}
     break;
 
-  case 132:
+  case 133:
 
-/* Line 1455 of yacc.c  */
-#line 911 "go.y"
+/* Line 1806 of yacc.c  */
+#line 919 "go.y"
     {
 		(yyval.node) = (yyvsp[(3) - (5)].node);
 		(yyval.node)->right = (yyvsp[(1) - (5)].node);
@@ -3627,10 +3667,10 @@ yyreduce:
 	}
     break;
 
-  case 133:
+  case 134:
 
-/* Line 1455 of yacc.c  */
-#line 917 "go.y"
+/* Line 1806 of yacc.c  */
+#line 925 "go.y"
     {
 		yyerror("cannot parenthesize type in composite literal");
 		(yyval.node) = (yyvsp[(5) - (7)].node);
@@ -3639,10 +3679,10 @@ yyreduce:
 	}
     break;
 
-  case 135:
+  case 136:
 
-/* Line 1455 of yacc.c  */
-#line 926 "go.y"
+/* Line 1806 of yacc.c  */
+#line 934 "go.y"
     {
 		// composite expression.
 		// make node early so we get the right line number.
@@ -3650,29 +3690,29 @@ yyreduce:
 	}
     break;
 
-  case 136:
+  case 137:
 
-/* Line 1455 of yacc.c  */
-#line 934 "go.y"
+/* Line 1806 of yacc.c  */
+#line 942 "go.y"
     {
 		(yyval.node) = nod(OKEY, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 138:
+  case 139:
 
-/* Line 1455 of yacc.c  */
-#line 941 "go.y"
+/* Line 1806 of yacc.c  */
+#line 949 "go.y"
     {
 		(yyval.node) = (yyvsp[(2) - (4)].node);
 		(yyval.node)->list = (yyvsp[(3) - (4)].list);
 	}
     break;
 
-  case 140:
+  case 141:
 
-/* Line 1455 of yacc.c  */
-#line 949 "go.y"
+/* Line 1806 of yacc.c  */
+#line 957 "go.y"
     {
 		(yyval.node) = (yyvsp[(2) - (3)].node);
 		
@@ -3690,28 +3730,28 @@ yyreduce:
 	}
     break;
 
-  case 144:
+  case 145:
 
-/* Line 1455 of yacc.c  */
-#line 974 "go.y"
+/* Line 1806 of yacc.c  */
+#line 982 "go.y"
     {
 		(yyval.i) = LBODY;
 	}
     break;
 
-  case 145:
+  case 146:
 
-/* Line 1455 of yacc.c  */
-#line 978 "go.y"
+/* Line 1806 of yacc.c  */
+#line 986 "go.y"
     {
 		(yyval.i) = '{';
 	}
     break;
 
-  case 146:
+  case 147:
 
-/* Line 1455 of yacc.c  */
-#line 989 "go.y"
+/* Line 1806 of yacc.c  */
+#line 997 "go.y"
     {
 		if((yyvsp[(1) - (1)].sym) == S)
 			(yyval.node) = N;
@@ -3720,28 +3760,28 @@ yyreduce:
 	}
     break;
 
-  case 147:
+  case 148:
 
-/* Line 1455 of yacc.c  */
-#line 998 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1006 "go.y"
     {
 		(yyval.node) = dclname((yyvsp[(1) - (1)].sym));
 	}
     break;
 
-  case 148:
+  case 149:
 
-/* Line 1455 of yacc.c  */
-#line 1003 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1011 "go.y"
     {
 		(yyval.node) = N;
 	}
     break;
 
-  case 150:
+  case 151:
 
-/* Line 1455 of yacc.c  */
-#line 1010 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1018 "go.y"
     {
 		(yyval.sym) = (yyvsp[(1) - (1)].sym);
 		// during imports, unqualified non-exported identifiers are from builtinpkg
@@ -3750,19 +3790,19 @@ yyreduce:
 	}
     break;
 
-  case 152:
+  case 153:
 
-/* Line 1455 of yacc.c  */
-#line 1018 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1026 "go.y"
     {
 		(yyval.sym) = S;
 	}
     break;
 
-  case 153:
+  case 154:
 
-/* Line 1455 of yacc.c  */
-#line 1024 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1032 "go.y"
     {
 		if((yyvsp[(2) - (4)].val).u.sval->len == 0)
 			(yyval.sym) = pkglookup((yyvsp[(4) - (4)].sym)->name, importpkg);
@@ -3771,10 +3811,10 @@ yyreduce:
 	}
     break;
 
-  case 154:
+  case 155:
 
-/* Line 1455 of yacc.c  */
-#line 1033 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1041 "go.y"
     {
 		(yyval.node) = oldname((yyvsp[(1) - (1)].sym));
 		if((yyval.node)->pack != N)
@@ -3782,56 +3822,56 @@ yyreduce:
 	}
     break;
 
-  case 156:
+  case 157:
 
-/* Line 1455 of yacc.c  */
-#line 1053 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1061 "go.y"
     {
 		yyerror("final argument in variadic function missing type");
 		(yyval.node) = nod(ODDD, typenod(typ(TINTER)), N);
 	}
     break;
 
-  case 157:
+  case 158:
 
-/* Line 1455 of yacc.c  */
-#line 1058 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1066 "go.y"
     {
 		(yyval.node) = nod(ODDD, (yyvsp[(2) - (2)].node), N);
 	}
     break;
 
-  case 163:
+  case 164:
 
-/* Line 1455 of yacc.c  */
-#line 1069 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1077 "go.y"
     {
 		(yyval.node) = nod(OTPAREN, (yyvsp[(2) - (3)].node), N);
 	}
     break;
 
-  case 167:
+  case 168:
 
-/* Line 1455 of yacc.c  */
-#line 1078 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1086 "go.y"
     {
 		(yyval.node) = nod(OIND, (yyvsp[(2) - (2)].node), N);
 	}
     break;
 
-  case 172:
+  case 173:
 
-/* Line 1455 of yacc.c  */
-#line 1088 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1096 "go.y"
     {
 		(yyval.node) = nod(OTPAREN, (yyvsp[(2) - (3)].node), N);
 	}
     break;
 
-  case 182:
+  case 183:
 
-/* Line 1455 of yacc.c  */
-#line 1109 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1117 "go.y"
     {
 		if((yyvsp[(1) - (3)].node)->op == OPACK) {
 			Sym *s;
@@ -3844,77 +3884,77 @@ yyreduce:
 	}
     break;
 
-  case 183:
+  case 184:
 
-/* Line 1455 of yacc.c  */
-#line 1122 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1130 "go.y"
     {
 		(yyval.node) = nod(OTARRAY, (yyvsp[(2) - (4)].node), (yyvsp[(4) - (4)].node));
 	}
     break;
 
-  case 184:
+  case 185:
 
-/* Line 1455 of yacc.c  */
-#line 1126 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1134 "go.y"
     {
 		// array literal of nelem
 		(yyval.node) = nod(OTARRAY, nod(ODDD, N, N), (yyvsp[(4) - (4)].node));
 	}
     break;
 
-  case 185:
+  case 186:
 
-/* Line 1455 of yacc.c  */
-#line 1131 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1139 "go.y"
     {
 		(yyval.node) = nod(OTCHAN, (yyvsp[(2) - (2)].node), N);
 		(yyval.node)->etype = Cboth;
 	}
     break;
 
-  case 186:
+  case 187:
 
-/* Line 1455 of yacc.c  */
-#line 1136 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1144 "go.y"
     {
 		(yyval.node) = nod(OTCHAN, (yyvsp[(3) - (3)].node), N);
 		(yyval.node)->etype = Csend;
 	}
     break;
 
-  case 187:
+  case 188:
 
-/* Line 1455 of yacc.c  */
-#line 1141 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1149 "go.y"
     {
 		(yyval.node) = nod(OTMAP, (yyvsp[(3) - (5)].node), (yyvsp[(5) - (5)].node));
 	}
     break;
 
-  case 190:
+  case 191:
 
-/* Line 1455 of yacc.c  */
-#line 1149 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1157 "go.y"
     {
 		(yyval.node) = nod(OIND, (yyvsp[(2) - (2)].node), N);
 	}
     break;
 
-  case 191:
+  case 192:
 
-/* Line 1455 of yacc.c  */
-#line 1155 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1163 "go.y"
     {
 		(yyval.node) = nod(OTCHAN, (yyvsp[(3) - (3)].node), N);
 		(yyval.node)->etype = Crecv;
 	}
     break;
 
-  case 192:
+  case 193:
 
-/* Line 1455 of yacc.c  */
-#line 1162 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1170 "go.y"
     {
 		(yyval.node) = nod(OTSTRUCT, N, N);
 		(yyval.node)->list = (yyvsp[(3) - (5)].list);
@@ -3922,20 +3962,20 @@ yyreduce:
 	}
     break;
 
-  case 193:
+  case 194:
 
-/* Line 1455 of yacc.c  */
-#line 1168 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1176 "go.y"
     {
 		(yyval.node) = nod(OTSTRUCT, N, N);
 		fixlbrace((yyvsp[(2) - (3)].i));
 	}
     break;
 
-  case 194:
+  case 195:
 
-/* Line 1455 of yacc.c  */
-#line 1175 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1183 "go.y"
     {
 		(yyval.node) = nod(OTINTER, N, N);
 		(yyval.node)->list = (yyvsp[(3) - (5)].list);
@@ -3943,20 +3983,20 @@ yyreduce:
 	}
     break;
 
-  case 195:
+  case 196:
 
-/* Line 1455 of yacc.c  */
-#line 1181 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1189 "go.y"
     {
 		(yyval.node) = nod(OTINTER, N, N);
 		fixlbrace((yyvsp[(2) - (3)].i));
 	}
     break;
 
-  case 196:
+  case 197:
 
-/* Line 1455 of yacc.c  */
-#line 1192 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1200 "go.y"
     {
 		(yyval.node) = (yyvsp[(2) - (3)].node);
 		if((yyval.node) == N)
@@ -3967,10 +4007,10 @@ yyreduce:
 	}
     break;
 
-  case 197:
+  case 198:
 
-/* Line 1455 of yacc.c  */
-#line 1203 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1211 "go.y"
     {
 		Node *t;
 
@@ -4001,10 +4041,10 @@ yyreduce:
 	}
     break;
 
-  case 198:
+  case 199:
 
-/* Line 1455 of yacc.c  */
-#line 1232 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1240 "go.y"
     {
 		Node *rcvr, *t;
 
@@ -4043,10 +4083,10 @@ yyreduce:
 	}
     break;
 
-  case 199:
+  case 200:
 
-/* Line 1455 of yacc.c  */
-#line 1271 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1279 "go.y"
     {
 		Sym *s;
 		Type *t;
@@ -4071,10 +4111,10 @@ yyreduce:
 	}
     break;
 
-  case 200:
+  case 201:
 
-/* Line 1455 of yacc.c  */
-#line 1294 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1302 "go.y"
     {
 		(yyval.node) = methodname1(newname((yyvsp[(4) - (8)].sym)), (yyvsp[(2) - (8)].list)->n->right); 
 		(yyval.node)->type = functype((yyvsp[(2) - (8)].list)->n, (yyvsp[(6) - (8)].list), (yyvsp[(8) - (8)].list));
@@ -4091,10 +4131,10 @@ yyreduce:
 	}
     break;
 
-  case 201:
+  case 202:
 
-/* Line 1455 of yacc.c  */
-#line 1311 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1319 "go.y"
     {
 		(yyvsp[(3) - (5)].list) = checkarglist((yyvsp[(3) - (5)].list), 1);
 		(yyval.node) = nod(OTFUNC, N, N);
@@ -4103,19 +4143,19 @@ yyreduce:
 	}
     break;
 
-  case 202:
+  case 203:
 
-/* Line 1455 of yacc.c  */
-#line 1319 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1327 "go.y"
     {
 		(yyval.list) = nil;
 	}
     break;
 
-  case 203:
+  case 204:
 
-/* Line 1455 of yacc.c  */
-#line 1323 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1331 "go.y"
     {
 		(yyval.list) = (yyvsp[(2) - (3)].list);
 		if((yyval.list) == nil)
@@ -4123,75 +4163,75 @@ yyreduce:
 	}
     break;
 
-  case 204:
+  case 205:
 
-/* Line 1455 of yacc.c  */
-#line 1331 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1339 "go.y"
     {
 		(yyval.list) = nil;
 	}
     break;
 
-  case 205:
+  case 206:
 
-/* Line 1455 of yacc.c  */
-#line 1335 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1343 "go.y"
     {
 		(yyval.list) = list1(nod(ODCLFIELD, N, (yyvsp[(1) - (1)].node)));
 	}
     break;
 
-  case 206:
+  case 207:
 
-/* Line 1455 of yacc.c  */
-#line 1339 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1347 "go.y"
     {
 		(yyvsp[(2) - (3)].list) = checkarglist((yyvsp[(2) - (3)].list), 0);
 		(yyval.list) = (yyvsp[(2) - (3)].list);
 	}
     break;
 
-  case 207:
+  case 208:
 
-/* Line 1455 of yacc.c  */
-#line 1346 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1354 "go.y"
     {
 		closurehdr((yyvsp[(1) - (1)].node));
 	}
     break;
 
-  case 208:
+  case 209:
 
-/* Line 1455 of yacc.c  */
-#line 1352 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1360 "go.y"
     {
 		(yyval.node) = closurebody((yyvsp[(3) - (4)].list));
 		fixlbrace((yyvsp[(2) - (4)].i));
 	}
     break;
 
-  case 209:
+  case 210:
 
-/* Line 1455 of yacc.c  */
-#line 1357 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1365 "go.y"
     {
 		(yyval.node) = closurebody(nil);
 	}
     break;
 
-  case 210:
+  case 211:
 
-/* Line 1455 of yacc.c  */
-#line 1368 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1376 "go.y"
     {
 		(yyval.list) = nil;
 	}
     break;
 
-  case 211:
+  case 212:
 
-/* Line 1455 of yacc.c  */
-#line 1372 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1380 "go.y"
     {
 		(yyval.list) = concat((yyvsp[(1) - (3)].list), (yyvsp[(2) - (3)].list));
 		if(nsyntaxerrors == 0)
@@ -4199,73 +4239,73 @@ yyreduce:
 	}
     break;
 
-  case 213:
+  case 214:
 
-/* Line 1455 of yacc.c  */
-#line 1381 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1389 "go.y"
     {
 		(yyval.list) = concat((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list));
 	}
     break;
 
-  case 215:
+  case 216:
 
-/* Line 1455 of yacc.c  */
-#line 1388 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1396 "go.y"
     {
 		(yyval.list) = concat((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list));
 	}
     break;
 
-  case 216:
+  case 217:
 
-/* Line 1455 of yacc.c  */
-#line 1394 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1402 "go.y"
     {
 		(yyval.list) = list1((yyvsp[(1) - (1)].node));
 	}
     break;
 
-  case 217:
+  case 218:
 
-/* Line 1455 of yacc.c  */
-#line 1398 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1406 "go.y"
     {
 		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 219:
+  case 220:
 
-/* Line 1455 of yacc.c  */
-#line 1405 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1413 "go.y"
     {
 		(yyval.list) = concat((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list));
 	}
     break;
 
-  case 220:
+  case 221:
 
-/* Line 1455 of yacc.c  */
-#line 1411 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1419 "go.y"
     {
 		(yyval.list) = list1((yyvsp[(1) - (1)].node));
 	}
     break;
 
-  case 221:
+  case 222:
 
-/* Line 1455 of yacc.c  */
-#line 1415 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1423 "go.y"
     {
 		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 222:
+  case 223:
 
-/* Line 1455 of yacc.c  */
-#line 1421 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1429 "go.y"
     {
 		NodeList *l;
 
@@ -4290,20 +4330,20 @@ yyreduce:
 	}
     break;
 
-  case 223:
+  case 224:
 
-/* Line 1455 of yacc.c  */
-#line 1444 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1452 "go.y"
     {
 		(yyvsp[(1) - (2)].node)->val = (yyvsp[(2) - (2)].val);
 		(yyval.list) = list1((yyvsp[(1) - (2)].node));
 	}
     break;
 
-  case 224:
+  case 225:
 
-/* Line 1455 of yacc.c  */
-#line 1449 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1457 "go.y"
     {
 		(yyvsp[(2) - (4)].node)->val = (yyvsp[(4) - (4)].val);
 		(yyval.list) = list1((yyvsp[(2) - (4)].node));
@@ -4311,10 +4351,10 @@ yyreduce:
 	}
     break;
 
-  case 225:
+  case 226:
 
-/* Line 1455 of yacc.c  */
-#line 1455 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1463 "go.y"
     {
 		(yyvsp[(2) - (3)].node)->right = nod(OIND, (yyvsp[(2) - (3)].node)->right, N);
 		(yyvsp[(2) - (3)].node)->val = (yyvsp[(3) - (3)].val);
@@ -4322,10 +4362,10 @@ yyreduce:
 	}
     break;
 
-  case 226:
+  case 227:
 
-/* Line 1455 of yacc.c  */
-#line 1461 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1469 "go.y"
     {
 		(yyvsp[(3) - (5)].node)->right = nod(OIND, (yyvsp[(3) - (5)].node)->right, N);
 		(yyvsp[(3) - (5)].node)->val = (yyvsp[(5) - (5)].val);
@@ -4334,10 +4374,10 @@ yyreduce:
 	}
     break;
 
-  case 227:
+  case 228:
 
-/* Line 1455 of yacc.c  */
-#line 1468 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1476 "go.y"
     {
 		(yyvsp[(3) - (5)].node)->right = nod(OIND, (yyvsp[(3) - (5)].node)->right, N);
 		(yyvsp[(3) - (5)].node)->val = (yyvsp[(5) - (5)].val);
@@ -4346,10 +4386,10 @@ yyreduce:
 	}
     break;
 
-  case 228:
+  case 229:
 
-/* Line 1455 of yacc.c  */
-#line 1477 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1485 "go.y"
     {
 		Node *n;
 
@@ -4360,10 +4400,10 @@ yyreduce:
 	}
     break;
 
-  case 229:
+  case 230:
 
-/* Line 1455 of yacc.c  */
-#line 1486 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1494 "go.y"
     {
 		Pkg *pkg;
 
@@ -4378,48 +4418,48 @@ yyreduce:
 	}
     break;
 
-  case 230:
+  case 231:
 
-/* Line 1455 of yacc.c  */
-#line 1501 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1509 "go.y"
     {
 		(yyval.node) = embedded((yyvsp[(1) - (1)].sym));
 	}
     break;
 
-  case 231:
+  case 232:
 
-/* Line 1455 of yacc.c  */
-#line 1507 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1515 "go.y"
     {
 		(yyval.node) = nod(ODCLFIELD, (yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].node));
 		ifacedcl((yyval.node));
 	}
     break;
 
-  case 232:
+  case 233:
 
-/* Line 1455 of yacc.c  */
-#line 1512 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1520 "go.y"
     {
 		(yyval.node) = nod(ODCLFIELD, N, oldname((yyvsp[(1) - (1)].sym)));
 	}
     break;
 
-  case 233:
+  case 234:
 
-/* Line 1455 of yacc.c  */
-#line 1516 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1524 "go.y"
     {
 		(yyval.node) = nod(ODCLFIELD, N, oldname((yyvsp[(2) - (3)].sym)));
 		yyerror("cannot parenthesize embedded type");
 	}
     break;
 
-  case 234:
+  case 235:
 
-/* Line 1455 of yacc.c  */
-#line 1523 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1531 "go.y"
     {
 		// without func keyword
 		(yyvsp[(2) - (4)].list) = checkarglist((yyvsp[(2) - (4)].list), 1);
@@ -4429,10 +4469,10 @@ yyreduce:
 	}
     break;
 
-  case 236:
+  case 237:
 
-/* Line 1455 of yacc.c  */
-#line 1537 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1545 "go.y"
     {
 		(yyval.node) = nod(ONONAME, N, N);
 		(yyval.node)->sym = (yyvsp[(1) - (2)].sym);
@@ -4440,10 +4480,10 @@ yyreduce:
 	}
     break;
 
-  case 237:
+  case 238:
 
-/* Line 1455 of yacc.c  */
-#line 1543 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1551 "go.y"
     {
 		(yyval.node) = nod(ONONAME, N, N);
 		(yyval.node)->sym = (yyvsp[(1) - (2)].sym);
@@ -4451,83 +4491,83 @@ yyreduce:
 	}
     break;
 
-  case 239:
+  case 240:
 
-/* Line 1455 of yacc.c  */
-#line 1552 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1560 "go.y"
     {
 		(yyval.list) = list1((yyvsp[(1) - (1)].node));
 	}
     break;
 
-  case 240:
+  case 241:
 
-/* Line 1455 of yacc.c  */
-#line 1556 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1564 "go.y"
     {
 		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 241:
+  case 242:
 
-/* Line 1455 of yacc.c  */
-#line 1561 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1569 "go.y"
     {
 		(yyval.list) = nil;
 	}
     break;
 
-  case 242:
+  case 243:
 
-/* Line 1455 of yacc.c  */
-#line 1565 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1573 "go.y"
     {
 		(yyval.list) = (yyvsp[(1) - (2)].list);
 	}
     break;
 
-  case 243:
+  case 244:
 
-/* Line 1455 of yacc.c  */
-#line 1573 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1581 "go.y"
     {
 		(yyval.node) = N;
 	}
     break;
 
-  case 245:
+  case 246:
 
-/* Line 1455 of yacc.c  */
-#line 1578 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1586 "go.y"
     {
 		(yyval.node) = liststmt((yyvsp[(1) - (1)].list));
 	}
     break;
 
-  case 247:
+  case 248:
 
-/* Line 1455 of yacc.c  */
-#line 1583 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1591 "go.y"
     {
 		(yyval.node) = N;
 	}
     break;
 
-  case 253:
+  case 254:
 
-/* Line 1455 of yacc.c  */
-#line 1594 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1602 "go.y"
     {
 		(yyvsp[(1) - (2)].node) = nod(OLABEL, (yyvsp[(1) - (2)].node), N);
 		(yyvsp[(1) - (2)].node)->sym = dclstack;  // context, for goto restrictions
 	}
     break;
 
-  case 254:
+  case 255:
 
-/* Line 1455 of yacc.c  */
-#line 1599 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1607 "go.y"
     {
 		NodeList *l;
 
@@ -4539,66 +4579,66 @@ yyreduce:
 	}
     break;
 
-  case 255:
+  case 256:
 
-/* Line 1455 of yacc.c  */
-#line 1609 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1617 "go.y"
     {
 		// will be converted to OFALL
 		(yyval.node) = nod(OXFALL, N, N);
 	}
     break;
 
-  case 256:
+  case 257:
 
-/* Line 1455 of yacc.c  */
-#line 1614 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1622 "go.y"
     {
 		(yyval.node) = nod(OBREAK, (yyvsp[(2) - (2)].node), N);
 	}
     break;
 
-  case 257:
+  case 258:
 
-/* Line 1455 of yacc.c  */
-#line 1618 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1626 "go.y"
     {
 		(yyval.node) = nod(OCONTINUE, (yyvsp[(2) - (2)].node), N);
 	}
     break;
 
-  case 258:
+  case 259:
 
-/* Line 1455 of yacc.c  */
-#line 1622 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1630 "go.y"
     {
 		(yyval.node) = nod(OPROC, (yyvsp[(2) - (2)].node), N);
 	}
     break;
 
-  case 259:
+  case 260:
 
-/* Line 1455 of yacc.c  */
-#line 1626 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1634 "go.y"
     {
 		(yyval.node) = nod(ODEFER, (yyvsp[(2) - (2)].node), N);
 	}
     break;
 
-  case 260:
+  case 261:
 
-/* Line 1455 of yacc.c  */
-#line 1630 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1638 "go.y"
     {
 		(yyval.node) = nod(OGOTO, (yyvsp[(2) - (2)].node), N);
 		(yyval.node)->sym = dclstack;  // context, for goto restrictions
 	}
     break;
 
-  case 261:
+  case 262:
 
-/* Line 1455 of yacc.c  */
-#line 1635 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1643 "go.y"
     {
 		(yyval.node) = nod(ORETURN, N, N);
 		(yyval.node)->list = (yyvsp[(2) - (2)].list);
@@ -4617,10 +4657,10 @@ yyreduce:
 	}
     break;
 
-  case 262:
+  case 263:
 
-/* Line 1455 of yacc.c  */
-#line 1654 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1662 "go.y"
     {
 		(yyval.list) = nil;
 		if((yyvsp[(1) - (1)].node) != N)
@@ -4628,10 +4668,10 @@ yyreduce:
 	}
     break;
 
-  case 263:
+  case 264:
 
-/* Line 1455 of yacc.c  */
-#line 1660 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1668 "go.y"
     {
 		(yyval.list) = (yyvsp[(1) - (3)].list);
 		if((yyvsp[(3) - (3)].node) != N)
@@ -4639,244 +4679,244 @@ yyreduce:
 	}
     break;
 
-  case 264:
+  case 265:
 
-/* Line 1455 of yacc.c  */
-#line 1668 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1676 "go.y"
     {
 		(yyval.list) = list1((yyvsp[(1) - (1)].node));
 	}
     break;
 
-  case 265:
+  case 266:
 
-/* Line 1455 of yacc.c  */
-#line 1672 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1680 "go.y"
     {
 		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 266:
+  case 267:
 
-/* Line 1455 of yacc.c  */
-#line 1678 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1686 "go.y"
     {
 		(yyval.list) = list1((yyvsp[(1) - (1)].node));
 	}
     break;
 
-  case 267:
+  case 268:
 
-/* Line 1455 of yacc.c  */
-#line 1682 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1690 "go.y"
     {
 		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 268:
+  case 269:
 
-/* Line 1455 of yacc.c  */
-#line 1688 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1696 "go.y"
     {
 		(yyval.list) = list1((yyvsp[(1) - (1)].node));
 	}
     break;
 
-  case 269:
+  case 270:
 
-/* Line 1455 of yacc.c  */
-#line 1692 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1700 "go.y"
     {
 		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 270:
+  case 271:
 
-/* Line 1455 of yacc.c  */
-#line 1698 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1706 "go.y"
     {
 		(yyval.list) = list1((yyvsp[(1) - (1)].node));
 	}
     break;
 
-  case 271:
+  case 272:
 
-/* Line 1455 of yacc.c  */
-#line 1702 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1710 "go.y"
     {
 		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 272:
+  case 273:
 
-/* Line 1455 of yacc.c  */
-#line 1711 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1719 "go.y"
     {
 		(yyval.list) = list1((yyvsp[(1) - (1)].node));
 	}
     break;
 
-  case 273:
+  case 274:
 
-/* Line 1455 of yacc.c  */
-#line 1715 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1723 "go.y"
     {
 		(yyval.list) = list1((yyvsp[(1) - (1)].node));
 	}
     break;
 
-  case 274:
+  case 275:
 
-/* Line 1455 of yacc.c  */
-#line 1719 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1727 "go.y"
     {
 		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 275:
+  case 276:
 
-/* Line 1455 of yacc.c  */
-#line 1723 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1731 "go.y"
     {
 		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 276:
+  case 277:
 
-/* Line 1455 of yacc.c  */
-#line 1728 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1736 "go.y"
     {
 		(yyval.list) = nil;
 	}
     break;
 
-  case 277:
+  case 278:
 
-/* Line 1455 of yacc.c  */
-#line 1732 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1740 "go.y"
     {
 		(yyval.list) = (yyvsp[(1) - (2)].list);
 	}
     break;
 
-  case 282:
+  case 283:
 
-/* Line 1455 of yacc.c  */
-#line 1746 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1754 "go.y"
     {
 		(yyval.node) = N;
 	}
     break;
 
-  case 284:
+  case 285:
 
-/* Line 1455 of yacc.c  */
-#line 1752 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1760 "go.y"
     {
 		(yyval.list) = nil;
 	}
     break;
 
-  case 286:
+  case 287:
 
-/* Line 1455 of yacc.c  */
-#line 1758 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1766 "go.y"
     {
 		(yyval.node) = N;
 	}
     break;
 
-  case 288:
+  case 289:
 
-/* Line 1455 of yacc.c  */
-#line 1764 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1772 "go.y"
     {
 		(yyval.list) = nil;
 	}
     break;
 
-  case 290:
+  case 291:
 
-/* Line 1455 of yacc.c  */
-#line 1770 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1778 "go.y"
     {
 		(yyval.list) = nil;
 	}
     break;
 
-  case 292:
+  case 293:
 
-/* Line 1455 of yacc.c  */
-#line 1776 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1784 "go.y"
     {
 		(yyval.list) = nil;
 	}
     break;
 
-  case 294:
+  case 295:
 
-/* Line 1455 of yacc.c  */
-#line 1782 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1790 "go.y"
     {
 		(yyval.val).ctype = CTxxx;
 	}
     break;
 
-  case 296:
+  case 297:
 
-/* Line 1455 of yacc.c  */
-#line 1792 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1800 "go.y"
     {
 		importimport((yyvsp[(2) - (4)].sym), (yyvsp[(3) - (4)].val).u.sval);
 	}
     break;
 
-  case 297:
+  case 298:
 
-/* Line 1455 of yacc.c  */
-#line 1796 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1804 "go.y"
     {
 		importvar((yyvsp[(2) - (4)].sym), (yyvsp[(3) - (4)].type));
 	}
     break;
 
-  case 298:
+  case 299:
 
-/* Line 1455 of yacc.c  */
-#line 1800 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1808 "go.y"
     {
 		importconst((yyvsp[(2) - (5)].sym), types[TIDEAL], (yyvsp[(4) - (5)].node));
 	}
     break;
 
-  case 299:
+  case 300:
 
-/* Line 1455 of yacc.c  */
-#line 1804 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1812 "go.y"
     {
 		importconst((yyvsp[(2) - (6)].sym), (yyvsp[(3) - (6)].type), (yyvsp[(5) - (6)].node));
 	}
     break;
 
-  case 300:
+  case 301:
 
-/* Line 1455 of yacc.c  */
-#line 1808 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1816 "go.y"
     {
 		importtype((yyvsp[(2) - (4)].type), (yyvsp[(3) - (4)].type));
 	}
     break;
 
-  case 301:
+  case 302:
 
-/* Line 1455 of yacc.c  */
-#line 1812 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1820 "go.y"
     {
 		if((yyvsp[(2) - (4)].node) == N)
 			break;
@@ -4894,39 +4934,39 @@ yyreduce:
 	}
     break;
 
-  case 302:
+  case 303:
 
-/* Line 1455 of yacc.c  */
-#line 1830 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1838 "go.y"
     {
 		(yyval.sym) = (yyvsp[(1) - (1)].sym);
 		structpkg = (yyval.sym)->pkg;
 	}
     break;
 
-  case 303:
+  case 304:
 
-/* Line 1455 of yacc.c  */
-#line 1837 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1845 "go.y"
     {
 		(yyval.type) = pkgtype((yyvsp[(1) - (1)].sym));
 		importsym((yyvsp[(1) - (1)].sym), OTYPE);
 	}
     break;
 
-  case 309:
+  case 310:
 
-/* Line 1455 of yacc.c  */
-#line 1857 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1865 "go.y"
     {
 		(yyval.type) = pkgtype((yyvsp[(1) - (1)].sym));
 	}
     break;
 
-  case 310:
+  case 311:
 
-/* Line 1455 of yacc.c  */
-#line 1861 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1869 "go.y"
     {
 		// predefined name like uint8
 		(yyvsp[(1) - (1)].sym) = pkglookup((yyvsp[(1) - (1)].sym)->name, builtinpkg);
@@ -4938,64 +4978,64 @@ yyreduce:
 	}
     break;
 
-  case 311:
+  case 312:
 
-/* Line 1455 of yacc.c  */
-#line 1871 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1879 "go.y"
     {
 		(yyval.type) = aindex(N, (yyvsp[(3) - (3)].type));
 	}
     break;
 
-  case 312:
+  case 313:
 
-/* Line 1455 of yacc.c  */
-#line 1875 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1883 "go.y"
     {
 		(yyval.type) = aindex(nodlit((yyvsp[(2) - (4)].val)), (yyvsp[(4) - (4)].type));
 	}
     break;
 
-  case 313:
+  case 314:
 
-/* Line 1455 of yacc.c  */
-#line 1879 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1887 "go.y"
     {
 		(yyval.type) = maptype((yyvsp[(3) - (5)].type), (yyvsp[(5) - (5)].type));
 	}
     break;
 
-  case 314:
+  case 315:
 
-/* Line 1455 of yacc.c  */
-#line 1883 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1891 "go.y"
     {
 		(yyval.type) = tostruct((yyvsp[(3) - (4)].list));
 	}
     break;
 
-  case 315:
+  case 316:
 
-/* Line 1455 of yacc.c  */
-#line 1887 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1895 "go.y"
     {
 		(yyval.type) = tointerface((yyvsp[(3) - (4)].list));
 	}
     break;
 
-  case 316:
+  case 317:
 
-/* Line 1455 of yacc.c  */
-#line 1891 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1899 "go.y"
     {
 		(yyval.type) = ptrto((yyvsp[(2) - (2)].type));
 	}
     break;
 
-  case 317:
+  case 318:
 
-/* Line 1455 of yacc.c  */
-#line 1895 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1903 "go.y"
     {
 		(yyval.type) = typ(TCHAN);
 		(yyval.type)->type = (yyvsp[(2) - (2)].type);
@@ -5003,10 +5043,10 @@ yyreduce:
 	}
     break;
 
-  case 318:
+  case 319:
 
-/* Line 1455 of yacc.c  */
-#line 1901 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1909 "go.y"
     {
 		(yyval.type) = typ(TCHAN);
 		(yyval.type)->type = (yyvsp[(3) - (4)].type);
@@ -5014,10 +5054,10 @@ yyreduce:
 	}
     break;
 
-  case 319:
+  case 320:
 
-/* Line 1455 of yacc.c  */
-#line 1907 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1915 "go.y"
     {
 		(yyval.type) = typ(TCHAN);
 		(yyval.type)->type = (yyvsp[(3) - (3)].type);
@@ -5025,10 +5065,10 @@ yyreduce:
 	}
     break;
 
-  case 320:
+  case 321:
 
-/* Line 1455 of yacc.c  */
-#line 1915 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1923 "go.y"
     {
 		(yyval.type) = typ(TCHAN);
 		(yyval.type)->type = (yyvsp[(3) - (3)].type);
@@ -5036,19 +5076,19 @@ yyreduce:
 	}
     break;
 
-  case 321:
+  case 322:
 
-/* Line 1455 of yacc.c  */
-#line 1923 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1931 "go.y"
     {
 		(yyval.type) = functype(nil, (yyvsp[(3) - (5)].list), (yyvsp[(5) - (5)].list));
 	}
     break;
 
-  case 322:
+  case 323:
 
-/* Line 1455 of yacc.c  */
-#line 1929 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1937 "go.y"
     {
 		(yyval.node) = nod(ODCLFIELD, N, typenod((yyvsp[(2) - (3)].type)));
 		if((yyvsp[(1) - (3)].sym))
@@ -5057,10 +5097,10 @@ yyreduce:
 	}
     break;
 
-  case 323:
+  case 324:
 
-/* Line 1455 of yacc.c  */
-#line 1936 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1944 "go.y"
     {
 		Type *t;
 	
@@ -5076,10 +5116,10 @@ yyreduce:
 	}
     break;
 
-  case 324:
+  case 325:
 
-/* Line 1455 of yacc.c  */
-#line 1952 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1960 "go.y"
     {
 		Sym *s;
 
@@ -5097,64 +5137,64 @@ yyreduce:
 	}
     break;
 
-  case 325:
+  case 326:
 
-/* Line 1455 of yacc.c  */
-#line 1970 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1978 "go.y"
     {
 		(yyval.node) = nod(ODCLFIELD, newname((yyvsp[(1) - (5)].sym)), typenod(functype(fakethis(), (yyvsp[(3) - (5)].list), (yyvsp[(5) - (5)].list))));
 	}
     break;
 
-  case 326:
+  case 327:
 
-/* Line 1455 of yacc.c  */
-#line 1974 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1982 "go.y"
     {
 		(yyval.node) = nod(ODCLFIELD, N, typenod((yyvsp[(1) - (1)].type)));
 	}
     break;
 
-  case 327:
+  case 328:
 
-/* Line 1455 of yacc.c  */
-#line 1979 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1987 "go.y"
     {
 		(yyval.list) = nil;
 	}
     break;
 
-  case 329:
+  case 330:
 
-/* Line 1455 of yacc.c  */
-#line 1986 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1994 "go.y"
     {
 		(yyval.list) = (yyvsp[(2) - (3)].list);
 	}
     break;
 
-  case 330:
+  case 331:
 
-/* Line 1455 of yacc.c  */
-#line 1990 "go.y"
+/* Line 1806 of yacc.c  */
+#line 1998 "go.y"
     {
 		(yyval.list) = list1(nod(ODCLFIELD, N, typenod((yyvsp[(1) - (1)].type))));
 	}
     break;
 
-  case 331:
+  case 332:
 
-/* Line 1455 of yacc.c  */
-#line 2000 "go.y"
+/* Line 1806 of yacc.c  */
+#line 2008 "go.y"
     {
 		(yyval.node) = nodlit((yyvsp[(1) - (1)].val));
 	}
     break;
 
-  case 332:
+  case 333:
 
-/* Line 1455 of yacc.c  */
-#line 2004 "go.y"
+/* Line 1806 of yacc.c  */
+#line 2012 "go.y"
     {
 		(yyval.node) = nodlit((yyvsp[(2) - (2)].val));
 		switch((yyval.node)->val.ctype){
@@ -5171,10 +5211,10 @@ yyreduce:
 	}
     break;
 
-  case 333:
+  case 334:
 
-/* Line 1455 of yacc.c  */
-#line 2019 "go.y"
+/* Line 1806 of yacc.c  */
+#line 2027 "go.y"
     {
 		(yyval.node) = oldname(pkglookup((yyvsp[(1) - (1)].sym)->name, builtinpkg));
 		if((yyval.node)->op != OLITERAL)
@@ -5182,10 +5222,10 @@ yyreduce:
 	}
     break;
 
-  case 335:
+  case 336:
 
-/* Line 1455 of yacc.c  */
-#line 2028 "go.y"
+/* Line 1806 of yacc.c  */
+#line 2036 "go.y"
     {
 		if((yyvsp[(2) - (5)].node)->val.ctype == CTRUNE && (yyvsp[(4) - (5)].node)->val.ctype == CTINT) {
 			(yyval.node) = (yyvsp[(2) - (5)].node);
@@ -5196,55 +5236,55 @@ yyreduce:
 	}
     break;
 
-  case 338:
+  case 339:
 
-/* Line 1455 of yacc.c  */
-#line 2042 "go.y"
+/* Line 1806 of yacc.c  */
+#line 2050 "go.y"
     {
 		(yyval.list) = list1((yyvsp[(1) - (1)].node));
 	}
     break;
 
-  case 339:
+  case 340:
 
-/* Line 1455 of yacc.c  */
-#line 2046 "go.y"
+/* Line 1806 of yacc.c  */
+#line 2054 "go.y"
     {
 		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 340:
+  case 341:
 
-/* Line 1455 of yacc.c  */
-#line 2052 "go.y"
+/* Line 1806 of yacc.c  */
+#line 2060 "go.y"
     {
 		(yyval.list) = list1((yyvsp[(1) - (1)].node));
 	}
     break;
 
-  case 341:
+  case 342:
 
-/* Line 1455 of yacc.c  */
-#line 2056 "go.y"
+/* Line 1806 of yacc.c  */
+#line 2064 "go.y"
     {
 		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 342:
+  case 343:
 
-/* Line 1455 of yacc.c  */
-#line 2062 "go.y"
+/* Line 1806 of yacc.c  */
+#line 2070 "go.y"
     {
 		(yyval.list) = list1((yyvsp[(1) - (1)].node));
 	}
     break;
 
-  case 343:
+  case 344:
 
-/* Line 1455 of yacc.c  */
-#line 2066 "go.y"
+/* Line 1806 of yacc.c  */
+#line 2074 "go.y"
     {
 		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
 	}
@@ -5252,10 +5292,21 @@ yyreduce:
 
 
 
-/* Line 1455 of yacc.c  */
-#line 5258 "y.tab.c"
+/* Line 1806 of yacc.c  */
+#line 5298 "y.tab.c"
       default: break;
     }
+  /* User semantic actions sometimes alter yychar, and that requires
+     that yytoken be updated with the new translation.  We take the
+     approach of translating immediately before every use of yytoken.
+     One alternative is translating here after every semantic action,
+     but that translation would be missed if the semantic action invokes
+     YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
+     if it invokes YYBACKUP.  In the case of YYABORT or YYACCEPT, an
+     incorrect destructor might then be invoked immediately.  In the
+     case of YYERROR or YYBACKUP, subsequent parser actions might lead
+     to an incorrect destructor call or verbose syntax error message
+     before the lookahead is translated.  */
   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
 
   YYPOPSTACK (yylen);
@@ -5283,6 +5334,10 @@ yyreduce:
 | yyerrlab -- here on detecting error |
 `------------------------------------*/
 yyerrlab:
+  /* Make sure we have latest lookahead translation.  See comments at
+     user semantic actions for why this is necessary.  */
+  yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
+
   /* If not already recovering from an error, report this error.  */
   if (!yyerrstatus)
     {
@@ -5290,37 +5345,36 @@ yyerrlab:
 #if ! YYERROR_VERBOSE
       yyerror (YY_("syntax error"));
 #else
+# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
+                                        yyssp, yytoken)
       {
-	YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
-	if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
-	  {
-	    YYSIZE_T yyalloc = 2 * yysize;
-	    if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
-	      yyalloc = YYSTACK_ALLOC_MAXIMUM;
-	    if (yymsg != yymsgbuf)
-	      YYSTACK_FREE (yymsg);
-	    yymsg = (char *) YYSTACK_ALLOC (yyalloc);
-	    if (yymsg)
-	      yymsg_alloc = yyalloc;
-	    else
-	      {
-		yymsg = yymsgbuf;
-		yymsg_alloc = sizeof yymsgbuf;
-	      }
-	  }
-
-	if (0 < yysize && yysize <= yymsg_alloc)
-	  {
-	    (void) yysyntax_error (yymsg, yystate, yychar);
-	    yyerror (yymsg);
-	  }
-	else
-	  {
-	    yyerror (YY_("syntax error"));
-	    if (yysize != 0)
-	      goto yyexhaustedlab;
-	  }
+        char *yymsgp = YY_("syntax error");
+        int yysyntax_error_status;
+        yysyntax_error_status = YYSYNTAX_ERROR;
+        if (yysyntax_error_status == 0)
+          yymsgp = yymsg;
+        else if (yysyntax_error_status == 1)
+          {
+            if (yymsg != yymsgbuf)
+              YYSTACK_FREE (yymsg);
+            yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
+            if (!yymsg)
+              {
+                yymsg = yymsgbuf;
+                yymsg_alloc = sizeof yymsgbuf;
+                yysyntax_error_status = 2;
+              }
+            else
+              {
+                yysyntax_error_status = YYSYNTAX_ERROR;
+                yymsgp = yymsg;
+              }
+          }
+        yyerror (yymsgp);
+        if (yysyntax_error_status == 2)
+          goto yyexhaustedlab;
       }
+# undef YYSYNTAX_ERROR
 #endif
     }
 
@@ -5379,7 +5433,7 @@ yyerrlab1:
   for (;;)
     {
       yyn = yypact[yystate];
-      if (yyn != YYPACT_NINF)
+      if (!yypact_value_is_default (yyn))
 	{
 	  yyn += YYTERROR;
 	  if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
@@ -5438,8 +5492,13 @@ yyexhaustedlab:
 
 yyreturn:
   if (yychar != YYEMPTY)
-     yydestruct ("Cleanup: discarding lookahead",
-		 yytoken, &yylval);
+    {
+      /* Make sure we have latest lookahead translation.  See comments at
+         user semantic actions for why this is necessary.  */
+      yytoken = YYTRANSLATE (yychar);
+      yydestruct ("Cleanup: discarding lookahead",
+                  yytoken, &yylval);
+    }
   /* Do not reclaim the symbols of the rule which action triggered
      this YYABORT or YYACCEPT.  */
   YYPOPSTACK (yylen);
@@ -5464,8 +5523,8 @@ yyreturn:
 
 
 
-/* Line 1675 of yacc.c  */
-#line 2070 "go.y"
+/* Line 2067 of yacc.c  */
+#line 2078 "go.y"
 
 
 static void
diff --git a/src/cmd/gc/y.tab.h b/src/cmd/gc/y.tab.h
index 11e19b6..bc6c47d 100644
--- a/src/cmd/gc/y.tab.h
+++ b/src/cmd/gc/y.tab.h
@@ -1,10 +1,8 @@
+/* A Bison parser, made by GNU Bison 2.5.  */
 
-/* A Bison parser, made by GNU Bison 2.4.1.  */
-
-/* Skeleton interface for Bison's Yacc-like parsers in C
+/* Bison interface for Yacc-like parsers in C
    
-      Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
-   Free Software Foundation, Inc.
+      Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
    
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -148,7 +146,7 @@
 typedef union YYSTYPE
 {
 
-/* Line 1676 of yacc.c  */
+/* Line 2068 of yacc.c  */
 #line 28 "go.y"
 
 	Node*		node;
@@ -160,8 +158,8 @@ typedef union YYSTYPE
 
 
 
-/* Line 1676 of yacc.c  */
-#line 165 "y.tab.h"
+/* Line 2068 of yacc.c  */
+#line 163 "y.tab.h"
 } YYSTYPE;
 # define YYSTYPE_IS_TRIVIAL 1
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
diff --git a/src/cmd/gc/yerr.h b/src/cmd/gc/yerr.h
index 731ca7c..588890d 100644
--- a/src/cmd/gc/yerr.h
+++ b/src/cmd/gc/yerr.h
@@ -14,25 +14,25 @@ static struct {
 	// is converted by bisonerrors into the yystate and yychar caused
 	// by that token list.
 
-	220, ',',
+	221, ',',
 	"unexpected comma during import block",
 
-	376, ';',
+	377, ';',
 	"unexpected semicolon or newline before {",
 
-	397, ';',
+	398, ';',
 	"unexpected semicolon or newline before {",
 
-	236, ';',
+	237, ';',
 	"unexpected semicolon or newline before {",
 
-	473, LBODY,
+	474, LBODY,
 	"unexpected semicolon or newline before {",
 
 	22, '{',
 	"unexpected semicolon or newline before {",
 
-	143, ';',
+	144, ';',
 	"unexpected semicolon or newline in type declaration",
 
 	37, '}',
@@ -44,30 +44,30 @@ static struct {
 	37, ',',
 	"unexpected comma in channel type",
 
-	436, LELSE,
+	437, LELSE,
 	"unexpected semicolon or newline before else",
 
-	256, ',',
+	257, ',',
 	"name list not allowed in interface type",
 
-	236, LVAR,
+	237, LVAR,
 	"var declaration not allowed in for initializer",
 
 	65, '{',
 	"unexpected { at end of statement",
 
-	375, '{',
+	376, '{',
 	"unexpected { at end of statement",
 	
-	124, ';',
+	125, ';',
 	"argument to go/defer must be function call",
 	
-	424, ';',
+	425, ';',
 	"need trailing comma before newline in composite literal",
 	
-	111, LNAME,
+	112, LNAME,
 	"nested func not allowed",
 
-	614, ';',
+	615, ';',
 	"else must be followed by if or statement block"
 };
diff --git a/src/cmd/go/build.go b/src/cmd/go/build.go
index caffa1f..c330bd5 100644
--- a/src/cmd/go/build.go
+++ b/src/cmd/go/build.go
@@ -23,7 +23,7 @@ import (
 )
 
 var cmdBuild = &Command{
-	UsageLine: "build [-a] [-n] [-o output] [-p n] [-v] [-x] [-work] [importpath... | gofiles...]",
+	UsageLine: "build [-o output] [build flags] [packages]",
 	Short:     "compile packages and dependencies",
 	Long: `
 Build compiles the packages named by the import paths,
@@ -33,25 +33,43 @@ If the arguments are a list of .go files, build treats them as a list
 of source files specifying a single package.
 
 When the command line specifies a single main package,
-build writes the resulting executable to output (default a.out).
+build writes the resulting executable to output.
 Otherwise build compiles the packages but discards the results,
 serving only as a check that the packages can be built.
 
-The -a flag forces rebuilding of packages that are already up-to-date.
-The -n flag prints the commands but does not run them.
-The -v flag prints the names of packages as they are compiled.
-The -x flag prints the commands.
-
-The -o flag specifies the output file name.
-It is an error to use -o when the command line specifies multiple packages.
-
-The -p flag specifies the number of builds that can be run in parallel.
-The default is the number of CPUs available.
-
-The -work flag causes build to print the name of the temporary work
-directory and not delete it when exiting.
-
-For more about import paths, see 'go help importpath'.
+The -o flag specifies the output file name.  If not specified, the
+name is packagename.a (for a non-main package) or the base
+name of the first source file (for a main package).
+
+The build flags are shared by the build, install, run, and test commands:
+
+	-a
+		force rebuilding of packages that are already up-to-date.
+	-n
+		print the commands but do not run them.
+	-p n
+		the number of builds that can be run in parallel.
+		The default is the number of CPUs available.
+	-v
+		print the names of packages as they are compiled.
+	-work
+		print the name of the temporary work directory and
+		do not delete it when exiting.
+	-x
+		print the commands.
+
+	-gccgoflags 'arg list'
+		arguments to pass on each gccgo compiler/linker invocation
+	-gcflags 'arg list'
+		arguments to pass on each 5g, 6g, or 8g compiler invocation
+	-ldflags 'flag list'
+		arguments to pass on each 5l, 6l, or 8l linker invocation
+	-tags 'tag list'
+		a list of build tags to consider satisfied during the build.
+		See the documentation for the go/build package for
+		more information about build tags.
+
+For more about specifying packages, see 'go help packages'.
 
 See also: go install, go get, go clean.
 	`,
@@ -73,9 +91,12 @@ var buildP = runtime.NumCPU() // -p flag
 var buildV bool               // -v flag
 var buildX bool               // -x flag
 var buildO = cmdBuild.Flag.String("o", "", "output file")
-var buildWork bool // -work flag
+var buildWork bool           // -work flag
+var buildGcflags []string    // -gcflags flag
+var buildLdflags []string    // -ldflags flag
+var buildGccgoflags []string // -gccgoflags flag
 
-var buildContext = build.DefaultContext
+var buildContext = build.Default
 
 // addBuildFlags adds the flags common to the build and install commands.
 func addBuildFlags(cmd *Command) {
@@ -85,20 +106,16 @@ func addBuildFlags(cmd *Command) {
 	cmd.Flag.BoolVar(&buildV, "v", false, "")
 	cmd.Flag.BoolVar(&buildX, "x", false, "")
 	cmd.Flag.BoolVar(&buildWork, "work", false, "")
-
-	// TODO(rsc): This -t flag is used by buildscript.sh but
-	// not documented.  Should be documented but the
-	// usage lines are getting too long.  Probably need to say
-	// that these flags are applicable to every command and
-	// document them in one help message instead of on every
-	// command's help message.
-	cmd.Flag.Var((*stringsFlag)(&buildContext.BuildTags), "t", "")
+	cmd.Flag.Var((*stringsFlag)(&buildGcflags), "gcflags", "")
+	cmd.Flag.Var((*stringsFlag)(&buildLdflags), "ldflags", "")
+	cmd.Flag.Var((*stringsFlag)(&buildGccgoflags), "gccgoflags", "")
+	cmd.Flag.Var((*stringsFlag)(&buildContext.BuildTags), "tags", "")
 }
 
 type stringsFlag []string
 
 func (v *stringsFlag) Set(s string) error {
-	*v = append(*v, s)
+	*v = strings.Fields(s)
 	return nil
 }
 
@@ -110,17 +127,11 @@ func runBuild(cmd *Command, args []string) {
 	var b builder
 	b.init()
 
-	var pkgs []*Package
-	if len(args) > 0 && strings.HasSuffix(args[0], ".go") {
-		pkg := goFilesPackage(args, "")
-		pkgs = append(pkgs, pkg)
-	} else {
-		pkgs = packagesForBuild(args)
-	}
+	pkgs := packagesForBuild(args)
 
 	if len(pkgs) == 1 && pkgs[0].Name == "main" && *buildO == "" {
 		_, *buildO = path.Split(pkgs[0].ImportPath)
-		if b.goos == "windows" {
+		if goos == "windows" {
 			*buildO += ".exe"
 		}
 	}
@@ -145,24 +156,14 @@ func runBuild(cmd *Command, args []string) {
 }
 
 var cmdInstall = &Command{
-	UsageLine: "install [-a] [-n] [-p n] [-v] [-x] [-work] [importpath...]",
+	UsageLine: "install [build flags] [packages]",
 	Short:     "compile and install packages and dependencies",
 	Long: `
 Install compiles and installs the packages named by the import paths,
 along with their dependencies.
 
-The -a flag forces reinstallation of packages that are already up-to-date.
-The -n flag prints the commands but does not run them.
-The -v flag prints the names of packages as they are compiled.
-The -x flag prints the commands.
-
-The -p flag specifies the number of builds that can be run in parallel.
-The default is the number of CPUs available.
-
-The -work flag causes build to print the name of the temporary work
-directory and not delete it when exiting.
-
-For more about import paths, see 'go help importpath'.
+For more about the build flags, see 'go help build'.
+For more about specifying packages, see 'go help packages'.
 
 See also: go build, go get, go clean.
 	`,
@@ -171,6 +172,13 @@ See also: go build, go get, go clean.
 func runInstall(cmd *Command, args []string) {
 	pkgs := packagesForBuild(args)
 
+	for _, p := range pkgs {
+		if p.Target == "" && (!p.Standard || p.ImportPath != "unsafe") {
+			errorf("go install: no install location for %s", p.ImportPath)
+		}
+	}
+	exitIfErrors()
+
 	var b builder
 	b.init()
 	a := &action{}
@@ -180,16 +188,32 @@ func runInstall(cmd *Command, args []string) {
 	b.do(a)
 }
 
+// Global build parameters (used during package load)
+var (
+	goarch    string
+	goos      string
+	archChar  string
+	exeSuffix string
+)
+
+func init() {
+	goarch = buildContext.GOARCH
+	goos = buildContext.GOOS
+	if goos == "windows" {
+		exeSuffix = ".exe"
+	}
+	var err error
+	archChar, err = build.ArchChar(goarch)
+	if err != nil {
+		fatalf("%s", err)
+	}
+}
+
 // A builder holds global state about a build.
-// It does not hold per-package state, because eventually we will
-// build packages in parallel, and the builder will be shared.
+// It does not hold per-package state, because we
+// build packages in parallel, and the builder is shared.
 type builder struct {
 	work        string               // the temporary work directory (ends in filepath.Separator)
-	arch        string               // e.g., "6"
-	goarch      string               // the $GOARCH
-	goos        string               // the $GOOS
-	exe         string               // the executable suffix - "" or ".exe"
-	gcflags     []string             // additional flags for Go compiler
 	actionCache map[cacheKey]*action // a cache of already-constructed actions
 	mkdirCache  map[string]bool      // a cache of created directories
 	print       func(args ...interface{}) (int, error)
@@ -243,26 +267,25 @@ const (
 )
 
 var (
-	gobin  = build.Path[0].BinDir()
-	goroot = build.Path[0].Path
+	goroot       = filepath.Clean(runtime.GOROOT())
+	gobin        = defaultGobin()
+	gorootSrcPkg = filepath.Join(goroot, "src/pkg")
+	gorootPkg    = filepath.Join(goroot, "pkg")
+	gorootSrc    = filepath.Join(goroot, "src")
 )
 
+func defaultGobin() string {
+	if s := os.Getenv("GOBIN"); s != "" {
+		return s
+	}
+	return filepath.Join(goroot, "bin")
+}
+
 func (b *builder) init() {
 	var err error
 	b.print = fmt.Print
 	b.actionCache = make(map[cacheKey]*action)
 	b.mkdirCache = make(map[string]bool)
-	b.goarch = buildContext.GOARCH
-	b.goos = buildContext.GOOS
-	if b.goos == "windows" {
-		b.exe = ".exe"
-	}
-	b.gcflags = strings.Fields(os.Getenv("GCFLAGS"))
-
-	b.arch, err = build.ArchChar(b.goarch)
-	if err != nil {
-		fatalf("%s", err)
-	}
 
 	if buildN {
 		b.work = "$WORK"
@@ -281,21 +304,26 @@ func (b *builder) init() {
 }
 
 // goFilesPackage creates a package for building a collection of Go files
-// (typically named on the command line).  If target is given, the package
-// target is target.  Otherwise, the target is named p.a for
+// (typically named on the command line).  The target is named p.a for
 // package p or named after the first Go file for package main.
-func goFilesPackage(gofiles []string, target string) *Package {
+func goFilesPackage(gofiles []string) *Package {
 	// TODO: Remove this restriction.
 	for _, f := range gofiles {
-		if !strings.HasSuffix(f, ".go") || strings.Contains(f, "/") || strings.Contains(f, string(filepath.Separator)) {
-			fatalf("named files must be in current directory and .go files")
+		if !strings.HasSuffix(f, ".go") {
+			fatalf("named files must be .go files")
 		}
 	}
 
-	// Synthesize fake "directory" that only shows those two files,
+	var stk importStack
+	ctxt := buildContext
+	ctxt.UseAllFiles = true
+
+	// Synthesize fake "directory" that only shows the named files,
 	// to make it look like this is a standard package or
-	// command directory.
-	var dir []os.FileInfo
+	// command directory.  So that local imports resolve
+	// consistently, the files must all be in the same directory.
+	var dirent []os.FileInfo
+	var dir string
 	for _, file := range gofiles {
 		fi, err := os.Stat(file)
 		if err != nil {
@@ -304,36 +332,39 @@ func goFilesPackage(gofiles []string, target string) *Package {
 		if fi.IsDir() {
 			fatalf("%s is a directory, should be a Go file", file)
 		}
-		dir = append(dir, fi)
-	}
-	ctxt := buildContext
-	ctxt.ReadDir = func(string) ([]os.FileInfo, error) { return dir, nil }
-	pwd, _ := os.Getwd()
-	var stk importStack
-	pkg := scanPackage(&ctxt, &build.Tree{Path: "."}, "<command line>", "<command line>", pwd+"/.", &stk, true)
-	if pkg.Error != nil {
-		fatalf("%s", pkg.Error)
-	}
-	printed := map[error]bool{}
-	for _, err := range pkg.DepsErrors {
-		// Since these are errors in dependencies,
-		// the same error might show up multiple times,
-		// once in each package that depends on it.
-		// Only print each once.
-		if !printed[err] {
-			printed[err] = true
-			errorf("%s", err)
+		dir1, _ := filepath.Split(file)
+		if dir == "" {
+			dir = dir1
+		} else if dir != dir1 {
+			fatalf("named files must all be in one directory; have %s and %s", dir, dir1)
 		}
+		dirent = append(dirent, fi)
 	}
-	if target != "" {
-		pkg.target = target
-	} else if pkg.Name == "main" {
-		pkg.target = gofiles[0][:len(gofiles[0])-len(".go")]
-	} else {
-		pkg.target = pkg.Name + ".a"
+	ctxt.ReadDir = func(string) ([]os.FileInfo, error) { return dirent, nil }
+
+	if !filepath.IsAbs(dir) {
+		dir = filepath.Join(cwd, dir)
 	}
-	pkg.ImportPath = "_/" + pkg.target
-	exitIfErrors()
+
+	bp, err := ctxt.ImportDir(dir, 0)
+	pkg := new(Package)
+	pkg.load(&stk, bp, err)
+	pkg.localPrefix = dirToImportPath(dir)
+	pkg.ImportPath = "command-line-arguments"
+
+	if *buildO == "" {
+		if pkg.Name == "main" {
+			_, elem := filepath.Split(gofiles[0])
+			*buildO = elem[:len(elem)-len(".go")]
+		} else {
+			*buildO = pkg.Name + ".a"
+		}
+	}
+	pkg.target = ""
+	pkg.Target = ""
+	pkg.Stale = true
+
+	computeStale(pkg)
 	return pkg
 }
 
@@ -346,7 +377,7 @@ func (b *builder) action(mode buildMode, depMode buildMode, p *Package) *action
 		return a
 	}
 
-	a = &action{p: p, pkgdir: p.t.PkgDir()}
+	a = &action{p: p, pkgdir: p.build.PkgRoot}
 	if p.pkgdir != "" { // overrides p.t
 		a.pkgdir = p.pkgdir
 	}
@@ -362,7 +393,7 @@ func (b *builder) action(mode buildMode, depMode buildMode, p *Package) *action
 	// using cgo, to make sure we do not overwrite the binary while
 	// a package is using it.  If this is a cross-build, then the cgo we
 	// are writing is not the cgo we need to use.
-	if b.goos == runtime.GOOS && b.goarch == runtime.GOARCH {
+	if goos == runtime.GOOS && goarch == runtime.GOARCH {
 		if len(p.CgoFiles) > 0 || p.Standard && p.ImportPath == "runtime/cgo" {
 			var stk importStack
 			p1 := loadPackage("cmd/cgo", &stk)
@@ -388,14 +419,18 @@ func (b *builder) action(mode buildMode, depMode buildMode, p *Package) *action
 		}
 	}
 
-	if !p.Stale && !buildA && p.target != "" {
+	if !p.Stale && p.target != "" {
 		// p.Stale==false implies that p.target is up-to-date.
 		// Record target name for use by actions depending on this one.
 		a.target = p.target
 		return a
 	}
 
-	a.objdir = filepath.Join(b.work, filepath.FromSlash(a.p.ImportPath+"/_obj")) + string(filepath.Separator)
+	if p.local {
+		// Imported via local path.  No permanent target.
+		mode = modeBuild
+	}
+	a.objdir = filepath.Join(b.work, a.p.ImportPath, "_obj") + string(filepath.Separator)
 	a.objpkg = buildToolchain.pkgpath(b.work, a.p)
 	a.link = p.Name == "main"
 
@@ -410,7 +445,7 @@ func (b *builder) action(mode buildMode, depMode buildMode, p *Package) *action
 		if a.link {
 			// An executable file.
 			// (This is the name of a temporary file.)
-			a.target = a.objdir + "a.out" + b.exe
+			a.target = a.objdir + "a.out" + exeSuffix
 		}
 	}
 
@@ -560,7 +595,7 @@ func (b *builder) build(a *action) error {
 
 	// Run cgo.
 	if len(a.p.CgoFiles) > 0 {
-		// In a package using cgo, cgo compiles the C and assembly files with gcc.  
+		// In a package using cgo, cgo compiles the C and assembly files with gcc.
 		// There is one exception: runtime/cgo's job is to bridge the
 		// cgo and non-cgo worlds, so it necessarily has files in both.
 		// In that case gcc only gets the gcc_* files.
@@ -611,31 +646,31 @@ func (b *builder) build(a *action) error {
 	// Copy .h files named for goos or goarch or goos_goarch
 	// to names using GOOS and GOARCH.
 	// For example, defs_linux_amd64.h becomes defs_GOOS_GOARCH.h.
-	_goos_goarch := "_" + b.goos + "_" + b.goarch + ".h"
-	_goos := "_" + b.goos + ".h"
-	_goarch := "_" + b.goarch + ".h"
+	_goos_goarch := "_" + goos + "_" + goarch + ".h"
+	_goos := "_" + goos + ".h"
+	_goarch := "_" + goarch + ".h"
 	for _, file := range a.p.HFiles {
 		switch {
 		case strings.HasSuffix(file, _goos_goarch):
 			targ := file[:len(file)-len(_goos_goarch)] + "_GOOS_GOARCH.h"
-			if err := b.copyFile(obj+targ, filepath.Join(a.p.Dir, file), 0666); err != nil {
+			if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0666); err != nil {
 				return err
 			}
 		case strings.HasSuffix(file, _goarch):
 			targ := file[:len(file)-len(_goarch)] + "_GOARCH.h"
-			if err := b.copyFile(obj+targ, filepath.Join(a.p.Dir, file), 0666); err != nil {
+			if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0666); err != nil {
 				return err
 			}
 		case strings.HasSuffix(file, _goos):
 			targ := file[:len(file)-len(_goos)] + "_GOOS.h"
-			if err := b.copyFile(obj+targ, filepath.Join(a.p.Dir, file), 0666); err != nil {
+			if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0666); err != nil {
 				return err
 			}
 		}
 	}
 
 	for _, file := range cfiles {
-		out := file[:len(file)-len(".c")] + "." + b.arch
+		out := file[:len(file)-len(".c")] + "." + archChar
 		if err := buildToolchain.cc(b, a.p, obj, obj+out, file); err != nil {
 			return err
 		}
@@ -644,7 +679,7 @@ func (b *builder) build(a *action) error {
 
 	// Assemble .s files.
 	for _, file := range sfiles {
-		out := file[:len(file)-len(".s")] + "." + b.arch
+		out := file[:len(file)-len(".s")] + "." + archChar
 		if err := buildToolchain.asm(b, a.p, obj, obj+out, file); err != nil {
 			return err
 		}
@@ -701,7 +736,7 @@ func (b *builder) install(a *action) error {
 		defer os.Remove(a1.target)
 	}
 
-	return b.copyFile(a.target, a1.target, perm)
+	return b.copyFile(a, a.target, a1.target, perm)
 }
 
 // includeArgs returns the -I or -L directory list for access
@@ -709,16 +744,16 @@ func (b *builder) install(a *action) error {
 func (b *builder) includeArgs(flag string, all []*action) []string {
 	inc := []string{}
 	incMap := map[string]bool{
-		b.work:                 true, // handled later
-		build.Path[0].PkgDir(): true, // goroot
-		"":                     true, // ignore empty strings
+		b.work:    true, // handled later
+		gorootPkg: true,
+		"":        true, // ignore empty strings
 	}
 
 	// Look in the temporary space for results of test-specific actions.
 	// This is the $WORK/my/package/_test directory for the
 	// package being built, so there are few of these.
 	for _, a1 := range all {
-		if dir := a1.pkgdir; dir != a1.p.t.PkgDir() && !incMap[dir] {
+		if dir := a1.pkgdir; dir != a1.p.build.PkgRoot && !incMap[dir] {
 			incMap[dir] = true
 			inc = append(inc, flag, dir)
 		}
@@ -730,11 +765,13 @@ func (b *builder) includeArgs(flag string, all []*action) []string {
 
 	// Finally, look in the installed package directories for each action.
 	for _, a1 := range all {
-		if dir := a1.pkgdir; dir == a1.p.t.PkgDir() && !incMap[dir] {
+		if dir := a1.pkgdir; dir == a1.p.build.PkgRoot && !incMap[dir] {
+			incMap[dir] = true
 			if _, ok := buildToolchain.(gccgoToolchain); ok {
-				dir = filepath.Join(filepath.Dir(dir), "gccgo", filepath.Base(dir))
+				dir = filepath.Join(dir, "gccgo")
+			} else {
+				dir = filepath.Join(dir, goos+"_"+goarch)
 			}
-			incMap[dir] = true
 			inc = append(inc, flag, dir)
 		}
 	}
@@ -743,7 +780,7 @@ func (b *builder) includeArgs(flag string, all []*action) []string {
 }
 
 // copyFile is like 'cp src dst'.
-func (b *builder) copyFile(dst, src string, perm os.FileMode) error {
+func (b *builder) copyFile(a *action, dst, src string, perm os.FileMode) error {
 	if buildN || buildX {
 		b.showcmd("", "cp %s %s", src, dst)
 		if buildN {
@@ -841,7 +878,7 @@ func isObject(s string) bool {
 //
 func (b *builder) fmtcmd(dir string, format string, args ...interface{}) string {
 	cmd := fmt.Sprintf(format, args...)
-	if dir != "" {
+	if dir != "" && dir != "/" {
 		cmd = strings.Replace(" "+cmd, " "+dir, " .", -1)[1:]
 		if b.scriptDir != dir {
 			b.scriptDir = dir
@@ -889,8 +926,7 @@ func (b *builder) showcmd(dir string, format string, args ...interface{}) {
 func (b *builder) showOutput(dir, desc, out string) {
 	prefix := "# " + desc
 	suffix := "\n" + out
-	pwd, _ := os.Getwd()
-	if reldir, err := filepath.Rel(pwd, dir); err == nil && len(reldir) < len(dir) {
+	if reldir := shortPath(dir); reldir != dir {
 		suffix = strings.Replace(suffix, " "+dir, " "+reldir, -1)
 		suffix = strings.Replace(suffix, "\n"+dir, "\n"+reldir, -1)
 	}
@@ -901,6 +937,14 @@ func (b *builder) showOutput(dir, desc, out string) {
 	b.print(prefix, suffix)
 }
 
+// shortPath returns an absolute or relative name for path, whatever is shorter.
+func shortPath(path string) string {
+	if rel, err := filepath.Rel(cwd, path); err == nil && len(rel) < len(path) {
+		return rel
+	}
+	return path
+}
+
 // relPaths returns a copy of paths with absolute paths
 // made relative to the current directory if they would be shorter.
 func relPaths(paths []string) []string {
@@ -924,7 +968,7 @@ func relPaths(paths []string) []string {
 var errPrintedOutput = errors.New("already printed output - no need to show error")
 
 // run runs the command given by cmdline in the directory dir.
-// If the commnd fails, run prints information about the failure
+// If the command fails, run prints information about the failure
 // and returns a non-nil error.
 func (b *builder) run(dir string, desc string, cmdargs ...interface{}) error {
 	out, err := b.runOut(dir, desc, cmdargs...)
@@ -1006,15 +1050,16 @@ func mkAbs(dir, f string) string {
 
 type toolchain interface {
 	// gc runs the compiler in a specific directory on a set of files
-	// and returns the name of the generated output file. 
+	// and returns the name of the generated output file.
+	// The compiler runs in the directory dir.
 	gc(b *builder, p *Package, obj string, importArgs []string, gofiles []string) (ofile string, err error)
 	// cc runs the toolchain's C compiler in a directory on a C file
 	// to produce an output file.
 	cc(b *builder, p *Package, objdir, ofile, cfile string) error
 	// asm runs the assembler in a specific directory on a specific file
-	// to generate the named output file. 
+	// to generate the named output file.
 	asm(b *builder, p *Package, obj, ofile, sfile string) error
-	// pkgpath creates the appropriate destination path for a package file.
+	// pkgpath builds an appropriate path for a temporary package file.
 	pkgpath(basedir string, p *Package) string
 	// pack runs the archive packer in a specific directory to create
 	// an archive from a set of object files.
@@ -1022,6 +1067,9 @@ type toolchain interface {
 	pack(b *builder, p *Package, objDir, afile string, ofiles []string) error
 	// ld runs the linker to create a package starting at mainpkg.
 	ld(b *builder, p *Package, out string, allactions []*action, mainpkg string, ofiles []string) error
+
+	compiler() string
+	linker() string
 }
 
 type goToolchain struct{}
@@ -1030,7 +1078,9 @@ type gccgoToolchain struct{}
 var buildToolchain toolchain
 
 func init() {
+	// TODO(rsc): Decide how to trigger gccgo.  Issue 3157.
 	if os.Getenv("GC") == "gccgo" {
+		buildContext.Gccgo = true
 		buildToolchain = gccgoToolchain{}
 	} else {
 		buildToolchain = goToolchain{}
@@ -1039,8 +1089,16 @@ func init() {
 
 // The Go toolchain.
 
+func (goToolchain) compiler() string {
+	return tool(archChar + "g")
+}
+
+func (goToolchain) linker() string {
+	return tool(archChar + "l")
+}
+
 func (goToolchain) gc(b *builder, p *Package, obj string, importArgs []string, gofiles []string) (ofile string, err error) {
-	out := "_go_." + b.arch
+	out := "_go_." + archChar
 	ofile = obj + out
 	gcargs := []string{"-p", p.ImportPath}
 	if p.Standard && p.ImportPath == "runtime" {
@@ -1049,7 +1107,7 @@ func (goToolchain) gc(b *builder, p *Package, obj string, importArgs []string, g
 		gcargs = append(gcargs, "-+")
 	}
 
-	args := stringList(tool(b.arch+"g"), "-o", ofile, b.gcflags, gcargs, importArgs)
+	args := stringList(tool(archChar+"g"), "-o", ofile, buildGcflags, gcargs, "-D", p.localPrefix, importArgs)
 	for _, f := range gofiles {
 		args = append(args, mkAbs(p.Dir, f))
 	}
@@ -1058,11 +1116,12 @@ func (goToolchain) gc(b *builder, p *Package, obj string, importArgs []string, g
 
 func (goToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
 	sfile = mkAbs(p.Dir, sfile)
-	return b.run(p.Dir, p.ImportPath, tool(b.arch+"a"), "-I", obj, "-o", ofile, "-DGOOS_"+b.goos, "-DGOARCH_"+b.goarch, sfile)
+	return b.run(p.Dir, p.ImportPath, tool(archChar+"a"), "-I", obj, "-o", ofile, "-DGOOS_"+goos, "-DGOARCH_"+goarch, sfile)
 }
 
 func (goToolchain) pkgpath(basedir string, p *Package) string {
-	return filepath.Join(basedir, filepath.FromSlash(p.ImportPath+".a"))
+	end := filepath.FromSlash(p.ImportPath + ".a")
+	return filepath.Join(basedir, end)
 }
 
 func (goToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []string) error {
@@ -1075,19 +1134,29 @@ func (goToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []s
 
 func (goToolchain) ld(b *builder, p *Package, out string, allactions []*action, mainpkg string, ofiles []string) error {
 	importArgs := b.includeArgs("-L", allactions)
-	return b.run(p.Dir, p.ImportPath, tool(b.arch+"l"), "-o", out, importArgs, mainpkg)
+	return b.run(p.Dir, p.ImportPath, tool(archChar+"l"), "-o", out, importArgs, buildLdflags, mainpkg)
 }
 
 func (goToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
-	inc := filepath.Join(goroot, "pkg", fmt.Sprintf("%s_%s", b.goos, b.goarch))
+	inc := filepath.Join(goroot, "pkg", fmt.Sprintf("%s_%s", goos, goarch))
 	cfile = mkAbs(p.Dir, cfile)
-	return b.run(p.Dir, p.ImportPath, tool(b.arch+"c"), "-FVw",
+	return b.run(p.Dir, p.ImportPath, tool(archChar+"c"), "-FVw",
 		"-I", objdir, "-I", inc, "-o", ofile,
-		"-DGOOS_"+b.goos, "-DGOARCH_"+b.goarch, cfile)
+		"-DGOOS_"+goos, "-DGOARCH_"+goarch, cfile)
 }
 
 // The Gccgo toolchain.
 
+var gccgoBin, _ = exec.LookPath("gccgo")
+
+func (gccgoToolchain) compiler() string {
+	return gccgoBin
+}
+
+func (gccgoToolchain) linker() string {
+	return gccgoBin
+}
+
 func (gccgoToolchain) gc(b *builder, p *Package, obj string, importArgs []string, gofiles []string) (ofile string, err error) {
 	out := p.Name + ".o"
 	ofile = obj + out
@@ -1099,7 +1168,7 @@ func (gccgoToolchain) gc(b *builder, p *Package, obj string, importArgs []string
 			gcargs = append(gcargs, "-fgo-prefix=go_"+p.ImportPath)
 		}
 	}
-	args := stringList("gccgo", importArgs, "-c", b.gcflags, gcargs, "-o", ofile)
+	args := stringList("gccgo", importArgs, "-c", gcargs, "-o", ofile, buildGccgoflags)
 	for _, f := range gofiles {
 		args = append(args, mkAbs(p.Dir, f))
 	}
@@ -1108,12 +1177,13 @@ func (gccgoToolchain) gc(b *builder, p *Package, obj string, importArgs []string
 
 func (gccgoToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
 	sfile = mkAbs(p.Dir, sfile)
-	return b.run(p.Dir, p.ImportPath, "gccgo", "-I", obj, "-o", ofile, "-DGOOS_"+b.goos, "-DGOARCH_"+b.goarch, sfile)
+	return b.run(p.Dir, p.ImportPath, "gccgo", "-I", obj, "-o", ofile, "-DGOOS_"+goos, "-DGOARCH_"+goarch, sfile)
 }
 
 func (gccgoToolchain) pkgpath(basedir string, p *Package) string {
-	afile := filepath.Join(basedir, filepath.FromSlash(p.ImportPath+".a"))
-	// prepend "lib" to the basename
+	end := filepath.FromSlash(p.ImportPath + ".a")
+	afile := filepath.Join(basedir, end)
+	// add "lib" to the final element
 	return filepath.Join(filepath.Dir(afile), "lib"+filepath.Base(afile))
 }
 
@@ -1127,28 +1197,33 @@ func (gccgoToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles
 
 func (tools gccgoToolchain) ld(b *builder, p *Package, out string, allactions []*action, mainpkg string, ofiles []string) error {
 	// gccgo needs explicit linking with all package dependencies,
-	// and all LDFLAGS from cgo dependencies
-	afiles := []string{}
+	// and all LDFLAGS from cgo dependencies.
+	afiles := make(map[*Package]string)
 	ldflags := []string{}
-	seen := map[*Package]bool{}
+	cgoldflags := []string{}
 	for _, a := range allactions {
-		if a.p != nil && !seen[a.p] {
-			seen[a.p] = true
+		if a.p != nil {
 			if !a.p.Standard {
-				afiles = append(afiles, a.target)
+				if afiles[a.p] == "" || a.objpkg != a.target {
+					afiles[a.p] = a.target
+				}
 			}
-			ldflags = append(ldflags, a.p.CgoLDFLAGS...)
+			cgoldflags = append(cgoldflags, a.p.CgoLDFLAGS...)
 		}
 	}
-	return b.run(p.Dir, p.ImportPath, "gccgo", "-o", out, ofiles, "-Wl,-(", afiles, ldflags, "-Wl,-)")
+	for _, afile := range afiles {
+		ldflags = append(ldflags, afile)
+	}
+	ldflags = append(ldflags, cgoldflags...)
+	return b.run(p.Dir, p.ImportPath, "gccgo", "-o", out, buildGccgoflags, ofiles, "-Wl,-(", ldflags, "-Wl,-)")
 }
 
 func (gccgoToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
-	inc := filepath.Join(goroot, "pkg", fmt.Sprintf("%s_%s", b.goos, b.goarch))
+	inc := filepath.Join(goroot, "pkg", fmt.Sprintf("%s_%s", goos, goarch))
 	cfile = mkAbs(p.Dir, cfile)
 	return b.run(p.Dir, p.ImportPath, "gcc", "-Wall", "-g",
 		"-I", objdir, "-I", inc, "-o", ofile,
-		"-DGOOS_"+b.goos, "-DGOARCH_"+b.goarch, "-c", cfile)
+		"-DGOOS_"+goos, "-DGOARCH_"+goarch, "-c", cfile)
 }
 
 // gcc runs the gcc C compiler to create an object from a single C file.
@@ -1169,10 +1244,10 @@ func (b *builder) gccCmd(objdir string) []string {
 
 	// Definitely want -fPIC but on Windows gcc complains
 	// "-fPIC ignored for target (all code is position independent)"
-	if b.goos != "windows" {
+	if goos != "windows" {
 		a = append(a, "-fPIC")
 	}
-	switch b.arch {
+	switch archChar {
 	case "8":
 		a = append(a, "-m32")
 	case "6":
@@ -1181,7 +1256,7 @@ func (b *builder) gccCmd(objdir string) []string {
 	// gcc-4.5 and beyond require explicit "-pthread" flag
 	// for multithreading with pthread library.
 	if buildContext.CgoEnabled {
-		switch b.goos {
+		switch goos {
 		case "windows":
 			a = append(a, "-mthreads")
 		default:
@@ -1198,14 +1273,14 @@ func envList(key string) []string {
 var cgoRe = regexp.MustCompile(`[/\\:]`)
 
 func (b *builder) cgo(p *Package, cgoExe, obj string, gccfiles []string) (outGo, outObj []string, err error) {
-	if b.goos != toolGOOS {
+	if goos != toolGOOS {
 		return nil, nil, errors.New("cannot use cgo when compiling for a different operating system")
 	}
 
-	cgoCFLAGS := stringList(envList("CGO_CFLAGS"), p.info.CgoCFLAGS)
-	cgoLDFLAGS := stringList(envList("CGO_LDFLAGS"), p.info.CgoLDFLAGS)
+	cgoCFLAGS := stringList(envList("CGO_CFLAGS"), p.CgoCFLAGS)
+	cgoLDFLAGS := stringList(envList("CGO_LDFLAGS"), p.CgoLDFLAGS)
 
-	if pkgs := p.info.CgoPkgConfig; len(pkgs) > 0 {
+	if pkgs := p.CgoPkgConfig; len(pkgs) > 0 {
 		out, err := b.runOut(p.Dir, p.ImportPath, "pkg-config", "--cflags", pkgs)
 		if err != nil {
 			b.showOutput(p.Dir, "pkg-config --cflags "+strings.Join(pkgs, " "), string(out))
@@ -1255,7 +1330,7 @@ func (b *builder) cgo(p *Package, cgoExe, obj string, gccfiles []string) (outGo,
 	outGo = append(outGo, gofiles...)
 
 	// cc _cgo_defun.c
-	defunObj := obj + "_cgo_defun." + b.arch
+	defunObj := obj + "_cgo_defun." + archChar
 	if err := buildToolchain.cc(b, p, obj, defunObj, defunC); err != nil {
 		return nil, nil, err
 	}
@@ -1298,7 +1373,7 @@ func (b *builder) cgo(p *Package, cgoExe, obj string, gccfiles []string) (outGo,
 	}
 
 	// cc _cgo_import.ARCH
-	importObj := obj + "_cgo_import." + b.arch
+	importObj := obj + "_cgo_import." + archChar
 	if err := buildToolchain.cc(b, p, obj, importObj, importC); err != nil {
 		return nil, nil, err
 	}
diff --git a/src/cmd/go/clean.go b/src/cmd/go/clean.go
index 1ea12b9..809e0f0 100644
--- a/src/cmd/go/clean.go
+++ b/src/cmd/go/clean.go
@@ -13,7 +13,7 @@ import (
 )
 
 var cmdClean = &Command{
-	UsageLine: "clean [-i] [-r] [-n] [-x] [importpath...]",
+	UsageLine: "clean [-i] [-r] [-n] [-x] [packages]",
 	Short:     "remove object files",
 	Long: `
 Clean removes object files from package source directories.
@@ -50,6 +50,8 @@ The -r flag causes clean to be applied recursively to all the
 dependencies of the packages named by the import paths.
 
 The -x flag causes clean to print remove commands as it executes them.
+
+For more about specifying packages, see 'go help packages'.
 	`,
 }
 
diff --git a/src/cmd/go/doc.go b/src/cmd/go/doc.go
index e2df7be..8df57ff 100644
--- a/src/cmd/go/doc.go
+++ b/src/cmd/go/doc.go
@@ -5,7 +5,9 @@
 /*
 Go is a tool for managing Go source code.
 
-Usage: go command [arguments]
+Usage:
+
+	go command [arguments]
 
 The commands are:
 
@@ -28,7 +30,7 @@ Use "go help [command]" for more information about a command.
 Additional help topics:
 
     gopath      GOPATH environment variable
-    importpath  description of import paths
+    packages    description of package lists
     remote      remote import path syntax
     testflag    description of testing flags
     testfunc    description of testing functions
@@ -40,7 +42,7 @@ Compile packages and dependencies
 
 Usage:
 
-	go build [-a] [-n] [-o output] [-p n] [-v] [-x] [importpath... | gofiles...]
+	go build [-o output] [build flags] [packages]
 
 Build compiles the packages named by the import paths,
 along with their dependencies, but it does not install the results.
@@ -49,22 +51,43 @@ If the arguments are a list of .go files, build treats them as a list
 of source files specifying a single package.
 
 When the command line specifies a single main package,
-build writes the resulting executable to output (default a.out).
+build writes the resulting executable to output.
 Otherwise build compiles the packages but discards the results,
 serving only as a check that the packages can be built.
 
-The -a flag forces rebuilding of packages that are already up-to-date.
-The -n flag prints the commands but does not run them.
-The -v flag prints the names of packages as they are compiled.
-The -x flag prints the commands.
+The -o flag specifies the output file name.  If not specified, the
+name is packagename.a (for a non-main package) or the base
+name of the first source file (for a main package).
 
-The -o flag specifies the output file name.
-It is an error to use -o when the command line specifies multiple packages.
+The build flags are shared by the build, install, run, and test commands:
 
-The -p flag specifies the number of builds that can be run in parallel.
-The default is the number of CPUs available.
-
-For more about import paths, see 'go help importpath'.
+	-a
+		force rebuilding of packages that are already up-to-date.
+	-n
+		print the commands but do not run them.
+	-p n
+		the number of builds that can be run in parallel.
+		The default is the number of CPUs available.
+	-v
+		print the names of packages as they are compiled.
+	-work
+		print the name of the temporary work directory and
+		do not delete it when exiting.
+	-x
+		print the commands.
+
+	-gccgoflags 'arg list'
+		arguments to pass on each gccgo compiler/linker invocation
+	-gcflags 'arg list'
+		arguments to pass on each 5g, 6g, or 8g compiler invocation
+	-ldflags 'flag list'
+		arguments to pass on each 5l, 6l, or 8l linker invocation
+	-tags 'tag list'
+		a list of build tags to consider satisfied during the build.
+		See the documentation for the go/build package for
+		more information about build tags.
+
+For more about specifying packages, see 'go help packages'.
 
 See also: go install, go get, go clean.
 
@@ -73,7 +96,7 @@ Remove object files
 
 Usage:
 
-	go clean [-i] [-r] [-n] [-x] [importpath...]
+	go clean [-i] [-r] [-n] [-x] [packages]
 
 Clean removes object files from package source directories.
 The go command builds most objects in a temporary directory,
@@ -110,18 +133,20 @@ dependencies of the packages named by the import paths.
 
 The -x flag causes clean to print remove commands as it executes them.
 
+For more about specifying packages, see 'go help packages'.
+
 
 Run godoc on package sources
 
 Usage:
 
-	go doc [importpath...]
+	go doc [packages]
 
 Doc runs the godoc command on the packages named by the
 import paths.
 
 For more about godoc, see 'godoc godoc'.
-For more about import paths, see 'go help importpath'.
+For more about specifying packages, see 'go help packages'.
 
 To run godoc with specific options, run godoc itself.
 
@@ -132,12 +157,12 @@ Run go tool fix on packages
 
 Usage:
 
-	go fix [importpath...]
+	go fix [packages]
 
 Fix runs the Go fix command on the packages named by the import paths.
 
 For more about fix, see 'godoc fix'.
-For more about import paths, see 'go help importpath'.
+For more about specifying packages, see 'go help packages'.
 
 To run fix with specific options, run 'go tool fix'.
 
@@ -148,13 +173,13 @@ Run gofmt on package sources
 
 Usage:
 
-	go fmt [importpath...]
+	go fmt [packages]
 
 Fmt runs the command 'gofmt -l -w' on the packages named
 by the import paths.  It prints the names of the files that are modified.
 
 For more about gofmt, see 'godoc gofmt'.
-For more about import paths, see 'go help importpath'.
+For more about specifying packages, see 'go help packages'.
 
 To run gofmt with specific options, run gofmt itself.
 
@@ -165,7 +190,7 @@ Download and install packages and dependencies
 
 Usage:
 
-	go get [-a] [-d] [-fix] [-n] [-p n] [-u] [-v] [-x] [importpath...]
+	go get [-a] [-d] [-fix] [-n] [-p n] [-u] [-v] [-x] [packages]
 
 Get downloads and installs the packages named by the import paths,
 along with their dependencies.
@@ -180,12 +205,12 @@ The -fix flag instructs get to run the fix tool on the downloaded packages
 before resolving dependencies or building the code.
 
 The -u flag instructs get to use the network to update the named packages
-and their dependencies.  By default, get uses the network to check out 
+and their dependencies.  By default, get uses the network to check out
 missing packages but does not use it to look for updates to existing packages.
 
 TODO: Explain versions better.
 
-For more about import paths, see 'go help importpath'.
+For more about specifying packages, see 'go help packages'.
 
 For more about how 'go get' finds source code to
 download, see 'go help remote'.
@@ -197,20 +222,13 @@ Compile and install packages and dependencies
 
 Usage:
 
-	go install [-a] [-n] [-p n] [-v] [-x] [importpath...]
+	go install [build flags] [packages]
 
 Install compiles and installs the packages named by the import paths,
 along with their dependencies.
 
-The -a flag forces reinstallation of packages that are already up-to-date.
-The -n flag prints the commands but does not run them.
-The -v flag prints the names of packages as they are compiled.
-The -x flag prints the commands.
-
-The -p flag specifies the number of builds that can be run in parallel.
-The default is the number of CPUs available.
-
-For more about import paths, see 'go help importpath'.
+For more about the build flags, see 'go help build'.
+For more about specifying packages, see 'go help packages'.
 
 See also: go build, go get, go clean.
 
@@ -219,7 +237,7 @@ List packages
 
 Usage:
 
-	go list [-e] [-f format] [-json] [importpath...]
+	go list [-e] [-f format] [-json] [packages]
 
 List lists the packages named by the import paths, one per line.
 
@@ -274,20 +292,18 @@ printing.  Erroneous packages will have a non-empty ImportPath and
 a non-nil Error field; other information may or may not be missing
 (zeroed).
 
-For more about import paths, see 'go help importpath'.
+For more about specifying packages, see 'go help packages'.
 
 
 Compile and run Go program
 
 Usage:
 
-	go run [-a] [-n] [-x] gofiles... [arguments...]
+	go run [build flags] gofiles... [arguments...]
 
 Run compiles and runs the main package comprising the named Go source files.
 
-The -a flag forces reinstallation of packages that are already up-to-date.
-The -n flag prints the commands but does not run them.
-The -x flag prints the commands.
+For more about build flags, see 'go help build'.
 
 See also: go build.
 
@@ -296,7 +312,7 @@ Test packages
 
 Usage:
 
-	go test [-c] [-file a.go -file b.go ...] [-i] [-p n] [-x] [importpath...] [flags for test binary]
+	go test [-c] [-i] [build flags] [packages] [flags for test binary]
 
 'Go test' automates testing the packages named by the import paths.
 It prints a summary of the test results in the format:
@@ -314,17 +330,23 @@ benchmark functions, and example functions.  See 'go help testfunc' for more.
 
 By default, go test needs no arguments.  It compiles and tests the package
 with source in the current directory, including tests, and runs the tests.
-If file names are given (with flag -file=test.go, one per extra test source file),
-only those test files are added to the package.  (The non-test files are always
-compiled.)
 
 The package is built in a temporary directory so it does not interfere with the
 non-test installation.
 
-See 'go help testflag' for details about flags handled by 'go test'
-and the test binary.
+In addition to the build flags, the flags handled by 'go test' itself are:
 
-See 'go help importpath' for more about import paths.
+	-c  Compile the test binary to pkg.test but do not run it.
+
+	-i
+	    Install packages that are dependencies of the test.
+	    Do not run the test.
+
+The test binary also accepts flags that control execution of the test; these
+flags are also accessible by 'go test'.  See 'go help testflag' for details.
+
+For more about build flags, see 'go help build'.
+For more about specifying packages, see 'go help packages'.
 
 See also: go build, go vet.
 
@@ -333,11 +355,14 @@ Run specified go tool
 
 Usage:
 
-	go tool command [args...]
+	go tool [-n] command [args...]
 
 Tool runs the go tool command identified by the arguments.
 With no arguments it prints the list of known tools.
 
+The -n flag causes tool to print the command that would be
+executed but not execute it.
+
 For more about each tool command, see 'go tool command -h'.
 
 
@@ -354,12 +379,12 @@ Run go tool vet on packages
 
 Usage:
 
-	go vet [importpath...]
+	go vet [packages]
 
 Vet runs the Go vet command on the packages named by the import paths.
 
 For more about vet, see 'godoc vet'.
-For more about import paths, see 'go help importpath'.
+For more about specifying packages, see 'go help packages'.
 
 To run the vet tool with specific options, run 'go tool vet'.
 
@@ -368,6 +393,9 @@ See also: go fmt, go fix.
 
 GOPATH environment variable
 
+The Go path is used to resolve import statements.
+It is implemented by and documented in the go/build package.
+
 The GOPATH environment variable lists places to look for Go code.
 On Unix, the value is a colon-separated string.
 On Windows, the value is a semicolon-separated string.
@@ -421,11 +449,13 @@ but new packages are always downloaded into the first directory
 in the list.
 
 
-Description of import paths
+Description of package lists
+
+Many commands apply to a set of packages:
 
-Many commands apply to a set of packages named by import paths:
+	go action [packages]
 
-	go action [importpath...]
+Usually, [packages] is a list of import paths.
 
 An import path that is a rooted path or that begins with
 a . or .. element is interpreted as a file system path and
@@ -450,7 +480,8 @@ each of which can match any string, including the empty string and
 strings containing slashes.  Such a pattern expands to all package
 directories found in the GOPATH trees with names matching the
 patterns.  For example, encoding/... expands to all packages
-in the encoding tree.
+in subdirectories of the encoding tree, while net... expands to
+net and all its subdirectories.
 
 An import path can also name a package to be downloaded from
 a remote repository.  Run 'go help remote' for details.
@@ -462,6 +493,11 @@ internally at Google all begin with 'google', and paths
 denoting remote repositories begin with the path to the code,
 such as 'code.google.com/p/project'.
 
+As a special case, if the package list is a list of .go files from a
+single directory, the command is applied to a single synthesized
+package made up of exactly those files, ignoring any build constraints
+in those files and ignoring any other files in the directory.
+
 
 Remote import path syntax
 
@@ -541,31 +577,15 @@ Description of testing flags
 The 'go test' command takes both flags that apply to 'go test' itself
 and flags that apply to the resulting test binary.
 
-The flags handled by 'go test' are:
-
-	-c  Compile the test binary to pkg.test but do not run it.
-
-	-file a.go
-	    Use only the tests in the source file a.go.
-	    Multiple -file flags may be provided.
-
-	-i
-	    Install packages that are dependencies of the test.
-
-	-p n
-	    Compile and test up to n packages in parallel.
-	    The default value is the number of CPUs available.
-
-	-x  Print each subcommand go test executes.
-
-The resulting test binary, called pkg.test, where pkg is the name of the
+The test binary, called pkg.test, where pkg is the name of the
 directory containing the package sources, has its own flags:
 
 	-test.v
 	    Verbose output: log all tests as they are run.
 
 	-test.run pattern
-	    Run only those tests matching the regular expression.
+	    Run only those tests and examples matching the regular
+	    expression.
 
 	-test.bench pattern
 	    Run benchmarks matching the regular expression.
@@ -605,7 +625,7 @@ directory containing the package sources, has its own flags:
 		The default is 1 second.
 
 	-test.cpu 1,2,4
-	    Specify a list of GOMAXPROCS values for which the tests or 
+	    Specify a list of GOMAXPROCS values for which the tests or
 	    benchmarks should be executed.  The default is the current value
 	    of GOMAXPROCS.
 
@@ -613,9 +633,9 @@ For convenience, each of these -test.X flags of the test binary is
 also available as the flag -X in 'go test' itself.  Flags not listed
 here are passed through unaltered.  For instance, the command
 
-	go test -x -v -cpuprofile=prof.out -dir=testdata -update -file x_test.go
+	go test -x -v -cpuprofile=prof.out -dir=testdata -update
 
-will compile the test binary using x_test.go and then run it as
+will compile the test binary and then run it as
 
 	pkg.test -test.v -test.cpuprofile=prof.out -dir=testdata -update
 
@@ -636,8 +656,10 @@ A benchmark function is one named BenchmarkXXX and should have the signature,
 
 An example function is similar to a test function but, instead of using *testing.T
 to report success or failure, prints output to os.Stdout and os.Stderr.
-That output is compared against the function's doc comment.
-An example without a doc comment is compiled but not executed.
+That output is compared against the function's "Output:" comment, which
+must be the last comment in the function body (see example below). An
+example with no such comment, or with no text after "Output:" is compiled
+but not executed.
 
 Godoc displays the body of ExampleXXX to demonstrate the use
 of the function, constant, or variable XXX.  An example of a method M with
@@ -647,11 +669,16 @@ where xxx is a suffix not beginning with an upper case letter.
 
 Here is an example of an example:
 
-	// The output of this example function.
 	func ExamplePrintln() {
-		Println("The output of this example function.")
+		Println("The output of\nthis example.")
+		// Output: The output of
+		// this example.
 	}
 
+The entire test file is presented as the example when it contains a single
+example function, at least one other function, type, variable, or constant
+declaration, and no test or benchmark functions.
+
 See the documentation of the testing package for more information.
 
 
diff --git a/src/cmd/go/fix.go b/src/cmd/go/fix.go
index 6a0ad07..ef02b57 100644
--- a/src/cmd/go/fix.go
+++ b/src/cmd/go/fix.go
@@ -6,13 +6,13 @@ package main
 
 var cmdFix = &Command{
 	Run:       runFix,
-	UsageLine: "fix [importpath...]",
+	UsageLine: "fix [packages]",
 	Short:     "run go tool fix on packages",
 	Long: `
 Fix runs the Go fix command on the packages named by the import paths.
 
 For more about fix, see 'godoc fix'.
-For more about import paths, see 'go help importpath'.
+For more about specifying packages, see 'go help packages'.
 
 To run fix with specific options, run 'go tool fix'.
 
diff --git a/src/cmd/go/fmt.go b/src/cmd/go/fmt.go
index 4a47e2e..cea9b0a 100644
--- a/src/cmd/go/fmt.go
+++ b/src/cmd/go/fmt.go
@@ -6,14 +6,14 @@ package main
 
 var cmdFmt = &Command{
 	Run:       runFmt,
-	UsageLine: "fmt [importpath...]",
+	UsageLine: "fmt [packages]",
 	Short:     "run gofmt on package sources",
 	Long: `
 Fmt runs the command 'gofmt -l -w' on the packages named
 by the import paths.  It prints the names of the files that are modified.
 
 For more about gofmt, see 'godoc gofmt'.
-For more about import paths, see 'go help importpath'.
+For more about specifying packages, see 'go help packages'.
 
 To run gofmt with specific options, run gofmt itself.
 
@@ -32,14 +32,14 @@ func runFmt(cmd *Command, args []string) {
 
 var cmdDoc = &Command{
 	Run:       runDoc,
-	UsageLine: "doc [importpath...]",
+	UsageLine: "doc [packages]",
 	Short:     "run godoc on package sources",
 	Long: `
 Doc runs the godoc command on the packages named by the
 import paths.
 
 For more about godoc, see 'godoc godoc'.
-For more about import paths, see 'go help importpath'.
+For more about specifying packages, see 'go help packages'.
 
 To run godoc with specific options, run godoc itself.
 
@@ -49,6 +49,10 @@ See also: go fix, go fmt, go vet.
 
 func runDoc(cmd *Command, args []string) {
 	for _, pkg := range packages(args) {
+		if pkg.ImportPath == "command-line arguments" {
+			errorf("go doc: cannot use package file list")
+			continue
+		}
 		run("godoc", pkg.Dir)
 	}
 }
diff --git a/src/cmd/go/get.go b/src/cmd/go/get.go
index e66810c..0ad22ad 100644
--- a/src/cmd/go/get.go
+++ b/src/cmd/go/get.go
@@ -8,7 +8,6 @@ package main
 
 import (
 	"fmt"
-	"go/build"
 	"os"
 	"path/filepath"
 	"runtime"
@@ -17,7 +16,7 @@ import (
 )
 
 var cmdGet = &Command{
-	UsageLine: "get [-a] [-d] [-fix] [-n] [-p n] [-u] [-v] [-x] [importpath...]",
+	UsageLine: "get [-a] [-d] [-fix] [-n] [-p n] [-u] [-v] [-x] [packages]",
 	Short:     "download and install packages and dependencies",
 	Long: `
 Get downloads and installs the packages named by the import paths,
@@ -33,12 +32,12 @@ The -fix flag instructs get to run the fix tool on the downloaded packages
 before resolving dependencies or building the code.
 
 The -u flag instructs get to use the network to update the named packages
-and their dependencies.  By default, get uses the network to check out 
+and their dependencies.  By default, get uses the network to check out
 missing packages but does not use it to look for updates to existing packages.
 
 TODO: Explain versions better.
 
-For more about import paths, see 'go help importpath'.
+For more about specifying packages, see 'go help packages'.
 
 For more about how 'go get' finds source code to
 download, see 'go help remote'.
@@ -151,22 +150,35 @@ func download(arg string, stk *importStack) {
 // downloadPackage runs the create or download command
 // to make the first copy of or update a copy of the given package.
 func downloadPackage(p *Package) error {
-	// Analyze the import path to determine the version control system,
-	// repository, and the import path for the root of the repository.
-	vcs, repo, rootPath, err := vcsForImportPath(p.ImportPath)
+	var (
+		vcs            *vcsCmd
+		repo, rootPath string
+		err            error
+	)
+	if p.build.SrcRoot != "" {
+		// Directory exists.  Look for checkout along path to src.
+		vcs, rootPath, err = vcsForDir(p)
+		repo = "<local>" // should be unused; make distinctive
+	} else {
+		// Analyze the import path to determine the version control system,
+		// repository, and the import path for the root of the repository.
+		vcs, repo, rootPath, err = vcsForImportPath(p.ImportPath)
+	}
 	if err != nil {
 		return err
 	}
-	if p.t == nil {
+
+	if p.build.SrcRoot == "" {
 		// Package not found.  Put in first directory of $GOPATH or else $GOROOT.
-		p.t = build.Path[0] // $GOROOT
-		if len(build.Path) > 1 {
-			p.t = build.Path[1] // first in $GOPATH
+		if list := filepath.SplitList(buildContext.GOPATH); len(list) > 0 {
+			p.build.SrcRoot = filepath.Join(list[0], "src")
+			p.build.PkgRoot = filepath.Join(list[0], "pkg")
+		} else {
+			p.build.SrcRoot = filepath.Join(goroot, "src", "pkg")
+			p.build.PkgRoot = filepath.Join(goroot, "pkg")
 		}
-		p.Dir = filepath.Join(p.t.SrcDir(), p.ImportPath)
 	}
-	root := filepath.Join(p.t.SrcDir(), rootPath)
-
+	root := filepath.Join(p.build.SrcRoot, rootPath)
 	// If we've considered this repository already, don't do it again.
 	if downloadRootCache[root] {
 		return nil
@@ -206,6 +218,14 @@ func downloadPackage(p *Package) error {
 		}
 	}
 
+	if buildN {
+		// Do not show tag sync in -n; it's noise more than anything,
+		// and since we're not running commands, no tag will be found.
+		// But avoid printing nothing.
+		fmt.Fprintf(os.Stderr, "# cd %s; %s sync/update\n", root, vcs.cmd)
+		return nil
+	}
+
 	// Select and sync to appropriate version of the repository.
 	tags, err := vcs.tags(root)
 	if err != nil {
diff --git a/src/cmd/go/help.go b/src/cmd/go/help.go
index 33716ef..60654a2 100644
--- a/src/cmd/go/help.go
+++ b/src/cmd/go/help.go
@@ -4,13 +4,15 @@
 
 package main
 
-var helpImportpath = &Command{
-	UsageLine: "importpath",
-	Short:     "description of import paths",
+var helpPackages = &Command{
+	UsageLine: "packages",
+	Short:     "description of package lists",
 	Long: `
-Many commands apply to a set of packages named by import paths:
+Many commands apply to a set of packages:
 
-	go action [importpath...]
+	go action [packages]
+
+Usually, [packages] is a list of import paths.
 
 An import path that is a rooted path or that begins with
 a . or .. element is interpreted as a file system path and
@@ -35,7 +37,8 @@ each of which can match any string, including the empty string and
 strings containing slashes.  Such a pattern expands to all package
 directories found in the GOPATH trees with names matching the
 patterns.  For example, encoding/... expands to all packages
-in the encoding tree.
+in subdirectories of the encoding tree, while net... expands to
+net and all its subdirectories.
 
 An import path can also name a package to be downloaded from
 a remote repository.  Run 'go help remote' for details.
@@ -46,6 +49,11 @@ unique prefix that belongs to you.  For example, paths used
 internally at Google all begin with 'google', and paths
 denoting remote repositories begin with the path to the code,
 such as 'code.google.com/p/project'.
+
+As a special case, if the package list is a list of .go files from a
+single directory, the command is applied to a single synthesized
+package made up of exactly those files, ignoring any build constraints
+in those files and ignoring any other files in the directory.
 	`,
 }
 
@@ -130,6 +138,9 @@ var helpGopath = &Command{
 	UsageLine: "gopath",
 	Short:     "GOPATH environment variable",
 	Long: `
+The Go path is used to resolve import statements.
+It is implemented by and documented in the go/build package.
+
 The GOPATH environment variable lists places to look for Go code.
 On Unix, the value is a colon-separated string.
 On Windows, the value is a semicolon-separated string.
diff --git a/src/cmd/go/list.go b/src/cmd/go/list.go
index 30baaa7..fa3f5d3 100644
--- a/src/cmd/go/list.go
+++ b/src/cmd/go/list.go
@@ -7,12 +7,13 @@ package main
 import (
 	"bufio"
 	"encoding/json"
+	"io"
 	"os"
 	"text/template"
 )
 
 var cmdList = &Command{
-	UsageLine: "list [-e] [-f format] [-json] [importpath...]",
+	UsageLine: "list [-e] [-f format] [-json] [packages]",
 	Short:     "list packages",
 	Long: `
 List lists the packages named by the import paths, one per line.
@@ -68,7 +69,7 @@ printing.  Erroneous packages will have a non-empty ImportPath and
 a non-nil Error field; other information may or may not be missing
 (zeroed).
 
-For more about import paths, see 'go help importpath'.
+For more about specifying packages, see 'go help packages'.
 	`,
 }
 
@@ -82,8 +83,8 @@ var listJson = cmdList.Flag.Bool("json", false, "")
 var nl = []byte{'\n'}
 
 func runList(cmd *Command, args []string) {
-	out := bufio.NewWriter(os.Stdout)
-	defer out.Flush()
+	out := newCountingWriter(os.Stdout)
+	defer out.w.Flush()
 
 	var do func(*Package)
 	if *listJson {
@@ -97,15 +98,19 @@ func runList(cmd *Command, args []string) {
 			out.Write(nl)
 		}
 	} else {
-		tmpl, err := template.New("main").Parse(*listFmt + "\n")
+		tmpl, err := template.New("main").Parse(*listFmt)
 		if err != nil {
 			fatalf("%s", err)
 		}
 		do = func(p *Package) {
+			out.Reset()
 			if err := tmpl.Execute(out, p); err != nil {
 				out.Flush()
 				fatalf("%s", err)
 			}
+			if out.Count() > 0 {
+				out.w.WriteRune('\n')
+			}
 		}
 	}
 
@@ -118,3 +123,33 @@ func runList(cmd *Command, args []string) {
 		do(pkg)
 	}
 }
+
+// CountingWriter counts its data, so we can avoid appending a newline
+// if there was no actual output.
+type CountingWriter struct {
+	w     *bufio.Writer
+	count int64
+}
+
+func newCountingWriter(w io.Writer) *CountingWriter {
+	return &CountingWriter{
+		w: bufio.NewWriter(w),
+	}
+}
+
+func (cw *CountingWriter) Write(p []byte) (n int, err error) {
+	cw.count += int64(len(p))
+	return cw.w.Write(p)
+}
+
+func (cw *CountingWriter) Flush() {
+	cw.w.Flush()
+}
+
+func (cw *CountingWriter) Reset() {
+	cw.count = 0
+}
+
+func (cw *CountingWriter) Count() int64 {
+	return cw.count
+}
diff --git a/src/cmd/go/main.go b/src/cmd/go/main.go
index b07d720..3a0f7a0 100644
--- a/src/cmd/go/main.go
+++ b/src/cmd/go/main.go
@@ -88,7 +88,7 @@ var commands = []*Command{
 	cmdVet,
 
 	helpGopath,
-	helpImportpath,
+	helpPackages,
 	helpRemote,
 	helpTestflag,
 	helpTestfunc,
@@ -141,7 +141,9 @@ func main() {
 
 var usageTemplate = `Go is a tool for managing Go source code.
 
-Usage: go command [arguments]
+Usage:
+
+	go command [arguments]
 
 The commands are:
 {{range .}}{{if .Runnable}}
@@ -251,7 +253,24 @@ func importPaths(args []string) []string {
 	}
 	var out []string
 	for _, a := range args {
-		if isLocalPath(a) && strings.Contains(a, "...") {
+		// Arguments are supposed to be import paths, but
+		// as a courtesy to Windows developers, rewrite \ to /
+		// in command-line arguments.  Handles .\... and so on.
+		if filepath.Separator == '\\' {
+			a = strings.Replace(a, `\`, `/`, -1)
+		}
+
+		// Put argument in canonical form, but preserve leading ./.
+		if strings.HasPrefix(a, "./") {
+			a = "./" + path.Clean(a)
+			if a == "./." {
+				a = "."
+			}
+		} else {
+			a = path.Clean(a)
+		}
+
+		if build.IsLocalImport(a) && strings.Contains(a, "...") {
 			out = append(out, allPackagesInFS(a)...)
 			continue
 		}
@@ -350,7 +369,6 @@ func allPackages(pattern string) []string {
 	var pkgs []string
 
 	// Commands
-	goroot := build.Path[0].Path
 	cmd := filepath.Join(goroot, "src/cmd") + string(filepath.Separator)
 	filepath.Walk(cmd, func(path string, fi os.FileInfo, err error) error {
 		if err != nil || !fi.IsDir() || path == cmd {
@@ -362,7 +380,7 @@ func allPackages(pattern string) []string {
 			return filepath.SkipDir
 		}
 
-		_, err = build.ScanDir(path)
+		_, err = build.ImportDir(path, 0)
 		if err != nil {
 			return nil
 		}
@@ -378,11 +396,11 @@ func allPackages(pattern string) []string {
 		return nil
 	})
 
-	for _, t := range build.Path {
-		if pattern == "std" && !t.Goroot {
+	for _, src := range buildContext.SrcDirs() {
+		if pattern == "std" && src != gorootSrcPkg {
 			continue
 		}
-		src := t.SrcDir() + string(filepath.Separator)
+		src = filepath.Clean(src) + string(filepath.Separator)
 		filepath.Walk(src, func(path string, fi os.FileInfo, err error) error {
 			if err != nil || !fi.IsDir() || path == src {
 				return nil
@@ -403,21 +421,13 @@ func allPackages(pattern string) []string {
 			}
 			have[name] = true
 
-			_, err = build.ScanDir(path)
+			_, err = build.ImportDir(path, 0)
 			if err != nil && strings.Contains(err.Error(), "no Go source files") {
 				return nil
 			}
-
 			if match(name) {
 				pkgs = append(pkgs, name)
 			}
-
-			// Avoid go/build test data.
-			// TODO: Move it into a testdata directory.
-			if path == filepath.Join(build.Path[0].SrcDir(), "go/build") {
-				return filepath.SkipDir
-			}
-
 			return nil
 		})
 	}
@@ -465,7 +475,7 @@ func allPackagesInFS(pattern string) []string {
 		if !match(name) {
 			return nil
 		}
-		if _, err = build.ScanDir(path); err != nil {
+		if _, err = build.ImportDir(path, 0); err != nil {
 			return nil
 		}
 		pkgs = append(pkgs, name)
@@ -494,10 +504,3 @@ func stringList(args ...interface{}) []string {
 	}
 	return x
 }
-
-// isLocalPath returns true if arg is an import path denoting
-// a local file system directory.  That is, it returns true if the
-// path begins with ./ or ../ .
-func isLocalPath(arg string) bool {
-	return arg == "." || arg == ".." || strings.HasPrefix(arg, "./") || strings.HasPrefix(arg, "../")
-}
diff --git a/src/cmd/go/pkg.go b/src/cmd/go/pkg.go
index 718b9fe..3763000 100644
--- a/src/cmd/go/pkg.go
+++ b/src/cmd/go/pkg.go
@@ -6,11 +6,13 @@ package main
 
 import (
 	"bytes"
+	"errors"
 	"fmt"
 	"go/build"
-	"go/doc"
 	"go/scanner"
+	"go/token"
 	"os"
+	pathpkg "path"
 	"path/filepath"
 	"sort"
 	"strings"
@@ -22,42 +24,79 @@ type Package struct {
 	// Note: These fields are part of the go command's public API.
 	// See list.go.  It is okay to add fields, but not to change or
 	// remove existing ones.  Keep in sync with list.go
-	ImportPath string        // import path of package in dir
+	Dir        string        `json:",omitempty"` // directory containing package sources
+	ImportPath string        `json:",omitempty"` // import path of package in dir
 	Name       string        `json:",omitempty"` // package name
 	Doc        string        `json:",omitempty"` // package documentation string
-	Dir        string        `json:",omitempty"` // directory containing package sources
 	Target     string        `json:",omitempty"` // install path
-	Version    string        `json:",omitempty"` // version of installed package (TODO)
+	Goroot     bool          `json:",omitempty"` // is this package found in the Go root?
 	Standard   bool          `json:",omitempty"` // is this package part of the standard Go library?
 	Stale      bool          `json:",omitempty"` // would 'go install' do anything for this package?
 	Incomplete bool          `json:",omitempty"` // was there an error loading this package or dependencies?
 	Error      *PackageError `json:",omitempty"` // error loading this package (not dependencies)
 
+	Root string `json:",omitempty"` // root dir of tree this package belongs to
+
 	// Source files
-	GoFiles      []string `json:",omitempty"` // .go source files (excluding CgoFiles, TestGoFiles and XTestGoFiles)
-	TestGoFiles  []string `json:",omitempty"` // _test.go source files internal to the package they are testing
-	XTestGoFiles []string `json:",omitempty"` //_test.go source files external to the package they are testing
-	CFiles       []string `json:",omitempty"` // .c source files
-	HFiles       []string `json:",omitempty"` // .h source files
-	SFiles       []string `json:",omitempty"` // .s source files
-	CgoFiles     []string `json:",omitempty"` // .go sources files that import "C"
+	GoFiles  []string `json:",omitempty"` // .go source files (excluding CgoFiles, TestGoFiles XTestGoFiles)
+	CgoFiles []string `json:",omitempty"` // .go sources files that import "C"
+	CFiles   []string `json:",omitempty"` // .c source files
+	HFiles   []string `json:",omitempty"` // .h source files
+	SFiles   []string `json:",omitempty"` // .s source files
+
+	// Cgo directives
 	CgoCFLAGS    []string `json:",omitempty"` // cgo: flags for C compiler
 	CgoLDFLAGS   []string `json:",omitempty"` // cgo: flags for linker
+	CgoPkgConfig []string `json:",omitempty"` // cgo: pkg-config names
 
 	// Dependency information
 	Imports    []string        `json:",omitempty"` // import paths used by this package
 	Deps       []string        `json:",omitempty"` // all (recursively) imported dependencies
 	DepsErrors []*PackageError `json:",omitempty"` // errors loading dependencies
 
+	// Test information
+	TestGoFiles  []string `json:",omitempty"` // _test.go files in package
+	TestImports  []string `json:",omitempty"` // imports from TestGoFiles
+	XTestGoFiles []string `json:",omitempty"` // _test.go files outside package
+	XTestImports []string `json:",omitempty"` // imports from XTestGoFiles
+
 	// Unexported fields are not part of the public API.
-	t       *build.Tree
-	pkgdir  string
-	info    *build.DirInfo
-	imports []*Package
-	deps    []*Package
-	gofiles []string // GoFiles+CgoFiles+TestGoFiles+XTestGoFiles files, absolute paths
-	target  string   // installed file for this package (may be executable)
-	fake    bool     // synthesized package
+	build       *build.Package
+	pkgdir      string // overrides build.PkgDir
+	imports     []*Package
+	deps        []*Package
+	gofiles     []string // GoFiles+CgoFiles+TestGoFiles+XTestGoFiles files, absolute paths
+	target      string   // installed file for this package (may be executable)
+	fake        bool     // synthesized package
+	forceBuild  bool     // this package must be rebuilt
+	local       bool     // imported via local path (./ or ../)
+	localPrefix string   // interpret ./ and ../ imports relative to this prefix
+}
+
+func (p *Package) copyBuild(pp *build.Package) {
+	p.build = pp
+
+	p.Dir = pp.Dir
+	p.ImportPath = pp.ImportPath
+	p.Name = pp.Name
+	p.Doc = pp.Doc
+	p.Root = pp.Root
+	// TODO? Target
+	p.Goroot = pp.Goroot
+	p.Standard = p.Goroot && p.ImportPath != "" && !strings.Contains(p.ImportPath, ".")
+	p.GoFiles = pp.GoFiles
+	p.CgoFiles = pp.CgoFiles
+	p.CFiles = pp.CFiles
+	p.HFiles = pp.HFiles
+	p.SFiles = pp.SFiles
+	p.CgoCFLAGS = pp.CgoCFLAGS
+	p.CgoLDFLAGS = pp.CgoLDFLAGS
+	p.CgoPkgConfig = pp.CgoPkgConfig
+	p.Imports = pp.Imports
+	p.TestGoFiles = pp.TestGoFiles
+	p.TestImports = pp.TestImports
+	p.XTestGoFiles = pp.XTestGoFiles
+	p.XTestImports = pp.XTestImports
 }
 
 // A PackageError describes an error loading information about a package.
@@ -69,9 +108,11 @@ type PackageError struct {
 
 func (p *PackageError) Error() string {
 	if p.Pos != "" {
-		return strings.Join(p.ImportStack, "\n\timports ") + ": " + p.Pos + ": " + p.Err
+		// Omit import stack.  The full path to the file where the error
+		// is the most important thing.
+		return p.Pos + ": " + p.Err
 	}
-	return strings.Join(p.ImportStack, "\n\timports ") + ": " + p.Err
+	return "package " + strings.Join(p.ImportStack, "\n\timports ") + ": " + p.Err
 }
 
 // An importStack is a stack of import paths.
@@ -122,86 +163,61 @@ func reloadPackage(arg string, stk *importStack) *Package {
 	return loadPackage(arg, stk)
 }
 
-// loadPackage scans directory named by arg,
-// which is either an import path or a file system path
-// (if the latter, must be rooted or begin with . or ..),
-// and returns a *Package describing the package
-// found in that directory.
-func loadPackage(arg string, stk *importStack) *Package {
-	stk.push(arg)
-	defer stk.pop()
+// dirToImportPath returns the pseudo-import path we use for a package
+// outside the Go path.  It begins with _/ and then contains the full path
+// to the directory.  If the package lives in c:\home\gopher\my\pkg then
+// the pseudo-import path is _/c_/home/gopher/my/pkg.
+// Using a pseudo-import path like this makes the ./ imports no longer
+// a special case, so that all the code to deal with ordinary imports works
+// automatically.
+func dirToImportPath(dir string) string {
+	return pathpkg.Join("_", strings.Replace(filepath.ToSlash(dir), ":", "_", -1))
+}
 
-	// Check package cache.
-	if p := packageCache[arg]; p != nil {
-		return reusePackage(p, stk)
-	}
+// loadImport scans the directory named by path, which must be an import path,
+// but possibly a local import path (an absolute file system path or one beginning
+// with ./ or ../).  A local relative path is interpreted relative to srcDir.
+// It returns a *Package describing the package found in that directory.
+func loadImport(path string, srcDir string, stk *importStack, importPos []token.Position) *Package {
+	stk.push(path)
+	defer stk.pop()
 
-	// Find basic information about package path.
-	isCmd := false
-	t, importPath, err := build.FindTree(arg)
-	dir := ""
-	// Maybe it is a standard command.
-	if err != nil && strings.HasPrefix(arg, "cmd/") {
-		goroot := build.Path[0]
-		p := filepath.Join(goroot.Path, "src", arg)
-		if st, err1 := os.Stat(p); err1 == nil && st.IsDir() {
-			t = goroot
-			importPath = arg
-			dir = p
-			err = nil
-			isCmd = true
-		}
+	// Determine canonical identifier for this package.
+	// For a local import the identifier is the pseudo-import path
+	// we create from the full directory to the package.
+	// Otherwise it is the usual import path.
+	importPath := path
+	isLocal := build.IsLocalImport(path)
+	if isLocal {
+		importPath = dirToImportPath(filepath.Join(srcDir, path))
 	}
-	// Maybe it is a path to a standard command.
-	if err != nil && (filepath.IsAbs(arg) || isLocalPath(arg)) {
-		arg, _ := filepath.Abs(arg)
-		goroot := build.Path[0]
-		cmd := filepath.Join(goroot.Path, "src", "cmd") + string(filepath.Separator)
-		if st, err1 := os.Stat(arg); err1 == nil && st.IsDir() && strings.HasPrefix(arg, cmd) {
-			t = goroot
-			importPath = filepath.FromSlash(arg[len(cmd):])
-			dir = arg
-			err = nil
-			isCmd = true
-		}
-	}
-	if err != nil {
-		p := &Package{
-			ImportPath: arg,
-			Error: &PackageError{
-				ImportStack: stk.copy(),
-				Err:         err.Error(),
-			},
-			Incomplete: true,
-		}
-		packageCache[arg] = p
-		return p
+	if p := packageCache[importPath]; p != nil {
+		return reusePackage(p, stk)
 	}
 
-	if dir == "" {
-		dir = filepath.Join(t.SrcDir(), filepath.FromSlash(importPath))
-	}
+	p := new(Package)
+	p.local = isLocal
+	p.ImportPath = importPath
+	packageCache[importPath] = p
 
-	// Maybe we know the package by its directory.
-	p := packageCache[dir]
-	if p != nil {
-		packageCache[importPath] = p
-		p = reusePackage(p, stk)
-	} else {
-		p = scanPackage(&buildContext, t, arg, importPath, dir, stk, false)
+	// Load package.
+	// Import always returns bp != nil, even if an error occurs,
+	// in order to return partial information.
+	bp, err := buildContext.Import(path, srcDir, build.AllowBinary)
+	bp.ImportPath = importPath
+	p.load(stk, bp, err)
+	if p.Error != nil && len(importPos) > 0 {
+		pos := importPos[0]
+		pos.Filename = shortPath(pos.Filename)
+		p.Error.Pos = pos.String()
 	}
 
-	// If we loaded the files from the Go root's cmd/ tree,
-	// it must be a command (package main).
-	if isCmd && p.Error == nil && p.Name != "main" {
-		p.Error = &PackageError{
-			ImportStack: stk.copy(),
-			Err:         fmt.Sprintf("expected package main in %q; found package %s", dir, p.Name),
-		}
-	}
 	return p
 }
 
+// reusePackage reuses package p to satisfy the import at the top
+// of the import stack stk.  If this use causes an import loop,
+// reusePackage updates p's error information to record the loop.
 func reusePackage(p *Package, stk *importStack) *Package {
 	// We use p.imports==nil to detect a package that
 	// is in the midst of its own loadPackage call
@@ -222,7 +238,7 @@ func reusePackage(p *Package, stk *importStack) *Package {
 }
 
 // isGoTool is the list of directories for Go programs that are installed in
-// $GOROOT/bin/tool.
+// $GOROOT/pkg/tool.
 var isGoTool = map[string]bool{
 	"cmd/api":      true,
 	"cmd/cgo":      true,
@@ -233,126 +249,73 @@ var isGoTool = map[string]bool{
 	"exp/ebnflint": true,
 }
 
-func scanPackage(ctxt *build.Context, t *build.Tree, arg, importPath, dir string, stk *importStack, useAllFiles bool) *Package {
-	// Read the files in the directory to learn the structure
-	// of the package.
-	p := &Package{
-		ImportPath: importPath,
-		Dir:        dir,
-		Standard:   t.Goroot && !strings.Contains(importPath, "."),
-		t:          t,
+// expandScanner expands a scanner.List error into all the errors in the list.
+// The default Error method only shows the first error.
+func expandScanner(err error) error {
+	// Look for parser errors.
+	if err, ok := err.(scanner.ErrorList); ok {
+		// Prepare error with \n before each message.
+		// When printed in something like context: %v
+		// this will put the leading file positions each on
+		// its own line.  It will also show all the errors
+		// instead of just the first, as err.Error does.
+		var buf bytes.Buffer
+		for _, e := range err {
+			e.Pos.Filename = shortPath(e.Pos.Filename)
+			buf.WriteString("\n")
+			buf.WriteString(e.Error())
+		}
+		return errors.New(buf.String())
 	}
-	packageCache[dir] = p
-	packageCache[importPath] = p
+	return err
+}
+
+// load populates p using information from bp, err, which should
+// be the result of calling build.Context.Import.
+func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package {
+	p.copyBuild(bp)
+
+	// The localPrefix is the path we interpret ./ imports relative to.
+	// Now that we've fixed the import path, it's just the import path.
+	// Synthesized main packages sometimes override this.
+	p.localPrefix = p.ImportPath
 
-	ctxt.UseAllFiles = useAllFiles
-	info, err := ctxt.ScanDir(dir)
-	useAllFiles = false // flag does not apply to dependencies
 	if err != nil {
+		p.Incomplete = true
+		err = expandScanner(err)
 		p.Error = &PackageError{
 			ImportStack: stk.copy(),
 			Err:         err.Error(),
 		}
-		// Look for parser errors.
-		if err, ok := err.(scanner.ErrorList); ok {
-			// Prepare error with \n before each message.
-			// When printed in something like context: %v
-			// this will put the leading file positions each on
-			// its own line.  It will also show all the errors
-			// instead of just the first, as err.Error does.
-			var buf bytes.Buffer
-			for _, e := range err {
-				buf.WriteString("\n")
-				buf.WriteString(e.Error())
-			}
-			p.Error.Err = buf.String()
-		}
-		p.Incomplete = true
 		return p
 	}
 
-	p.info = info
-	p.Name = info.Package
-	p.Doc = doc.Synopsis(info.PackageComment.Text())
-	p.Imports = info.Imports
-	p.GoFiles = info.GoFiles
-	p.TestGoFiles = info.TestGoFiles
-	p.XTestGoFiles = info.XTestGoFiles
-	p.CFiles = info.CFiles
-	p.HFiles = info.HFiles
-	p.SFiles = info.SFiles
-	p.CgoFiles = info.CgoFiles
-	p.CgoCFLAGS = info.CgoCFLAGS
-	p.CgoLDFLAGS = info.CgoLDFLAGS
-
-	if info.Package == "main" {
-		_, elem := filepath.Split(importPath)
-		full := ctxt.GOOS + "_" + ctxt.GOARCH + "/" + elem
-		if t.Goroot && isGoTool[p.ImportPath] {
-			p.target = filepath.Join(t.Path, "pkg/tool", full)
-		} else {
-			if ctxt.GOOS != toolGOOS || ctxt.GOARCH != toolGOARCH {
-				// Install cross-compiled binaries to subdirectories of bin.
-				elem = full
-			}
-			p.target = filepath.Join(t.BinDir(), elem)
+	if p.Name == "main" {
+		_, elem := filepath.Split(p.Dir)
+		full := buildContext.GOOS + "_" + buildContext.GOARCH + "/" + elem
+		if buildContext.GOOS != toolGOOS || buildContext.GOARCH != toolGOARCH {
+			// Install cross-compiled binaries to subdirectories of bin.
+			elem = full
 		}
-		if ctxt.GOOS == "windows" {
+		p.target = filepath.Join(p.build.BinDir, elem)
+		if p.Goroot && isGoTool[p.ImportPath] {
+			p.target = filepath.Join(gorootPkg, "tool", full)
+		}
+		if buildContext.GOOS == "windows" {
 			p.target += ".exe"
 		}
+	} else if p.local {
+		// Local import turned into absolute path.
+		// No permanent install target.
+		p.target = ""
 	} else {
-		dir := t.PkgDir()
-		// For gccgo, rewrite p.target with the expected library name.
-		if _, ok := buildToolchain.(gccgoToolchain); ok {
-			dir = filepath.Join(filepath.Dir(dir), "gccgo", filepath.Base(dir))
-		}
-		p.target = buildToolchain.pkgpath(dir, p)
-	}
-
-	var built time.Time
-	if fi, err := os.Stat(p.target); err == nil {
-		built = fi.ModTime()
-	}
-
-	// Build list of full paths to all Go files in the package,
-	// for use by commands like go fmt.
-	for _, f := range info.GoFiles {
-		p.gofiles = append(p.gofiles, filepath.Join(dir, f))
-	}
-	for _, f := range info.CgoFiles {
-		p.gofiles = append(p.gofiles, filepath.Join(dir, f))
-	}
-	for _, f := range info.TestGoFiles {
-		p.gofiles = append(p.gofiles, filepath.Join(dir, f))
-	}
-	for _, f := range info.XTestGoFiles {
-		p.gofiles = append(p.gofiles, filepath.Join(dir, f))
-	}
-
-	sort.Strings(p.gofiles)
-
-	srcss := [][]string{
-		p.GoFiles,
-		p.CFiles,
-		p.HFiles,
-		p.SFiles,
-		p.CgoFiles,
-	}
-Stale:
-	for _, srcs := range srcss {
-		for _, src := range srcs {
-			if fi, err := os.Stat(filepath.Join(p.Dir, src)); err != nil || fi.ModTime().After(built) {
-				//println("STALE", p.ImportPath, "needs", src, err)
-				p.Stale = true
-				break Stale
-			}
-		}
+		p.target = p.build.PkgObj
 	}
 
 	importPaths := p.Imports
 	// Packages that use cgo import runtime/cgo implicitly,
 	// except runtime/cgo itself.
-	if len(info.CgoFiles) > 0 && (!p.Standard || p.ImportPath != "runtime/cgo") {
+	if len(p.CgoFiles) > 0 && (!p.Standard || p.ImportPath != "runtime/cgo") {
 		importPaths = append(importPaths, "runtime/cgo")
 	}
 	// Everything depends on runtime, except runtime and unsafe.
@@ -360,45 +323,34 @@ Stale:
 		importPaths = append(importPaths, "runtime")
 	}
 
-	// Record package under both import path and full directory name.
-	packageCache[dir] = p
-	packageCache[importPath] = p
+	// Build list of full paths to all Go files in the package,
+	// for use by commands like go fmt.
+	p.gofiles = stringList(p.GoFiles, p.CgoFiles, p.TestGoFiles, p.XTestGoFiles)
+	for i := range p.gofiles {
+		p.gofiles[i] = filepath.Join(p.Dir, p.gofiles[i])
+	}
+	sort.Strings(p.gofiles)
 
 	// Build list of imported packages and full dependency list.
 	imports := make([]*Package, 0, len(p.Imports))
 	deps := make(map[string]bool)
-	for _, path := range importPaths {
+	for i, path := range importPaths {
 		if path == "C" {
 			continue
 		}
-		deps[path] = true
-		p1 := loadPackage(path, stk)
-		if p1.Error != nil {
-			if info.ImportPos != nil && len(info.ImportPos[path]) > 0 {
-				pos := info.ImportPos[path][0]
-				p1.Error.Pos = pos.String()
-			}
+		p1 := loadImport(path, p.Dir, stk, p.build.ImportPos[path])
+		if p1.local {
+			path = p1.ImportPath
+			importPaths[i] = path
 		}
+		deps[path] = true
 		imports = append(imports, p1)
 		for _, dep := range p1.Deps {
 			deps[dep] = true
 		}
-		if p1.Stale {
-			p.Stale = true
-		}
 		if p1.Incomplete {
 			p.Incomplete = true
 		}
-		// p1.target can be empty only if p1 is not a real package,
-		// such as package unsafe or the temporary packages
-		// created during go test.
-		if !p.Stale && p1.target != "" {
-			if fi, err := os.Stat(p1.target); err != nil || fi.ModTime().After(built) {
-				//println("STALE", p.ImportPath, "needs", p1.target, err)
-				//println("BUILT", built.String(), "VS", fi.ModTime().String())
-				p.Stale = true
-			}
-		}
 	}
 	p.imports = imports
 
@@ -418,17 +370,193 @@ Stale:
 		}
 	}
 
-	// unsafe is a fake package and is never out-of-date.
+	// unsafe is a fake package.
 	if p.Standard && p.ImportPath == "unsafe" {
-		p.Stale = false
 		p.target = ""
 	}
 
 	p.Target = p.target
-
 	return p
 }
 
+// packageList returns the list of packages in the dag rooted at roots
+// as visited in a depth-first post-order traversal.
+func packageList(roots []*Package) []*Package {
+	seen := map[*Package]bool{}
+	all := []*Package{}
+	var walk func(*Package)
+	walk = func(p *Package) {
+		if seen[p] {
+			return
+		}
+		seen[p] = true
+		for _, p1 := range p.imports {
+			walk(p1)
+		}
+		all = append(all, p)
+	}
+	for _, root := range roots {
+		walk(root)
+	}
+	return all
+}
+
+// computeStale computes the Stale flag in the package dag that starts
+// at the named pkgs (command-line arguments).
+func computeStale(pkgs ...*Package) {
+	topRoot := map[string]bool{}
+	for _, p := range pkgs {
+		topRoot[p.Root] = true
+	}
+
+	for _, p := range packageList(pkgs) {
+		p.Stale = isStale(p, topRoot)
+	}
+}
+
+// isStale reports whether package p needs to be rebuilt.
+func isStale(p *Package, topRoot map[string]bool) bool {
+	if p.Standard && p.ImportPath == "unsafe" {
+		// fake, builtin package
+		return false
+	}
+	if p.Error != nil {
+		return true
+	}
+
+	// A package without Go sources means we only found
+	// the installed .a file.  Since we don't know how to rebuild
+	// it, it can't be stale, even if -a is set.  This enables binary-only
+	// distributions of Go packages, although such binaries are
+	// only useful with the specific version of the toolchain that
+	// created them.
+	if len(p.gofiles) == 0 {
+		return false
+	}
+
+	if buildA || p.target == "" || p.Stale {
+		return true
+	}
+
+	// Package is stale if completely unbuilt.
+	var built time.Time
+	if fi, err := os.Stat(p.target); err == nil {
+		built = fi.ModTime()
+	}
+	if built.IsZero() {
+		return true
+	}
+
+	olderThan := func(file string) bool {
+		fi, err := os.Stat(file)
+		return err != nil || fi.ModTime().After(built)
+	}
+
+	// Package is stale if a dependency is, or if a dependency is newer.
+	for _, p1 := range p.deps {
+		if p1.Stale || p1.target != "" && olderThan(p1.target) {
+			return true
+		}
+	}
+
+	// As a courtesy to developers installing new versions of the compiler
+	// frequently, define that packages are stale if they are
+	// older than the compiler, and commands if they are older than
+	// the linker.  This heuristic will not work if the binaries are back-dated,
+	// as some binary distributions may do, but it does handle a very
+	// common case.  See issue 3036.
+	if olderThan(buildToolchain.compiler()) {
+		return true
+	}
+	if p.build.IsCommand() && olderThan(buildToolchain.linker()) {
+		return true
+	}
+
+	// Have installed copy, probably built using current compilers,
+	// and built after its imported packages.  The only reason now
+	// that we'd have to rebuild it is if the sources were newer than
+	// the package.   If a package p is not in the same tree as any
+	// package named on the command-line, assume it is up-to-date
+	// no matter what the modification times on the source files indicate.
+	// This avoids rebuilding $GOROOT packages when people are
+	// working outside the Go root, and it effectively makes each tree
+	// listed in $GOPATH a separate compilation world.
+	// See issue 3149.
+	if p.Root != "" && !topRoot[p.Root] {
+		return false
+	}
+
+	srcs := stringList(p.GoFiles, p.CFiles, p.HFiles, p.SFiles, p.CgoFiles)
+	for _, src := range srcs {
+		if olderThan(filepath.Join(p.Dir, src)) {
+			return true
+		}
+	}
+
+	return false
+}
+
+var cwd, _ = os.Getwd()
+
+var cmdCache = map[string]*Package{}
+
+// loadPackage is like loadImport but is used for command-line arguments,
+// not for paths found in import statements.  In addition to ordinary import paths,
+// loadPackage accepts pseudo-paths beginning with cmd/ to denote commands
+// in the Go command directory, as well as paths to those directories.
+func loadPackage(arg string, stk *importStack) *Package {
+	if build.IsLocalImport(arg) {
+		dir := arg
+		if !filepath.IsAbs(dir) {
+			if abs, err := filepath.Abs(dir); err == nil {
+				// interpret relative to current directory
+				dir = abs
+			}
+		}
+		if sub, ok := hasSubdir(gorootSrc, dir); ok && strings.HasPrefix(sub, "cmd/") && !strings.Contains(sub[4:], "/") {
+			arg = sub
+		}
+	}
+	if strings.HasPrefix(arg, "cmd/") && !strings.Contains(arg[4:], "/") {
+		if p := cmdCache[arg]; p != nil {
+			return p
+		}
+		stk.push(arg)
+		defer stk.pop()
+		bp, err := build.ImportDir(filepath.Join(gorootSrc, arg), 0)
+		bp.ImportPath = arg
+		bp.Goroot = true
+		bp.BinDir = gobin
+		bp.Root = goroot
+		bp.SrcRoot = gorootSrc
+		p := new(Package)
+		cmdCache[arg] = p
+		p.load(stk, bp, err)
+		if p.Error == nil && p.Name != "main" {
+			p.Error = &PackageError{
+				ImportStack: stk.copy(),
+				Err:         fmt.Sprintf("expected package main but found package %s in %s", p.Name, p.Dir),
+			}
+		}
+		return p
+	}
+
+	// Wasn't a command; must be a package.
+	// If it is a local import path but names a standard package,
+	// we treat it as if the user specified the standard package.
+	// This lets you run go test ./ioutil in package io and be
+	// referring to io/ioutil rather than a hypothetical import of
+	// "./ioutil".
+	if build.IsLocalImport(arg) {
+		bp, _ := build.ImportDir(filepath.Join(cwd, arg), build.FindOnly)
+		if bp.ImportPath != "" && bp.ImportPath != "." {
+			arg = bp.ImportPath
+		}
+	}
+
+	return loadImport(arg, cwd, stk, nil)
+}
+
 // packages returns the packages named by the
 // command line arguments 'args'.  If a named package
 // cannot be loaded at all (for example, if the directory does not exist),
@@ -438,11 +566,8 @@ Stale:
 // package is still returned, with p.Incomplete = true
 // and details in p.DepsErrors.
 func packages(args []string) []*Package {
-	args = importPaths(args)
 	var pkgs []*Package
-	var stk importStack
-	for _, arg := range args {
-		pkg := loadPackage(arg, &stk)
+	for _, pkg := range packagesAndErrors(args) {
 		if pkg.Error != nil {
 			errorf("can't load package: %s", pkg.Error)
 			continue
@@ -452,17 +577,24 @@ func packages(args []string) []*Package {
 	return pkgs
 }
 
-// packagesAndErrors is like 'packages' but returns a 
+// packagesAndErrors is like 'packages' but returns a
 // *Package for every argument, even the ones that
 // cannot be loaded at all.
 // The packages that fail to load will have p.Error != nil.
 func packagesAndErrors(args []string) []*Package {
+	if len(args) > 0 && strings.HasSuffix(args[0], ".go") {
+		return []*Package{goFilesPackage(args)}
+	}
+
 	args = importPaths(args)
 	var pkgs []*Package
 	var stk importStack
 	for _, arg := range args {
 		pkgs = append(pkgs, loadPackage(arg, &stk))
 	}
+
+	computeStale(pkgs...)
+
 	return pkgs
 }
 
@@ -490,3 +622,26 @@ func packagesForBuild(args []string) []*Package {
 	exitIfErrors()
 	return pkgs
 }
+
+// hasSubdir reports whether dir is a subdirectory of
+// (possibly multiple levels below) root.
+// If so, it sets rel to the path fragment that must be
+// appended to root to reach dir.
+func hasSubdir(root, dir string) (rel string, ok bool) {
+	if p, err := filepath.EvalSymlinks(root); err == nil {
+		root = p
+	}
+	if p, err := filepath.EvalSymlinks(dir); err == nil {
+		dir = p
+	}
+	const sep = string(filepath.Separator)
+	root = filepath.Clean(root)
+	if !strings.HasSuffix(root, sep) {
+		root += sep
+	}
+	dir = filepath.Clean(dir)
+	if !strings.HasPrefix(dir, root) {
+		return "", false
+	}
+	return filepath.ToSlash(dir[len(root):]), true
+}
diff --git a/src/cmd/go/run.go b/src/cmd/go/run.go
index f317620..2976d5c 100644
--- a/src/cmd/go/run.go
+++ b/src/cmd/go/run.go
@@ -12,14 +12,12 @@ import (
 )
 
 var cmdRun = &Command{
-	UsageLine: "run [-a] [-n] [-x] gofiles... [arguments...]",
+	UsageLine: "run [build flags] gofiles... [arguments...]",
 	Short:     "compile and run Go program",
 	Long: `
 Run compiles and runs the main package comprising the named Go source files.
 
-The -a flag forces reinstallation of packages that are already up-to-date.
-The -n flag prints the commands but does not run them.
-The -x flag prints the commands.
+For more about build flags, see 'go help build'.
 
 See also: go build.
 	`,
@@ -46,7 +44,13 @@ func runRun(cmd *Command, args []string) {
 		i++
 	}
 	files, cmdArgs := args[:i], args[i:]
-	p := goFilesPackage(files, "")
+	p := goFilesPackage(files)
+	if p.Error != nil {
+		fatalf("%s", p.Error)
+	}
+	if p.Name != "main" {
+		fatalf("cannot run non-main package")
+	}
 	p.target = "" // must build - not up to date
 	a1 := b.action(modeBuild, modeBuild, p)
 	a := &action{f: (*builder).runProgram, args: cmdArgs, deps: []*action{a1}}
diff --git a/src/cmd/go/test.bash b/src/cmd/go/test.bash
new file mode 100755
index 0000000..daca144
--- /dev/null
+++ b/src/cmd/go/test.bash
@@ -0,0 +1,75 @@
+#!/bin/bash
+# Copyright 2012 The Go Authors.  All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+set -e
+go build -o testgo
+
+ok=true
+
+# Test that error messages have file:line information
+# at beginning of line.
+for i in testdata/errmsg/*.go
+do
+	# TODO: |cat should not be necessary here but is.
+	./testgo test $i 2>&1 | cat >err.out || true
+	if ! grep -q "^$i:" err.out; then
+		echo "$i: missing file:line in error message"
+		cat err.out
+		ok=false
+	fi
+done
+
+# Test local (./) imports.
+./testgo build -o hello testdata/local/easy.go
+./hello >hello.out
+if ! grep -q '^easysub\.Hello' hello.out; then
+	echo "testdata/local/easy.go did not generate expected output"
+	cat hello.out
+	ok=false
+fi
+
+./testgo build -o hello testdata/local/easysub/main.go
+./hello >hello.out
+if ! grep -q '^easysub\.Hello' hello.out; then
+	echo "testdata/local/easysub/main.go did not generate expected output"
+	cat hello.out
+	ok=false
+fi
+
+./testgo build -o hello testdata/local/hard.go
+./hello >hello.out
+if ! grep -q '^sub\.Hello' hello.out || ! grep -q '^subsub\.Hello' hello.out ; then
+	echo "testdata/local/hard.go did not generate expected output"
+	cat hello.out
+	ok=false
+fi
+
+rm -f err.out hello.out hello
+
+# Test that go install x.go fails.
+if ./testgo install testdata/local/easy.go >/dev/null 2>&1; then
+	echo "go install testdata/local/easy.go succeeded"
+	ok=false
+fi
+
+# Test tests with relative imports.
+if ! ./testgo test ./testdata/testimport; then
+	echo "go test ./testdata/testimport failed"
+	ok=false
+fi
+
+# Test tests with relative imports in packages synthesized
+# from Go files named on the command line.
+if ! ./testgo test ./testdata/testimport/*.go; then
+	echo "go test ./testdata/testimport/*.go failed"
+	ok=false
+fi
+
+if $ok; then
+	echo PASS
+else
+	echo FAIL
+	exit 1
+fi
diff --git a/src/cmd/go/test.go b/src/cmd/go/test.go
index 57cdc76..6ca49d1 100644
--- a/src/cmd/go/test.go
+++ b/src/cmd/go/test.go
@@ -32,7 +32,7 @@ func init() {
 
 var cmdTest = &Command{
 	CustomFlags: true,
-	UsageLine:   "test [-c] [-i] [-p n] [-x] [importpath...] [flags for test binary]",
+	UsageLine:   "test [-c] [-i] [build flags] [packages] [flags for test binary]",
 	Short:       "test packages",
 	Long: `
 'Go test' automates testing the packages named by the import paths.
@@ -55,7 +55,7 @@ with source in the current directory, including tests, and runs the tests.
 The package is built in a temporary directory so it does not interfere with the
 non-test installation.
 
-The flags handled by 'go test' itself are:
+In addition to the build flags, the flags handled by 'go test' itself are:
 
 	-c  Compile the test binary to pkg.test but do not run it.
 
@@ -63,19 +63,14 @@ The flags handled by 'go test' itself are:
 	    Install packages that are dependencies of the test.
 	    Do not run the test.
 
-	-p n
-	    Compile and test up to n packages in parallel.
-	    The default value is the number of CPUs available.
-
-	-x  Print each subcommand go test executes.
-
 The test binary also accepts flags that control execution of the test; these
 flags are also accessible by 'go test'.  See 'go help testflag' for details.
 
-See 'go help importpath' for more about import paths.
+For more about build flags, see 'go help build'.
+For more about specifying packages, see 'go help packages'.
 
 See also: go build, go vet.
-	`,
+`,
 }
 
 var helpTestflag = &Command{
@@ -92,7 +87,8 @@ directory containing the package sources, has its own flags:
 	    Verbose output: log all tests as they are run.
 
 	-test.run pattern
-	    Run only those tests matching the regular expression.
+	    Run only those tests and examples matching the regular
+	    expression.
 
 	-test.bench pattern
 	    Run benchmarks matching the regular expression.
@@ -132,7 +128,7 @@ directory containing the package sources, has its own flags:
 		The default is 1 second.
 
 	-test.cpu 1,2,4
-	    Specify a list of GOMAXPROCS values for which the tests or 
+	    Specify a list of GOMAXPROCS values for which the tests or
 	    benchmarks should be executed.  The default is the current value
 	    of GOMAXPROCS.
 
@@ -145,7 +141,7 @@ here are passed through unaltered.  For instance, the command
 will compile the test binary and then run it as
 
 	pkg.test -test.v -test.cpuprofile=prof.out -dir=testdata -update
-	`,
+`,
 }
 
 var helpTestfunc = &Command{
@@ -166,8 +162,10 @@ A benchmark function is one named BenchmarkXXX and should have the signature,
 
 An example function is similar to a test function but, instead of using *testing.T
 to report success or failure, prints output to os.Stdout and os.Stderr.
-That output is compared against the function's doc comment.
-An example without a doc comment is compiled but not executed.
+That output is compared against the function's "Output:" comment, which
+must be the last comment in the function body (see example below). An
+example with no such comment, or with no text after "Output:" is compiled
+but not executed.
 
 Godoc displays the body of ExampleXXX to demonstrate the use
 of the function, constant, or variable XXX.  An example of a method M with
@@ -178,8 +176,9 @@ where xxx is a suffix not beginning with an upper case letter.
 Here is an example of an example:
 
 	func ExamplePrintln() {
-		Println("The output of this example function.")
-		// Output: The output of this example function.
+		Println("The output of\nthis example.")
+		// Output: The output of
+		// this example.
 	}
 
 The entire test file is presented as the example when it contains a single
@@ -187,7 +186,7 @@ example function, at least one other function, type, variable, or constant
 declaration, and no test or benchmark functions.
 
 See the documentation of the testing package for more information.
-		`,
+`,
 }
 
 var (
@@ -260,10 +259,10 @@ func runTest(cmd *Command, args []string) {
 		}
 		for _, p := range pkgs {
 			// Dependencies for each test.
-			for _, path := range p.info.Imports {
+			for _, path := range p.Imports {
 				deps[path] = true
 			}
-			for _, path := range p.info.TestImports {
+			for _, path := range p.TestImports {
 				deps[path] = true
 			}
 		}
@@ -290,7 +289,10 @@ func runTest(cmd *Command, args []string) {
 			a.deps = append(a.deps, b.action(modeInstall, modeInstall, p))
 		}
 		b.do(a)
-		return
+		if !testC {
+			return
+		}
+		b.init()
 	}
 
 	var builds, runs, prints []*action
@@ -299,7 +301,15 @@ func runTest(cmd *Command, args []string) {
 	for _, p := range pkgs {
 		buildTest, runTest, printTest, err := b.test(p)
 		if err != nil {
-			errorf("%s", err)
+			str := err.Error()
+			if strings.HasPrefix(str, "\n") {
+				str = str[1:]
+			}
+			if p.ImportPath != "" {
+				errorf("# %s\n%s", p.ImportPath, str)
+			} else {
+				errorf("%s", str)
+			}
 			continue
 		}
 		builds = append(builds, buildTest)
@@ -341,7 +351,7 @@ func runTest(cmd *Command, args []string) {
 
 	warned := false
 	for _, a := range actionList(root) {
-		if a.p != nil && a.f != nil && !okBuild[a.p] && !a.p.fake {
+		if a.p != nil && a.f != nil && !okBuild[a.p] && !a.p.fake && !a.p.local {
 			okBuild[a.p] = true // don't warn again
 			if !warned {
 				fmt.Fprintf(os.Stderr, "warning: building out-of-date packages:\n")
@@ -362,7 +372,7 @@ func runTest(cmd *Command, args []string) {
 }
 
 func (b *builder) test(p *Package) (buildAction, runAction, printAction *action, err error) {
-	if len(p.info.TestGoFiles)+len(p.info.XTestGoFiles) == 0 {
+	if len(p.TestGoFiles)+len(p.XTestGoFiles) == 0 {
 		build := &action{p: p}
 		run := &action{p: p}
 		print := &action{f: (*builder).notest, p: p, deps: []*action{build}}
@@ -375,20 +385,26 @@ func (b *builder) test(p *Package) (buildAction, runAction, printAction *action,
 	//	pmain - pkg.test binary
 	var ptest, pxtest, pmain *Package
 
-	// go/build does not distinguish the dependencies used
-	// by the TestGoFiles from the dependencies used by the
-	// XTestGoFiles, so we build one list and use it for both
-	// ptest and pxtest.  No harm done.
-	var imports []*Package
+	var imports, ximports []*Package
 	var stk importStack
 	stk.push(p.ImportPath + "_test")
-	for _, path := range p.info.TestImports {
-		p1 := loadPackage(path, &stk)
+	for _, path := range p.TestImports {
+		p1 := loadImport(path, p.Dir, &stk, p.build.TestImportPos[path])
 		if p1.Error != nil {
 			return nil, nil, nil, p1.Error
 		}
 		imports = append(imports, p1)
 	}
+	for _, path := range p.XTestImports {
+		if path == p.ImportPath {
+			continue
+		}
+		p1 := loadImport(path, p.Dir, &stk, p.build.XTestImportPos[path])
+		if p1.Error != nil {
+			return nil, nil, nil, p1.Error
+		}
+		ximports = append(ximports, p1)
+	}
 	stk.pop()
 
 	// Use last element of import path, not package name.
@@ -423,17 +439,29 @@ func (b *builder) test(p *Package) (buildAction, runAction, printAction *action,
 	}
 
 	// Test package.
-	if len(p.info.TestGoFiles) > 0 {
+	if len(p.TestGoFiles) > 0 {
 		ptest = new(Package)
 		*ptest = *p
 		ptest.GoFiles = nil
 		ptest.GoFiles = append(ptest.GoFiles, p.GoFiles...)
-		ptest.GoFiles = append(ptest.GoFiles, p.info.TestGoFiles...)
+		ptest.GoFiles = append(ptest.GoFiles, p.TestGoFiles...)
 		ptest.target = ""
-		ptest.Imports = stringList(p.info.Imports, p.info.TestImports)
+		ptest.Imports = stringList(p.Imports, p.TestImports)
 		ptest.imports = append(append([]*Package{}, p.imports...), imports...)
 		ptest.pkgdir = testDir
 		ptest.fake = true
+		ptest.Stale = true
+		ptest.build = new(build.Package)
+		*ptest.build = *p.build
+		m := map[string][]token.Position{}
+		for k, v := range p.build.ImportPos {
+			m[k] = append(m[k], v...)
+		}
+		for k, v := range p.build.TestImportPos {
+			m[k] = append(m[k], v...)
+		}
+		ptest.build.ImportPos = m
+		computeStale(ptest)
 		a := b.action(modeBuild, modeBuild, ptest)
 		a.objdir = testDir + string(filepath.Separator)
 		a.objpkg = ptestObj
@@ -444,20 +472,23 @@ func (b *builder) test(p *Package) (buildAction, runAction, printAction *action,
 	}
 
 	// External test package.
-	if len(p.info.XTestGoFiles) > 0 {
+	if len(p.XTestGoFiles) > 0 {
 		pxtest = &Package{
-			Name:       p.Name + "_test",
-			ImportPath: p.ImportPath + "_test",
-			Dir:        p.Dir,
-			GoFiles:    p.info.XTestGoFiles,
-			Imports:    p.info.TestImports,
-			t:          p.t,
-			info:       &build.DirInfo{},
-			imports:    imports,
-			pkgdir:     testDir,
-			fake:       true,
+			Name:        p.Name + "_test",
+			ImportPath:  p.ImportPath + "_test",
+			localPrefix: p.localPrefix,
+			Dir:         p.Dir,
+			GoFiles:     p.XTestGoFiles,
+			Imports:     p.XTestImports,
+			build: &build.Package{
+				ImportPos: p.build.XTestImportPos,
+			},
+			imports: append(ximports, ptest),
+			pkgdir:  testDir,
+			fake:    true,
+			Stale:   true,
 		}
-		pxtest.imports = append(pxtest.imports, ptest)
+		computeStale(pxtest)
 		a := b.action(modeBuild, modeBuild, pxtest)
 		a.objdir = testDir + string(filepath.Separator)
 		a.objpkg = buildToolchain.pkgpath(testDir, pxtest)
@@ -466,13 +497,14 @@ func (b *builder) test(p *Package) (buildAction, runAction, printAction *action,
 
 	// Action for building pkg.test.
 	pmain = &Package{
-		Name:    "main",
-		Dir:     testDir,
-		GoFiles: []string{"_testmain.go"},
-		t:       p.t,
-		info:    &build.DirInfo{},
-		imports: []*Package{ptest},
-		fake:    true,
+		Name:       "main",
+		Dir:        testDir,
+		GoFiles:    []string{"_testmain.go"},
+		ImportPath: "testmain",
+		imports:    []*Package{ptest},
+		build:      &build.Package{},
+		fake:       true,
+		Stale:      true,
 	}
 	if pxtest != nil {
 		pmain.imports = append(pmain.imports, pxtest)
@@ -480,20 +512,21 @@ func (b *builder) test(p *Package) (buildAction, runAction, printAction *action,
 
 	// The generated main also imports testing and regexp.
 	stk.push("testmain")
-	ptesting := loadPackage("testing", &stk)
+	ptesting := loadImport("testing", "", &stk, nil)
 	if ptesting.Error != nil {
 		return nil, nil, nil, ptesting.Error
 	}
-	pregexp := loadPackage("regexp", &stk)
+	pregexp := loadImport("regexp", "", &stk, nil)
 	if pregexp.Error != nil {
 		return nil, nil, nil, pregexp.Error
 	}
 	pmain.imports = append(pmain.imports, ptesting, pregexp)
+	computeStale(pmain)
 
 	a := b.action(modeBuild, modeBuild, pmain)
 	a.objdir = testDir + string(filepath.Separator)
 	a.objpkg = filepath.Join(testDir, "main.a")
-	a.target = filepath.Join(testDir, testBinary) + b.exe
+	a.target = filepath.Join(testDir, testBinary) + exeSuffix
 	pmainAction := a
 
 	if testC {
@@ -502,7 +535,7 @@ func (b *builder) test(p *Package) (buildAction, runAction, printAction *action,
 			f:      (*builder).install,
 			deps:   []*action{pmainAction},
 			p:      pmain,
-			target: testBinary + b.exe,
+			target: testBinary + exeSuffix,
 		}
 		printAction = &action{p: p, deps: []*action{runAction}} // nop
 	} else {
@@ -646,14 +679,13 @@ func isTest(name, prefix string) bool {
 func writeTestmain(out string, p *Package) error {
 	t := &testFuncs{
 		Package: p,
-		Info:    p.info,
 	}
-	for _, file := range p.info.TestGoFiles {
+	for _, file := range p.TestGoFiles {
 		if err := t.load(filepath.Join(p.Dir, file), "_test", &t.NeedTest); err != nil {
 			return err
 		}
 	}
-	for _, file := range p.info.XTestGoFiles {
+	for _, file := range p.XTestGoFiles {
 		if err := t.load(filepath.Join(p.Dir, file), "_xtest", &t.NeedXtest); err != nil {
 			return err
 		}
@@ -677,7 +709,6 @@ type testFuncs struct {
 	Benchmarks []testFunc
 	Examples   []testFunc
 	Package    *Package
-	Info       *build.DirInfo
 	NeedTest   bool
 	NeedXtest  bool
 }
@@ -693,7 +724,7 @@ var testFileSet = token.NewFileSet()
 func (t *testFuncs) load(filename, pkg string, seen *bool) error {
 	f, err := parser.ParseFile(testFileSet, filename, nil, parser.ParseComments)
 	if err != nil {
-		return err
+		return expandScanner(err)
 	}
 	for _, d := range f.Decls {
 		n, ok := d.(*ast.FuncDecl)
diff --git a/src/cmd/go/testdata/errmsg/x.go b/src/cmd/go/testdata/errmsg/x.go
new file mode 100644
index 0000000..60f5b6e
--- /dev/null
+++ b/src/cmd/go/testdata/errmsg/x.go
@@ -0,0 +1,3 @@
+package foo
+
+import "bar"
diff --git a/src/cmd/go/testdata/errmsg/x1_test.go b/src/cmd/go/testdata/errmsg/x1_test.go
new file mode 100644
index 0000000..eb1a679
--- /dev/null
+++ b/src/cmd/go/testdata/errmsg/x1_test.go
@@ -0,0 +1,3 @@
+package foo_test
+
+import "bar"
diff --git a/src/cmd/go/testdata/errmsg/x_test.go b/src/cmd/go/testdata/errmsg/x_test.go
new file mode 100644
index 0000000..60f5b6e
--- /dev/null
+++ b/src/cmd/go/testdata/errmsg/x_test.go
@@ -0,0 +1,3 @@
+package foo
+
+import "bar"
diff --git a/src/cmd/go/testdata/local/easy.go b/src/cmd/go/testdata/local/easy.go
new file mode 100644
index 0000000..4eeb517
--- /dev/null
+++ b/src/cmd/go/testdata/local/easy.go
@@ -0,0 +1,7 @@
+package main
+
+import "./easysub"
+
+func main() {
+	easysub.Hello()
+}
diff --git a/src/cmd/go/testdata/local/easysub/easysub.go b/src/cmd/go/testdata/local/easysub/easysub.go
new file mode 100644
index 0000000..07040da
--- /dev/null
+++ b/src/cmd/go/testdata/local/easysub/easysub.go
@@ -0,0 +1,7 @@
+package easysub
+
+import "fmt"
+
+func Hello() {
+	fmt.Println("easysub.Hello")
+}
diff --git a/src/cmd/go/testdata/local/easysub/main.go b/src/cmd/go/testdata/local/easysub/main.go
new file mode 100644
index 0000000..6c30b52
--- /dev/null
+++ b/src/cmd/go/testdata/local/easysub/main.go
@@ -0,0 +1,9 @@
+// +build ignore
+
+package main
+
+import "."
+
+func main() {
+	easysub.Hello()
+}
diff --git a/src/cmd/go/testdata/local/hard.go b/src/cmd/go/testdata/local/hard.go
new file mode 100644
index 0000000..2ffac3f
--- /dev/null
+++ b/src/cmd/go/testdata/local/hard.go
@@ -0,0 +1,7 @@
+package main
+
+import "./sub"
+
+func main() {
+	sub.Hello()
+}
diff --git a/src/cmd/go/testdata/local/sub/sub.go b/src/cmd/go/testdata/local/sub/sub.go
new file mode 100644
index 0000000..d5dbf6d
--- /dev/null
+++ b/src/cmd/go/testdata/local/sub/sub.go
@@ -0,0 +1,12 @@
+package sub
+
+import (
+	"fmt"
+
+	subsub "./sub"
+)
+
+func Hello() {
+	fmt.Println("sub.Hello")
+	subsub.Hello()
+}
diff --git a/src/cmd/go/testdata/local/sub/sub/subsub.go b/src/cmd/go/testdata/local/sub/sub/subsub.go
new file mode 100644
index 0000000..4cc7223
--- /dev/null
+++ b/src/cmd/go/testdata/local/sub/sub/subsub.go
@@ -0,0 +1,7 @@
+package subsub
+
+import "fmt"
+
+func Hello() {
+	fmt.Println("subsub.Hello")
+}
diff --git a/src/cmd/go/testdata/testimport/p.go b/src/cmd/go/testdata/testimport/p.go
new file mode 100644
index 0000000..f94d2cd
--- /dev/null
+++ b/src/cmd/go/testdata/testimport/p.go
@@ -0,0 +1,3 @@
+package p
+
+func F() int { return 1 }
diff --git a/src/cmd/go/testdata/testimport/p1/p1.go b/src/cmd/go/testdata/testimport/p1/p1.go
new file mode 100644
index 0000000..fd31527
--- /dev/null
+++ b/src/cmd/go/testdata/testimport/p1/p1.go
@@ -0,0 +1,3 @@
+package p1
+
+func F() int { return 1 }
diff --git a/src/cmd/go/testdata/testimport/p2/p2.go b/src/cmd/go/testdata/testimport/p2/p2.go
new file mode 100644
index 0000000..d488886
--- /dev/null
+++ b/src/cmd/go/testdata/testimport/p2/p2.go
@@ -0,0 +1,3 @@
+package p2
+
+func F() int { return 1 }
diff --git a/src/cmd/go/testdata/testimport/p_test.go b/src/cmd/go/testdata/testimport/p_test.go
new file mode 100644
index 0000000..a3fb4a9
--- /dev/null
+++ b/src/cmd/go/testdata/testimport/p_test.go
@@ -0,0 +1,13 @@
+package p
+
+import (
+	"./p1"
+
+	"testing"
+)
+
+func TestF(t *testing.T) {
+	if F() != p1.F() {
+		t.Fatal(F())
+	}
+}
diff --git a/src/cmd/go/testdata/testimport/x_test.go b/src/cmd/go/testdata/testimport/x_test.go
new file mode 100644
index 0000000..b253e3f
--- /dev/null
+++ b/src/cmd/go/testdata/testimport/x_test.go
@@ -0,0 +1,15 @@
+package p_test
+
+import (
+	. "../testimport"
+
+	"./p2"
+
+	"testing"
+)
+
+func TestF1(t *testing.T) {
+	if F() != p2.F() {
+		t.Fatal(F())
+	}
+}
diff --git a/src/cmd/go/vcs.go b/src/cmd/go/vcs.go
index 2a7bdd0..cf34102 100644
--- a/src/cmd/go/vcs.go
+++ b/src/cmd/go/vcs.go
@@ -10,6 +10,7 @@ import (
 	"fmt"
 	"os"
 	"os/exec"
+	"path/filepath"
 	"regexp"
 	"strings"
 )
@@ -269,6 +270,38 @@ type vcsPath struct {
 	regexp *regexp.Regexp // cached compiled form of re
 }
 
+// vcsForDir inspects dir and its parents to determine the
+// version control system and code repository to use.
+// On return, root is the import path
+// corresponding to the root of the repository
+// (thus root is a prefix of importPath).
+func vcsForDir(p *Package) (vcs *vcsCmd, root string, err error) {
+	// Clean and double-check that dir is in (a subdirectory of) srcRoot.
+	dir := filepath.Clean(p.Dir)
+	srcRoot := filepath.Clean(p.build.SrcRoot)
+	if len(dir) <= len(srcRoot) || dir[len(srcRoot)] != filepath.Separator {
+		return nil, "", fmt.Errorf("directory %q is outside source root %q", dir, srcRoot)
+	}
+
+	for len(dir) > len(srcRoot) {
+		for _, vcs := range vcsList {
+			if fi, err := os.Stat(filepath.Join(dir, "."+vcs.cmd)); err == nil && fi.IsDir() {
+				return vcs, dir[len(srcRoot)+1:], nil
+			}
+		}
+
+		// Move to parent.
+		ndir := filepath.Dir(dir)
+		if len(ndir) >= len(dir) {
+			// Shouldn't happen, but just in case, stop.
+			break
+		}
+		dir = ndir
+	}
+
+	return nil, "", fmt.Errorf("directory %q is not using a known version control system", dir)
+}
+
 // vcsForImportPath analyzes importPath to determine the
 // version control system, and code repository to use.
 // On return, repo is the repository URL and root is the
diff --git a/src/cmd/go/vet.go b/src/cmd/go/vet.go
index 51dcec2..a672b99 100644
--- a/src/cmd/go/vet.go
+++ b/src/cmd/go/vet.go
@@ -6,13 +6,13 @@ package main
 
 var cmdVet = &Command{
 	Run:       runVet,
-	UsageLine: "vet [importpath...]",
+	UsageLine: "vet [packages]",
 	Short:     "run go tool vet on packages",
 	Long: `
 Vet runs the Go vet command on the packages named by the import paths.
 
 For more about vet, see 'godoc vet'.
-For more about import paths, see 'go help importpath'.
+For more about specifying packages, see 'go help packages'.
 
 To run the vet tool with specific options, run 'go tool vet'.
 
diff --git a/src/cmd/godoc/codewalk.go b/src/cmd/godoc/codewalk.go
index 7edf324..018259f 100644
--- a/src/cmd/godoc/codewalk.go
+++ b/src/cmd/godoc/codewalk.go
@@ -72,17 +72,17 @@ func codewalk(w http.ResponseWriter, r *http.Request) {
 
 // A Codewalk represents a single codewalk read from an XML file.
 type Codewalk struct {
-	Title string `xml:"attr"`
-	File  []string
-	Step  []*Codestep
+	Title string      `xml:"title,attr"`
+	File  []string    `xml:"file"`
+	Step  []*Codestep `xml:"step"`
 }
 
 // A Codestep is a single step in a codewalk.
 type Codestep struct {
 	// Filled in from XML
-	Src   string `xml:"attr"`
-	Title string `xml:"attr"`
-	XML   string `xml:"innerxml"`
+	Src   string `xml:"src,attr"`
+	Title string `xml:"title,attr"`
+	XML   string `xml:",innerxml"`
 
 	// Derived from Src; not in XML.
 	Err    error
diff --git a/src/cmd/godoc/dirtrees.go b/src/cmd/godoc/dirtrees.go
index 90f2c80..1acde99 100644
--- a/src/cmd/godoc/dirtrees.go
+++ b/src/cmd/godoc/dirtrees.go
@@ -15,15 +15,20 @@ import (
 	"os"
 	"path/filepath"
 	"strings"
-	"unicode"
 )
 
+// Conventional name for directories containing test data.
+// Excluded from directory trees.
+//
+const testdataDirName = "testdata"
+
 type Directory struct {
-	Depth int
-	Path  string // includes Name
-	Name  string
-	Text  string       // package documentation, if any
-	Dirs  []*Directory // subdirectories
+	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
+	Dirs     []*Directory // subdirectories
 }
 
 func isGoFile(fi os.FileInfo) bool {
@@ -44,48 +49,13 @@ func isPkgDir(fi os.FileInfo) bool {
 		name[0] != '_' && name[0] != '.' // ignore _files and .files
 }
 
-func firstSentence(s string) string {
-	i := -1 // index+1 of first terminator (punctuation ending a sentence)
-	j := -1 // index+1 of first terminator followed by white space
-	prev := 'A'
-	for k, ch := range s {
-		k1 := k + 1
-		if ch == '.' || ch == '!' || ch == '?' {
-			if i < 0 {
-				i = k1 // first terminator
-			}
-			if k1 < len(s) && s[k1] <= ' ' {
-				if j < 0 {
-					j = k1 // first terminator followed by white space
-				}
-				if !unicode.IsUpper(prev) {
-					j = k1
-					break
-				}
-			}
-		}
-		prev = ch
-	}
-
-	if j < 0 {
-		// use the next best terminator
-		j = i
-		if j < 0 {
-			// no terminator at all, use the entire string
-			j = len(s)
-		}
-	}
-
-	return s[0:j]
-}
-
 type treeBuilder struct {
 	pathFilter func(string) bool
 	maxDepth   int
 }
 
 func (b *treeBuilder) newDirTree(fset *token.FileSet, path, name string, depth int) *Directory {
-	if b.pathFilter != nil && !b.pathFilter(path) {
+	if b.pathFilter != nil && !b.pathFilter(path) || name == testdataDirName {
 		return nil
 	}
 
@@ -93,7 +63,11 @@ func (b *treeBuilder) newDirTree(fset *token.FileSet, path, name string, depth i
 		// return a dummy directory so that the parent directory
 		// doesn't get discarded just because we reached the max
 		// directory depth
-		return &Directory{depth, path, name, "", nil}
+		return &Directory{
+			Depth: depth,
+			Path:  path,
+			Name:  name,
+		}
 	}
 
 	list, err := fs.ReadDir(path)
@@ -176,7 +150,14 @@ func (b *treeBuilder) newDirTree(fset *token.FileSet, path, name string, depth i
 		}
 	}
 
-	return &Directory{depth, path, name, synopsis, dirs}
+	return &Directory{
+		Depth:    depth,
+		Path:     path,
+		Name:     name,
+		HasPkg:   hasPkgFiles,
+		Synopsis: synopsis,
+		Dirs:     dirs,
+	}
 }
 
 // newDirectory creates a new package directory tree with at most maxDepth
@@ -278,9 +259,10 @@ func (dir *Directory) lookup(path string) *Directory {
 type DirEntry struct {
 	Depth    int    // >= 0
 	Height   int    // = DirList.MaxHeight - Depth, > 0
-	Path     string // includes Name, relative to DirList root
-	Name     string
-	Synopsis string
+	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
 }
 
 type DirList struct {
@@ -335,7 +317,8 @@ func (root *Directory) listing(skipRoot bool) *DirList {
 		}
 		p.Path = path
 		p.Name = d.Name
-		p.Synopsis = d.Text
+		p.HasPkg = d.HasPkg
+		p.Synopsis = d.Synopsis
 		i++
 	}
 
diff --git a/src/cmd/godoc/godoc.go b/src/cmd/godoc/godoc.go
index 7249658..e5f7a73 100644
--- a/src/cmd/godoc/godoc.go
+++ b/src/cmd/godoc/godoc.go
@@ -15,6 +15,7 @@ import (
 	"go/printer"
 	"go/token"
 	"io"
+	"io/ioutil"
 	"log"
 	"net/http"
 	"net/url"
@@ -69,7 +70,7 @@ var (
 	// search index
 	indexEnabled = flag.Bool("index", false, "enable search index")
 	indexFiles   = flag.String("index_files", "", "glob pattern specifying index files;"+
-		"if not empty, the index is read from these files in sorted order")
+			"if not empty, the index is read from these files in sorted order")
 	maxResults    = flag.Int("maxresults", 10000, "maximum number of full text search results shown")
 	indexThrottle = flag.Float64("index_throttle", 0.75, "index throttle value; 0.0 = no time allocated, 1.0 = full throttle")
 
@@ -90,11 +91,11 @@ var (
 
 func initHandlers() {
 	paths := filepath.SplitList(*pkgPath)
-	for _, t := range build.Path {
-		if t.Goroot {
-			continue
+	gorootSrc := filepath.Join(build.Default.GOROOT, "src", "pkg")
+	for _, p := range build.Default.SrcDirs() {
+		if p != gorootSrc {
+			paths = append(paths, p)
 		}
-		paths = append(paths, t.SrcDir())
 	}
 	fsMap.Init(paths)
 
@@ -1002,11 +1003,13 @@ func fsReadDir(dir string) ([]os.FileInfo, error) {
 	return fs.ReadDir(dir)
 }
 
-// fsReadFile implements ReadFile for the go/build package.
-func fsReadFile(dir, name string) (path string, data []byte, err error) {
-	path = filepath.Join(dir, name)
-	data, err = ReadFile(fs, path)
-	return
+// fsOpenFile implements OpenFile for the go/build package.
+func fsOpenFile(name string) (r io.ReadCloser, err error) {
+	data, err := ReadFile(fs, name)
+	if err != nil {
+		return nil, err
+	}
+	return ioutil.NopCloser(bytes.NewReader(data)), nil
 }
 
 func inList(name string, list []string) bool {
@@ -1039,10 +1042,11 @@ func (h *httpHandler) getPageInfo(abspath, relpath, pkgname string, mode PageInf
 		// To use different pair, such as if we allowed the user
 		// to choose, set ctxt.GOOS and ctxt.GOARCH before
 		// calling ctxt.ScanDir.
-		ctxt := build.DefaultContext
+		ctxt := build.Default
+		ctxt.IsAbsPath = path.IsAbs
 		ctxt.ReadDir = fsReadDir
-		ctxt.ReadFile = fsReadFile
-		dir, err := ctxt.ScanDir(abspath)
+		ctxt.OpenFile = fsOpenFile
+		dir, err := ctxt.ImportDir(abspath, 0)
 		if err == nil {
 			pkgFiles = append(dir.GoFiles, dir.CgoFiles...)
 		}
diff --git a/src/cmd/godoc/main.go b/src/cmd/godoc/main.go
index 8d59220..5f42105 100644
--- a/src/cmd/godoc/main.go
+++ b/src/cmd/godoc/main.go
@@ -7,7 +7,7 @@
 // Web server tree:
 //
 //	http://godoc/		main landing page
-//	http://godoc/doc/	serve from $GOROOT/doc - spec, mem, tutorial, etc.
+//	http://godoc/doc/	serve from $GOROOT/doc - spec, mem, etc.
 //	http://godoc/src/	serve files from $GOROOT/src; .go gets pretty-printed
 //	http://godoc/cmd/	serve documentation about commands
 //	http://godoc/pkg/	serve documentation about packages
@@ -99,7 +99,6 @@ func exec(rw http.ResponseWriter, args []string) (status int) {
 		log.Printf("os.StartProcess(%q): %v", bin, err)
 		return 2
 	}
-	defer p.Release()
 
 	var buf bytes.Buffer
 	io.Copy(&buf, r)
@@ -389,9 +388,9 @@ func main() {
 	}
 	relpath := path
 	abspath := path
-	if t, pkg, err := build.FindTree(path); err == nil {
-		relpath = pkg
-		abspath = filepath.Join(t.SrcDir(), pkg)
+	if bp, _ := build.Import(path, "", build.FindOnly); bp.Dir != "" && bp.ImportPath != "" {
+		relpath = bp.ImportPath
+		abspath = bp.Dir
 	} else if !filepath.IsAbs(path) {
 		abspath = absolutePath(path, pkgHandler.fsRoot)
 	} else {
diff --git a/src/cmd/ld/data.c b/src/cmd/ld/data.c
index 397ae83..786c10b 100644
--- a/src/cmd/ld/data.c
+++ b/src/cmd/ld/data.c
@@ -1023,6 +1023,11 @@ textaddress(void)
 		}
 		va += sym->size;
 	}
+	
+	// Align end of code so that rodata starts aligned.
+	// 128 bytes is likely overkill but definitely cheap.
+	va = rnd(va, 128);
+
 	sect->len = va - sect->vaddr;
 }
 
diff --git a/src/cmd/ld/lib.c b/src/cmd/ld/lib.c
index 34440b8..4a100ca 100644
--- a/src/cmd/ld/lib.c
+++ b/src/cmd/ld/lib.c
@@ -39,8 +39,9 @@ int iconv(Fmt*);
 
 char	symname[]	= SYMDEF;
 char	pkgname[]	= "__.PKGDEF";
-char*	libdir[16];
+char**	libdir;
 int	nlibdir = 0;
+static int	maxlibdir = 0;
 static int	cout = -1;
 
 char*	goroot;
@@ -51,9 +52,19 @@ char*	theline;
 void
 Lflag(char *arg)
 {
-	if(nlibdir >= nelem(libdir)-1) {
-		print("too many -L's: %d\n", nlibdir);
-		usage();
+	char **p;
+
+	if(nlibdir >= maxlibdir) {
+		if (maxlibdir == 0)
+			maxlibdir = 8;
+		else
+			maxlibdir *= 2;
+		p = realloc(libdir, maxlibdir * sizeof(*p));
+		if (p == nil) {
+			print("too many -L's: %d\n", nlibdir);
+			usage();
+		}
+		libdir = p;
 	}
 	libdir[nlibdir++] = arg;
 }
@@ -69,7 +80,7 @@ libinit(void)
 		print("goarch is not known: %s\n", goarch);
 
 	// add goroot to the end of the libdir list.
-	libdir[nlibdir++] = smprint("%s/pkg/%s_%s", goroot, goos, goarch);
+	Lflag(smprint("%s/pkg/%s_%s", goroot, goos, goarch));
 
 	// Unix doesn't like it when we write to a running (or, sometimes,
 	// recently run) binary, so remove the output file before writing it.
diff --git a/src/cmd/ld/lib.h b/src/cmd/ld/lib.h
index 9e39c74..02dac6e 100644
--- a/src/cmd/ld/lib.h
+++ b/src/cmd/ld/lib.h
@@ -103,7 +103,7 @@ struct Section
 };
 
 extern	char	symname[];
-extern	char	*libdir[];
+extern	char	**libdir;
 extern	int	nlibdir;
 
 EXTERN	char*	INITENTRY;
diff --git a/src/cmd/objdump/main.c b/src/cmd/objdump/main.c
new file mode 100644
index 0000000..b684be7
--- /dev/null
+++ b/src/cmd/objdump/main.c
@@ -0,0 +1,68 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+ * objdump simulation - only enough to make pprof work on Macs
+ */
+
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include <mach.h>
+
+void
+usage(void)
+{
+	fprint(2, "usage: objdump binary start stop\n");
+	fprint(2, "Disassembles binary from PC start up to stop.\n");
+	exits("usage");
+}
+
+void
+main(int argc, char **argv)
+{
+	int fd, n;
+	uvlong pc, start, stop;
+	Fhdr fhdr;
+	Biobuf bout;
+	char buf[1024];
+	Map *text;
+
+	ARGBEGIN{
+	default:
+		usage();
+	}ARGEND
+
+	if(argc != 3)
+		usage();
+	start = strtoull(argv[1], 0, 16);
+	stop = strtoull(argv[2], 0, 16);
+
+	fd = open(argv[0], OREAD);
+	if(fd < 0)
+		sysfatal("open %s: %r", argv[0]);
+	if(crackhdr(fd, &fhdr) <= 0)
+		sysfatal("crackhdr: %r");
+	machbytype(fhdr.type);
+	if(syminit(fd, &fhdr) <= 0)
+		sysfatal("syminit: %r");
+	text = loadmap(nil, fd, &fhdr);
+	if(text == nil)
+		sysfatal("loadmap: %r");
+
+	Binit(&bout, 1, OWRITE);
+	for(pc=start; pc<stop; ) {
+		if(fileline(buf, sizeof buf, pc))
+			Bprint(&bout, "%s\n", buf);
+		buf[0] = '\0';
+		machdata->das(text, pc, 0, buf, sizeof buf);
+		Bprint(&bout, " %llx: %s\n", pc, buf);
+		n = machdata->instsize(text, pc);
+		if(n <= 0)
+			break;
+		pc += n;
+	}
+	Bflush(&bout);
+	exits(0);
+}
diff --git a/src/cmd/pack/doc.go b/src/cmd/pack/doc.go
index 6cbc357..8b17f3c 100644
--- a/src/cmd/pack/doc.go
+++ b/src/cmd/pack/doc.go
@@ -12,7 +12,8 @@ It adds a special Go-specific section __.PKGDEF that collects all the
 Go type information from the files in the archive; that section is
 used by the compiler when importing the package during compilation.
 
-Usage: go tool pack [uvnbailogS][mrxtdpq][P prefix] archive files ...
+Usage:
+	go tool pack [uvnbailogS][mrxtdpq][P prefix] archive files ...
 
 The new option 'g' causes pack to maintain the __.PKGDEF section
 as files are added to the archive.
diff --git a/src/cmd/prof/doc.go b/src/cmd/prof/doc.go
index 08aa086..0072f9a 100644
--- a/src/cmd/prof/doc.go
+++ b/src/cmd/prof/doc.go
@@ -16,8 +16,8 @@ the program's state even when it is not running, such as when it is
 asleep or waiting for I/O.  Each thread contributes equally to the
 statistics.
 
-
-Usage: prof -p pid [-t total_secs] [-d delta_msec] [6.out args ...]
+Usage:
+	go tool prof -p pid [-t total_secs] [-d delta_msec] [6.out args ...]
 
 The output modes (default -h) are:
 
diff --git a/src/cmd/vet/doc.go b/src/cmd/vet/doc.go
index 2495e80..e51fe37 100644
--- a/src/cmd/vet/doc.go
+++ b/src/cmd/vet/doc.go
@@ -4,18 +4,42 @@
 
 /*
 
-Vet does simple checking of Go source code.
+Vet examines Go source code and reports suspicious constructs, such as Printf
+calls whose arguments do not align with the format string. Vet uses heuristics
+that do not guarantee all reports are genuine problems, but it can find errors
+not caught by the compilers.
 
-It checks for simple errors in calls to functions named
+Available checks:
+
+1. Printf family
+
+Suspicious calls to functions in the Printf familiy, including any functions
+with these names:
 	Print Printf Println
 	Fprint Fprintf Fprintln
 	Sprint Sprintf Sprintln
 	Error Errorf
 	Fatal Fatalf
+	Panic Panicf Panicln
 If the function name ends with an 'f', the function is assumed to take
 a format descriptor string in the manner of fmt.Printf. If not, vet
 complains about arguments that look like format descriptor strings.
 
+It also checks for errors such as using a Writer as the first argument of
+Printf.
+
+2. Methods
+
+Non-standard signatures for methods with familiar names, including:
+	Format GobEncode GobDecode MarshalJSON MarshalXML
+	Peek ReadByte ReadFrom ReadRune Scan Seek 
+	UnmarshalJSON UnreadByte UnreadRune WriteByte
+	WriteTo
+
+3. Struct tags
+
+Struct tags that do not follow the format understood by reflect.StructTag.Get.
+
 Usage:
 
 	go tool vet [flag] [file.go ...]
diff --git a/src/cmd/vet/print.go b/src/cmd/vet/print.go
index e0717f8..ee9a33c 100644
--- a/src/cmd/vet/print.go
+++ b/src/cmd/vet/print.go
@@ -167,7 +167,7 @@ var printVerbs = []printVerb{
 	{'b', numFlag},
 	{'c', "-"},
 	{'d', numFlag},
-	{'e', "-."},
+	{'e', numFlag},
 	{'E', numFlag},
 	{'f', numFlag},
 	{'F', numFlag},
diff --git a/src/cmd/yacc/Makefile b/src/cmd/yacc/Makefile
index 4d84891..56e9542 100644
--- a/src/cmd/yacc/Makefile
+++ b/src/cmd/yacc/Makefile
@@ -5,3 +5,6 @@
 units: yacc.go units.y
 	go run yacc.go -p units_ units.y
 	go build -o units y.go
+
+clean:
+	rm -f y.go y.output units
diff --git a/src/cmd/yacc/doc.go b/src/cmd/yacc/doc.go
index 9874a2a..4a2c2a3 100644
--- a/src/cmd/yacc/doc.go
+++ b/src/cmd/yacc/doc.go
@@ -4,10 +4,13 @@
 
 /*
 
-Yacc is a version of yacc for Go. It is run with the command
-	go tool yacc args...
+Yacc is a version of yacc for Go.
 It is written in Go and generates parsers written in Go.
 
+Usage:
+
+	go tool yacc args...
+
 It is largely transliterated from the Inferno version written in Limbo
 which in turn was largely transliterated from the Plan 9 version
 written in C and documented at
diff --git a/src/cmd/yacc/units.y b/src/cmd/yacc/units.y
index f10cb7c..7258e3e 100644
--- a/src/cmd/yacc/units.y
+++ b/src/cmd/yacc/units.y
@@ -15,9 +15,8 @@
 // example of a Go yacc program
 // usage is
 //	go tool yacc -p "units_" units.y (produces y.go)
-//	6g y.go
-//	6l y.6
-//	./6.out $GOROOT/src/cmd/yacc/units
+//	go build -o units y.go
+//	./units $GOROOT/src/cmd/yacc/units.txt
 //	you have: c
 //	you want: furlongs/fortnight
 //		* 1.8026178e+12
@@ -288,9 +287,14 @@ func main() {
 
 	flag.Parse()
 
-	file = os.Getenv("GOROOT") + "/src/cmd/yacc/units.txt"
+	if dir := os.Getenv("GOROOT"); dir != "" {
+		file = dir + "/src/cmd/yacc/units.txt"
+	}
 	if flag.NArg() > 0 {
 		file = flag.Arg(0)
+	} else if file == "" {
+		fmt.Fprintf(os.Stderr, "can not find data file units.txt; provide it as argument or set $GOROOT\n")
+		os.Exit(1)
 	}
 
 	f, err := os.Open(file)
diff --git a/src/libmach/8db.c b/src/libmach/8db.c
index 3101e13..ce1b4dd 100644
--- a/src/libmach/8db.c
+++ b/src/libmach/8db.c
@@ -1,11 +1,11 @@
 // Inferno libmach/8db.c
 // http://code.google.com/p/inferno-os/source/browse/utils/libmach/8db.c
 //
-// 	Copyright © 1994-1999 Lucent Technologies Inc.
-// 	Power PC support Copyright © 1995-2004 C H Forsyth (forsyth at terzarima.net).
-// 	Portions Copyright © 1997-1999 Vita Nuova Limited.
-// 	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
-// 	Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
+//	Copyright © 1994-1999 Lucent Technologies Inc.
+//	Power PC support Copyright © 1995-2004 C H Forsyth (forsyth at terzarima.net).
+//	Portions Copyright © 1997-1999 Vita Nuova Limited.
+//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
+//	Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
 //	Portions Copyright © 2009 The Go Authors.  All rights reserved.
 //
 // Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -2088,18 +2088,23 @@ immediate(Instr *ip, vlong val)
 static void
 pea(Instr *ip)
 {
+	int base;
+
+	base = ip->base;
+	if(base >= 0 && (ip->rex & REXB))
+		base += 8;
+
 	if (ip->mod == 3) {
 		if (ip->osize == 'B')
 			bprint(ip, (ip->rex & REXB? breg64: breg)[(uchar)ip->base]);
-		else if(ip->rex & REXB)
-			bprint(ip, "%s%s", ANAME(ip), reg[ip->base+8]);
 		else
-			bprint(ip, "%s%s", ANAME(ip), reg[(uchar)ip->base]);
+			bprint(ip, "%s%s", ANAME(ip), reg[base]);
 		return;
 	}
+
 	if (ip->segment)
 		bprint(ip, ip->segment);
-	if (ip->asize == 'E' && ip->base == SP)
+	if (ip->asize == 'E' && base == SP)
 		plocal(ip);
 	else {
 		if (ip->base < 0)
diff --git a/src/make.bash b/src/make.bash
index cb7051b..aaee75e 100755
--- a/src/make.bash
+++ b/src/make.bash
@@ -3,6 +3,29 @@
 # Use of this source code is governed by a BSD-style
 # license that can be found in the LICENSE file.
 
+# Environment variables that control make.bash:
+#
+# GOROOT_FINAL: The expected final Go root, baked into binaries.
+# The default is the location of the Go tree during the build.
+#
+# GOHOSTARCH: The architecture for host tools (compilers and
+# binaries).  Binaries of this type must be executable on the current
+# system, so the only common reason to set this is to set
+# GOHOSTARCH=386 on an amd64 machine.
+#
+# GOARCH: The target architecture for installed packages and tools.
+#
+# GOOS: The target operating system for installed packages and tools.
+#
+# GO_GCFLAGS: Additional 5g/6g/8g arguments to use when
+# building the packages and commands.
+#
+# GO_LDFLAGS: Additional 5l/6l/8l arguments to use when
+# building the packages and commands.
+#
+# CGO_ENABLED: Setting this to 0 disables the use of cgo
+# in the built and installed packages and tools.
+
 set -e
 if [ ! -f run.bash ]; then
 	echo 'make.bash must be run from $GOROOT/src' 1>&2
@@ -66,11 +89,11 @@ echo
 
 if [ "$1" = "--dist-tool" ]; then
 	# Stop after building dist tool.
-	mkdir -p $GOTOOLDIR
+	mkdir -p "$GOTOOLDIR"
 	if [ "$2" != "" ]; then
 		cp cmd/dist/dist "$2"
 	fi
-	mv cmd/dist/dist $GOTOOLDIR/dist
+	mv cmd/dist/dist "$GOTOOLDIR"/dist
 	exit 0
 fi
 
@@ -81,23 +104,23 @@ if [ "$1" = "--no-clean" ]; then
 fi
 ./cmd/dist/dist bootstrap $buildall -v # builds go_bootstrap
 # Delay move of dist tool to now, because bootstrap may clear tool directory.
-mv cmd/dist/dist $GOTOOLDIR/dist
-$GOTOOLDIR/go_bootstrap clean -i std
+mv cmd/dist/dist "$GOTOOLDIR"/dist
+"$GOTOOLDIR"/go_bootstrap clean -i std
 echo
 
 if [ "$GOHOSTARCH" != "$GOARCH" -o "$GOHOSTOS" != "$GOOS" ]; then
 	echo "# Building packages and commands for host, $GOHOSTOS/$GOHOSTARCH."
 	GOOS=$GOHOSTOS GOARCH=$GOHOSTARCH \
-		$GOTOOLDIR/go_bootstrap install -v std
+		"$GOTOOLDIR"/go_bootstrap install -gcflags "$GO_GCFLAGS" -ldflags "$GO_LDFLAGS" -v std
 	echo
 fi
 
 echo "# Building packages and commands for $GOOS/$GOARCH."
-$GOTOOLDIR/go_bootstrap install -v std
+"$GOTOOLDIR"/go_bootstrap install -gcflags "$GO_GCFLAGS" -ldflags "$GO_LDFLAGS" -v std
 echo
 
-rm -f $GOTOOLDIR/go_bootstrap
+rm -f "$GOTOOLDIR"/go_bootstrap
 
 if [ "$1" != "--no-banner" ]; then
-	$GOTOOLDIR/dist banner
+	"$GOTOOLDIR"/dist banner
 fi
diff --git a/src/pkg/archive/zip/reader.go b/src/pkg/archive/zip/reader.go
index c300986..f3826dc 100644
--- a/src/pkg/archive/zip/reader.go
+++ b/src/pkg/archive/zip/reader.go
@@ -169,48 +169,21 @@ func (r *checksumReader) Read(b []byte) (n int, err error) {
 
 func (r *checksumReader) Close() error { return r.rc.Close() }
 
-func readFileHeader(f *File, r io.Reader) error {
-	var b [fileHeaderLen]byte
-	if _, err := io.ReadFull(r, b[:]); err != nil {
-		return err
-	}
-	c := binary.LittleEndian
-	if sig := c.Uint32(b[:4]); sig != fileHeaderSignature {
-		return ErrFormat
-	}
-	f.ReaderVersion = c.Uint16(b[4:6])
-	f.Flags = c.Uint16(b[6:8])
-	f.Method = c.Uint16(b[8:10])
-	f.ModifiedTime = c.Uint16(b[10:12])
-	f.ModifiedDate = c.Uint16(b[12:14])
-	f.CRC32 = c.Uint32(b[14:18])
-	f.CompressedSize = c.Uint32(b[18:22])
-	f.UncompressedSize = c.Uint32(b[22:26])
-	filenameLen := int(c.Uint16(b[26:28]))
-	extraLen := int(c.Uint16(b[28:30]))
-	d := make([]byte, filenameLen+extraLen)
-	if _, err := io.ReadFull(r, d); err != nil {
-		return err
-	}
-	f.Name = string(d[:filenameLen])
-	f.Extra = d[filenameLen:]
-	return nil
-}
-
 // findBodyOffset does the minimum work to verify the file has a header
 // and returns the file body offset.
 func (f *File) findBodyOffset() (int64, error) {
 	r := io.NewSectionReader(f.zipr, f.headerOffset, f.zipsize-f.headerOffset)
-	var b [fileHeaderLen]byte
-	if _, err := io.ReadFull(r, b[:]); err != nil {
+	var buf [fileHeaderLen]byte
+	if _, err := io.ReadFull(r, buf[:]); err != nil {
 		return 0, err
 	}
-	c := binary.LittleEndian
-	if sig := c.Uint32(b[:4]); sig != fileHeaderSignature {
+	b := readBuf(buf[:])
+	if sig := b.uint32(); sig != fileHeaderSignature {
 		return 0, ErrFormat
 	}
-	filenameLen := int(c.Uint16(b[26:28]))
-	extraLen := int(c.Uint16(b[28:30]))
+	b = b[22:] // skip over most of the header
+	filenameLen := int(b.uint16())
+	extraLen := int(b.uint16())
 	return int64(fileHeaderLen + filenameLen + extraLen), nil
 }
 
@@ -218,30 +191,29 @@ func (f *File) findBodyOffset() (int64, error) {
 // It returns io.ErrUnexpectedEOF if it cannot read a complete header,
 // and ErrFormat if it doesn't find a valid header signature.
 func readDirectoryHeader(f *File, r io.Reader) error {
-	var b [directoryHeaderLen]byte
-	if _, err := io.ReadFull(r, b[:]); err != nil {
+	var buf [directoryHeaderLen]byte
+	if _, err := io.ReadFull(r, buf[:]); err != nil {
 		return err
 	}
-	c := binary.LittleEndian
-	if sig := c.Uint32(b[:4]); sig != directoryHeaderSignature {
+	b := readBuf(buf[:])
+	if sig := b.uint32(); sig != directoryHeaderSignature {
 		return ErrFormat
 	}
-	f.CreatorVersion = c.Uint16(b[4:6])
-	f.ReaderVersion = c.Uint16(b[6:8])
-	f.Flags = c.Uint16(b[8:10])
-	f.Method = c.Uint16(b[10:12])
-	f.ModifiedTime = c.Uint16(b[12:14])
-	f.ModifiedDate = c.Uint16(b[14:16])
-	f.CRC32 = c.Uint32(b[16:20])
-	f.CompressedSize = c.Uint32(b[20:24])
-	f.UncompressedSize = c.Uint32(b[24:28])
-	filenameLen := int(c.Uint16(b[28:30]))
-	extraLen := int(c.Uint16(b[30:32]))
-	commentLen := int(c.Uint16(b[32:34]))
-	// startDiskNumber := c.Uint16(b[34:36])    // Unused
-	// internalAttributes := c.Uint16(b[36:38]) // Unused
-	f.ExternalAttrs = c.Uint32(b[38:42])
-	f.headerOffset = int64(c.Uint32(b[42:46]))
+	f.CreatorVersion = b.uint16()
+	f.ReaderVersion = b.uint16()
+	f.Flags = b.uint16()
+	f.Method = b.uint16()
+	f.ModifiedTime = b.uint16()
+	f.ModifiedDate = b.uint16()
+	f.CRC32 = b.uint32()
+	f.CompressedSize = b.uint32()
+	f.UncompressedSize = b.uint32()
+	filenameLen := int(b.uint16())
+	extraLen := int(b.uint16())
+	commentLen := int(b.uint16())
+	b = b[4:] // skipped start disk number and internal attributes (2x uint16)
+	f.ExternalAttrs = b.uint32()
+	f.headerOffset = int64(b.uint32())
 	d := make([]byte, filenameLen+extraLen+commentLen)
 	if _, err := io.ReadFull(r, d); err != nil {
 		return err
@@ -253,30 +225,30 @@ func readDirectoryHeader(f *File, r io.Reader) error {
 }
 
 func readDataDescriptor(r io.Reader, f *File) error {
-	var b [dataDescriptorLen]byte
-	if _, err := io.ReadFull(r, b[:]); err != nil {
+	var buf [dataDescriptorLen]byte
+	if _, err := io.ReadFull(r, buf[:]); err != nil {
 		return err
 	}
-	c := binary.LittleEndian
-	f.CRC32 = c.Uint32(b[:4])
-	f.CompressedSize = c.Uint32(b[4:8])
-	f.UncompressedSize = c.Uint32(b[8:12])
+	b := readBuf(buf[:])
+	f.CRC32 = b.uint32()
+	f.CompressedSize = b.uint32()
+	f.UncompressedSize = b.uint32()
 	return nil
 }
 
 func readDirectoryEnd(r io.ReaderAt, size int64) (dir *directoryEnd, err error) {
 	// look for directoryEndSignature in the last 1k, then in the last 65k
-	var b []byte
+	var buf []byte
 	for i, bLen := range []int64{1024, 65 * 1024} {
 		if bLen > size {
 			bLen = size
 		}
-		b = make([]byte, int(bLen))
-		if _, err := r.ReadAt(b, size-bLen); err != nil && err != io.EOF {
+		buf = make([]byte, int(bLen))
+		if _, err := r.ReadAt(buf, size-bLen); err != nil && err != io.EOF {
 			return nil, err
 		}
-		if p := findSignatureInBlock(b); p >= 0 {
-			b = b[p:]
+		if p := findSignatureInBlock(buf); p >= 0 {
+			buf = buf[p:]
 			break
 		}
 		if i == 1 || bLen == size {
@@ -285,16 +257,21 @@ func readDirectoryEnd(r io.ReaderAt, size int64) (dir *directoryEnd, err error)
 	}
 
 	// read header into struct
-	c := binary.LittleEndian
-	d := new(directoryEnd)
-	d.diskNbr = c.Uint16(b[4:6])
-	d.dirDiskNbr = c.Uint16(b[6:8])
-	d.dirRecordsThisDisk = c.Uint16(b[8:10])
-	d.directoryRecords = c.Uint16(b[10:12])
-	d.directorySize = c.Uint32(b[12:16])
-	d.directoryOffset = c.Uint32(b[16:20])
-	d.commentLen = c.Uint16(b[20:22])
-	d.comment = string(b[22 : 22+int(d.commentLen)])
+	b := readBuf(buf[4:]) // skip signature
+	d := &directoryEnd{
+		diskNbr:            b.uint16(),
+		dirDiskNbr:         b.uint16(),
+		dirRecordsThisDisk: b.uint16(),
+		directoryRecords:   b.uint16(),
+		directorySize:      b.uint32(),
+		directoryOffset:    b.uint32(),
+		commentLen:         b.uint16(),
+	}
+	l := int(d.commentLen)
+	if l > len(b) {
+		return nil, errors.New("zip: invalid comment length")
+	}
+	d.comment = string(b[:l])
 	return d, nil
 }
 
@@ -311,3 +288,17 @@ func findSignatureInBlock(b []byte) int {
 	}
 	return -1
 }
+
+type readBuf []byte
+
+func (b *readBuf) uint16() uint16 {
+	v := binary.LittleEndian.Uint16(*b)
+	*b = (*b)[2:]
+	return v
+}
+
+func (b *readBuf) uint32() uint32 {
+	v := binary.LittleEndian.Uint32(*b)
+	*b = (*b)[4:]
+	return v
+}
diff --git a/src/pkg/archive/zip/reader_test.go b/src/pkg/archive/zip/reader_test.go
index ea9e002..066a615 100644
--- a/src/pkg/archive/zip/reader_test.go
+++ b/src/pkg/archive/zip/reader_test.go
@@ -165,7 +165,7 @@ func readTestZip(t *testing.T, zt ZipTest) {
 		t.Errorf("%s: comment=%q, want %q", zt.Name, z.Comment, zt.Comment)
 	}
 	if len(z.File) != len(zt.File) {
-		t.Errorf("%s: file count=%d, want %d", zt.Name, len(z.File), len(zt.File))
+		t.Fatalf("%s: file count=%d, want %d", zt.Name, len(z.File), len(zt.File))
 	}
 
 	// test read of each file
diff --git a/src/pkg/archive/zip/struct.go b/src/pkg/archive/zip/struct.go
index 35dcec6..fdbd16d 100644
--- a/src/pkg/archive/zip/struct.go
+++ b/src/pkg/archive/zip/struct.go
@@ -100,16 +100,6 @@ type directoryEnd struct {
 	comment            string
 }
 
-func recoverError(errp *error) {
-	if e := recover(); e != nil {
-		if err, ok := e.(error); ok {
-			*errp = err
-			return
-		}
-		panic(e)
-	}
-}
-
 // msDosTimeToTime converts an MS-DOS date and time into a time.Time.
 // The resolution is 2s.
 // See: http://msdn.microsoft.com/en-us/library/ms724247(v=VS.85).aspx
diff --git a/src/pkg/archive/zip/writer.go b/src/pkg/archive/zip/writer.go
index c591aed..b2cc55b 100644
--- a/src/pkg/archive/zip/writer.go
+++ b/src/pkg/archive/zip/writer.go
@@ -37,10 +37,10 @@ func NewWriter(w io.Writer) *Writer {
 
 // Close finishes writing the zip file by writing the central directory.
 // It does not (and can not) close the underlying writer.
-func (w *Writer) Close() (err error) {
+func (w *Writer) Close() error {
 	if w.last != nil && !w.last.closed {
-		if err = w.last.close(); err != nil {
-			return
+		if err := w.last.close(); err != nil {
+			return err
 		}
 		w.last = nil
 	}
@@ -49,43 +49,55 @@ func (w *Writer) Close() (err error) {
 	}
 	w.closed = true
 
-	defer recoverError(&err)
-
 	// write central directory
 	start := w.cw.count
 	for _, h := range w.dir {
-		write(w.cw, uint32(directoryHeaderSignature))
-		write(w.cw, h.CreatorVersion)
-		write(w.cw, h.ReaderVersion)
-		write(w.cw, h.Flags)
-		write(w.cw, h.Method)
-		write(w.cw, h.ModifiedTime)
-		write(w.cw, h.ModifiedDate)
-		write(w.cw, h.CRC32)
-		write(w.cw, h.CompressedSize)
-		write(w.cw, h.UncompressedSize)
-		write(w.cw, uint16(len(h.Name)))
-		write(w.cw, uint16(len(h.Extra)))
-		write(w.cw, uint16(len(h.Comment)))
-		write(w.cw, uint16(0)) // disk number start
-		write(w.cw, uint16(0)) // internal file attributes
-		write(w.cw, h.ExternalAttrs)
-		write(w.cw, h.offset)
-		writeBytes(w.cw, []byte(h.Name))
-		writeBytes(w.cw, h.Extra)
-		writeBytes(w.cw, []byte(h.Comment))
+		var buf [directoryHeaderLen]byte
+		b := writeBuf(buf[:])
+		b.uint32(uint32(directoryHeaderSignature))
+		b.uint16(h.CreatorVersion)
+		b.uint16(h.ReaderVersion)
+		b.uint16(h.Flags)
+		b.uint16(h.Method)
+		b.uint16(h.ModifiedTime)
+		b.uint16(h.ModifiedDate)
+		b.uint32(h.CRC32)
+		b.uint32(h.CompressedSize)
+		b.uint32(h.UncompressedSize)
+		b.uint16(uint16(len(h.Name)))
+		b.uint16(uint16(len(h.Extra)))
+		b.uint16(uint16(len(h.Comment)))
+		b = b[4:] // skip disk number start and internal file attr (2x uint16)
+		b.uint32(h.ExternalAttrs)
+		b.uint32(h.offset)
+		if _, err := w.cw.Write(buf[:]); err != nil {
+			return err
+		}
+		if _, err := io.WriteString(w.cw, h.Name); err != nil {
+			return err
+		}
+		if _, err := w.cw.Write(h.Extra); err != nil {
+			return err
+		}
+		if _, err := io.WriteString(w.cw, h.Comment); err != nil {
+			return err
+		}
 	}
 	end := w.cw.count
 
 	// write end record
-	write(w.cw, uint32(directoryEndSignature))
-	write(w.cw, uint16(0))          // disk number
-	write(w.cw, uint16(0))          // disk number where directory starts
-	write(w.cw, uint16(len(w.dir))) // number of entries this disk
-	write(w.cw, uint16(len(w.dir))) // number of entries total
-	write(w.cw, uint32(end-start))  // size of directory
-	write(w.cw, uint32(start))      // start of directory
-	write(w.cw, uint16(0))          // size of comment
+	var buf [directoryEndLen]byte
+	b := writeBuf(buf[:])
+	b.uint32(uint32(directoryEndSignature))
+	b = b[4:]                     // skip over disk number and first disk number (2x uint16)
+	b.uint16(uint16(len(w.dir)))  // number of entries this disk
+	b.uint16(uint16(len(w.dir)))  // number of entries total
+	b.uint32(uint32(end - start)) // size of directory
+	b.uint32(uint32(start))       // start of directory
+	// skipped size of comment (always zero)
+	if _, err := w.cw.Write(buf[:]); err != nil {
+		return err
+	}
 
 	return w.cw.w.(*bufio.Writer).Flush()
 }
@@ -152,22 +164,28 @@ func (w *Writer) CreateHeader(fh *FileHeader) (io.Writer, error) {
 	return fw, nil
 }
 
-func writeHeader(w io.Writer, h *FileHeader) (err error) {
-	defer recoverError(&err)
-	write(w, uint32(fileHeaderSignature))
-	write(w, h.ReaderVersion)
-	write(w, h.Flags)
-	write(w, h.Method)
-	write(w, h.ModifiedTime)
-	write(w, h.ModifiedDate)
-	write(w, h.CRC32)
-	write(w, h.CompressedSize)
-	write(w, h.UncompressedSize)
-	write(w, uint16(len(h.Name)))
-	write(w, uint16(len(h.Extra)))
-	writeBytes(w, []byte(h.Name))
-	writeBytes(w, h.Extra)
-	return nil
+func writeHeader(w io.Writer, h *FileHeader) error {
+	var buf [fileHeaderLen]byte
+	b := writeBuf(buf[:])
+	b.uint32(uint32(fileHeaderSignature))
+	b.uint16(h.ReaderVersion)
+	b.uint16(h.Flags)
+	b.uint16(h.Method)
+	b.uint16(h.ModifiedTime)
+	b.uint16(h.ModifiedDate)
+	b.uint32(h.CRC32)
+	b.uint32(h.CompressedSize)
+	b.uint32(h.UncompressedSize)
+	b.uint16(uint16(len(h.Name)))
+	b.uint16(uint16(len(h.Extra)))
+	if _, err := w.Write(buf[:]); err != nil {
+		return err
+	}
+	if _, err := io.WriteString(w, h.Name); err != nil {
+		return err
+	}
+	_, err := w.Write(h.Extra)
+	return err
 }
 
 type fileWriter struct {
@@ -188,13 +206,13 @@ func (w *fileWriter) Write(p []byte) (int, error) {
 	return w.rawCount.Write(p)
 }
 
-func (w *fileWriter) close() (err error) {
+func (w *fileWriter) close() error {
 	if w.closed {
 		return errors.New("zip: file closed twice")
 	}
 	w.closed = true
-	if err = w.comp.Close(); err != nil {
-		return
+	if err := w.comp.Close(); err != nil {
+		return err
 	}
 
 	// update FileHeader
@@ -204,12 +222,13 @@ func (w *fileWriter) close() (err error) {
 	fh.UncompressedSize = uint32(w.rawCount.count)
 
 	// write data descriptor
-	defer recoverError(&err)
-	write(w.zipw, fh.CRC32)
-	write(w.zipw, fh.CompressedSize)
-	write(w.zipw, fh.UncompressedSize)
-
-	return nil
+	var buf [dataDescriptorLen]byte
+	b := writeBuf(buf[:])
+	b.uint32(fh.CRC32)
+	b.uint32(fh.CompressedSize)
+	b.uint32(fh.UncompressedSize)
+	_, err := w.zipw.Write(buf[:])
+	return err
 }
 
 type countWriter struct {
@@ -231,18 +250,14 @@ func (w nopCloser) Close() error {
 	return nil
 }
 
-func write(w io.Writer, data interface{}) {
-	if err := binary.Write(w, binary.LittleEndian, data); err != nil {
-		panic(err)
-	}
+type writeBuf []byte
+
+func (b *writeBuf) uint16(v uint16) {
+	binary.LittleEndian.PutUint16(*b, v)
+	*b = (*b)[2:]
 }
 
-func writeBytes(w io.Writer, b []byte) {
-	n, err := w.Write(b)
-	if err != nil {
-		panic(err)
-	}
-	if n != len(b) {
-		panic(io.ErrShortWrite)
-	}
+func (b *writeBuf) uint32(v uint32) {
+	binary.LittleEndian.PutUint32(*b, v)
+	*b = (*b)[4:]
 }
diff --git a/src/pkg/bufio/bufio.go b/src/pkg/bufio/bufio.go
index 6f3b1ee..b44d0e7 100644
--- a/src/pkg/bufio/bufio.go
+++ b/src/pkg/bufio/bufio.go
@@ -23,7 +23,6 @@ var (
 	ErrInvalidUnreadRune = errors.New("bufio: invalid use of UnreadRune")
 	ErrBufferFull        = errors.New("bufio: buffer full")
 	ErrNegativeCount     = errors.New("bufio: negative count")
-	errInternal          = errors.New("bufio: internal error")
 )
 
 // Buffered input.
diff --git a/src/pkg/crypto/ecdsa/ecdsa.go b/src/pkg/crypto/ecdsa/ecdsa.go
index d2f7d8f..b28239b 100644
--- a/src/pkg/crypto/ecdsa/ecdsa.go
+++ b/src/pkg/crypto/ecdsa/ecdsa.go
@@ -7,7 +7,7 @@
 package ecdsa
 
 // References:
-//   [NSA]: Suite B implementor's guide to FIPS 186-3,
+//   [NSA]: Suite B implementer's guide to FIPS 186-3,
 //     http://www.nsa.gov/ia/_files/ecdsa.pdf
 //   [SECG]: SECG, SEC1
 //     http://www.secg.org/download/aid-780/sec1-v2.pdf
diff --git a/src/pkg/crypto/tls/root_darwin.go b/src/pkg/crypto/tls/root_darwin.go
index db1b18b..911a9a6 100644
--- a/src/pkg/crypto/tls/root_darwin.go
+++ b/src/pkg/crypto/tls/root_darwin.go
@@ -5,11 +5,9 @@
 package tls
 
 /*
-// Note: We disable -Werror here because the code in this file uses a deprecated API to stay
-// compatible with both Mac OS X 10.6 and 10.7. Using a deprecated function on Darwin generates
-// a warning.
-#cgo CFLAGS: -Wno-error -Wno-deprecated-declarations
+#cgo CFLAGS: -mmacosx-version-min=10.6 -D__MAC_OS_X_VERSION_MAX_ALLOWED=1060
 #cgo LDFLAGS: -framework CoreFoundation -framework Security
+
 #include <CoreFoundation/CoreFoundation.h>
 #include <Security/Security.h>
 
@@ -40,26 +38,12 @@ int FetchPEMRoots(CFDataRef *pemRoots) {
 			continue;
 		}
 
-		// SecKeychainImportExport is deprecated in >= OS X 10.7, and has been replaced by
-		// SecItemExport.  If we're built on a host with a Lion SDK, this code gets conditionally
-		// included in the output, also for binaries meant for 10.6.
-		//
-		// To make sure that we run on both Mac OS X 10.6 and 10.7 we use weak linking
-		// and check whether SecItemExport is available before we attempt to call it. On
-		// 10.6, this won't be the case, and we'll fall back to calling SecKeychainItemExport.
-#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
-		if (SecItemExport) {
-			err = SecItemExport(cert, kSecFormatX509Cert, kSecItemPemArmour, NULL, &data);
-			if (err != noErr) {
-				continue;
-			}
-		} else
-#endif
-		if (data == NULL) {
-			err = SecKeychainItemExport(cert, kSecFormatX509Cert, kSecItemPemArmour, NULL, &data);
-			if (err != noErr) {
-				continue;
-			}
+		// Note: SecKeychainItemExport is deprecated as of 10.7 in favor of SecItemExport.
+		// Once we support weak imports via cgo we should prefer that, and fall back to this
+		// for older systems.
+		err = SecKeychainItemExport(cert, kSecFormatX509Cert, kSecItemPemArmour, NULL, &data);
+		if (err != noErr) {
+			continue;
 		}
 
 		if (data != NULL) {
diff --git a/src/pkg/crypto/x509/verify.go b/src/pkg/crypto/x509/verify.go
index 87b1cb7..3859dd8 100644
--- a/src/pkg/crypto/x509/verify.go
+++ b/src/pkg/crypto/x509/verify.go
@@ -135,8 +135,8 @@ func (c *Certificate) isValid(certType int, opts *VerifyOptions) error {
 
 // Verify attempts to verify c by building one or more chains from c to a
 // certificate in opts.roots, using certificates in opts.Intermediates if
-// needed. If successful, it returns one or chains where the first element of
-// the chain is c and the last element is from opts.Roots.
+// needed. If successful, it returns one or more chains where the first
+// element of the chain is c and the last element is from opts.Roots.
 //
 // WARNING: this doesn't do any revocation checking.
 func (c *Certificate) Verify(opts VerifyOptions) (chains [][]*Certificate, err error) {
diff --git a/src/pkg/crypto/x509/x509.go b/src/pkg/crypto/x509/x509.go
index 3116525..f5da86b 100644
--- a/src/pkg/crypto/x509/x509.go
+++ b/src/pkg/crypto/x509/x509.go
@@ -153,7 +153,7 @@ const (
 //
 // md2WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 2 }
 //
-// md5WithRSAEncryption OBJECT IDENTIFER ::= { pkcs-1 4 }
+// md5WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 4 }
 //
 // sha-1WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 5 }
 // 
@@ -172,9 +172,9 @@ const (
 //
 // RFC 5758 3.1 DSA Signature Algorithms
 //
-// dsaWithSha356 OBJECT IDENTIFER ::= {
+// dsaWithSha256 OBJECT IDENTIFIER ::= {
 //    joint-iso-ccitt(2) country(16) us(840) organization(1) gov(101)
-//    algorithms(4) id-dsa-with-sha2(3) 2}
+//    csor(3) algorithms(4) id-dsa-with-sha2(3) 2}
 //
 var (
 	oidSignatureMD2WithRSA    = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 2}
diff --git a/src/pkg/encoding/binary/binary.go b/src/pkg/encoding/binary/binary.go
index b26b1bb..02f090d 100644
--- a/src/pkg/encoding/binary/binary.go
+++ b/src/pkg/encoding/binary/binary.go
@@ -29,17 +29,13 @@ type ByteOrder interface {
 	String() string
 }
 
-// This is byte instead of struct{} so that it can be compared,
-// allowing, e.g., order == binary.LittleEndian.
-type unused byte
-
 // LittleEndian is the little-endian implementation of ByteOrder.
 var LittleEndian littleEndian
 
 // BigEndian is the big-endian implementation of ByteOrder.
 var BigEndian bigEndian
 
-type littleEndian unused
+type littleEndian struct{}
 
 func (littleEndian) Uint16(b []byte) uint16 { return uint16(b[0]) | uint16(b[1])<<8 }
 
@@ -79,7 +75,7 @@ func (littleEndian) String() string { return "LittleEndian" }
 
 func (littleEndian) GoString() string { return "binary.LittleEndian" }
 
-type bigEndian unused
+type bigEndian struct{}
 
 func (bigEndian) Uint16(b []byte) uint16 { return uint16(b[1]) | uint16(b[0])<<8 }
 
diff --git a/src/pkg/encoding/binary/example_test.go b/src/pkg/encoding/binary/example_test.go
index 405ea67..dec12eb 100644
--- a/src/pkg/encoding/binary/example_test.go
+++ b/src/pkg/encoding/binary/example_test.go
@@ -25,9 +25,9 @@ func ExampleWrite() {
 func ExampleWrite_multi() {
 	buf := new(bytes.Buffer)
 	var data = []interface{}{
+		uint16(61374),
 		int8(-54),
 		uint8(254),
-		uint16(48826),
 	}
 	for _, v := range data {
 		err := binary.Write(buf, binary.LittleEndian, v)
@@ -36,7 +36,7 @@ func ExampleWrite_multi() {
 		}
 	}
 	fmt.Printf("%x", buf.Bytes())
-	// Output: cafebabe
+	// Output: beefcafe
 }
 
 func ExampleRead() {
diff --git a/src/pkg/encoding/gob/Makefile b/src/pkg/encoding/gob/Makefile
deleted file mode 100644
index 3de845e..0000000
--- a/src/pkg/encoding/gob/Makefile
+++ /dev/null
@@ -1,9 +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.
-
-# Help for debugging.
-dump:	dump.go
-	go clean -i  # remove installed copy
-	go build -t gob-debug -o dump dump.go
-
diff --git a/src/pkg/encoding/gob/codec_test.go b/src/pkg/encoding/gob/codec_test.go
index d365f82..ebcbb78 100644
--- a/src/pkg/encoding/gob/codec_test.go
+++ b/src/pkg/encoding/gob/codec_test.go
@@ -1455,11 +1455,14 @@ func TestFuzz(t *testing.T) {
 func TestFuzzRegressions(t *testing.T) {
 	// An instance triggering a type name of length ~102 GB.
 	testFuzz(t, 1328492090837718000, 100, new(float32))
+	// An instance triggering a type name of 1.6 GB.
+	// Commented out because it takes 5m to run.
+	//testFuzz(t, 1330522872628565000, 100, new(int))
 }
 
 func testFuzz(t *testing.T, seed int64, n int, input ...interface{}) {
-	t.Logf("seed=%d n=%d\n", seed, n)
 	for _, e := range input {
+		t.Logf("seed=%d n=%d e=%T", seed, n, e)
 		rng := rand.New(rand.NewSource(seed))
 		for i := 0; i < n; i++ {
 			encFuzzDec(rng, e)
diff --git a/src/pkg/encoding/gob/debug.go b/src/pkg/encoding/gob/debug.go
index b54ef46..31d1351 100644
--- a/src/pkg/encoding/gob/debug.go
+++ b/src/pkg/encoding/gob/debug.go
@@ -3,14 +3,15 @@
 // license that can be found in the LICENSE file.
 
 // Delete the next line to include in the gob package.
-// +build gob-debug
+// +build ignore
 
 package gob
 
 // This file is not normally included in the gob package.  Used only for debugging the package itself.
-// Add debug.go to the files listed in the Makefile to add Debug to the gob package.
 // Except for reading uints, it is an implementation of a reader that is independent of
 // the one implemented by Decoder.
+// To enable the Debug function, delete the +build ignore line above and do
+//	go install
 
 import (
 	"bytes"
diff --git a/src/pkg/encoding/gob/decode.go b/src/pkg/encoding/gob/decode.go
index a0bb985..0708a83 100644
--- a/src/pkg/encoding/gob/decode.go
+++ b/src/pkg/encoding/gob/decode.go
@@ -392,12 +392,12 @@ func decUint8Slice(i *decInstr, state *decoderState, p unsafe.Pointer) {
 		}
 		p = *(*unsafe.Pointer)(p)
 	}
-	n := int(state.decodeUint())
-	if n < 0 {
-		errorf("negative length decoding []byte")
+	n := state.decodeUint()
+	if n > uint64(state.b.Len()) {
+		errorf("length of []byte exceeds input size (%d bytes)", n)
 	}
 	slice := (*[]uint8)(p)
-	if cap(*slice) < n {
+	if uint64(cap(*slice)) < n {
 		*slice = make([]uint8, n)
 	} else {
 		*slice = (*slice)[0:n]
@@ -417,7 +417,11 @@ func decString(i *decInstr, state *decoderState, p unsafe.Pointer) {
 		}
 		p = *(*unsafe.Pointer)(p)
 	}
-	b := make([]byte, state.decodeUint())
+	n := state.decodeUint()
+	if n > uint64(state.b.Len()) {
+		errorf("string length exceeds input size (%d bytes)", n)
+	}
+	b := make([]byte, n)
 	state.b.Read(b)
 	// It would be a shame to do the obvious thing here,
 	//	*(*string)(p) = string(b)
@@ -647,7 +651,11 @@ func (dec *Decoder) ignoreMap(state *decoderState, keyOp, elemOp decOp) {
 // decodeSlice decodes a slice and stores the slice header through p.
 // Slices are encoded as an unsigned length followed by the elements.
 func (dec *Decoder) decodeSlice(atyp reflect.Type, state *decoderState, p uintptr, elemOp decOp, elemWid uintptr, indir, elemIndir int, ovfl error) {
-	n := int(uintptr(state.decodeUint()))
+	nr := state.decodeUint()
+	if nr > uint64(state.b.Len()) {
+		errorf("length of slice exceeds input size (%d elements)", nr)
+	}
+	n := int(nr)
 	if indir > 0 {
 		up := unsafe.Pointer(p)
 		if *(*unsafe.Pointer)(up) == nil {
@@ -702,6 +710,9 @@ func (dec *Decoder) decodeInterface(ityp reflect.Type, state *decoderState, p ui
 		*(*[2]uintptr)(unsafe.Pointer(p)) = ivalue.InterfaceData()
 		return
 	}
+	if len(name) > 1024 {
+		errorf("name too long (%d bytes): %.20q...", len(name), name)
+	}
 	// The concrete type must be registered.
 	typ, ok := nameToConcreteType[name]
 	if !ok {
diff --git a/src/pkg/encoding/gob/dump.go b/src/pkg/encoding/gob/dump.go
index e23a11e..17238c9 100644
--- a/src/pkg/encoding/gob/dump.go
+++ b/src/pkg/encoding/gob/dump.go
@@ -7,6 +7,7 @@
 package main
 
 // Need to compile package gob with debug.go to build this program.
+// See comments in debug.go for how to do this.
 
 import (
 	"encoding/gob"
diff --git a/src/pkg/encoding/gob/encoder_test.go b/src/pkg/encoding/gob/encoder_test.go
index 3bfae30..050786d 100644
--- a/src/pkg/encoding/gob/encoder_test.go
+++ b/src/pkg/encoding/gob/encoder_test.go
@@ -709,7 +709,7 @@ func TestGobPtrSlices(t *testing.T) {
 		t.Fatal("decode:", err)
 	}
 	if !reflect.DeepEqual(in, out) {
-		t.Fatal("got %v; wanted %v", out, in)
+		t.Fatalf("got %v; wanted %v", out, in)
 	}
 }
 
diff --git a/src/pkg/encoding/json/decode_test.go b/src/pkg/encoding/json/decode_test.go
index 0eec586..d758758 100644
--- a/src/pkg/encoding/json/decode_test.go
+++ b/src/pkg/encoding/json/decode_test.go
@@ -239,16 +239,6 @@ func TestEscape(t *testing.T) {
 	}
 }
 
-func TestHTMLEscape(t *testing.T) {
-	b, err := MarshalForHTML("foobarbaz<>&quux")
-	if err != nil {
-		t.Fatalf("MarshalForHTML error: %v", err)
-	}
-	if !bytes.Equal(b, []byte(`"foobarbaz\u003c\u003e\u0026quux"`)) {
-		t.Fatalf("Unexpected encoding of \"<>&\": %s", b)
-	}
-}
-
 // WrongString is a struct that's misusing the ,string modifier.
 type WrongString struct {
 	Message string `json:"result,string"`
diff --git a/src/pkg/encoding/json/encode.go b/src/pkg/encoding/json/encode.go
index 8a794b7..5425a3a 100644
--- a/src/pkg/encoding/json/encode.go
+++ b/src/pkg/encoding/json/encode.go
@@ -123,17 +123,6 @@ func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) {
 	return buf.Bytes(), nil
 }
 
-// MarshalForHTML is like Marshal but applies HTMLEscape to the output.
-func MarshalForHTML(v interface{}) ([]byte, error) {
-	b, err := Marshal(v)
-	if err != nil {
-		return nil, err
-	}
-	var buf bytes.Buffer
-	HTMLEscape(&buf, b)
-	return buf.Bytes(), nil
-}
-
 // HTMLEscape appends to dst the JSON-encoded src with <, >, and &
 // characters inside string literals changed to \u003c, \u003e, \u0026
 // so that the JSON will be safe to embed inside HTML <script> tags.
@@ -200,11 +189,6 @@ func (e *MarshalerError) Error() string {
 	return "json: error calling MarshalJSON for type " + e.Type.String() + ": " + e.Err.Error()
 }
 
-type interfaceOrPtrValue interface {
-	IsNil() bool
-	Elem() reflect.Value
-}
-
 var hex = "0123456789abcdef"
 
 // An encodeState encodes JSON into a bytes.Buffer.
@@ -276,7 +260,7 @@ func (e *encodeState) reflectValueQuoted(v reflect.Value, quoted bool) {
 		b, err := m.MarshalJSON()
 		if err == nil {
 			// copy JSON into buffer, checking validity.
-			err = Compact(&e.Buffer, b)
+			err = compact(&e.Buffer, b, true)
 		}
 		if err != nil {
 			e.error(&MarshalerError{v.Type(), err})
diff --git a/src/pkg/encoding/json/encode_test.go b/src/pkg/encoding/json/encode_test.go
index 7a726a9..cb1c77e 100644
--- a/src/pkg/encoding/json/encode_test.go
+++ b/src/pkg/encoding/json/encode_test.go
@@ -167,3 +167,22 @@ func TestRefValMarshal(t *testing.T) {
 		t.Errorf("got %q, want %q", got, want)
 	}
 }
+
+// C implements Marshaler and returns unescaped JSON.
+type C int
+
+func (C) MarshalJSON() ([]byte, error) {
+	return []byte(`"<&>"`), nil
+}
+
+func TestMarshalerEscaping(t *testing.T) {
+	var c C
+	const want = `"\u003c\u0026\u003e"`
+	b, err := Marshal(c)
+	if err != nil {
+		t.Fatalf("Marshal: %v", err)
+	}
+	if got := string(b); got != want {
+		t.Errorf("got %q, want %q", got, want)
+	}
+}
diff --git a/src/pkg/encoding/json/indent.go b/src/pkg/encoding/json/indent.go
index 5ba19b0..e8dfa4e 100644
--- a/src/pkg/encoding/json/indent.go
+++ b/src/pkg/encoding/json/indent.go
@@ -9,11 +9,24 @@ import "bytes"
 // Compact appends to dst the JSON-encoded src with
 // insignificant space characters elided.
 func Compact(dst *bytes.Buffer, src []byte) error {
+	return compact(dst, src, false)
+}
+
+func compact(dst *bytes.Buffer, src []byte, escape bool) error {
 	origLen := dst.Len()
 	var scan scanner
 	scan.reset()
 	start := 0
 	for i, c := range src {
+		if escape && (c == '<' || c == '>' || c == '&') {
+			if start < i {
+				dst.Write(src[start:i])
+			}
+			dst.WriteString(`\u00`)
+			dst.WriteByte(hex[c>>4])
+			dst.WriteByte(hex[c&0xF])
+			start = i + 1
+		}
 		v := scan.step(&scan, int(c))
 		if v >= scanSkipSpace {
 			if v == scanError {
diff --git a/src/pkg/encoding/xml/example_test.go b/src/pkg/encoding/xml/example_test.go
index 082ce68..97c8c0b 100644
--- a/src/pkg/encoding/xml/example_test.go
+++ b/src/pkg/encoding/xml/example_test.go
@@ -52,7 +52,7 @@ func ExampleMarshalIndent() {
 
 // This example demonstrates unmarshaling an XML excerpt into a value with
 // some preset fields. Note that the Phone field isn't modified and that
-// the XML <address> element is ignored. Also, the Groups field is assigned
+// the XML <Company> element is ignored. Also, the Groups field is assigned
 // considering the element path provided in its tag.
 func ExampleUnmarshal() {
 	type Email struct {
@@ -71,11 +71,11 @@ func ExampleUnmarshal() {
 		Address
 	}
 	v := Result{Name: "none", Phone: "none"}
-	v.Address = Address{"Hanga Roa", "Easter Island"}
 
 	data := `
 		<Person>
 			<FullName>Grace R. Emlin</FullName>
+			<Company>Example Inc.</Company>
 			<Email where="home">
 				<Addr>gre at example.com</Addr>
 			</Email>
@@ -86,7 +86,8 @@ func ExampleUnmarshal() {
 				<Value>Friends</Value>
 				<Value>Squash</Value>
 			</Group>
-			<Address>123 Main Street</Address>
+			<City>Hanga Roa</City>
+			<State>Easter Island</State>
 		</Person>
 	`
 	err := xml.Unmarshal([]byte(data), &v)
diff --git a/src/pkg/encoding/xml/marshal_test.go b/src/pkg/encoding/xml/marshal_test.go
index 9170fcc..b6978a1 100644
--- a/src/pkg/encoding/xml/marshal_test.go
+++ b/src/pkg/encoding/xml/marshal_test.go
@@ -136,12 +136,12 @@ type NamePrecedence struct {
 
 type XMLNameWithTag struct {
 	XMLName Name   `xml:"InXMLNameTag"`
-	Value   string ",chardata"
+	Value   string `xml:",chardata"`
 }
 
 type XMLNameWithoutTag struct {
 	XMLName Name
-	Value   string ",chardata"
+	Value   string `xml:",chardata"`
 }
 
 type NameInField struct {
@@ -532,9 +532,9 @@ var marshalTests = []struct {
 			InFieldName: "D",
 		},
 		ExpectXML: `<Parent>` +
-			`<InTag><Value>A</Value></InTag>` +
-			`<InXMLName><Value>B</Value></InXMLName>` +
-			`<InXMLNameTag><Value>C</Value></InXMLNameTag>` +
+			`<InTag>A</InTag>` +
+			`<InXMLName>B</InXMLName>` +
+			`<InXMLNameTag>C</InXMLNameTag>` +
 			`<InFieldName>D</InFieldName>` +
 			`</Parent>`,
 		MarshalOnly: true,
@@ -548,9 +548,9 @@ var marshalTests = []struct {
 			InFieldName: "D",
 		},
 		ExpectXML: `<Parent>` +
-			`<InTag><Value>A</Value></InTag>` +
-			`<FromNameVal><Value>B</Value></FromNameVal>` +
-			`<InXMLNameTag><Value>C</Value></InXMLNameTag>` +
+			`<InTag>A</InTag>` +
+			`<FromNameVal>B</FromNameVal>` +
+			`<InXMLNameTag>C</InXMLNameTag>` +
 			`<InFieldName>D</InFieldName>` +
 			`</Parent>`,
 		UnmarshalOnly: true,
diff --git a/src/pkg/exp/gotype/doc.go b/src/pkg/exp/gotype/doc.go
index 1aa0faa..1168086 100644
--- a/src/pkg/exp/gotype/doc.go
+++ b/src/pkg/exp/gotype/doc.go
@@ -34,6 +34,8 @@ The flags are:
 		Verbose mode.
 
 Debugging flags:
+	-comments
+		Parse comments (ignored if -ast not set).
 	-ast
 		Print AST (disables concurrent parsing).
 	-trace
diff --git a/src/pkg/exp/gotype/gotype.go b/src/pkg/exp/gotype/gotype.go
index a2a9361..30eaf22 100644
--- a/src/pkg/exp/gotype/gotype.go
+++ b/src/pkg/exp/gotype/gotype.go
@@ -27,8 +27,9 @@ var (
 	allErrors = flag.Bool("e", false, "print all (including spurious) errors")
 
 	// debugging support
-	printTrace = flag.Bool("trace", false, "print parse trace")
-	printAST   = flag.Bool("ast", false, "print AST")
+	parseComments = flag.Bool("comments", false, "parse comments (ignored if -ast not set)")
+	printTrace    = flag.Bool("trace", false, "print parse trace")
+	printAST      = flag.Bool("ast", false, "print AST")
 )
 
 var exitCode = 0
@@ -73,6 +74,9 @@ func parse(fset *token.FileSet, filename string, src []byte) *ast.File {
 	if *allErrors {
 		mode |= parser.SpuriousErrors
 	}
+	if *parseComments && *printAST {
+		mode |= parser.ParseComments
+	}
 	if *printTrace {
 		mode |= parser.Trace
 	}
diff --git a/src/pkg/exp/html/node.go b/src/pkg/exp/html/node.go
index 83f1730..c105a4e 100644
--- a/src/pkg/exp/html/node.go
+++ b/src/pkg/exp/html/node.go
@@ -110,7 +110,7 @@ func (s *nodeStack) top() *Node {
 	return nil
 }
 
-// index returns the index of the top-most occurence of n in the stack, or -1
+// index returns the index of the top-most occurrence of n in the stack, or -1
 // if n is not present.
 func (s *nodeStack) index(n *Node) int {
 	for i := len(*s) - 1; i >= 0; i-- {
diff --git a/src/pkg/exp/norm/forminfo.go b/src/pkg/exp/norm/forminfo.go
index fd7b395..c443b78 100644
--- a/src/pkg/exp/norm/forminfo.go
+++ b/src/pkg/exp/norm/forminfo.go
@@ -18,17 +18,17 @@ package norm
 // has the form:
 //    <header> <decomp_byte>* [<tccc> [<lccc>]]
 // The header contains the number of bytes in the decomposition (excluding this
-// length byte). The two most significant bits of this lenght byte correspond
+// length byte). The two most significant bits of this length byte correspond
 // to bit 2 and 3 of qcIfo (see below).  The byte sequence itself starts at v+1.
 // The byte sequence is followed by a trailing and leading CCC if the values
 // for these are not zero.  The value of v determines which ccc are appended
 // to the sequences.  For v < firstCCC, there are none, for v >= firstCCC,
-// the seqence is followed by a trailing ccc, and for v >= firstLeadingCC
+// the sequence is followed by a trailing ccc, and for v >= firstLeadingCC
 // there is an additional leading ccc.
 
 const (
 	qcInfoMask      = 0xF  // to clear all but the relevant bits in a qcInfo
-	headerLenMask   = 0x3F // extract the lenght value from the header byte
+	headerLenMask   = 0x3F // extract the length value from the header byte
 	headerFlagsMask = 0xC0 // extract the qcInfo bits from the header byte
 )
 
diff --git a/src/pkg/exp/proxy/per_host.go b/src/pkg/exp/proxy/per_host.go
index 397ef57..0c627e9 100644
--- a/src/pkg/exp/proxy/per_host.go
+++ b/src/pkg/exp/proxy/per_host.go
@@ -75,7 +75,7 @@ func (p *PerHost) dialerForRequest(host string) Dialer {
 }
 
 // AddFromString parses a string that contains comma-separated values
-// specifing hosts that should use the bypass proxy. Each value is either an
+// specifying hosts that should use the bypass proxy. Each value is either an
 // IP address, a CIDR range, a zone (*.example.com) or a hostname
 // (localhost). A best effort is made to parse the string and errors are
 // ignored.
diff --git a/src/pkg/exp/types/gcimporter.go b/src/pkg/exp/types/gcimporter.go
index 8b28aed..cb996f2 100644
--- a/src/pkg/exp/types/gcimporter.go
+++ b/src/pkg/exp/types/gcimporter.go
@@ -18,6 +18,7 @@ import (
 	"os"
 	"path/filepath"
 	"strconv"
+	"strings"
 	"text/scanner"
 )
 
@@ -39,11 +40,14 @@ func findPkg(path string) (filename, id string) {
 	switch path[0] {
 	default:
 		// "x" -> "$GOPATH/pkg/$GOOS_$GOARCH/x.ext", "x"
-		tree, pkg, err := build.FindTree(path)
-		if err != nil {
+		bp, _ := build.Import(path, "", build.FindOnly)
+		if bp.PkgObj == "" {
 			return
 		}
-		noext = filepath.Join(tree.PkgDir(), pkg)
+		noext = bp.PkgObj
+		if strings.HasSuffix(noext, ".a") {
+			noext = noext[:len(noext)-2]
+		}
 
 	case '.':
 		// "./x" -> "/this/directory/x.ext", "/this/directory/x"
@@ -742,7 +746,7 @@ func (p *gcParser) parseVarDecl() {
 }
 
 // FuncBody = "{" ... "}" .
-// 
+//
 func (p *gcParser) parseFuncBody() {
 	p.expect('{')
 	for i := 1; i > 0; p.next() {
diff --git a/src/pkg/exp/types/types.go b/src/pkg/exp/types/types.go
index 3aa8968..85d244c 100644
--- a/src/pkg/exp/types/types.go
+++ b/src/pkg/exp/types/types.go
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// PACKAGE UNDER CONSTRUCTION. ANY AND ALL PARTS MAY CHANGE.
-// Package types declares the types used to represent Go types.
+// Package types declares the types used to represent Go types
+// (UNDER CONSTRUCTION). ANY AND ALL PARTS MAY CHANGE.
 //
 package types
 
diff --git a/src/pkg/go/ast/example_test.go b/src/pkg/go/ast/example_test.go
new file mode 100644
index 0000000..632bfcf
--- /dev/null
+++ b/src/pkg/go/ast/example_test.go
@@ -0,0 +1,136 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ast_test
+
+import (
+	"fmt"
+	"go/ast"
+	"go/parser"
+	"go/token"
+)
+
+// This example demonstrates how to inspect the AST of a Go program.
+func ExampleInspect() {
+	// src is the input for which we want to inspect the AST.
+	src := `
+package p
+const c = 1.0
+var X = f(3.14)*2 + c
+`
+
+	// Create the AST by parsing src.
+	fset := token.NewFileSet() // positions are relative to fset
+	f, err := parser.ParseFile(fset, "src.go", src, 0)
+	if err != nil {
+		panic(err)
+	}
+
+	// Inspect the AST and print all identifiers and literals.
+	ast.Inspect(f, func(n ast.Node) bool {
+		var s string
+		switch x := n.(type) {
+		case *ast.BasicLit:
+			s = x.Value
+		case *ast.Ident:
+			s = x.Name
+		}
+		if s != "" {
+			fmt.Printf("%s:\t%s\n", fset.Position(n.Pos()), s)
+		}
+		return true
+	})
+
+	// output:
+	// src.go:2:9:	p
+	// src.go:3:7:	c
+	// src.go:3:11:	1.0
+	// src.go:4:5:	X
+	// src.go:4:9:	f
+	// src.go:4:11:	3.14
+	// src.go:4:17:	2
+	// src.go:4:21:	c
+}
+
+// This example shows what an AST looks like when printed for debugging.
+func ExamplePrint() {
+	// src is the input for which we want to print the AST.
+	src := `
+package main
+func main() {
+	println("Hello, World!")
+}
+`
+
+	// Create the AST by parsing src.
+	fset := token.NewFileSet() // positions are relative to fset
+	f, err := parser.ParseFile(fset, "", src, 0)
+	if err != nil {
+		panic(err)
+	}
+
+	// Print the AST.
+	ast.Print(fset, f)
+
+	// output:
+	//      0  *ast.File {
+	//      1  .  Package: 2:1
+	//      2  .  Name: *ast.Ident {
+	//      3  .  .  NamePos: 2:9
+	//      4  .  .  Name: "main"
+	//      5  .  }
+	//      6  .  Decls: []ast.Decl (len = 1) {
+	//      7  .  .  0: *ast.FuncDecl {
+	//      8  .  .  .  Name: *ast.Ident {
+	//      9  .  .  .  .  NamePos: 3:6
+	//     10  .  .  .  .  Name: "main"
+	//     11  .  .  .  .  Obj: *ast.Object {
+	//     12  .  .  .  .  .  Kind: func
+	//     13  .  .  .  .  .  Name: "main"
+	//     14  .  .  .  .  .  Decl: *(obj @ 7)
+	//     15  .  .  .  .  }
+	//     16  .  .  .  }
+	//     17  .  .  .  Type: *ast.FuncType {
+	//     18  .  .  .  .  Func: 3:1
+	//     19  .  .  .  .  Params: *ast.FieldList {
+	//     20  .  .  .  .  .  Opening: 3:10
+	//     21  .  .  .  .  .  Closing: 3:11
+	//     22  .  .  .  .  }
+	//     23  .  .  .  }
+	//     24  .  .  .  Body: *ast.BlockStmt {
+	//     25  .  .  .  .  Lbrace: 3:13
+	//     26  .  .  .  .  List: []ast.Stmt (len = 1) {
+	//     27  .  .  .  .  .  0: *ast.ExprStmt {
+	//     28  .  .  .  .  .  .  X: *ast.CallExpr {
+	//     29  .  .  .  .  .  .  .  Fun: *ast.Ident {
+	//     30  .  .  .  .  .  .  .  .  NamePos: 4:2
+	//     31  .  .  .  .  .  .  .  .  Name: "println"
+	//     32  .  .  .  .  .  .  .  }
+	//     33  .  .  .  .  .  .  .  Lparen: 4:9
+	//     34  .  .  .  .  .  .  .  Args: []ast.Expr (len = 1) {
+	//     35  .  .  .  .  .  .  .  .  0: *ast.BasicLit {
+	//     36  .  .  .  .  .  .  .  .  .  ValuePos: 4:10
+	//     37  .  .  .  .  .  .  .  .  .  Kind: STRING
+	//     38  .  .  .  .  .  .  .  .  .  Value: "\"Hello, World!\""
+	//     39  .  .  .  .  .  .  .  .  }
+	//     40  .  .  .  .  .  .  .  }
+	//     41  .  .  .  .  .  .  .  Ellipsis: -
+	//     42  .  .  .  .  .  .  .  Rparen: 4:25
+	//     43  .  .  .  .  .  .  }
+	//     44  .  .  .  .  .  }
+	//     45  .  .  .  .  }
+	//     46  .  .  .  .  Rbrace: 5:1
+	//     47  .  .  .  }
+	//     48  .  .  }
+	//     49  .  }
+	//     50  .  Scope: *ast.Scope {
+	//     51  .  .  Objects: map[string]*ast.Object (len = 1) {
+	//     52  .  .  .  "main": *(obj @ 11)
+	//     53  .  .  }
+	//     54  .  }
+	//     55  .  Unresolved: []*ast.Ident (len = 1) {
+	//     56  .  .  0: *(obj @ 29)
+	//     57  .  }
+	//     58  }
+}
diff --git a/src/pkg/go/ast/print.go b/src/pkg/go/ast/print.go
index f6c63c0..02cf9e0 100644
--- a/src/pkg/go/ast/print.go
+++ b/src/pkg/go/ast/print.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// This file contains printing suppport for ASTs.
+// This file contains printing support for ASTs.
 
 package ast
 
diff --git a/src/pkg/go/build/build.go b/src/pkg/go/build/build.go
index 68e8d34..eece761 100644
--- a/src/pkg/go/build/build.go
+++ b/src/pkg/go/build/build.go
@@ -2,10 +2,948 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Package build provides tools for building Go packages.
 package build
 
-import "errors"
+import (
+	"bytes"
+	"errors"
+	"fmt"
+	"go/ast"
+	"go/doc"
+	"go/parser"
+	"go/token"
+	"io"
+	"io/ioutil"
+	"log"
+	"os"
+	pathpkg "path"
+	"path/filepath"
+	"runtime"
+	"sort"
+	"strconv"
+	"strings"
+	"unicode"
+)
+
+// A Context specifies the supporting context for a build.
+type Context struct {
+	GOARCH      string   // target architecture
+	GOOS        string   // target operating system
+	GOROOT      string   // Go root
+	GOPATH      string   // Go path
+	CgoEnabled  bool     // whether cgo can be used
+	BuildTags   []string // additional tags to recognize in +build lines
+	UseAllFiles bool     // use files regardless of +build lines, file names
+	Gccgo       bool     // assume use of gccgo when computing object paths
+
+	// By default, Import uses the operating system's file system calls
+	// to read directories and files.  To read from other sources,
+	// callers can set the following functions.  They all have default
+	// behaviors that use the local file system, so clients need only set
+	// the functions whose behaviors they wish to change.
+
+	// JoinPath joins the sequence of path fragments into a single path.
+	// If JoinPath is nil, Import uses filepath.Join.
+	JoinPath func(elem ...string) string
+
+	// SplitPathList splits the path list into a slice of individual paths.
+	// If SplitPathList is nil, Import uses filepath.SplitList.
+	SplitPathList func(list string) []string
+
+	// IsAbsPath reports whether path is an absolute path.
+	// If IsAbsPath is nil, Import uses filepath.IsAbs.
+	IsAbsPath func(path string) bool
+
+	// IsDir reports whether the path names a directory.
+	// If IsDir is nil, Import calls os.Stat and uses the result's IsDir method.
+	IsDir func(path string) bool
+
+	// HasSubdir reports whether dir is a subdirectory of
+	// (perhaps multiple levels below) root.
+	// If so, HasSubdir sets rel to a slash-separated path that
+	// can be joined to root to produce a path equivalent to dir.
+	// If HasSubdir is nil, Import uses an implementation built on
+	// filepath.EvalSymlinks.
+	HasSubdir func(root, dir string) (rel string, ok bool)
+
+	// ReadDir returns a slice of os.FileInfo, sorted by Name,
+	// describing the content of the named directory.
+	// If ReadDir is nil, Import uses io.ReadDir.
+	ReadDir func(dir string) (fi []os.FileInfo, err error)
+
+	// OpenFile opens a file (not a directory) for reading.
+	// If OpenFile is nil, Import uses os.Open.
+	OpenFile func(path string) (r io.ReadCloser, err error)
+}
+
+// joinPath calls ctxt.JoinPath (if not nil) or else filepath.Join.
+func (ctxt *Context) joinPath(elem ...string) string {
+	if f := ctxt.JoinPath; f != nil {
+		return f(elem...)
+	}
+	return filepath.Join(elem...)
+}
+
+// splitPathList calls ctxt.SplitPathList (if not nil) or else filepath.SplitList.
+func (ctxt *Context) splitPathList(s string) []string {
+	if f := ctxt.SplitPathList; f != nil {
+		return f(s)
+	}
+	return filepath.SplitList(s)
+}
+
+// isAbsPath calls ctxt.IsAbsSPath (if not nil) or else filepath.IsAbs.
+func (ctxt *Context) isAbsPath(path string) bool {
+	if f := ctxt.IsAbsPath; f != nil {
+		return f(path)
+	}
+	return filepath.IsAbs(path)
+}
+
+// isDir calls ctxt.IsDir (if not nil) or else uses os.Stat.
+func (ctxt *Context) isDir(path string) bool {
+	if f := ctxt.IsDir; f != nil {
+		return f(path)
+	}
+	fi, err := os.Stat(path)
+	return err == nil && fi.IsDir()
+}
+
+// hasSubdir calls ctxt.HasSubdir (if not nil) or else uses
+// the local file system to answer the question.
+func (ctxt *Context) hasSubdir(root, dir string) (rel string, ok bool) {
+	if f := ctxt.HasSubdir; f != nil {
+		return f(root, dir)
+	}
+
+	if p, err := filepath.EvalSymlinks(root); err == nil {
+		root = p
+	}
+	if p, err := filepath.EvalSymlinks(dir); err == nil {
+		dir = p
+	}
+	const sep = string(filepath.Separator)
+	root = filepath.Clean(root)
+	if !strings.HasSuffix(root, sep) {
+		root += sep
+	}
+	dir = filepath.Clean(dir)
+	if !strings.HasPrefix(dir, root) {
+		return "", false
+	}
+	return filepath.ToSlash(dir[len(root):]), true
+}
+
+// readDir calls ctxt.ReadDir (if not nil) or else ioutil.ReadDir.
+func (ctxt *Context) readDir(path string) ([]os.FileInfo, error) {
+	if f := ctxt.ReadDir; f != nil {
+		return f(path)
+	}
+	return ioutil.ReadDir(path)
+}
+
+// openFile calls ctxt.OpenFile (if not nil) or else os.Open.
+func (ctxt *Context) openFile(path string) (io.ReadCloser, error) {
+	if fn := ctxt.OpenFile; fn != nil {
+		return fn(path)
+	}
+
+	f, err := os.Open(path)
+	if err != nil {
+		return nil, err // nil interface
+	}
+	return f, nil
+}
+
+// isFile determines whether path is a file by trying to open it.
+// It reuses openFile instead of adding another function to the
+// list in Context.
+func (ctxt *Context) isFile(path string) bool {
+	f, err := ctxt.openFile(path)
+	if err != nil {
+		return false
+	}
+	f.Close()
+	return true
+}
+
+// gopath returns the list of Go path directories.
+func (ctxt *Context) gopath() []string {
+	var all []string
+	for _, p := range ctxt.splitPathList(ctxt.GOPATH) {
+		if p == "" || p == ctxt.GOROOT {
+			// Empty paths are uninteresting.
+			// If the path is the GOROOT, ignore it.
+			// People sometimes set GOPATH=$GOROOT, which is useless
+			// but would cause us to find packages with import paths
+			// like "pkg/math".
+			// Do not get confused by this common mistake.
+			continue
+		}
+		all = append(all, p)
+	}
+	return all
+}
+
+// SrcDirs returns a list of package source root directories.
+// It draws from the current Go root and Go path but omits directories
+// that do not exist.
+func (ctxt *Context) SrcDirs() []string {
+	var all []string
+	if ctxt.GOROOT != "" {
+		dir := ctxt.joinPath(ctxt.GOROOT, "src", "pkg")
+		if ctxt.isDir(dir) {
+			all = append(all, dir)
+		}
+	}
+	for _, p := range ctxt.gopath() {
+		dir := ctxt.joinPath(p, "src")
+		if ctxt.isDir(dir) {
+			all = append(all, dir)
+		}
+	}
+	return all
+}
+
+// Default is the default Context for builds.
+// It uses the GOARCH, GOOS, GOROOT, and GOPATH environment variables
+// if set, or else the compiled code's GOARCH, GOOS, and GOROOT.
+var Default Context = defaultContext()
+
+var cgoEnabled = map[string]bool{
+	"darwin/386":    true,
+	"darwin/amd64":  true,
+	"linux/386":     true,
+	"linux/amd64":   true,
+	"freebsd/386":   true,
+	"freebsd/amd64": true,
+	"windows/386":   true,
+	"windows/amd64": true,
+}
+
+func defaultContext() Context {
+	var c Context
+
+	c.GOARCH = envOr("GOARCH", runtime.GOARCH)
+	c.GOOS = envOr("GOOS", runtime.GOOS)
+	c.GOROOT = runtime.GOROOT()
+	c.GOPATH = envOr("GOPATH", "")
+
+	switch os.Getenv("CGO_ENABLED") {
+	case "1":
+		c.CgoEnabled = true
+	case "0":
+		c.CgoEnabled = false
+	default:
+		c.CgoEnabled = cgoEnabled[c.GOOS+"/"+c.GOARCH]
+	}
+
+	return c
+}
+
+func envOr(name, def string) string {
+	s := os.Getenv(name)
+	if s == "" {
+		return def
+	}
+	return s
+}
+
+// An ImportMode controls the behavior of the Import method.
+type ImportMode uint
+
+const (
+	// If FindOnly is set, Import stops after locating the directory
+	// that should contain the sources for a package.  It does not
+	// read any files in the directory.
+	FindOnly ImportMode = 1 << iota
+
+	// If AllowBinary is set, Import can be satisfied by a compiled
+	// package object without corresponding sources.
+	AllowBinary
+)
+
+// A Package describes the Go package found in a directory.
+type Package struct {
+	Dir        string // directory containing package sources
+	Name       string // package name
+	Doc        string // documentation synopsis
+	ImportPath string // import path of package ("" if unknown)
+	Root       string // root of Go tree where this package lives
+	SrcRoot    string // package source root directory ("" if unknown)
+	PkgRoot    string // package install root directory ("" if unknown)
+	BinDir     string // command install directory ("" if unknown)
+	Goroot     bool   // package found in Go root
+	PkgObj     string // installed .a file
+
+	// Source files
+	GoFiles  []string // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
+	CgoFiles []string // .go source files that import "C"
+	CFiles   []string // .c source files
+	HFiles   []string // .h source files
+	SFiles   []string // .s source files
+
+	// Cgo directives
+	CgoPkgConfig []string // Cgo pkg-config directives
+	CgoCFLAGS    []string // Cgo CFLAGS directives
+	CgoLDFLAGS   []string // Cgo LDFLAGS directives
+
+	// Dependency information
+	Imports   []string                    // imports from GoFiles, CgoFiles
+	ImportPos map[string][]token.Position // line information for Imports
+
+	// Test information
+	TestGoFiles    []string                    // _test.go files in package
+	TestImports    []string                    // imports from TestGoFiles
+	TestImportPos  map[string][]token.Position // line information for TestImports
+	XTestGoFiles   []string                    // _test.go files outside package
+	XTestImports   []string                    // imports from XTestGoFiles
+	XTestImportPos map[string][]token.Position // line information for XTestImports
+}
+
+// IsCommand reports whether the package is considered a
+// command to be installed (not just a library).
+// Packages named "main" are treated as commands.
+func (p *Package) IsCommand() bool {
+	return p.Name == "main"
+}
+
+// ImportDir is like Import but processes the Go package found in
+// the named directory.
+func (ctxt *Context) ImportDir(dir string, mode ImportMode) (*Package, error) {
+	return ctxt.Import(".", dir, mode)
+}
+
+// Import returns details about the Go package named by the import path,
+// interpreting local import paths relative to the src directory.  If the path
+// is a local import path naming a package that can be imported using a
+// standard import path, the returned package will set p.ImportPath to
+// that path.
+//
+// In the directory containing the package, .go, .c, .h, and .s files are
+// considered part of the package except for:
+//
+//	- .go files in package documentation
+//	- files starting with _ or .
+//	- files with build constraints not satisfied by the context
+//
+// If an error occurs, Import returns a non-nil error also returns a non-nil
+// *Package containing partial information.
+//
+func (ctxt *Context) Import(path string, src string, mode ImportMode) (*Package, error) {
+	p := &Package{
+		ImportPath: path,
+	}
+
+	var pkga string
+	if ctxt.Gccgo {
+		dir, elem := pathpkg.Split(p.ImportPath)
+		pkga = "pkg/gccgo/" + dir + "lib" + elem + ".a"
+	} else {
+		pkga = "pkg/" + ctxt.GOOS + "_" + ctxt.GOARCH + "/" + p.ImportPath + ".a"
+	}
+
+	binaryOnly := false
+	if IsLocalImport(path) {
+		if src == "" {
+			return p, fmt.Errorf("import %q: import relative to unknown directory", path)
+		}
+		if !ctxt.isAbsPath(path) {
+			p.Dir = ctxt.joinPath(src, path)
+		}
+		// Determine canonical import path, if any.
+		if ctxt.GOROOT != "" {
+			root := ctxt.joinPath(ctxt.GOROOT, "src", "pkg")
+			if sub, ok := ctxt.hasSubdir(root, p.Dir); ok {
+				p.Goroot = true
+				p.ImportPath = sub
+				p.Root = ctxt.GOROOT
+				goto Found
+			}
+		}
+		all := ctxt.gopath()
+		for i, root := range all {
+			rootsrc := ctxt.joinPath(root, "src")
+			if sub, ok := ctxt.hasSubdir(rootsrc, p.Dir); ok {
+				// We found a potential import path for dir,
+				// but check that using it wouldn't find something
+				// else first.
+				if ctxt.GOROOT != "" {
+					if dir := ctxt.joinPath(ctxt.GOROOT, "src", sub); ctxt.isDir(dir) {
+						goto Found
+					}
+				}
+				for _, earlyRoot := range all[:i] {
+					if dir := ctxt.joinPath(earlyRoot, "src", sub); ctxt.isDir(dir) {
+						goto Found
+					}
+				}
+
+				// sub would not name some other directory instead of this one.
+				// Record it.
+				p.ImportPath = sub
+				p.Root = root
+				goto Found
+			}
+		}
+		// It's okay that we didn't find a root containing dir.
+		// Keep going with the information we have.
+	} else {
+		if strings.HasPrefix(path, "/") {
+			return p, fmt.Errorf("import %q: cannot import absolute path", path)
+		}
+		// Determine directory from import path.
+		if ctxt.GOROOT != "" {
+			dir := ctxt.joinPath(ctxt.GOROOT, "src", "pkg", path)
+			isDir := ctxt.isDir(dir)
+			binaryOnly = !isDir && mode&AllowBinary != 0 && ctxt.isFile(ctxt.joinPath(ctxt.GOROOT, pkga))
+			if isDir || binaryOnly {
+				p.Dir = dir
+				p.Goroot = true
+				p.Root = ctxt.GOROOT
+				goto Found
+			}
+		}
+		for _, root := range ctxt.gopath() {
+			dir := ctxt.joinPath(root, "src", path)
+			isDir := ctxt.isDir(dir)
+			binaryOnly = !isDir && mode&AllowBinary != 0 && ctxt.isFile(ctxt.joinPath(root, pkga))
+			if isDir || binaryOnly {
+				p.Dir = dir
+				p.Root = root
+				goto Found
+			}
+		}
+		return p, fmt.Errorf("import %q: cannot find package", path)
+	}
+
+Found:
+	if p.Root != "" {
+		if p.Goroot {
+			p.SrcRoot = ctxt.joinPath(p.Root, "src", "pkg")
+		} else {
+			p.SrcRoot = ctxt.joinPath(p.Root, "src")
+		}
+		p.PkgRoot = ctxt.joinPath(p.Root, "pkg")
+		p.BinDir = ctxt.joinPath(p.Root, "bin")
+		p.PkgObj = ctxt.joinPath(p.Root, pkga)
+	}
+
+	if mode&FindOnly != 0 {
+		return p, nil
+	}
+	if binaryOnly && (mode&AllowBinary) != 0 {
+		return p, nil
+	}
+
+	dirs, err := ctxt.readDir(p.Dir)
+	if err != nil {
+		return p, err
+	}
+
+	var Sfiles []string // files with ".S" (capital S)
+	var firstFile string
+	imported := make(map[string][]token.Position)
+	testImported := make(map[string][]token.Position)
+	xTestImported := make(map[string][]token.Position)
+	fset := token.NewFileSet()
+	for _, d := range dirs {
+		if d.IsDir() {
+			continue
+		}
+		name := d.Name()
+		if strings.HasPrefix(name, "_") ||
+			strings.HasPrefix(name, ".") {
+			continue
+		}
+		if !ctxt.UseAllFiles && !ctxt.goodOSArchFile(name) {
+			continue
+		}
+
+		i := strings.LastIndex(name, ".")
+		if i < 0 {
+			i = len(name)
+		}
+		ext := name[i:]
+		switch ext {
+		case ".go", ".c", ".s", ".h", ".S":
+			// tentatively okay
+		default:
+			// skip
+			continue
+		}
+
+		filename := ctxt.joinPath(p.Dir, name)
+		f, err := ctxt.openFile(filename)
+		if err != nil {
+			return p, err
+		}
+		data, err := ioutil.ReadAll(f)
+		f.Close()
+		if err != nil {
+			return p, fmt.Errorf("read %s: %v", filename, err)
+		}
+
+		// Look for +build comments to accept or reject the file.
+		if !ctxt.UseAllFiles && !ctxt.shouldBuild(data) {
+			continue
+		}
+
+		// Going to save the file.  For non-Go files, can stop here.
+		switch ext {
+		case ".c":
+			p.CFiles = append(p.CFiles, name)
+			continue
+		case ".h":
+			p.HFiles = append(p.HFiles, name)
+			continue
+		case ".s":
+			p.SFiles = append(p.SFiles, name)
+			continue
+		case ".S":
+			Sfiles = append(Sfiles, name)
+			continue
+		}
+
+		pf, err := parser.ParseFile(fset, filename, data, parser.ImportsOnly|parser.ParseComments)
+		if err != nil {
+			return p, err
+		}
+
+		pkg := string(pf.Name.Name)
+		if pkg == "documentation" {
+			continue
+		}
+
+		isTest := strings.HasSuffix(name, "_test.go")
+		isXTest := false
+		if isTest && strings.HasSuffix(pkg, "_test") {
+			isXTest = true
+			pkg = pkg[:len(pkg)-len("_test")]
+		}
+
+		if p.Name == "" {
+			p.Name = pkg
+			firstFile = name
+		} else if pkg != p.Name {
+			return p, fmt.Errorf("found packages %s (%s) and %s (%s) in %s", p.Name, firstFile, pkg, name, p.Dir)
+		}
+		if pf.Doc != nil && p.Doc == "" {
+			p.Doc = doc.Synopsis(pf.Doc.Text())
+		}
+
+		// Record imports and information about cgo.
+		isCgo := false
+		for _, decl := range pf.Decls {
+			d, ok := decl.(*ast.GenDecl)
+			if !ok {
+				continue
+			}
+			for _, dspec := range d.Specs {
+				spec, ok := dspec.(*ast.ImportSpec)
+				if !ok {
+					continue
+				}
+				quoted := string(spec.Path.Value)
+				path, err := strconv.Unquote(quoted)
+				if err != nil {
+					log.Panicf("%s: parser returned invalid quoted string: <%s>", filename, quoted)
+				}
+				if isXTest {
+					xTestImported[path] = append(xTestImported[path], fset.Position(spec.Pos()))
+				} else if isTest {
+					testImported[path] = append(testImported[path], fset.Position(spec.Pos()))
+				} else {
+					imported[path] = append(imported[path], fset.Position(spec.Pos()))
+				}
+				if path == "C" {
+					if isTest {
+						return p, fmt.Errorf("use of cgo in test %s not supported", filename)
+					}
+					cg := spec.Doc
+					if cg == nil && len(d.Specs) == 1 {
+						cg = d.Doc
+					}
+					if cg != nil {
+						if err := ctxt.saveCgo(filename, p, cg); err != nil {
+							return p, err
+						}
+					}
+					isCgo = true
+				}
+			}
+		}
+		if isCgo {
+			if ctxt.CgoEnabled {
+				p.CgoFiles = append(p.CgoFiles, name)
+			}
+		} else if isXTest {
+			p.XTestGoFiles = append(p.XTestGoFiles, name)
+		} else if isTest {
+			p.TestGoFiles = append(p.TestGoFiles, name)
+		} else {
+			p.GoFiles = append(p.GoFiles, name)
+		}
+	}
+	if p.Name == "" {
+		return p, fmt.Errorf("no Go source files in %s", p.Dir)
+	}
+
+	p.Imports, p.ImportPos = cleanImports(imported)
+	p.TestImports, p.TestImportPos = cleanImports(testImported)
+	p.XTestImports, p.XTestImportPos = cleanImports(xTestImported)
+
+	// add the .S files only if we are using cgo
+	// (which means gcc will compile them).
+	// The standard assemblers expect .s files.
+	if len(p.CgoFiles) > 0 {
+		p.SFiles = append(p.SFiles, Sfiles...)
+		sort.Strings(p.SFiles)
+	}
+
+	return p, nil
+}
+
+func cleanImports(m map[string][]token.Position) ([]string, map[string][]token.Position) {
+	all := make([]string, 0, len(m))
+	for path := range m {
+		all = append(all, path)
+	}
+	sort.Strings(all)
+	return all, m
+}
+
+// Import is shorthand for Default.Import.
+func Import(path, src string, mode ImportMode) (*Package, error) {
+	return Default.Import(path, src, mode)
+}
+
+// ImportDir is shorthand for Default.ImportDir.
+func ImportDir(dir string, mode ImportMode) (*Package, error) {
+	return Default.ImportDir(dir, mode)
+}
+
+var slashslash = []byte("//")
+
+// shouldBuild reports whether it is okay to use this file,
+// The rule is that in the file's leading run of // comments
+// and blank lines, which must be followed by a blank line
+// (to avoid including a Go package clause doc comment),
+// lines beginning with '// +build' are taken as build directives.
+//
+// The file is accepted only if each such line lists something
+// matching the file.  For example:
+//
+//	// +build windows linux
+//
+// marks the file as applicable only on Windows and Linux.
+//
+func (ctxt *Context) shouldBuild(content []byte) bool {
+	// Pass 1. Identify leading run of // comments and blank lines,
+	// which must be followed by a blank line.
+	end := 0
+	p := content
+	for len(p) > 0 {
+		line := p
+		if i := bytes.IndexByte(line, '\n'); i >= 0 {
+			line, p = line[:i], p[i+1:]
+		} else {
+			p = p[len(p):]
+		}
+		line = bytes.TrimSpace(line)
+		if len(line) == 0 { // Blank line
+			end = cap(content) - cap(line) // &line[0] - &content[0]
+			continue
+		}
+		if !bytes.HasPrefix(line, slashslash) { // Not comment line
+			break
+		}
+	}
+	content = content[:end]
+
+	// Pass 2.  Process each line in the run.
+	p = content
+	for len(p) > 0 {
+		line := p
+		if i := bytes.IndexByte(line, '\n'); i >= 0 {
+			line, p = line[:i], p[i+1:]
+		} else {
+			p = p[len(p):]
+		}
+		line = bytes.TrimSpace(line)
+		if bytes.HasPrefix(line, slashslash) {
+			line = bytes.TrimSpace(line[len(slashslash):])
+			if len(line) > 0 && line[0] == '+' {
+				// Looks like a comment +line.
+				f := strings.Fields(string(line))
+				if f[0] == "+build" {
+					ok := false
+					for _, tok := range f[1:] {
+						if ctxt.match(tok) {
+							ok = true
+							break
+						}
+					}
+					if !ok {
+						return false // this one doesn't match
+					}
+				}
+			}
+		}
+	}
+	return true // everything matches
+}
+
+// saveCgo saves the information from the #cgo lines in the import "C" comment.
+// These lines set CFLAGS and LDFLAGS and pkg-config directives that affect
+// the way cgo's C code is built.
+//
+// TODO(rsc): This duplicates code in cgo.
+// Once the dust settles, remove this code from cgo.
+func (ctxt *Context) saveCgo(filename string, di *Package, cg *ast.CommentGroup) error {
+	text := cg.Text()
+	for _, line := range strings.Split(text, "\n") {
+		orig := line
+
+		// Line is
+		//	#cgo [GOOS/GOARCH...] LDFLAGS: stuff
+		//
+		line = strings.TrimSpace(line)
+		if len(line) < 5 || line[:4] != "#cgo" || (line[4] != ' ' && line[4] != '\t') {
+			continue
+		}
+
+		// Split at colon.
+		line = strings.TrimSpace(line[4:])
+		i := strings.Index(line, ":")
+		if i < 0 {
+			return fmt.Errorf("%s: invalid #cgo line: %s", filename, orig)
+		}
+		line, argstr := line[:i], line[i+1:]
+
+		// Parse GOOS/GOARCH stuff.
+		f := strings.Fields(line)
+		if len(f) < 1 {
+			return fmt.Errorf("%s: invalid #cgo line: %s", filename, orig)
+		}
+
+		cond, verb := f[:len(f)-1], f[len(f)-1]
+		if len(cond) > 0 {
+			ok := false
+			for _, c := range cond {
+				if ctxt.match(c) {
+					ok = true
+					break
+				}
+			}
+			if !ok {
+				continue
+			}
+		}
+
+		args, err := splitQuoted(argstr)
+		if err != nil {
+			return fmt.Errorf("%s: invalid #cgo line: %s", filename, orig)
+		}
+		for _, arg := range args {
+			if !safeName(arg) {
+				return fmt.Errorf("%s: malformed #cgo argument: %s", filename, arg)
+			}
+		}
+
+		switch verb {
+		case "CFLAGS":
+			di.CgoCFLAGS = append(di.CgoCFLAGS, args...)
+		case "LDFLAGS":
+			di.CgoLDFLAGS = append(di.CgoLDFLAGS, args...)
+		case "pkg-config":
+			di.CgoPkgConfig = append(di.CgoPkgConfig, args...)
+		default:
+			return fmt.Errorf("%s: invalid #cgo verb: %s", filename, orig)
+		}
+	}
+	return nil
+}
+
+var safeBytes = []byte("+-.,/0123456789=ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz:")
+
+func safeName(s string) bool {
+	if s == "" {
+		return false
+	}
+	for i := 0; i < len(s); i++ {
+		if c := s[i]; c < 0x80 && bytes.IndexByte(safeBytes, c) < 0 {
+			return false
+		}
+	}
+	return true
+}
+
+// splitQuoted splits the string s around each instance of one or more consecutive
+// white space characters while taking into account quotes and escaping, and
+// returns an array of substrings of s or an empty list if s contains only white space.
+// Single quotes and double quotes are recognized to prevent splitting within the
+// quoted region, and are removed from the resulting substrings. If a quote in s
+// isn't closed err will be set and r will have the unclosed argument as the
+// last element.  The backslash is used for escaping.
+//
+// For example, the following string:
+//
+//     a b:"c d" 'e''f'  "g\""
+//
+// Would be parsed as:
+//
+//     []string{"a", "b:c d", "ef", `g"`}
+//
+func splitQuoted(s string) (r []string, err error) {
+	var args []string
+	arg := make([]rune, len(s))
+	escaped := false
+	quoted := false
+	quote := '\x00'
+	i := 0
+	for _, rune := range s {
+		switch {
+		case escaped:
+			escaped = false
+		case rune == '\\':
+			escaped = true
+			continue
+		case quote != '\x00':
+			if rune == quote {
+				quote = '\x00'
+				continue
+			}
+		case rune == '"' || rune == '\'':
+			quoted = true
+			quote = rune
+			continue
+		case unicode.IsSpace(rune):
+			if quoted || i > 0 {
+				quoted = false
+				args = append(args, string(arg[:i]))
+				i = 0
+			}
+			continue
+		}
+		arg[i] = rune
+		i++
+	}
+	if quoted || i > 0 {
+		args = append(args, string(arg[:i]))
+	}
+	if quote != 0 {
+		err = errors.New("unclosed quote")
+	} else if escaped {
+		err = errors.New("unfinished escaping")
+	}
+	return args, err
+}
+
+// match returns true if the name is one of:
+//
+//	$GOOS
+//	$GOARCH
+//	cgo (if cgo is enabled)
+//	!cgo (if cgo is disabled)
+//	tag (if tag is listed in ctxt.BuildTags)
+//	!tag (if tag is not listed in ctxt.BuildTags)
+//	a slash-separated list of any of these
+//
+func (ctxt *Context) match(name string) bool {
+	if name == "" {
+		return false
+	}
+	if i := strings.Index(name, ","); i >= 0 {
+		// comma-separated list
+		return ctxt.match(name[:i]) && ctxt.match(name[i+1:])
+	}
+	if strings.HasPrefix(name, "!!") { // bad syntax, reject always
+		return false
+	}
+	if strings.HasPrefix(name, "!") { // negation
+		return !ctxt.match(name[1:])
+	}
+
+	// Tags must be letters, digits, underscores.
+	// Unlike in Go identifiers, all digits is fine (e.g., "386").
+	for _, c := range name {
+		if !unicode.IsLetter(c) && !unicode.IsDigit(c) && c != '_' {
+			return false
+		}
+	}
+
+	// special tags
+	if ctxt.CgoEnabled && name == "cgo" {
+		return true
+	}
+	if name == ctxt.GOOS || name == ctxt.GOARCH {
+		return true
+	}
+
+	// other tags
+	for _, tag := range ctxt.BuildTags {
+		if tag == name {
+			return true
+		}
+	}
+
+	return false
+}
+
+// goodOSArchFile returns false if the name contains a $GOOS or $GOARCH
+// suffix which does not match the current system.
+// The recognized name formats are:
+//
+//     name_$(GOOS).*
+//     name_$(GOARCH).*
+//     name_$(GOOS)_$(GOARCH).*
+//     name_$(GOOS)_test.*
+//     name_$(GOARCH)_test.*
+//     name_$(GOOS)_$(GOARCH)_test.*
+//
+func (ctxt *Context) goodOSArchFile(name string) bool {
+	if dot := strings.Index(name, "."); dot != -1 {
+		name = name[:dot]
+	}
+	l := strings.Split(name, "_")
+	if n := len(l); n > 0 && l[n-1] == "test" {
+		l = l[:n-1]
+	}
+	n := len(l)
+	if n >= 2 && knownOS[l[n-2]] && knownArch[l[n-1]] {
+		return l[n-2] == ctxt.GOOS && l[n-1] == ctxt.GOARCH
+	}
+	if n >= 1 && knownOS[l[n-1]] {
+		return l[n-1] == ctxt.GOOS
+	}
+	if n >= 1 && knownArch[l[n-1]] {
+		return l[n-1] == ctxt.GOARCH
+	}
+	return true
+}
+
+var knownOS = make(map[string]bool)
+var knownArch = make(map[string]bool)
+
+func init() {
+	for _, v := range strings.Fields(goosList) {
+		knownOS[v] = true
+	}
+	for _, v := range strings.Fields(goarchList) {
+		knownArch[v] = true
+	}
+}
+
+// ToolDir is the directory containing build tools.
+var ToolDir = filepath.Join(runtime.GOROOT(), "pkg/tool/"+runtime.GOOS+"_"+runtime.GOARCH)
+
+// IsLocalImport reports whether the import path is
+// a local import path, like ".", "..", "./foo", or "../foo".
+func IsLocalImport(path string) bool {
+	return path == "." || path == ".." ||
+		strings.HasPrefix(path, "./") || strings.HasPrefix(path, "../")
+}
 
 // ArchChar returns the architecture character for the given goarch.
 // For example, ArchChar("amd64") returns "6".
diff --git a/src/pkg/go/build/build_test.go b/src/pkg/go/build/build_test.go
index 3c706a4..06b8b0e 100644
--- a/src/pkg/go/build/build_test.go
+++ b/src/pkg/go/build/build_test.go
@@ -5,83 +5,14 @@
 package build
 
 import (
+	"os"
 	"path/filepath"
-	"reflect"
 	"runtime"
-	"sort"
 	"testing"
 )
 
-func sortstr(x []string) []string {
-	sort.Strings(x)
-	return x
-}
-
-var buildPkgs = []struct {
-	dir  string
-	info *DirInfo
-}{
-	{
-		"go/build/pkgtest",
-		&DirInfo{
-			GoFiles:      []string{"pkgtest.go"},
-			SFiles:       []string{"sqrt_" + runtime.GOARCH + ".s"},
-			Package:      "pkgtest",
-			Imports:      []string{"bytes"},
-			TestImports:  []string{"fmt", "pkgtest"},
-			TestGoFiles:  sortstr([]string{"sqrt_test.go", "sqrt_" + runtime.GOARCH + "_test.go"}),
-			XTestGoFiles: []string{"xsqrt_test.go"},
-		},
-	},
-	{
-		"go/build/cmdtest",
-		&DirInfo{
-			GoFiles:     []string{"main.go"},
-			Package:     "main",
-			Imports:     []string{"go/build/pkgtest"},
-			TestImports: []string{},
-		},
-	},
-	{
-		"go/build/cgotest",
-		&DirInfo{
-			CgoFiles:    ifCgo([]string{"cgotest.go"}),
-			CFiles:      []string{"cgotest.c"},
-			HFiles:      []string{"cgotest.h"},
-			Imports:     []string{"C", "unsafe"},
-			TestImports: []string{},
-			Package:     "cgotest",
-		},
-	},
-}
-
-func ifCgo(x []string) []string {
-	if DefaultContext.CgoEnabled {
-		return x
-	}
-	return nil
-}
-
-func TestBuild(t *testing.T) {
-	for _, tt := range buildPkgs {
-		tree := Path[0] // Goroot
-		dir := filepath.Join(tree.SrcDir(), tt.dir)
-		info, err := ScanDir(dir)
-		if err != nil {
-			t.Errorf("ScanDir(%#q): %v", tt.dir, err)
-			continue
-		}
-		// Don't bother testing import positions.
-		tt.info.ImportPos, tt.info.TestImportPos = info.ImportPos, info.TestImportPos
-		if !reflect.DeepEqual(info, tt.info) {
-			t.Errorf("ScanDir(%#q) = %#v, want %#v\n", tt.dir, info, tt.info)
-			continue
-		}
-	}
-}
-
 func TestMatch(t *testing.T) {
-	ctxt := DefaultContext
+	ctxt := Default
 	what := "default"
 	match := func(tag string) {
 		if !ctxt.match(tag) {
@@ -106,3 +37,40 @@ func TestMatch(t *testing.T) {
 	match(runtime.GOOS + "," + runtime.GOARCH + ",!bar")
 	nomatch(runtime.GOOS + "," + runtime.GOARCH + ",bar")
 }
+
+func TestDotSlashImport(t *testing.T) {
+	p, err := ImportDir("testdata/other", 0)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if len(p.Imports) != 1 || p.Imports[0] != "./file" {
+		t.Fatalf("testdata/other: Imports=%v, want [./file]", p.Imports)
+	}
+
+	p1, err := Import("./file", "testdata/other", 0)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if p1.Name != "file" {
+		t.Fatalf("./file: Name=%q, want %q", p1.Name, "file")
+	}
+	dir := filepath.Clean("testdata/other/file") // Clean to use \ on Windows
+	if p1.Dir != dir {
+		t.Fatalf("./file: Dir=%q, want %q", p1.Name, dir)
+	}
+}
+
+func TestLocalDirectory(t *testing.T) {
+	cwd, err := os.Getwd()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	p, err := ImportDir(cwd, 0)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if p.ImportPath != "go/build" {
+		t.Fatalf("ImportPath=%q, want %q", p.ImportPath, "go/build")
+	}
+}
diff --git a/src/pkg/go/build/cgotest/cgotest.c b/src/pkg/go/build/cgotest/cgotest.c
deleted file mode 100644
index b13acb2..0000000
--- a/src/pkg/go/build/cgotest/cgotest.c
+++ /dev/null
@@ -1,9 +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.
-
-int
-Add(int x, int y, int *sum)
-{
-	sum = x+y;
-}
diff --git a/src/pkg/go/build/cgotest/cgotest.go b/src/pkg/go/build/cgotest/cgotest.go
deleted file mode 100644
index 93bbf06..0000000
--- a/src/pkg/go/build/cgotest/cgotest.go
+++ /dev/null
@@ -1,19 +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 cgotest
-
-/*
-char* greeting = "hello, world";
-*/
-// #include "cgotest.h"
-import "C"
-import "unsafe"
-
-var Greeting = C.GoString(C.greeting)
-
-func DoAdd(x, y int) (sum int) {
-	C.Add(C.int(x), C.int(y), (*C.int)(unsafe.Pointer(&sum)))
-	return
-}
diff --git a/src/pkg/go/build/cgotest/cgotest.h b/src/pkg/go/build/cgotest/cgotest.h
deleted file mode 100644
index 9c73643..0000000
--- a/src/pkg/go/build/cgotest/cgotest.h
+++ /dev/null
@@ -1,5 +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.
-
-extern int Add(int, int, int *);
diff --git a/src/pkg/go/build/cmdtest/main.go b/src/pkg/go/build/cmdtest/main.go
deleted file mode 100644
index bed4f48..0000000
--- a/src/pkg/go/build/cmdtest/main.go
+++ /dev/null
@@ -1,12 +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 main
-
-import "go/build/pkgtest"
-
-func main() {
-	pkgtest.Foo()
-	print(int(pkgtest.Sqrt(9)))
-}
diff --git a/src/pkg/go/build/dir.go b/src/pkg/go/build/dir.go
deleted file mode 100644
index 6b30f76..0000000
--- a/src/pkg/go/build/dir.go
+++ /dev/null
@@ -1,705 +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 build
-
-import (
-	"bytes"
-	"errors"
-	"fmt"
-	"go/ast"
-	"go/parser"
-	"go/token"
-	"io/ioutil"
-	"log"
-	"os"
-	"path"
-	"path/filepath"
-	"runtime"
-	"sort"
-	"strconv"
-	"strings"
-	"unicode"
-)
-
-// A Context specifies the supporting context for a build.
-type Context struct {
-	GOARCH      string   // target architecture
-	GOOS        string   // target operating system
-	CgoEnabled  bool     // whether cgo can be used
-	BuildTags   []string // additional tags to recognize in +build lines
-	UseAllFiles bool     // use files regardless of +build lines, file names
-
-	// By default, ScanDir uses the operating system's
-	// file system calls to read directories and files.
-	// Callers can override those calls to provide other
-	// ways to read data by setting ReadDir and ReadFile.
-	// ScanDir does not make any assumptions about the
-	// format of the strings dir and file: they can be
-	// slash-separated, backslash-separated, even URLs.
-
-	// ReadDir returns a slice of os.FileInfo, sorted by Name,
-	// describing the content of the named directory.
-	// The dir argument is the argument to ScanDir.
-	// If ReadDir is nil, ScanDir uses io.ReadDir.
-	ReadDir func(dir string) (fi []os.FileInfo, err error)
-
-	// ReadFile returns the content of the file named file
-	// in the directory named dir.  The dir argument is the
-	// argument to ScanDir, and the file argument is the
-	// Name field from an os.FileInfo returned by ReadDir.
-	// The returned path is the full name of the file, to be
-	// used in error messages.
-	//
-	// If ReadFile is nil, ScanDir uses filepath.Join(dir, file)
-	// as the path and ioutil.ReadFile to read the data.
-	ReadFile func(dir, file string) (path string, content []byte, err error)
-}
-
-func (ctxt *Context) readDir(dir string) ([]os.FileInfo, error) {
-	if f := ctxt.ReadDir; f != nil {
-		return f(dir)
-	}
-	return ioutil.ReadDir(dir)
-}
-
-func (ctxt *Context) readFile(dir, file string) (string, []byte, error) {
-	if f := ctxt.ReadFile; f != nil {
-		return f(dir, file)
-	}
-	p := filepath.Join(dir, file)
-	content, err := ioutil.ReadFile(p)
-	return p, content, err
-}
-
-// The DefaultContext is the default Context for builds.
-// It uses the GOARCH and GOOS environment variables
-// if set, or else the compiled code's GOARCH and GOOS.
-var DefaultContext Context = defaultContext()
-
-var cgoEnabled = map[string]bool{
-	"darwin/386":    true,
-	"darwin/amd64":  true,
-	"linux/386":     true,
-	"linux/amd64":   true,
-	"freebsd/386":   true,
-	"freebsd/amd64": true,
-	"windows/386":   true,
-	"windows/amd64": true,
-}
-
-func defaultContext() Context {
-	var c Context
-
-	c.GOARCH = envOr("GOARCH", runtime.GOARCH)
-	c.GOOS = envOr("GOOS", runtime.GOOS)
-
-	s := os.Getenv("CGO_ENABLED")
-	switch s {
-	case "1":
-		c.CgoEnabled = true
-	case "0":
-		c.CgoEnabled = false
-	default:
-		c.CgoEnabled = cgoEnabled[c.GOOS+"/"+c.GOARCH]
-	}
-
-	return c
-}
-
-func envOr(name, def string) string {
-	s := os.Getenv(name)
-	if s == "" {
-		return def
-	}
-	return s
-}
-
-type DirInfo struct {
-	Package        string                      // Name of package in dir
-	PackageComment *ast.CommentGroup           // Package comments from GoFiles
-	ImportPath     string                      // Import path of package in dir
-	Imports        []string                    // All packages imported by GoFiles
-	ImportPos      map[string][]token.Position // Source code location of imports
-
-	// Source files
-	GoFiles  []string // .go files in dir (excluding CgoFiles, TestGoFiles, XTestGoFiles)
-	HFiles   []string // .h files in dir
-	CFiles   []string // .c files in dir
-	SFiles   []string // .s (and, when using cgo, .S files in dir)
-	CgoFiles []string // .go files that import "C"
-
-	// Cgo directives
-	CgoPkgConfig []string // Cgo pkg-config directives
-	CgoCFLAGS    []string // Cgo CFLAGS directives
-	CgoLDFLAGS   []string // Cgo LDFLAGS directives
-
-	// Test information
-	TestGoFiles   []string // _test.go files in package
-	XTestGoFiles  []string // _test.go files outside package
-	TestImports   []string // All packages imported by (X)TestGoFiles
-	TestImportPos map[string][]token.Position
-}
-
-func (d *DirInfo) IsCommand() bool {
-	// TODO(rsc): This is at least a little bogus.
-	return d.Package == "main"
-}
-
-// ScanDir calls DefaultContext.ScanDir.
-func ScanDir(dir string) (info *DirInfo, err error) {
-	return DefaultContext.ScanDir(dir)
-}
-
-// TODO(rsc): Move this comment to a more appropriate place.
-
-// ScanDir returns a structure with details about the Go package
-// found in the given directory.
-//
-// Most .go, .c, .h, and .s files in the directory are considered part
-// of the package.  The exceptions are:
-//
-//	- .go files in package main (unless no other package is found)
-//	- .go files in package documentation
-//	- files starting with _ or .
-//	- files with build constraints not satisfied by the context
-//
-// Build Constraints
-//
-// A build constraint is a line comment beginning with the directive +build
-// that lists the conditions under which a file should be included in the package.
-// Constraints may appear in any kind of source file (not just Go), but
-// they must be appear near the top of the file, preceded
-// only by blank lines and other line comments.
-//
-// A build constraint is evaluated as the OR of space-separated options;
-// each option evaluates as the AND of its comma-separated terms;
-// and each term is an alphanumeric word or, preceded by !, its negation.
-// That is, the build constraint:
-//
-//	// +build linux,386 darwin,!cgo
-//
-// corresponds to the boolean formula:
-//
-//	(linux AND 386) OR (darwin AND (NOT cgo))
-//
-// During a particular build, the following words are satisfied:
-//
-//	- the target operating system, as spelled by runtime.GOOS
-//	- the target architecture, as spelled by runtime.GOARCH
-//	- "cgo", if ctxt.CgoEnabled is true
-//	- any additional words listed in ctxt.BuildTags
-//
-// If a file's name, after stripping the extension and a possible _test suffix,
-// matches *_GOOS, *_GOARCH, or *_GOOS_GOARCH for any known operating
-// system and architecture values, then the file is considered to have an implicit
-// build constraint requiring those terms.
-//
-// Examples
-//
-// To keep a file from being considered for the build:
-//
-//	// +build ignore
-//
-// (any other unsatisfied word will work as well, but ``ignore'' is conventional.)
-//
-// To build a file only when using cgo, and only on Linux and OS X:
-//
-//	// +build linux,cgo darwin,cgo
-// 
-// Such a file is usually paired with another file implementing the
-// default functionality for other systems, which in this case would
-// carry the constraint:
-//
-//	// +build !linux !darwin !cgo
-//
-// Naming a file dns_windows.go will cause it to be included only when
-// building the package for Windows; similarly, math_386.s will be included
-// only when building the package for 32-bit x86.
-//
-func (ctxt *Context) ScanDir(dir string) (info *DirInfo, err error) {
-	dirs, err := ctxt.readDir(dir)
-	if err != nil {
-		return nil, err
-	}
-
-	var Sfiles []string // files with ".S" (capital S)
-	var di DirInfo
-	var firstFile string
-	imported := make(map[string][]token.Position)
-	testImported := make(map[string][]token.Position)
-	fset := token.NewFileSet()
-	for _, d := range dirs {
-		if d.IsDir() {
-			continue
-		}
-		name := d.Name()
-		if strings.HasPrefix(name, "_") ||
-			strings.HasPrefix(name, ".") {
-			continue
-		}
-		if !ctxt.UseAllFiles && !ctxt.goodOSArchFile(name) {
-			continue
-		}
-
-		ext := path.Ext(name)
-		switch ext {
-		case ".go", ".c", ".s", ".h", ".S":
-			// tentatively okay
-		default:
-			// skip
-			continue
-		}
-
-		filename, data, err := ctxt.readFile(dir, name)
-		if err != nil {
-			return nil, err
-		}
-
-		// Look for +build comments to accept or reject the file.
-		if !ctxt.UseAllFiles && !ctxt.shouldBuild(data) {
-			continue
-		}
-
-		// Going to save the file.  For non-Go files, can stop here.
-		switch ext {
-		case ".c":
-			di.CFiles = append(di.CFiles, name)
-			continue
-		case ".h":
-			di.HFiles = append(di.HFiles, name)
-			continue
-		case ".s":
-			di.SFiles = append(di.SFiles, name)
-			continue
-		case ".S":
-			Sfiles = append(Sfiles, name)
-			continue
-		}
-
-		pf, err := parser.ParseFile(fset, filename, data, parser.ImportsOnly|parser.ParseComments)
-		if err != nil {
-			return nil, err
-		}
-
-		pkg := string(pf.Name.Name)
-		if pkg == "documentation" {
-			continue
-		}
-
-		isTest := strings.HasSuffix(name, "_test.go")
-		if isTest && strings.HasSuffix(pkg, "_test") {
-			pkg = pkg[:len(pkg)-len("_test")]
-		}
-
-		if di.Package == "" {
-			di.Package = pkg
-			firstFile = name
-		} else if pkg != di.Package {
-			return nil, fmt.Errorf("%s: found packages %s (%s) and %s (%s)", dir, di.Package, firstFile, pkg, name)
-		}
-		if pf.Doc != nil {
-			if di.PackageComment != nil {
-				di.PackageComment.List = append(di.PackageComment.List, pf.Doc.List...)
-			} else {
-				di.PackageComment = pf.Doc
-			}
-		}
-
-		// Record imports and information about cgo.
-		isCgo := false
-		for _, decl := range pf.Decls {
-			d, ok := decl.(*ast.GenDecl)
-			if !ok {
-				continue
-			}
-			for _, dspec := range d.Specs {
-				spec, ok := dspec.(*ast.ImportSpec)
-				if !ok {
-					continue
-				}
-				quoted := string(spec.Path.Value)
-				path, err := strconv.Unquote(quoted)
-				if err != nil {
-					log.Panicf("%s: parser returned invalid quoted string: <%s>", filename, quoted)
-				}
-				if isTest {
-					testImported[path] = append(testImported[path], fset.Position(spec.Pos()))
-				} else {
-					imported[path] = append(imported[path], fset.Position(spec.Pos()))
-				}
-				if path == "C" {
-					if isTest {
-						return nil, fmt.Errorf("%s: use of cgo in test not supported", filename)
-					}
-					cg := spec.Doc
-					if cg == nil && len(d.Specs) == 1 {
-						cg = d.Doc
-					}
-					if cg != nil {
-						if err := ctxt.saveCgo(filename, &di, cg); err != nil {
-							return nil, err
-						}
-					}
-					isCgo = true
-				}
-			}
-		}
-		if isCgo {
-			if ctxt.CgoEnabled {
-				di.CgoFiles = append(di.CgoFiles, name)
-			}
-		} else if isTest {
-			if pkg == string(pf.Name.Name) {
-				di.TestGoFiles = append(di.TestGoFiles, name)
-			} else {
-				di.XTestGoFiles = append(di.XTestGoFiles, name)
-			}
-		} else {
-			di.GoFiles = append(di.GoFiles, name)
-		}
-	}
-	if di.Package == "" {
-		return nil, fmt.Errorf("%s: no Go source files", dir)
-	}
-	di.Imports = make([]string, len(imported))
-	di.ImportPos = imported
-	i := 0
-	for p := range imported {
-		di.Imports[i] = p
-		i++
-	}
-	di.TestImports = make([]string, len(testImported))
-	di.TestImportPos = testImported
-	i = 0
-	for p := range testImported {
-		di.TestImports[i] = p
-		i++
-	}
-
-	// add the .S files only if we are using cgo
-	// (which means gcc will compile them).
-	// The standard assemblers expect .s files.
-	if len(di.CgoFiles) > 0 {
-		di.SFiles = append(di.SFiles, Sfiles...)
-		sort.Strings(di.SFiles)
-	}
-
-	// File name lists are sorted because ReadDir sorts.
-	sort.Strings(di.Imports)
-	sort.Strings(di.TestImports)
-	return &di, nil
-}
-
-var slashslash = []byte("//")
-
-// shouldBuild reports whether it is okay to use this file,
-// The rule is that in the file's leading run of // comments
-// and blank lines, which must be followed by a blank line
-// (to avoid including a Go package clause doc comment),
-// lines beginning with '// +build' are taken as build directives.
-//
-// The file is accepted only if each such line lists something
-// matching the file.  For example:
-//
-//	// +build windows linux
-//
-// marks the file as applicable only on Windows and Linux.
-//
-func (ctxt *Context) shouldBuild(content []byte) bool {
-	// Pass 1. Identify leading run of // comments and blank lines,
-	// which must be followed by a blank line.
-	end := 0
-	p := content
-	for len(p) > 0 {
-		line := p
-		if i := bytes.IndexByte(line, '\n'); i >= 0 {
-			line, p = line[:i], p[i+1:]
-		} else {
-			p = p[len(p):]
-		}
-		line = bytes.TrimSpace(line)
-		if len(line) == 0 { // Blank line
-			end = cap(content) - cap(line) // &line[0] - &content[0]
-			continue
-		}
-		if !bytes.HasPrefix(line, slashslash) { // Not comment line
-			break
-		}
-	}
-	content = content[:end]
-
-	// Pass 2.  Process each line in the run.
-	p = content
-	for len(p) > 0 {
-		line := p
-		if i := bytes.IndexByte(line, '\n'); i >= 0 {
-			line, p = line[:i], p[i+1:]
-		} else {
-			p = p[len(p):]
-		}
-		line = bytes.TrimSpace(line)
-		if bytes.HasPrefix(line, slashslash) {
-			line = bytes.TrimSpace(line[len(slashslash):])
-			if len(line) > 0 && line[0] == '+' {
-				// Looks like a comment +line.
-				f := strings.Fields(string(line))
-				if f[0] == "+build" {
-					ok := false
-					for _, tok := range f[1:] {
-						if ctxt.match(tok) {
-							ok = true
-							break
-						}
-					}
-					if !ok {
-						return false // this one doesn't match
-					}
-				}
-			}
-		}
-	}
-	return true // everything matches
-}
-
-// saveCgo saves the information from the #cgo lines in the import "C" comment.
-// These lines set CFLAGS and LDFLAGS and pkg-config directives that affect
-// the way cgo's C code is built.
-//
-// TODO(rsc): This duplicates code in cgo.
-// Once the dust settles, remove this code from cgo.
-func (ctxt *Context) saveCgo(filename string, di *DirInfo, cg *ast.CommentGroup) error {
-	text := cg.Text()
-	for _, line := range strings.Split(text, "\n") {
-		orig := line
-
-		// Line is
-		//	#cgo [GOOS/GOARCH...] LDFLAGS: stuff
-		//
-		line = strings.TrimSpace(line)
-		if len(line) < 5 || line[:4] != "#cgo" || (line[4] != ' ' && line[4] != '\t') {
-			continue
-		}
-
-		// Split at colon.
-		line = strings.TrimSpace(line[4:])
-		i := strings.Index(line, ":")
-		if i < 0 {
-			return fmt.Errorf("%s: invalid #cgo line: %s", filename, orig)
-		}
-		line, argstr := line[:i], line[i+1:]
-
-		// Parse GOOS/GOARCH stuff.
-		f := strings.Fields(line)
-		if len(f) < 1 {
-			return fmt.Errorf("%s: invalid #cgo line: %s", filename, orig)
-		}
-
-		cond, verb := f[:len(f)-1], f[len(f)-1]
-		if len(cond) > 0 {
-			ok := false
-			for _, c := range cond {
-				if ctxt.match(c) {
-					ok = true
-					break
-				}
-			}
-			if !ok {
-				continue
-			}
-		}
-
-		args, err := splitQuoted(argstr)
-		if err != nil {
-			return fmt.Errorf("%s: invalid #cgo line: %s", filename, orig)
-		}
-		for _, arg := range args {
-			if !safeName(arg) {
-				return fmt.Errorf("%s: malformed #cgo argument: %s", filename, arg)
-			}
-		}
-
-		switch verb {
-		case "CFLAGS":
-			di.CgoCFLAGS = append(di.CgoCFLAGS, args...)
-		case "LDFLAGS":
-			di.CgoLDFLAGS = append(di.CgoLDFLAGS, args...)
-		case "pkg-config":
-			di.CgoPkgConfig = append(di.CgoPkgConfig, args...)
-		default:
-			return fmt.Errorf("%s: invalid #cgo verb: %s", filename, orig)
-		}
-	}
-	return nil
-}
-
-var safeBytes = []byte("+-.,/0123456789=ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz:")
-
-func safeName(s string) bool {
-	if s == "" {
-		return false
-	}
-	for i := 0; i < len(s); i++ {
-		if c := s[i]; c < 0x80 && bytes.IndexByte(safeBytes, c) < 0 {
-			return false
-		}
-	}
-	return true
-}
-
-// splitQuoted splits the string s around each instance of one or more consecutive
-// white space characters while taking into account quotes and escaping, and
-// returns an array of substrings of s or an empty list if s contains only white space.
-// Single quotes and double quotes are recognized to prevent splitting within the
-// quoted region, and are removed from the resulting substrings. If a quote in s
-// isn't closed err will be set and r will have the unclosed argument as the
-// last element.  The backslash is used for escaping.
-//
-// For example, the following string:
-//
-//     a b:"c d" 'e''f'  "g\""
-//
-// Would be parsed as:
-//
-//     []string{"a", "b:c d", "ef", `g"`}
-//
-func splitQuoted(s string) (r []string, err error) {
-	var args []string
-	arg := make([]rune, len(s))
-	escaped := false
-	quoted := false
-	quote := '\x00'
-	i := 0
-	for _, rune := range s {
-		switch {
-		case escaped:
-			escaped = false
-		case rune == '\\':
-			escaped = true
-			continue
-		case quote != '\x00':
-			if rune == quote {
-				quote = '\x00'
-				continue
-			}
-		case rune == '"' || rune == '\'':
-			quoted = true
-			quote = rune
-			continue
-		case unicode.IsSpace(rune):
-			if quoted || i > 0 {
-				quoted = false
-				args = append(args, string(arg[:i]))
-				i = 0
-			}
-			continue
-		}
-		arg[i] = rune
-		i++
-	}
-	if quoted || i > 0 {
-		args = append(args, string(arg[:i]))
-	}
-	if quote != 0 {
-		err = errors.New("unclosed quote")
-	} else if escaped {
-		err = errors.New("unfinished escaping")
-	}
-	return args, err
-}
-
-// match returns true if the name is one of:
-//
-//	$GOOS
-//	$GOARCH
-//	cgo (if cgo is enabled)
-//	!cgo (if cgo is disabled)
-//	tag (if tag is listed in ctxt.BuildTags)
-//	!tag (if tag is not listed in ctxt.BuildTags)
-//	a slash-separated list of any of these
-//
-func (ctxt *Context) match(name string) bool {
-	if name == "" {
-		return false
-	}
-	if i := strings.Index(name, ","); i >= 0 {
-		// comma-separated list
-		return ctxt.match(name[:i]) && ctxt.match(name[i+1:])
-	}
-	if strings.HasPrefix(name, "!!") { // bad syntax, reject always
-		return false
-	}
-	if strings.HasPrefix(name, "!") { // negation
-		return !ctxt.match(name[1:])
-	}
-
-	// Tags must be letters, digits, underscores.
-	// Unlike in Go identifiers, all digits is fine (e.g., "386").
-	for _, c := range name {
-		if !unicode.IsLetter(c) && !unicode.IsDigit(c) && c != '_' {
-			return false
-		}
-	}
-
-	// special tags
-	if ctxt.CgoEnabled && name == "cgo" {
-		return true
-	}
-	if name == ctxt.GOOS || name == ctxt.GOARCH {
-		return true
-	}
-
-	// other tags
-	for _, tag := range ctxt.BuildTags {
-		if tag == name {
-			return true
-		}
-	}
-
-	return false
-}
-
-// goodOSArchFile returns false if the name contains a $GOOS or $GOARCH
-// suffix which does not match the current system.
-// The recognized name formats are:
-//
-//     name_$(GOOS).*
-//     name_$(GOARCH).*
-//     name_$(GOOS)_$(GOARCH).*
-//     name_$(GOOS)_test.*
-//     name_$(GOARCH)_test.*
-//     name_$(GOOS)_$(GOARCH)_test.*
-//
-func (ctxt *Context) goodOSArchFile(name string) bool {
-	if dot := strings.Index(name, "."); dot != -1 {
-		name = name[:dot]
-	}
-	l := strings.Split(name, "_")
-	if n := len(l); n > 0 && l[n-1] == "test" {
-		l = l[:n-1]
-	}
-	n := len(l)
-	if n >= 2 && knownOS[l[n-2]] && knownArch[l[n-1]] {
-		return l[n-2] == ctxt.GOOS && l[n-1] == ctxt.GOARCH
-	}
-	if n >= 1 && knownOS[l[n-1]] {
-		return l[n-1] == ctxt.GOOS
-	}
-	if n >= 1 && knownArch[l[n-1]] {
-		return l[n-1] == ctxt.GOARCH
-	}
-	return true
-}
-
-var knownOS = make(map[string]bool)
-var knownArch = make(map[string]bool)
-
-func init() {
-	for _, v := range strings.Fields(goosList) {
-		knownOS[v] = true
-	}
-	for _, v := range strings.Fields(goarchList) {
-		knownArch[v] = true
-	}
-}
diff --git a/src/pkg/go/build/doc.go b/src/pkg/go/build/doc.go
new file mode 100644
index 0000000..67c26ac
--- /dev/null
+++ b/src/pkg/go/build/doc.go
@@ -0,0 +1,109 @@
+// 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 build gathers information about Go packages.
+//
+// Go Path
+//
+// The Go path is a list of directory trees containing Go source code.
+// It is consulted to resolve imports that cannot be found in the standard
+// Go tree.  The default path is the value of the GOPATH environment
+// variable, interpreted as a path list appropriate to the operating system
+// (on Unix, the variable is a colon-separated string;
+// on Windows, a semicolon-separated string;
+// on Plan 9, a list).
+//
+// Each directory listed in the Go path must have a prescribed structure:
+//
+// The src/ directory holds source code.  The path below 'src' determines
+// the import path or executable name.
+//
+// The pkg/ directory holds installed package objects.
+// As in the Go tree, each target operating system and
+// architecture pair has its own subdirectory of pkg
+// (pkg/GOOS_GOARCH).
+// 
+// If DIR is a directory listed in the Go path, a package with
+// source in DIR/src/foo/bar can be imported as "foo/bar" and
+// has its compiled form installed to "DIR/pkg/GOOS_GOARCH/foo/bar.a"
+// (or, for gccgo, "DIR/pkg/gccgo/foo/libbar.a").
+// 
+// The bin/ directory holds compiled commands.
+// Each command is named for its source directory, but only
+// using the final element, not the entire path.  That is, the
+// command with source in DIR/src/foo/quux is installed into
+// DIR/bin/quux, not DIR/bin/foo/quux.  The foo/ is stripped
+// so that you can add DIR/bin to your PATH to get at the
+// installed commands.
+// 
+// Here's an example directory layout:
+// 
+//	GOPATH=/home/user/gocode
+// 
+//	/home/user/gocode/
+//	    src/
+//	        foo/
+//	            bar/               (go code in package bar)
+//	                x.go
+//	            quux/              (go code in package main)
+//	                y.go
+//	    bin/
+//	        quux                   (installed command)
+//	    pkg/
+//	        linux_amd64/
+//	            foo/
+//	                bar.a          (installed package object)
+//
+// Build Constraints
+//
+// A build constraint is a line comment beginning with the directive +build
+// that lists the conditions under which a file should be included in the package.
+// Constraints may appear in any kind of source file (not just Go), but
+// they must be appear near the top of the file, preceded
+// only by blank lines and other line comments.
+//
+// A build constraint is evaluated as the OR of space-separated options;
+// each option evaluates as the AND of its comma-separated terms;
+// and each term is an alphanumeric word or, preceded by !, its negation.
+// That is, the build constraint:
+//
+//	// +build linux,386 darwin,!cgo
+//
+// corresponds to the boolean formula:
+//
+//	(linux AND 386) OR (darwin AND (NOT cgo))
+//
+// During a particular build, the following words are satisfied:
+//
+//	- the target operating system, as spelled by runtime.GOOS
+//	- the target architecture, as spelled by runtime.GOARCH
+//	- "cgo", if ctxt.CgoEnabled is true
+//	- any additional words listed in ctxt.BuildTags
+//
+// If a file's name, after stripping the extension and a possible _test suffix,
+// matches *_GOOS, *_GOARCH, or *_GOOS_GOARCH for any known operating
+// system and architecture values, then the file is considered to have an implicit
+// build constraint requiring those terms.
+//
+// To keep a file from being considered for the build:
+//
+//	// +build ignore
+//
+// (any other unsatisfied word will work as well, but ``ignore'' is conventional.)
+//
+// To build a file only when using cgo, and only on Linux and OS X:
+//
+//	// +build linux,cgo darwin,cgo
+//
+// Such a file is usually paired with another file implementing the
+// default functionality for other systems, which in this case would
+// carry the constraint:
+//
+//	// +build !linux !darwin !cgo
+//
+// Naming a file dns_windows.go will cause it to be included only when
+// building the package for Windows; similarly, math_386.s will be included
+// only when building the package for 32-bit x86.
+//
+package build
diff --git a/src/pkg/go/build/path.go b/src/pkg/go/build/path.go
deleted file mode 100644
index e160ac3..0000000
--- a/src/pkg/go/build/path.go
+++ /dev/null
@@ -1,182 +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 build
-
-import (
-	"errors"
-	"fmt"
-	"os"
-	"path/filepath"
-	"runtime"
-)
-
-// ToolDir is the directory containing build tools.
-var ToolDir = filepath.Join(runtime.GOROOT(), "pkg/tool/"+runtime.GOOS+"_"+runtime.GOARCH)
-
-// Path is a validated list of Trees derived from $GOROOT and $GOPATH at init.
-var Path []*Tree
-
-// Tree describes a Go source tree, either $GOROOT or one from $GOPATH.
-type Tree struct {
-	Path   string
-	Goroot bool
-}
-
-func newTree(p string) (*Tree, error) {
-	if !filepath.IsAbs(p) {
-		return nil, errors.New("must be absolute")
-	}
-	ep, err := filepath.EvalSymlinks(p)
-	if err != nil {
-		return nil, err
-	}
-	return &Tree{Path: ep}, nil
-}
-
-// SrcDir returns the tree's package source directory.
-func (t *Tree) SrcDir() string {
-	if t.Goroot {
-		return filepath.Join(t.Path, "src", "pkg")
-	}
-	return filepath.Join(t.Path, "src")
-}
-
-// PkgDir returns the tree's package object directory.
-func (t *Tree) PkgDir() string {
-	goos, goarch := runtime.GOOS, runtime.GOARCH
-	if e := os.Getenv("GOOS"); e != "" {
-		goos = e
-	}
-	if e := os.Getenv("GOARCH"); e != "" {
-		goarch = e
-	}
-	return filepath.Join(t.Path, "pkg", goos+"_"+goarch)
-}
-
-// BinDir returns the tree's binary executable directory.
-func (t *Tree) BinDir() string {
-	if t.Goroot {
-		if gobin := os.Getenv("GOBIN"); gobin != "" {
-			return filepath.Clean(gobin)
-		}
-	}
-	return filepath.Join(t.Path, "bin")
-}
-
-// HasSrc returns whether the given package's
-// source can be found inside this Tree.
-func (t *Tree) HasSrc(pkg string) bool {
-	fi, err := os.Stat(filepath.Join(t.SrcDir(), pkg))
-	if err != nil {
-		return false
-	}
-	return fi.IsDir()
-}
-
-// HasPkg returns whether the given package's
-// object file can be found inside this Tree.
-func (t *Tree) HasPkg(pkg string) bool {
-	fi, err := os.Stat(filepath.Join(t.PkgDir(), pkg+".a"))
-	if err != nil {
-		return false
-	}
-	return !fi.IsDir()
-}
-
-var (
-	ErrNotFound     = errors.New("package could not be found locally")
-	ErrTreeNotFound = errors.New("no valid GOROOT or GOPATH could be found")
-)
-
-// FindTree takes an import or filesystem path and returns the
-// tree where the package source should be and the package import path.
-func FindTree(path string) (tree *Tree, pkg string, err error) {
-	if isLocalPath(path) {
-		if path, err = filepath.Abs(path); err != nil {
-			return
-		}
-		if path, err = filepath.EvalSymlinks(path); err != nil {
-			return
-		}
-		for _, t := range Path {
-			tpath := t.SrcDir() + string(filepath.Separator)
-			if !filepath.HasPrefix(path, tpath) {
-				continue
-			}
-			tree = t
-			pkg = filepath.ToSlash(path[len(tpath):])
-			return
-		}
-		err = fmt.Errorf("path %q not inside a GOPATH", path)
-		return
-	}
-	tree = defaultTree
-	pkg = filepath.ToSlash(path)
-	for _, t := range Path {
-		if t.HasSrc(pkg) {
-			tree = t
-			return
-		}
-	}
-	if tree == nil {
-		err = ErrTreeNotFound
-	} else {
-		err = ErrNotFound
-	}
-	return
-}
-
-// isLocalPath returns whether the given path is local (/foo ./foo ../foo . ..)
-// Windows paths that starts with drive letter (c:\foo c:foo) are considered local.
-func isLocalPath(s string) bool {
-	const sep = string(filepath.Separator)
-	return s == "." || s == ".." ||
-		filepath.HasPrefix(s, sep) ||
-		filepath.HasPrefix(s, "."+sep) || filepath.HasPrefix(s, ".."+sep) ||
-		filepath.VolumeName(s) != ""
-}
-
-var (
-	// argument lists used by the build's gc and ld methods
-	gcImportArgs []string
-	ldImportArgs []string
-
-	// default tree for remote packages
-	defaultTree *Tree
-)
-
-// set up Path: parse and validate GOROOT and GOPATH variables
-func init() {
-	root := runtime.GOROOT()
-	t, err := newTree(root)
-	if err == nil {
-		t.Goroot = true
-		Path = []*Tree{t}
-	}
-
-	for _, p := range filepath.SplitList(os.Getenv("GOPATH")) {
-		if p == "" {
-			continue
-		}
-		t, err := newTree(p)
-		if err != nil {
-			continue
-		}
-
-		Path = append(Path, t)
-		gcImportArgs = append(gcImportArgs, "-I", t.PkgDir())
-		ldImportArgs = append(ldImportArgs, "-L", t.PkgDir())
-
-		// select first GOPATH entry as default
-		if defaultTree == nil {
-			defaultTree = t
-		}
-	}
-
-	// use GOROOT if no valid GOPATH specified
-	if defaultTree == nil && len(Path) > 0 {
-		defaultTree = Path[0]
-	}
-}
diff --git a/src/pkg/go/build/pkgtest/pkgtest.go b/src/pkg/go/build/pkgtest/pkgtest.go
deleted file mode 100644
index 08eea1e..0000000
--- a/src/pkg/go/build/pkgtest/pkgtest.go
+++ /dev/null
@@ -1,13 +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 pkgtest
-
-import "bytes"
-
-func Foo() *bytes.Buffer {
-	return nil
-}
-
-func Sqrt(x float64) float64
diff --git a/src/pkg/go/build/pkgtest/sqrt_386.s b/src/pkg/go/build/pkgtest/sqrt_386.s
deleted file mode 100644
index d0a428d..0000000
--- a/src/pkg/go/build/pkgtest/sqrt_386.s
+++ /dev/null
@@ -1,10 +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.
-
-// func Sqrt(x float64) float64	
-TEXT ·Sqrt(SB),7,$0
-	FMOVD   x+0(FP),F0
-	FSQRT
-	FMOVDP  F0,r+8(FP)
-	RET
diff --git a/src/pkg/go/build/pkgtest/sqrt_386_test.go b/src/pkg/go/build/pkgtest/sqrt_386_test.go
deleted file mode 100644
index 26b483f..0000000
--- a/src/pkg/go/build/pkgtest/sqrt_386_test.go
+++ /dev/null
@@ -1 +0,0 @@
-package pkgtest
diff --git a/src/pkg/go/build/pkgtest/sqrt_amd64.s b/src/pkg/go/build/pkgtest/sqrt_amd64.s
deleted file mode 100644
index f5b329e..0000000
--- a/src/pkg/go/build/pkgtest/sqrt_amd64.s
+++ /dev/null
@@ -1,9 +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.
-
-// func Sqrt(x float64) float64
-TEXT ·Sqrt(SB),7,$0
-	SQRTSD x+0(FP), X0
-	MOVSD X0, r+8(FP)
-	RET
diff --git a/src/pkg/go/build/pkgtest/sqrt_amd64_test.go b/src/pkg/go/build/pkgtest/sqrt_amd64_test.go
deleted file mode 100644
index 26b483f..0000000
--- a/src/pkg/go/build/pkgtest/sqrt_amd64_test.go
+++ /dev/null
@@ -1 +0,0 @@
-package pkgtest
diff --git a/src/pkg/go/build/pkgtest/sqrt_arm.s b/src/pkg/go/build/pkgtest/sqrt_arm.s
deleted file mode 100644
index befbb8a..0000000
--- a/src/pkg/go/build/pkgtest/sqrt_arm.s
+++ /dev/null
@@ -1,10 +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.
-
-// func Sqrt(x float64) float64	
-TEXT ·Sqrt(SB),7,$0
-	MOVD   x+0(FP),F0
-	SQRTD  F0,F0
-	MOVD  F0,r+8(FP)
-	RET
diff --git a/src/pkg/go/build/pkgtest/sqrt_arm_test.go b/src/pkg/go/build/pkgtest/sqrt_arm_test.go
deleted file mode 100644
index 26b483f..0000000
--- a/src/pkg/go/build/pkgtest/sqrt_arm_test.go
+++ /dev/null
@@ -1 +0,0 @@
-package pkgtest
diff --git a/src/pkg/go/build/pkgtest/sqrt_test.go b/src/pkg/go/build/pkgtest/sqrt_test.go
deleted file mode 100644
index ee9fd5d..0000000
--- a/src/pkg/go/build/pkgtest/sqrt_test.go
+++ /dev/null
@@ -1,9 +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 pkgtest
-
-import "fmt"
-
-var _ = fmt.Printf
diff --git a/src/pkg/go/build/pkgtest/xsqrt_test.go b/src/pkg/go/build/pkgtest/xsqrt_test.go
deleted file mode 100644
index 3898d1d..0000000
--- a/src/pkg/go/build/pkgtest/xsqrt_test.go
+++ /dev/null
@@ -1,9 +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 pkgtest_test
-
-import "pkgtest"
-
-var _ = pkgtest.Foo
diff --git a/src/pkg/go/build/syslist_test.go b/src/pkg/go/build/syslist_test.go
index d27630d..9157faf 100644
--- a/src/pkg/go/build/syslist_test.go
+++ b/src/pkg/go/build/syslist_test.go
@@ -55,7 +55,7 @@ var tests = []GoodFileTest{
 
 func TestGoodOSArch(t *testing.T) {
 	for _, test := range tests {
-		if DefaultContext.goodOSArchFile(test.name) != test.result {
+		if Default.goodOSArchFile(test.name) != test.result {
 			t.Fatalf("goodOSArchFile(%q) != %v", test.name, test.result)
 		}
 	}
diff --git a/src/pkg/go/build/testdata/other/file/file.go b/src/pkg/go/build/testdata/other/file/file.go
new file mode 100644
index 0000000..bbfd3e9
--- /dev/null
+++ b/src/pkg/go/build/testdata/other/file/file.go
@@ -0,0 +1,5 @@
+// Test data - not compiled.
+
+package file
+
+func F() {}
diff --git a/src/pkg/go/build/testdata/other/main.go b/src/pkg/go/build/testdata/other/main.go
new file mode 100644
index 0000000..e090435
--- /dev/null
+++ b/src/pkg/go/build/testdata/other/main.go
@@ -0,0 +1,11 @@
+// Test data - not compiled.
+
+package main
+
+import (
+	"./file"
+)
+
+func main() {
+	file.F()
+}
diff --git a/src/pkg/go/doc/reader.go b/src/pkg/go/doc/reader.go
index 3558892..5eaae37 100644
--- a/src/pkg/go/doc/reader.go
+++ b/src/pkg/go/doc/reader.go
@@ -432,6 +432,17 @@ func (r *reader) readFile(src *ast.File) {
 				r.readValue(d)
 			case token.TYPE:
 				// types are handled individually
+				if len(d.Specs) == 1 && !d.Lparen.IsValid() {
+					// common case: single declaration w/o parentheses
+					// (if a single declaration is parenthesized,
+					// create a new fake declaration below, so that
+					// go/doc type declarations always appear w/o
+					// parentheses)
+					if s, ok := d.Specs[0].(*ast.TypeSpec); ok {
+						r.readType(d, s)
+					}
+					break
+				}
 				for _, spec := range d.Specs {
 					if s, ok := spec.(*ast.TypeSpec); ok {
 						// use an individual (possibly fake) declaration
@@ -439,8 +450,13 @@ func (r *reader) readFile(src *ast.File) {
 						// gets to (re-)use the declaration documentation
 						// if there's none associated with the spec itself
 						fake := &ast.GenDecl{
-							Doc:    d.Doc,
-							TokPos: d.Pos(),
+							Doc: d.Doc,
+							// don't use the existing TokPos because it
+							// will lead to the wrong selection range for
+							// the fake declaration if there are more
+							// than one type in the group (this affects
+							// src/cmd/godoc/godoc.go's posLink_urlFunc)
+							TokPos: s.Pos(),
 							Tok:    token.TYPE,
 							Specs:  []ast.Spec{s},
 						}
diff --git a/src/pkg/go/parser/parser.go b/src/pkg/go/parser/parser.go
index c1e6190..a122baf 100644
--- a/src/pkg/go/parser/parser.go
+++ b/src/pkg/go/parser/parser.go
@@ -14,6 +14,9 @@ import (
 	"go/ast"
 	"go/scanner"
 	"go/token"
+	"strconv"
+	"strings"
+	"unicode"
 )
 
 // The parser structure holds the parser's internal state.
@@ -1913,6 +1916,17 @@ func (p *parser) parseStmt() (s ast.Stmt) {
 
 type parseSpecFunction func(p *parser, doc *ast.CommentGroup, iota int) ast.Spec
 
+func isValidImport(lit string) bool {
+	const illegalChars = `!"#$%&'()*,:;<=>?[\]^{|}` + "`\uFFFD"
+	s, _ := strconv.Unquote(lit) // go/scanner returns a legal string literal
+	for _, r := range s {
+		if !unicode.IsGraphic(r) || unicode.IsSpace(r) || strings.ContainsRune(illegalChars, r) {
+			return false
+		}
+	}
+	return s != ""
+}
+
 func parseImportSpec(p *parser, doc *ast.CommentGroup, _ int) ast.Spec {
 	if p.trace {
 		defer un(trace(p, "ImportSpec"))
@@ -1929,6 +1943,9 @@ func parseImportSpec(p *parser, doc *ast.CommentGroup, _ int) ast.Spec {
 
 	var path *ast.BasicLit
 	if p.tok == token.STRING {
+		if !isValidImport(p.lit) {
+			p.error(p.pos, "invalid import path: "+p.lit)
+		}
 		path = &ast.BasicLit{ValuePos: p.pos, Kind: p.tok, Value: p.lit}
 		p.next()
 	} else {
diff --git a/src/pkg/go/parser/parser_test.go b/src/pkg/go/parser/parser_test.go
index a3ee852..93ca3d6 100644
--- a/src/pkg/go/parser/parser_test.go
+++ b/src/pkg/go/parser/parser_test.go
@@ -5,6 +5,7 @@
 package parser
 
 import (
+	"fmt"
 	"go/ast"
 	"go/token"
 	"os"
@@ -204,3 +205,48 @@ func TestVarScope(t *testing.T) {
 		}
 	}
 }
+
+var imports = map[string]bool{
+	`"a"`:        true,
+	"`a`":        true,
+	`"a/b"`:      true,
+	`"a.b"`:      true,
+	`"m\x61th"`:  true,
+	`"greek/αβ"`: true,
+	`""`:         false,
+
+	// Each of these pairs tests both `` vs "" strings
+	// and also use of invalid characters spelled out as
+	// escape sequences and written directly.
+	// For example `"\x00"` tests import "\x00"
+	// while "`\x00`" tests import `<actual-NUL-byte>`.
+	`"\x00"`:     false,
+	"`\x00`":     false,
+	`"\x7f"`:     false,
+	"`\x7f`":     false,
+	`"a!"`:       false,
+	"`a!`":       false,
+	`"a b"`:      false,
+	"`a b`":      false,
+	`"a\\b"`:     false,
+	"`a\\b`":     false,
+	"\"`a`\"":    false,
+	"`\"a\"`":    false,
+	`"\x80\x80"`: false,
+	"`\x80\x80`": false,
+	`"\xFFFD"`:   false,
+	"`\xFFFD`":   false,
+}
+
+func TestImports(t *testing.T) {
+	for path, isValid := range imports {
+		src := fmt.Sprintf("package p; import %s", path)
+		_, err := ParseFile(fset, "", src, 0)
+		switch {
+		case err != nil && isValid:
+			t.Errorf("ParseFile(%s): got %v; expected no error", src, err)
+		case err == nil && !isValid:
+			t.Errorf("ParseFile(%s): got no error; expected one", src)
+		}
+	}
+}
diff --git a/src/pkg/go/printer/nodes.go b/src/pkg/go/printer/nodes.go
index cd5e075..05b4ef5 100644
--- a/src/pkg/go/printer/nodes.go
+++ b/src/pkg/go/printer/nodes.go
@@ -12,6 +12,7 @@ import (
 	"bytes"
 	"go/ast"
 	"go/token"
+	"unicode/utf8"
 )
 
 // Other formatting issues:
@@ -82,46 +83,37 @@ func (p *printer) setComment(g *ast.CommentGroup) {
 type exprListMode uint
 
 const (
-	blankStart exprListMode = 1 << iota // print a blank before a non-empty list
-	blankEnd                            // print a blank after a non-empty list
-	commaSep                            // elements are separated by commas
-	commaTerm                           // list is optionally terminated by a comma
-	noIndent                            // no extra indentation in multi-line lists
+	commaTerm exprListMode = 1 << iota // list is optionally terminated by a comma
+	noIndent                           // no extra indentation in multi-line lists
 )
 
-// Sets multiLine to true if the identifier list spans multiple lines.
 // If indent is set, a multi-line identifier list is indented after the
 // first linebreak encountered.
-func (p *printer) identList(list []*ast.Ident, indent bool, multiLine *bool) {
+func (p *printer) identList(list []*ast.Ident, indent bool) {
 	// convert into an expression list so we can re-use exprList formatting
 	xlist := make([]ast.Expr, len(list))
 	for i, x := range list {
 		xlist[i] = x
 	}
-	mode := commaSep
+	var mode exprListMode
 	if !indent {
-		mode |= noIndent
+		mode = noIndent
 	}
-	p.exprList(token.NoPos, xlist, 1, mode, multiLine, token.NoPos)
+	p.exprList(token.NoPos, xlist, 1, mode, token.NoPos)
 }
 
 // Print a list of expressions. If the list spans multiple
 // source lines, the original line breaks are respected between
-// expressions. Sets multiLine to true if the list spans multiple
-// lines.
+// expressions.
 //
 // TODO(gri) Consider rewriting this to be independent of []ast.Expr
 //           so that we can use the algorithm for any kind of list
 //           (e.g., pass list via a channel over which to range).
-func (p *printer) exprList(prev0 token.Pos, list []ast.Expr, depth int, mode exprListMode, multiLine *bool, next0 token.Pos) {
+func (p *printer) exprList(prev0 token.Pos, list []ast.Expr, depth int, mode exprListMode, next0 token.Pos) {
 	if len(list) == 0 {
 		return
 	}
 
-	if mode&blankStart != 0 {
-		p.print(blank)
-	}
-
 	prev := p.posFor(prev0)
 	next := p.posFor(next0)
 	line := p.lineFor(list[0].Pos())
@@ -131,17 +123,11 @@ func (p *printer) exprList(prev0 token.Pos, list []ast.Expr, depth int, mode exp
 		// all list entries on a single line
 		for i, x := range list {
 			if i > 0 {
-				if mode&commaSep != 0 {
-					// use position of expression following the comma as
-					// comma position for correct comment placement
-					p.print(x.Pos(), token.COMMA)
-				}
-				p.print(blank)
+				// use position of expression following the comma as
+				// comma position for correct comment placement
+				p.print(x.Pos(), token.COMMA, blank)
 			}
-			p.expr0(x, depth, multiLine)
-		}
-		if mode&blankEnd != 0 {
-			p.print(blank)
+			p.expr0(x, depth)
 		}
 		return
 	}
@@ -161,7 +147,6 @@ func (p *printer) exprList(prev0 token.Pos, list []ast.Expr, depth int, mode exp
 	prevBreak := -1 // index of last expression that was followed by a linebreak
 	if prev.IsValid() && prev.Line < line && p.linebreak(line, 0, ws, true) {
 		ws = ignore
-		*multiLine = true
 		prevBreak = 0
 	}
 
@@ -215,15 +200,13 @@ func (p *printer) exprList(prev0 token.Pos, list []ast.Expr, depth int, mode exp
 
 		if i > 0 {
 			needsLinebreak := prevLine < line && prevLine > 0 && line > 0
-			if mode&commaSep != 0 {
-				// use position of expression following the comma as
-				// comma position for correct comment placement, but
-				// only if the expression is on the same line
-				if !needsLinebreak {
-					p.print(x.Pos())
-				}
-				p.print(token.COMMA)
+			// use position of expression following the comma as
+			// comma position for correct comment placement, but
+			// only if the expression is on the same line
+			if !needsLinebreak {
+				p.print(x.Pos())
 			}
+			p.print(token.COMMA)
 			needsBlank := true
 			if needsLinebreak {
 				// lines are broken using newlines so comments remain aligned
@@ -231,7 +214,6 @@ func (p *printer) exprList(prev0 token.Pos, list []ast.Expr, depth int, mode exp
 				// the same line in which case formfeed is used
 				if p.linebreak(line, 0, ws, useFF || prevBreak+1 < i) {
 					ws = ignore
-					*multiLine = true
 					prevBreak = i
 					needsBlank = false // we got a line break instead
 				}
@@ -245,11 +227,11 @@ func (p *printer) exprList(prev0 token.Pos, list []ast.Expr, depth int, mode exp
 			// we have a key:value expression that fits onto one line and
 			// is in a list with more then one entry: use a column for the
 			// key such that consecutive entries can align if possible
-			p.expr(pair.Key, multiLine)
+			p.expr(pair.Key)
 			p.print(pair.Colon, token.COLON, vtab)
-			p.expr(pair.Value, multiLine)
+			p.expr(pair.Value)
 		} else {
-			p.expr0(x, depth, multiLine)
+			p.expr0(x, depth)
 		}
 	}
 
@@ -264,18 +246,13 @@ func (p *printer) exprList(prev0 token.Pos, list []ast.Expr, depth int, mode exp
 		return
 	}
 
-	if mode&blankEnd != 0 {
-		p.print(blank)
-	}
-
 	if ws == ignore && mode&noIndent == 0 {
 		// unindent if we indented
 		p.print(unindent)
 	}
 }
 
-// Sets multiLine to true if the the parameter list spans multiple lines.
-func (p *printer) parameters(fields *ast.FieldList, multiLine *bool) {
+func (p *printer) parameters(fields *ast.FieldList) {
 	p.print(fields.Opening, token.LPAREN)
 	if len(fields.List) > 0 {
 		prevLine := p.lineFor(fields.Opening)
@@ -306,7 +283,6 @@ func (p *printer) parameters(fields *ast.FieldList, multiLine *bool) {
 			if needsLinebreak && p.linebreak(parLineBeg, 0, ws, true) {
 				// break line if the opening "(" or previous parameter ended on a different line
 				ws = ignore
-				*multiLine = true
 			} else if i > 0 {
 				p.print(blank)
 			}
@@ -318,11 +294,11 @@ func (p *printer) parameters(fields *ast.FieldList, multiLine *bool) {
 				// again at the end (and still ws == indent). Thus, a subsequent indent
 				// by a linebreak call after a type, or in the next multi-line identList
 				// will do the right thing.
-				p.identList(par.Names, ws == indent, multiLine)
+				p.identList(par.Names, ws == indent)
 				p.print(blank)
 			}
 			// parameter type
-			p.expr(par.Type, multiLine)
+			p.expr(par.Type)
 			prevLine = parLineEnd
 		}
 		// if the closing ")" is on a separate line from the last parameter,
@@ -339,27 +315,26 @@ func (p *printer) parameters(fields *ast.FieldList, multiLine *bool) {
 	p.print(fields.Closing, token.RPAREN)
 }
 
-// Sets multiLine to true if the signature spans multiple lines.
-func (p *printer) signature(params, result *ast.FieldList, multiLine *bool) {
-	p.parameters(params, multiLine)
+func (p *printer) signature(params, result *ast.FieldList) {
+	p.parameters(params)
 	n := result.NumFields()
 	if n > 0 {
 		p.print(blank)
 		if n == 1 && result.List[0].Names == nil {
 			// single anonymous result; no ()'s
-			p.expr(result.List[0].Type, multiLine)
+			p.expr(result.List[0].Type)
 			return
 		}
-		p.parameters(result, multiLine)
+		p.parameters(result)
 	}
 }
 
 func identListSize(list []*ast.Ident, maxSize int) (size int) {
 	for i, x := range list {
 		if i > 0 {
-			size += 2 // ", "
+			size += len(", ")
 		}
-		size += len(x.Name)
+		size += utf8.RuneCountInString(x.Name)
 		if size >= maxSize {
 			break
 		}
@@ -389,6 +364,10 @@ func (p *printer) setLineComment(text string) {
 	p.setComment(&ast.CommentGroup{List: []*ast.Comment{{Slash: token.NoPos, Text: text}}})
 }
 
+func (p *printer) isMultiLine(n ast.Node) bool {
+	return p.lineFor(n.End())-p.lineFor(n.Pos()) > 1
+}
+
 func (p *printer) fieldList(fields *ast.FieldList, isStruct, isIncomplete bool) {
 	lbrace := fields.Opening
 	list := fields.List
@@ -412,12 +391,12 @@ func (p *printer) fieldList(fields *ast.FieldList, isStruct, isIncomplete bool)
 					// no comments so no need for comma position
 					p.print(token.COMMA, blank)
 				}
-				p.expr(x, ignoreMultiLine)
+				p.expr(x)
 			}
 			if len(f.Names) > 0 {
 				p.print(blank)
 			}
-			p.expr(f.Type, ignoreMultiLine)
+			p.expr(f.Type)
 			p.print(blank, rbrace, token.RBRACE)
 			return
 		}
@@ -435,23 +414,22 @@ func (p *printer) fieldList(fields *ast.FieldList, isStruct, isIncomplete bool)
 		if len(list) == 1 {
 			sep = blank
 		}
-		var ml bool
+		newSection := false
 		for i, f := range list {
 			if i > 0 {
-				p.linebreak(p.lineFor(f.Pos()), 1, ignore, ml)
+				p.linebreak(p.lineFor(f.Pos()), 1, ignore, newSection)
 			}
-			ml = false
 			extraTabs := 0
 			p.setComment(f.Doc)
 			if len(f.Names) > 0 {
 				// named fields
-				p.identList(f.Names, false, &ml)
+				p.identList(f.Names, false)
 				p.print(sep)
-				p.expr(f.Type, &ml)
+				p.expr(f.Type)
 				extraTabs = 1
 			} else {
 				// anonymous field
-				p.expr(f.Type, &ml)
+				p.expr(f.Type)
 				extraTabs = 2
 			}
 			if f.Tag != nil {
@@ -459,7 +437,7 @@ func (p *printer) fieldList(fields *ast.FieldList, isStruct, isIncomplete bool)
 					p.print(sep)
 				}
 				p.print(sep)
-				p.expr(f.Tag, &ml)
+				p.expr(f.Tag)
 				extraTabs = 0
 			}
 			if f.Comment != nil {
@@ -468,6 +446,7 @@ func (p *printer) fieldList(fields *ast.FieldList, isStruct, isIncomplete bool)
 				}
 				p.setComment(f.Comment)
 			}
+			newSection = p.isMultiLine(f)
 		}
 		if isIncomplete {
 			if len(list) > 0 {
@@ -479,22 +458,22 @@ func (p *printer) fieldList(fields *ast.FieldList, isStruct, isIncomplete bool)
 
 	} else { // interface
 
-		var ml bool
+		newSection := false
 		for i, f := range list {
 			if i > 0 {
-				p.linebreak(p.lineFor(f.Pos()), 1, ignore, ml)
+				p.linebreak(p.lineFor(f.Pos()), 1, ignore, newSection)
 			}
-			ml = false
 			p.setComment(f.Doc)
 			if ftyp, isFtyp := f.Type.(*ast.FuncType); isFtyp {
 				// method
-				p.expr(f.Names[0], &ml)
-				p.signature(ftyp.Params, ftyp.Results, &ml)
+				p.expr(f.Names[0])
+				p.signature(ftyp.Params, ftyp.Results)
 			} else {
 				// embedded interface
-				p.expr(f.Type, &ml)
+				p.expr(f.Type)
 			}
 			p.setComment(f.Comment)
+			newSection = p.isMultiLine(f)
 		}
 		if isIncomplete {
 			if len(list) > 0 {
@@ -635,15 +614,14 @@ func reduceDepth(depth int) int {
 //	   cutoff is 6 (always use spaces) in Normal mode
 //	   and 4 (never use spaces) in Compact mode.
 //
-// Sets multiLine to true if the binary expression spans multiple lines.
-func (p *printer) binaryExpr(x *ast.BinaryExpr, prec1, cutoff, depth int, multiLine *bool) {
+func (p *printer) binaryExpr(x *ast.BinaryExpr, prec1, cutoff, depth int) {
 	prec := x.Op.Precedence()
 	if prec < prec1 {
 		// parenthesis needed
 		// Note: The parser inserts an ast.ParenExpr node; thus this case
 		//       can only occur if the AST is created in a different way.
 		p.print(token.LPAREN)
-		p.expr0(x, reduceDepth(depth), multiLine) // parentheses undo one level of depth
+		p.expr0(x, reduceDepth(depth)) // parentheses undo one level of depth
 		p.print(token.RPAREN)
 		return
 	}
@@ -651,7 +629,7 @@ func (p *printer) binaryExpr(x *ast.BinaryExpr, prec1, cutoff, depth int, multiL
 	printBlank := prec < cutoff
 
 	ws := indent
-	p.expr1(x.X, prec, depth+diffPrec(x.X, prec), multiLine)
+	p.expr1(x.X, prec, depth+diffPrec(x.X, prec))
 	if printBlank {
 		p.print(blank)
 	}
@@ -663,14 +641,13 @@ func (p *printer) binaryExpr(x *ast.BinaryExpr, prec1, cutoff, depth int, multiL
 		// in the source
 		if p.linebreak(yline, 1, ws, true) {
 			ws = ignore
-			*multiLine = true
 			printBlank = false // no blank after line break
 		}
 	}
 	if printBlank {
 		p.print(blank)
 	}
-	p.expr1(x.Y, prec+1, depth+1, multiLine)
+	p.expr1(x.Y, prec+1, depth+1)
 	if ws == ignore {
 		p.print(unindent)
 	}
@@ -681,8 +658,7 @@ func isBinary(expr ast.Expr) bool {
 	return ok
 }
 
-// Sets multiLine to true if the expression spans multiple lines.
-func (p *printer) expr1(expr ast.Expr, prec1, depth int, multiLine *bool) {
+func (p *printer) expr1(expr ast.Expr, prec1, depth int) {
 	p.print(expr.Pos())
 
 	switch x := expr.(type) {
@@ -697,12 +673,12 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int, multiLine *bool) {
 			p.internalError("depth < 1:", depth)
 			depth = 1
 		}
-		p.binaryExpr(x, prec1, cutoff(x, depth), depth, multiLine)
+		p.binaryExpr(x, prec1, cutoff(x, depth), depth)
 
 	case *ast.KeyValueExpr:
-		p.expr(x.Key, multiLine)
+		p.expr(x.Key)
 		p.print(x.Colon, token.COLON, blank)
-		p.expr(x.Value, multiLine)
+		p.expr(x.Value)
 
 	case *ast.StarExpr:
 		const prec = token.UnaryPrec
@@ -710,12 +686,12 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int, multiLine *bool) {
 			// parenthesis needed
 			p.print(token.LPAREN)
 			p.print(token.MUL)
-			p.expr(x.X, multiLine)
+			p.expr(x.X)
 			p.print(token.RPAREN)
 		} else {
 			// no parenthesis needed
 			p.print(token.MUL)
-			p.expr(x.X, multiLine)
+			p.expr(x.X)
 		}
 
 	case *ast.UnaryExpr:
@@ -723,7 +699,7 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int, multiLine *bool) {
 		if prec < prec1 {
 			// parenthesis needed
 			p.print(token.LPAREN)
-			p.expr(x, multiLine)
+			p.expr(x)
 			p.print(token.RPAREN)
 		} else {
 			// no parenthesis needed
@@ -732,42 +708,41 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int, multiLine *bool) {
 				// TODO(gri) Remove this code if it cannot be reached.
 				p.print(blank)
 			}
-			p.expr1(x.X, prec, depth, multiLine)
+			p.expr1(x.X, prec, depth)
 		}
 
 	case *ast.BasicLit:
 		p.print(x)
 
 	case *ast.FuncLit:
-		p.expr(x.Type, multiLine)
-		p.funcBody(x.Body, p.distance(x.Type.Pos(), p.pos), true, multiLine)
+		p.expr(x.Type)
+		p.funcBody(x.Body, p.distance(x.Type.Pos(), p.pos), true)
 
 	case *ast.ParenExpr:
 		if _, hasParens := x.X.(*ast.ParenExpr); hasParens {
 			// don't print parentheses around an already parenthesized expression
 			// TODO(gri) consider making this more general and incorporate precedence levels
-			p.expr0(x.X, reduceDepth(depth), multiLine) // parentheses undo one level of depth
+			p.expr0(x.X, reduceDepth(depth)) // parentheses undo one level of depth
 		} else {
 			p.print(token.LPAREN)
-			p.expr0(x.X, reduceDepth(depth), multiLine) // parentheses undo one level of depth
+			p.expr0(x.X, reduceDepth(depth)) // parentheses undo one level of depth
 			p.print(x.Rparen, token.RPAREN)
 		}
 
 	case *ast.SelectorExpr:
-		p.expr1(x.X, token.HighestPrec, depth, multiLine)
+		p.expr1(x.X, token.HighestPrec, depth)
 		p.print(token.PERIOD)
 		if line := p.lineFor(x.Sel.Pos()); p.pos.IsValid() && p.pos.Line < line {
 			p.print(indent, newline, x.Sel.Pos(), x.Sel, unindent)
-			*multiLine = true
 		} else {
 			p.print(x.Sel.Pos(), x.Sel)
 		}
 
 	case *ast.TypeAssertExpr:
-		p.expr1(x.X, token.HighestPrec, depth, multiLine)
+		p.expr1(x.X, token.HighestPrec, depth)
 		p.print(token.PERIOD, token.LPAREN)
 		if x.Type != nil {
-			p.expr(x.Type, multiLine)
+			p.expr(x.Type)
 		} else {
 			p.print(token.TYPE)
 		}
@@ -775,17 +750,17 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int, multiLine *bool) {
 
 	case *ast.IndexExpr:
 		// TODO(gri): should treat[] like parentheses and undo one level of depth
-		p.expr1(x.X, token.HighestPrec, 1, multiLine)
+		p.expr1(x.X, token.HighestPrec, 1)
 		p.print(x.Lbrack, token.LBRACK)
-		p.expr0(x.Index, depth+1, multiLine)
+		p.expr0(x.Index, depth+1)
 		p.print(x.Rbrack, token.RBRACK)
 
 	case *ast.SliceExpr:
 		// TODO(gri): should treat[] like parentheses and undo one level of depth
-		p.expr1(x.X, token.HighestPrec, 1, multiLine)
+		p.expr1(x.X, token.HighestPrec, 1)
 		p.print(x.Lbrack, token.LBRACK)
 		if x.Low != nil {
-			p.expr0(x.Low, depth+1, multiLine)
+			p.expr0(x.Low, depth+1)
 		}
 		// blanks around ":" if both sides exist and either side is a binary expression
 		if depth <= 1 && x.Low != nil && x.High != nil && (isBinary(x.Low) || isBinary(x.High)) {
@@ -794,7 +769,7 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int, multiLine *bool) {
 			p.print(token.COLON)
 		}
 		if x.High != nil {
-			p.expr0(x.High, depth+1, multiLine)
+			p.expr0(x.High, depth+1)
 		}
 		p.print(x.Rbrack, token.RBRACK)
 
@@ -802,21 +777,26 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int, multiLine *bool) {
 		if len(x.Args) > 1 {
 			depth++
 		}
-		p.expr1(x.Fun, token.HighestPrec, depth, multiLine)
+		p.expr1(x.Fun, token.HighestPrec, depth)
 		p.print(x.Lparen, token.LPAREN)
-		p.exprList(x.Lparen, x.Args, depth, commaSep|commaTerm, multiLine, x.Rparen)
 		if x.Ellipsis.IsValid() {
+			p.exprList(x.Lparen, x.Args, depth, 0, x.Ellipsis)
 			p.print(x.Ellipsis, token.ELLIPSIS)
+			if x.Rparen.IsValid() && p.lineFor(x.Ellipsis) < p.lineFor(x.Rparen) {
+				p.print(token.COMMA, formfeed)
+			}
+		} else {
+			p.exprList(x.Lparen, x.Args, depth, commaTerm, x.Rparen)
 		}
 		p.print(x.Rparen, token.RPAREN)
 
 	case *ast.CompositeLit:
 		// composite literal elements that are composite literals themselves may have the type omitted
 		if x.Type != nil {
-			p.expr1(x.Type, token.HighestPrec, depth, multiLine)
+			p.expr1(x.Type, token.HighestPrec, depth)
 		}
 		p.print(x.Lbrace, token.LBRACE)
-		p.exprList(x.Lbrace, x.Elts, 1, commaSep|commaTerm, multiLine, x.Rbrace)
+		p.exprList(x.Lbrace, x.Elts, 1, commaTerm, x.Rbrace)
 		// do not insert extra line breaks because of comments before
 		// the closing '}' as it might break the code if there is no
 		// trailing ','
@@ -825,16 +805,16 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int, multiLine *bool) {
 	case *ast.Ellipsis:
 		p.print(token.ELLIPSIS)
 		if x.Elt != nil {
-			p.expr(x.Elt, multiLine)
+			p.expr(x.Elt)
 		}
 
 	case *ast.ArrayType:
 		p.print(token.LBRACK)
 		if x.Len != nil {
-			p.expr(x.Len, multiLine)
+			p.expr(x.Len)
 		}
 		p.print(token.RBRACK)
-		p.expr(x.Elt, multiLine)
+		p.expr(x.Elt)
 
 	case *ast.StructType:
 		p.print(token.STRUCT)
@@ -842,7 +822,7 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int, multiLine *bool) {
 
 	case *ast.FuncType:
 		p.print(token.FUNC)
-		p.signature(x.Params, x.Results, multiLine)
+		p.signature(x.Params, x.Results)
 
 	case *ast.InterfaceType:
 		p.print(token.INTERFACE)
@@ -850,9 +830,9 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int, multiLine *bool) {
 
 	case *ast.MapType:
 		p.print(token.MAP, token.LBRACK)
-		p.expr(x.Key, multiLine)
+		p.expr(x.Key)
 		p.print(token.RBRACK)
-		p.expr(x.Value, multiLine)
+		p.expr(x.Value)
 
 	case *ast.ChanType:
 		switch x.Dir {
@@ -864,7 +844,7 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int, multiLine *bool) {
 			p.print(token.CHAN, token.ARROW)
 		}
 		p.print(blank)
-		p.expr(x.Value, multiLine)
+		p.expr(x.Value)
 
 	default:
 		panic("unreachable")
@@ -873,14 +853,13 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int, multiLine *bool) {
 	return
 }
 
-func (p *printer) expr0(x ast.Expr, depth int, multiLine *bool) {
-	p.expr1(x, token.LowestPrec, depth, multiLine)
+func (p *printer) expr0(x ast.Expr, depth int) {
+	p.expr1(x, token.LowestPrec, depth)
 }
 
-// Sets multiLine to true if the expression spans multiple lines.
-func (p *printer) expr(x ast.Expr, multiLine *bool) {
+func (p *printer) expr(x ast.Expr) {
 	const depth = 1
-	p.expr1(x, token.LowestPrec, depth, multiLine)
+	p.expr1(x, token.LowestPrec, depth)
 }
 
 // ----------------------------------------------------------------------------
@@ -894,13 +873,13 @@ func (p *printer) stmtList(list []ast.Stmt, _indent int, nextIsRBrace bool) {
 	if _indent > 0 {
 		p.print(indent)
 	}
-	var multiLine bool
+	multiLine := false
 	for i, s := range list {
 		// _indent == 0 only for lists of switch/select case clauses;
 		// in those cases each clause is a new section
 		p.linebreak(p.lineFor(s.Pos()), 1, ignore, i == 0 || _indent == 0 || multiLine)
-		multiLine = false
-		p.stmt(s, nextIsRBrace && i == len(list)-1, &multiLine)
+		p.stmt(s, nextIsRBrace && i == len(list)-1)
+		multiLine = p.isMultiLine(s)
 	}
 	if _indent > 0 {
 		p.print(unindent)
@@ -957,25 +936,25 @@ func (p *printer) controlClause(isForStmt bool, init ast.Stmt, expr ast.Expr, po
 	if init == nil && post == nil {
 		// no semicolons required
 		if expr != nil {
-			p.expr(stripParens(expr), ignoreMultiLine)
+			p.expr(stripParens(expr))
 			needsBlank = true
 		}
 	} else {
 		// all semicolons required
 		// (they are not separators, print them explicitly)
 		if init != nil {
-			p.stmt(init, false, ignoreMultiLine)
+			p.stmt(init, false)
 		}
 		p.print(token.SEMICOLON, blank)
 		if expr != nil {
-			p.expr(stripParens(expr), ignoreMultiLine)
+			p.expr(stripParens(expr))
 			needsBlank = true
 		}
 		if isForStmt {
 			p.print(token.SEMICOLON, blank)
 			needsBlank = false
 			if post != nil {
-				p.stmt(post, false, ignoreMultiLine)
+				p.stmt(post, false)
 				needsBlank = true
 			}
 		}
@@ -985,8 +964,7 @@ func (p *printer) controlClause(isForStmt bool, init ast.Stmt, expr ast.Expr, po
 	}
 }
 
-// Sets multiLine to true if the statements spans multiple lines.
-func (p *printer) stmt(stmt ast.Stmt, nextIsRBrace bool, multiLine *bool) {
+func (p *printer) stmt(stmt ast.Stmt, nextIsRBrace bool) {
 	p.print(stmt.Pos())
 
 	switch s := stmt.(type) {
@@ -994,7 +972,7 @@ func (p *printer) stmt(stmt ast.Stmt, nextIsRBrace bool, multiLine *bool) {
 		p.print("BadStmt")
 
 	case *ast.DeclStmt:
-		p.decl(s.Decl, multiLine)
+		p.decl(s.Decl)
 
 	case *ast.EmptyStmt:
 		// nothing to do
@@ -1004,7 +982,7 @@ func (p *printer) stmt(stmt ast.Stmt, nextIsRBrace bool, multiLine *bool) {
 		// is applied before the line break if there is no comment
 		// between (see writeWhitespace)
 		p.print(unindent)
-		p.expr(s.Label, multiLine)
+		p.expr(s.Label)
 		p.print(s.Colon, token.COLON, indent)
 		if e, isEmpty := s.Stmt.(*ast.EmptyStmt); isEmpty {
 			if !nextIsRBrace {
@@ -1014,21 +992,21 @@ func (p *printer) stmt(stmt ast.Stmt, nextIsRBrace bool, multiLine *bool) {
 		} else {
 			p.linebreak(p.lineFor(s.Stmt.Pos()), 1, ignore, true)
 		}
-		p.stmt(s.Stmt, nextIsRBrace, multiLine)
+		p.stmt(s.Stmt, nextIsRBrace)
 
 	case *ast.ExprStmt:
 		const depth = 1
-		p.expr0(s.X, depth, multiLine)
+		p.expr0(s.X, depth)
 
 	case *ast.SendStmt:
 		const depth = 1
-		p.expr0(s.Chan, depth, multiLine)
+		p.expr0(s.Chan, depth)
 		p.print(blank, s.Arrow, token.ARROW, blank)
-		p.expr0(s.Value, depth, multiLine)
+		p.expr0(s.Value, depth)
 
 	case *ast.IncDecStmt:
 		const depth = 1
-		p.expr0(s.X, depth+1, multiLine)
+		p.expr0(s.X, depth+1)
 		p.print(s.TokPos, s.Tok)
 
 	case *ast.AssignStmt:
@@ -1036,56 +1014,55 @@ func (p *printer) stmt(stmt ast.Stmt, nextIsRBrace bool, multiLine *bool) {
 		if len(s.Lhs) > 1 && len(s.Rhs) > 1 {
 			depth++
 		}
-		p.exprList(s.Pos(), s.Lhs, depth, commaSep, multiLine, s.TokPos)
-		p.print(blank, s.TokPos, s.Tok)
-		p.exprList(s.TokPos, s.Rhs, depth, blankStart|commaSep, multiLine, token.NoPos)
+		p.exprList(s.Pos(), s.Lhs, depth, 0, s.TokPos)
+		p.print(blank, s.TokPos, s.Tok, blank)
+		p.exprList(s.TokPos, s.Rhs, depth, 0, token.NoPos)
 
 	case *ast.GoStmt:
 		p.print(token.GO, blank)
-		p.expr(s.Call, multiLine)
+		p.expr(s.Call)
 
 	case *ast.DeferStmt:
 		p.print(token.DEFER, blank)
-		p.expr(s.Call, multiLine)
+		p.expr(s.Call)
 
 	case *ast.ReturnStmt:
 		p.print(token.RETURN)
 		if s.Results != nil {
-			p.exprList(s.Pos(), s.Results, 1, blankStart|commaSep, multiLine, token.NoPos)
+			p.print(blank)
+			p.exprList(s.Pos(), s.Results, 1, 0, token.NoPos)
 		}
 
 	case *ast.BranchStmt:
 		p.print(s.Tok)
 		if s.Label != nil {
 			p.print(blank)
-			p.expr(s.Label, multiLine)
+			p.expr(s.Label)
 		}
 
 	case *ast.BlockStmt:
 		p.block(s, 1)
-		*multiLine = true
 
 	case *ast.IfStmt:
 		p.print(token.IF)
 		p.controlClause(false, s.Init, s.Cond, nil)
 		p.block(s.Body, 1)
-		*multiLine = true
 		if s.Else != nil {
 			p.print(blank, token.ELSE, blank)
 			switch s.Else.(type) {
 			case *ast.BlockStmt, *ast.IfStmt:
-				p.stmt(s.Else, nextIsRBrace, ignoreMultiLine)
+				p.stmt(s.Else, nextIsRBrace)
 			default:
 				p.print(token.LBRACE, indent, formfeed)
-				p.stmt(s.Else, true, ignoreMultiLine)
+				p.stmt(s.Else, true)
 				p.print(unindent, formfeed, token.RBRACE)
 			}
 		}
 
 	case *ast.CaseClause:
 		if s.List != nil {
-			p.print(token.CASE)
-			p.exprList(s.Pos(), s.List, 1, blankStart|commaSep, multiLine, s.Colon)
+			p.print(token.CASE, blank)
+			p.exprList(s.Pos(), s.List, 1, 0, s.Colon)
 		} else {
 			p.print(token.DEFAULT)
 		}
@@ -1096,25 +1073,23 @@ func (p *printer) stmt(stmt ast.Stmt, nextIsRBrace bool, multiLine *bool) {
 		p.print(token.SWITCH)
 		p.controlClause(false, s.Init, s.Tag, nil)
 		p.block(s.Body, 0)
-		*multiLine = true
 
 	case *ast.TypeSwitchStmt:
 		p.print(token.SWITCH)
 		if s.Init != nil {
 			p.print(blank)
-			p.stmt(s.Init, false, ignoreMultiLine)
+			p.stmt(s.Init, false)
 			p.print(token.SEMICOLON)
 		}
 		p.print(blank)
-		p.stmt(s.Assign, false, ignoreMultiLine)
+		p.stmt(s.Assign, false)
 		p.print(blank)
 		p.block(s.Body, 0)
-		*multiLine = true
 
 	case *ast.CommClause:
 		if s.Comm != nil {
 			p.print(token.CASE, blank)
-			p.stmt(s.Comm, false, ignoreMultiLine)
+			p.stmt(s.Comm, false)
 		} else {
 			p.print(token.DEFAULT)
 		}
@@ -1129,29 +1104,26 @@ func (p *printer) stmt(stmt ast.Stmt, nextIsRBrace bool, multiLine *bool) {
 			p.print(body.Lbrace, token.LBRACE, body.Rbrace, token.RBRACE)
 		} else {
 			p.block(body, 0)
-			*multiLine = true
 		}
 
 	case *ast.ForStmt:
 		p.print(token.FOR)
 		p.controlClause(true, s.Init, s.Cond, s.Post)
 		p.block(s.Body, 1)
-		*multiLine = true
 
 	case *ast.RangeStmt:
 		p.print(token.FOR, blank)
-		p.expr(s.Key, multiLine)
+		p.expr(s.Key)
 		if s.Value != nil {
 			// use position of value following the comma as
 			// comma position for correct comment placement
 			p.print(s.Value.Pos(), token.COMMA, blank)
-			p.expr(s.Value, multiLine)
+			p.expr(s.Value)
 		}
 		p.print(blank, s.TokPos, s.Tok, blank, token.RANGE, blank)
-		p.expr(stripParens(s.X), multiLine)
+		p.expr(stripParens(s.X))
 		p.print(blank)
 		p.block(s.Body, 1)
-		*multiLine = true
 
 	default:
 		panic("unreachable")
@@ -1228,20 +1200,20 @@ func keepTypeColumn(specs []ast.Spec) []bool {
 	return m
 }
 
-func (p *printer) valueSpec(s *ast.ValueSpec, keepType, doIndent bool, multiLine *bool) {
+func (p *printer) valueSpec(s *ast.ValueSpec, keepType, doIndent bool) {
 	p.setComment(s.Doc)
-	p.identList(s.Names, doIndent, multiLine) // always present
+	p.identList(s.Names, doIndent) // always present
 	extraTabs := 3
 	if s.Type != nil || keepType {
 		p.print(vtab)
 		extraTabs--
 	}
 	if s.Type != nil {
-		p.expr(s.Type, multiLine)
+		p.expr(s.Type)
 	}
 	if s.Values != nil {
-		p.print(vtab, token.ASSIGN)
-		p.exprList(token.NoPos, s.Values, 1, blankStart|commaSep, multiLine, token.NoPos)
+		p.print(vtab, token.ASSIGN, blank)
+		p.exprList(token.NoPos, s.Values, 1, 0, token.NoPos)
 		extraTabs--
 	}
 	if s.Comment != nil {
@@ -1255,17 +1227,16 @@ func (p *printer) valueSpec(s *ast.ValueSpec, keepType, doIndent bool, multiLine
 // The parameter n is the number of specs in the group. If doIndent is set,
 // multi-line identifier lists in the spec are indented when the first
 // linebreak is encountered.
-// Sets multiLine to true if the spec spans multiple lines.
 //
-func (p *printer) spec(spec ast.Spec, n int, doIndent bool, multiLine *bool) {
+func (p *printer) spec(spec ast.Spec, n int, doIndent bool) {
 	switch s := spec.(type) {
 	case *ast.ImportSpec:
 		p.setComment(s.Doc)
 		if s.Name != nil {
-			p.expr(s.Name, multiLine)
+			p.expr(s.Name)
 			p.print(blank)
 		}
-		p.expr(s.Path, multiLine)
+		p.expr(s.Path)
 		p.setComment(s.Comment)
 		p.print(s.EndPos)
 
@@ -1274,26 +1245,26 @@ func (p *printer) spec(spec ast.Spec, n int, doIndent bool, multiLine *bool) {
 			p.internalError("expected n = 1; got", n)
 		}
 		p.setComment(s.Doc)
-		p.identList(s.Names, doIndent, multiLine) // always present
+		p.identList(s.Names, doIndent) // always present
 		if s.Type != nil {
 			p.print(blank)
-			p.expr(s.Type, multiLine)
+			p.expr(s.Type)
 		}
 		if s.Values != nil {
-			p.print(blank, token.ASSIGN)
-			p.exprList(token.NoPos, s.Values, 1, blankStart|commaSep, multiLine, token.NoPos)
+			p.print(blank, token.ASSIGN, blank)
+			p.exprList(token.NoPos, s.Values, 1, 0, token.NoPos)
 		}
 		p.setComment(s.Comment)
 
 	case *ast.TypeSpec:
 		p.setComment(s.Doc)
-		p.expr(s.Name, multiLine)
+		p.expr(s.Name)
 		if n == 1 {
 			p.print(blank)
 		} else {
 			p.print(vtab)
 		}
-		p.expr(s.Type, multiLine)
+		p.expr(s.Type)
 		p.setComment(s.Comment)
 
 	default:
@@ -1301,8 +1272,7 @@ func (p *printer) spec(spec ast.Spec, n int, doIndent bool, multiLine *bool) {
 	}
 }
 
-// Sets multiLine to true if the declaration spans multiple lines.
-func (p *printer) genDecl(d *ast.GenDecl, multiLine *bool) {
+func (p *printer) genDecl(d *ast.GenDecl) {
 	p.setComment(d.Doc)
 	p.print(d.Pos(), d.Tok, blank)
 
@@ -1315,32 +1285,31 @@ func (p *printer) genDecl(d *ast.GenDecl, multiLine *bool) {
 				// two or more grouped const/var declarations:
 				// determine if the type column must be kept
 				keepType := keepTypeColumn(d.Specs)
-				var ml bool
+				newSection := false
 				for i, s := range d.Specs {
 					if i > 0 {
-						p.linebreak(p.lineFor(s.Pos()), 1, ignore, ml)
+						p.linebreak(p.lineFor(s.Pos()), 1, ignore, newSection)
 					}
-					ml = false
-					p.valueSpec(s.(*ast.ValueSpec), keepType[i], false, &ml)
+					p.valueSpec(s.(*ast.ValueSpec), keepType[i], false)
+					newSection = p.isMultiLine(s)
 				}
 			} else {
-				var ml bool
+				newSection := false
 				for i, s := range d.Specs {
 					if i > 0 {
-						p.linebreak(p.lineFor(s.Pos()), 1, ignore, ml)
+						p.linebreak(p.lineFor(s.Pos()), 1, ignore, newSection)
 					}
-					ml = false
-					p.spec(s, n, false, &ml)
+					p.spec(s, n, false)
+					newSection = p.isMultiLine(s)
 				}
 			}
 			p.print(unindent, formfeed)
-			*multiLine = true
 		}
 		p.print(d.Rparen, token.RPAREN)
 
 	} else {
 		// single declaration
-		p.spec(d.Specs[0], 1, true, multiLine)
+		p.spec(d.Specs[0], 1, true)
 	}
 }
 
@@ -1404,8 +1373,7 @@ func (p *printer) isOneLineFunc(b *ast.BlockStmt, headerSize int) bool {
 	return headerSize+bodySize <= maxSize
 }
 
-// Sets multiLine to true if the function body spans multiple lines.
-func (p *printer) funcBody(b *ast.BlockStmt, headerSize int, isLit bool, multiLine *bool) {
+func (p *printer) funcBody(b *ast.BlockStmt, headerSize int, isLit bool) {
 	if b == nil {
 		return
 	}
@@ -1422,7 +1390,7 @@ func (p *printer) funcBody(b *ast.BlockStmt, headerSize int, isLit bool, multiLi
 				if i > 0 {
 					p.print(token.SEMICOLON, blank)
 				}
-				p.stmt(s, i == len(b.List)-1, ignoreMultiLine)
+				p.stmt(s, i == len(b.List)-1)
 			}
 			p.print(blank)
 		}
@@ -1432,7 +1400,6 @@ func (p *printer) funcBody(b *ast.BlockStmt, headerSize int, isLit bool, multiLi
 
 	p.print(blank)
 	p.block(b, 1)
-	*multiLine = true
 }
 
 // distance returns the column difference between from and to if both
@@ -1446,28 +1413,26 @@ func (p *printer) distance(from0 token.Pos, to token.Position) int {
 	return infinity
 }
 
-// Sets multiLine to true if the declaration spans multiple lines.
-func (p *printer) funcDecl(d *ast.FuncDecl, multiLine *bool) {
+func (p *printer) funcDecl(d *ast.FuncDecl) {
 	p.setComment(d.Doc)
 	p.print(d.Pos(), token.FUNC, blank)
 	if d.Recv != nil {
-		p.parameters(d.Recv, multiLine) // method: print receiver
+		p.parameters(d.Recv) // method: print receiver
 		p.print(blank)
 	}
-	p.expr(d.Name, multiLine)
-	p.signature(d.Type.Params, d.Type.Results, multiLine)
-	p.funcBody(d.Body, p.distance(d.Pos(), p.pos), false, multiLine)
+	p.expr(d.Name)
+	p.signature(d.Type.Params, d.Type.Results)
+	p.funcBody(d.Body, p.distance(d.Pos(), p.pos), false)
 }
 
-// Sets multiLine to true if the declaration spans multiple lines.
-func (p *printer) decl(decl ast.Decl, multiLine *bool) {
+func (p *printer) decl(decl ast.Decl) {
 	switch d := decl.(type) {
 	case *ast.BadDecl:
 		p.print(d.Pos(), "BadDecl")
 	case *ast.GenDecl:
-		p.genDecl(d, multiLine)
+		p.genDecl(d)
 	case *ast.FuncDecl:
-		p.funcDecl(d, multiLine)
+		p.funcDecl(d)
 	default:
 		panic("unreachable")
 	}
@@ -1490,7 +1455,7 @@ func declToken(decl ast.Decl) (tok token.Token) {
 func (p *printer) file(src *ast.File) {
 	p.setComment(src.Doc)
 	p.print(src.Pos(), token.PACKAGE, blank)
-	p.expr(src.Name, ignoreMultiLine)
+	p.expr(src.Name)
 
 	if len(src.Decls) > 0 {
 		tok := token.ILLEGAL
@@ -1509,7 +1474,7 @@ func (p *printer) file(src *ast.File) {
 				min = 2
 			}
 			p.linebreak(p.lineFor(d.Pos()), min, ignore, false)
-			p.decl(d, ignoreMultiLine)
+			p.decl(d)
 		}
 	}
 
diff --git a/src/pkg/go/printer/printer.go b/src/pkg/go/printer/printer.go
index 72f65a1..a027d32 100644
--- a/src/pkg/go/printer/printer.go
+++ b/src/pkg/go/printer/printer.go
@@ -34,9 +34,6 @@ const (
 	unindent = whiteSpace('<')
 )
 
-// Use ignoreMultiLine if the multiLine information is not important.
-var ignoreMultiLine = new(bool)
-
 // A pmode value represents the current printer mode.
 type pmode int
 
@@ -280,10 +277,9 @@ func (p *printer) writeString(pos token.Position, s string, isLit bool) {
 // it as is likely to help position the comment nicely.
 // pos is the comment position, next the position of the item
 // after all pending comments, prev is the previous comment in
-// a group of comments (or nil), and isKeyword indicates if the
-// next item is a keyword.
+// a group of comments (or nil), and tok is the next token.
 //
-func (p *printer) writeCommentPrefix(pos, next token.Position, prev, comment *ast.Comment, isKeyword bool) {
+func (p *printer) writeCommentPrefix(pos, next token.Position, prev, comment *ast.Comment, tok token.Token) {
 	if len(p.output) == 0 {
 		// the comment is the first item to be printed - don't write any whitespace
 		return
@@ -338,38 +334,41 @@ func (p *printer) writeCommentPrefix(pos, next token.Position, prev, comment *as
 		// comment on a different line:
 		// separate with at least one line break
 		droppedLinebreak := false
-		if prev == nil {
-			// first comment of a comment group
-			j := 0
-			for i, ch := range p.wsbuf {
-				switch ch {
-				case blank, vtab:
-					// ignore any horizontal whitespace before line breaks
-					p.wsbuf[i] = ignore
+		j := 0
+		for i, ch := range p.wsbuf {
+			switch ch {
+			case blank, vtab:
+				// ignore any horizontal whitespace before line breaks
+				p.wsbuf[i] = ignore
+				continue
+			case indent:
+				// apply pending indentation
+				continue
+			case unindent:
+				// if this is not the last unindent, apply it
+				// as it is (likely) belonging to the last
+				// construct (e.g., a multi-line expression list)
+				// and is not part of closing a block
+				if i+1 < len(p.wsbuf) && p.wsbuf[i+1] == unindent {
 					continue
-				case indent:
-					// apply pending indentation
+				}
+				// if the next token is not a closing }, apply the unindent
+				// if it appears that the comment is aligned with the
+				// token; otherwise assume the unindent is part of a
+				// closing block and stop (this scenario appears with
+				// comments before a case label where the comments
+				// apply to the next case instead of the current one)
+				if tok != token.RBRACE && pos.Column == next.Column {
 					continue
-				case unindent:
-					// if the next token is a keyword, apply the outdent
-					// if it appears that the comment is aligned with the
-					// keyword; otherwise assume the outdent is part of a
-					// closing block and stop (this scenario appears with
-					// comments before a case label where the comments
-					// apply to the next case instead of the current one)
-					if isKeyword && pos.Column == next.Column {
-						continue
-					}
-				case newline, formfeed:
-					// TODO(gri): may want to keep formfeed info in some cases
-					p.wsbuf[i] = ignore
-					droppedLinebreak = true
 				}
-				j = i
-				break
+			case newline, formfeed:
+				p.wsbuf[i] = ignore
+				droppedLinebreak = prev == nil // record only if first comment of a group
 			}
-			p.writeWhitespace(j)
+			j = i
+			break
 		}
+		p.writeWhitespace(j)
 
 		// determine number of linebreaks before the comment
 		n := 0
@@ -678,7 +677,7 @@ func (p *printer) intersperseComments(next token.Position, tok token.Token) (wro
 	var last *ast.Comment
 	for p.commentBefore(next) {
 		for _, c := range p.comment.List {
-			p.writeCommentPrefix(p.posFor(c.Pos()), next, last, c, tok.IsKeyword())
+			p.writeCommentPrefix(p.posFor(c.Pos()), next, last, c, tok)
 			p.writeComment(c)
 			last = c
 		}
@@ -1011,18 +1010,18 @@ func (p *printer) printNode(node interface{}) error {
 	// format node
 	switch n := node.(type) {
 	case ast.Expr:
-		p.expr(n, ignoreMultiLine)
+		p.expr(n)
 	case ast.Stmt:
 		// A labeled statement will un-indent to position the
 		// label. Set indent to 1 so we don't get indent "underflow".
 		if _, labeledStmt := n.(*ast.LabeledStmt); labeledStmt {
 			p.indent = 1
 		}
-		p.stmt(n, false, ignoreMultiLine)
+		p.stmt(n, false)
 	case ast.Decl:
-		p.decl(n, ignoreMultiLine)
+		p.decl(n)
 	case ast.Spec:
-		p.spec(n, 1, false, ignoreMultiLine)
+		p.spec(n, 1, false)
 	case *ast.File:
 		p.file(n)
 	default:
diff --git a/src/pkg/go/printer/printer_test.go b/src/pkg/go/printer/printer_test.go
index 2d4f613..497d671 100644
--- a/src/pkg/go/printer/printer_test.go
+++ b/src/pkg/go/printer/printer_test.go
@@ -154,15 +154,12 @@ var data = []entry{
 }
 
 func TestFiles(t *testing.T) {
-	for i, e := range data {
+	for _, e := range data {
 		source := filepath.Join(dataDir, e.source)
 		golden := filepath.Join(dataDir, e.golden)
 		check(t, source, golden, e.mode)
 		// TODO(gri) check that golden is idempotent
 		//check(t, golden, golden, e.mode)
-		if testing.Short() && i >= 3 {
-			break
-		}
 	}
 }
 
diff --git a/src/pkg/go/printer/testdata/comments.golden b/src/pkg/go/printer/testdata/comments.golden
index 4c6f1ab..d9aa2d8 100644
--- a/src/pkg/go/printer/testdata/comments.golden
+++ b/src/pkg/go/printer/testdata/comments.golden
@@ -168,6 +168,91 @@ func typeswitch(x interface{}) {
 	// this comment should not be indented
 }
 
+//
+// Indentation of comments after possibly indented multi-line constructs
+// (test cases for issue 3147).
+//
+
+func _() {
+	s := 1 +
+		2
+	// should be indented like s
+}
+
+func _() {
+	s := 1 +
+		2	// comment
+	// should be indented like s
+}
+
+func _() {
+	s := 1 +
+		2	// comment
+	// should be indented like s
+	_ = 0
+}
+
+func _() {
+	s := 1 +
+		2
+	// should be indented like s
+	_ = 0
+}
+
+func _() {
+	s := 1 +
+		2
+
+	// should be indented like s
+}
+
+func _() {
+	s := 1 +
+		2	// comment
+
+	// should be indented like s
+}
+
+func _() {
+	s := 1 +
+		2	// comment
+
+	// should be indented like s
+	_ = 0
+}
+
+func _() {
+	s := 1 +
+		2
+
+	// should be indented like s
+	_ = 0
+}
+
+// Test case from issue 3147.
+func f() {
+	templateText := "a" +	// A
+		"b" +	// B
+		"c"	// C
+
+	// should be aligned with f()
+	f()
+}
+
+// Modified test case from issue 3147.
+func f() {
+	templateText := "a" +	// A
+		"b" +	// B
+		"c"	// C
+
+		// may not be aligned with f() (source is not aligned)
+	f()
+}
+
+//
+// Test cases for alignment of lines in general comments.
+//
+
 func _() {
 	/* freestanding comment
 	   aligned		line
diff --git a/src/pkg/go/printer/testdata/comments.input b/src/pkg/go/printer/testdata/comments.input
index c0f8cca..6084b3f 100644
--- a/src/pkg/go/printer/testdata/comments.input
+++ b/src/pkg/go/printer/testdata/comments.input
@@ -171,6 +171,91 @@ func typeswitch(x interface{}) {
 	// this comment should not be indented
 }
 
+//
+// Indentation of comments after possibly indented multi-line constructs
+// (test cases for issue 3147).
+//
+
+func _() {
+	s := 1 +
+		2
+// should be indented like s
+}
+
+func _() {
+	s := 1 +
+		2 // comment
+		// should be indented like s
+}
+
+func _() {
+	s := 1 +
+		2 // comment
+	// should be indented like s
+	_ = 0
+}
+
+func _() {
+	s := 1 +
+		2
+	// should be indented like s
+	_ = 0
+}
+
+func _() {
+	s := 1 +
+		2
+
+// should be indented like s
+}
+
+func _() {
+	s := 1 +
+		2 // comment
+
+		// should be indented like s
+}
+
+func _() {
+	s := 1 +
+		2 // comment
+
+	// should be indented like s
+	_ = 0
+}
+
+func _() {
+	s := 1 +
+		2
+
+	// should be indented like s
+	_ = 0
+}
+
+// Test case from issue 3147.
+func f() {
+	templateText := "a" + // A
+		"b" + // B
+		"c" // C
+
+	// should be aligned with f()
+	f()
+}
+
+// Modified test case from issue 3147.
+func f() {
+	templateText := "a" + // A
+		"b" + // B
+		"c" // C
+
+		// may not be aligned with f() (source is not aligned)
+	f()
+}
+
+//
+// Test cases for alignment of lines in general comments.
+//
+
 func _() {
 	/* freestanding comment
 	   aligned		line
diff --git a/src/pkg/go/printer/testdata/declarations.golden b/src/pkg/go/printer/testdata/declarations.golden
index 928b8ce..7ed7cb6 100644
--- a/src/pkg/go/printer/testdata/declarations.golden
+++ b/src/pkg/go/printer/testdata/declarations.golden
@@ -83,13 +83,13 @@ import (
 // more import examples
 import (
 	"xxx"
-	"much longer name"	// comment
-	"short name"		// comment
+	"much_longer_name"	// comment
+	"short_name"		// comment
 )
 
 import (
 	_ "xxx"
-	"much longer name"	// comment
+	"much_longer_name"	// comment
 )
 
 import (
@@ -500,7 +500,7 @@ type _ struct {
 
 type _ struct {
 	a, b,
-	c, d	int	// this line should be indented
+	c, d		int	// this line should be indented
 	u, v, w, x	float	// this line should be indented
 	p, q,
 	r, s	float	// this line should be indented
@@ -562,7 +562,7 @@ var a2, b2,
 
 var (
 	a3, b3,
-	c3, d3	int	// this line should be indented
+	c3, d3		int	// this line should be indented
 	a4, b4, c4	int	// this line should be indented
 )
 
diff --git a/src/pkg/go/printer/testdata/declarations.input b/src/pkg/go/printer/testdata/declarations.input
index 68f9030..df8c2b1 100644
--- a/src/pkg/go/printer/testdata/declarations.input
+++ b/src/pkg/go/printer/testdata/declarations.input
@@ -84,13 +84,13 @@ import (
 // more import examples
 import (
 	"xxx"
-	"much longer name" // comment
-	"short name" // comment
+	"much_longer_name" // comment
+	"short_name" // comment
 )
 
 import (
 	_ "xxx"
-	"much longer name" // comment
+	"much_longer_name" // comment
 )
 
 import (
diff --git a/src/pkg/go/printer/testdata/expressions.golden b/src/pkg/go/printer/testdata/expressions.golden
index 95fdd95..45fa4d9 100644
--- a/src/pkg/go/printer/testdata/expressions.golden
+++ b/src/pkg/go/printer/testdata/expressions.golden
@@ -625,3 +625,25 @@ func f() {
 		log.Fatal(err)
 	}
 }
+
+// Handle multi-line argument lists ending in ... correctly.
+// Was issue 3130.
+func _() {
+	_ = append(s, a...)
+	_ = append(
+		s, a...)
+	_ = append(s,
+		a...)
+	_ = append(
+		s,
+		a...)
+	_ = append(s, a...,
+	)
+	_ = append(s,
+		a...,
+	)
+	_ = append(
+		s,
+		a...,
+	)
+}
diff --git a/src/pkg/go/printer/testdata/expressions.input b/src/pkg/go/printer/testdata/expressions.input
index d113149..f545c66 100644
--- a/src/pkg/go/printer/testdata/expressions.input
+++ b/src/pkg/go/printer/testdata/expressions.input
@@ -654,3 +654,25 @@ func f() {
 	    log.Fatal(err)
 	}
 }
+
+// Handle multi-line argument lists ending in ... correctly.
+// Was issue 3130.
+func _() {
+	_ = append(s, a...)
+	_ = append(
+		s, a...)
+	_ = append(s,
+		a...)
+	_ = append(
+		s,
+		a...)
+	_ = append(s, a...,
+	)
+	_ = append(s,
+		a...,
+	)
+	_ = append(
+		s,
+		a...,
+	)
+}
diff --git a/src/pkg/go/printer/testdata/expressions.raw b/src/pkg/go/printer/testdata/expressions.raw
index 3442ba9..87a4b00 100644
--- a/src/pkg/go/printer/testdata/expressions.raw
+++ b/src/pkg/go/printer/testdata/expressions.raw
@@ -625,3 +625,25 @@ func f() {
 		log.Fatal(err)
 	}
 }
+
+// Handle multi-line argument lists ending in ... correctly.
+// Was issue 3130.
+func _() {
+	_ = append(s, a...)
+	_ = append(
+		s, a...)
+	_ = append(s,
+		a...)
+	_ = append(
+		s,
+		a...)
+	_ = append(s, a...,
+	)
+	_ = append(s,
+		a...,
+	)
+	_ = append(
+		s,
+		a...,
+	)
+}
diff --git a/src/pkg/go/printer/testdata/parser.go b/src/pkg/go/printer/testdata/parser.go
index c85297f..dba8bbd 100644
--- a/src/pkg/go/printer/testdata/parser.go
+++ b/src/pkg/go/printer/testdata/parser.go
@@ -52,7 +52,7 @@ type parser struct {
 	// Non-syntactic parser control
 	exprLev int // < 0: in control clause, >= 0: in expression
 
-	// Ordinary identifer scopes
+	// Ordinary identifier scopes
 	pkgScope   *ast.Scope        // pkgScope.Outer == nil
 	topScope   *ast.Scope        // top-most scope; may be pkgScope
 	unresolved []*ast.Ident      // unresolved identifiers
diff --git a/src/pkg/go/printer/testdata/statements.golden b/src/pkg/go/printer/testdata/statements.golden
index 90e1743..ffca21e 100644
--- a/src/pkg/go/printer/testdata/statements.golden
+++ b/src/pkg/go/printer/testdata/statements.golden
@@ -8,6 +8,82 @@ var expr bool
 
 func use(x interface{})	{}
 
+// Formatting of multi-line return statements.
+func _f() {
+	return
+	return x, y, z
+	return T{}
+	return T{1, 2, 3},
+		x, y, z
+	return T{1, 2, 3},
+		x, y,
+		z
+	return T{1,
+		2,
+		3}
+	return T{1,
+		2,
+		3,
+	}
+	return T{
+		1,
+		2,
+		3}
+	return T{
+		1,
+		2,
+		3,
+	}
+	return T{
+		1,
+		T{1, 2, 3},
+		3,
+	}
+	return T{
+		1,
+		T{1,
+			2, 3},
+		3,
+	}
+	return T{
+		1,
+		T{1,
+			2,
+			3},
+		3,
+	}
+	return T{
+		1,
+		2,
+	},
+		nil
+	return T{
+		1,
+		2,
+	},
+		T{
+			x:	3,
+			y:	4,
+		},
+		nil
+	return x + y +
+		z
+	return func() {}
+	return func() {
+		_ = 0
+	}, T{
+		1, 2,
+	}
+	return func() {
+		_ = 0
+	}
+	return func() T {
+		return T{
+			1, 2,
+		}
+	}
+}
+
 // Formatting of if-statement headers.
 func _() {
 	if true {
diff --git a/src/pkg/go/printer/testdata/statements.input b/src/pkg/go/printer/testdata/statements.input
index 86a753c..99945e9 100644
--- a/src/pkg/go/printer/testdata/statements.input
+++ b/src/pkg/go/printer/testdata/statements.input
@@ -8,6 +8,82 @@ var expr bool
 
 func use(x interface{}) {}
 
+// Formatting of multi-line return statements.
+func _f() {
+	return
+	return x, y, z
+	return T{}
+	return T{1, 2, 3},
+		x, y, z
+	return T{1, 2, 3},
+		x, y,
+		z
+	return T{1,
+		2,
+		3}
+	return T{1,
+		2,
+		3,
+	}
+	return T{
+		1,
+		2,
+		3}
+	return T{
+		1,
+		2,
+		3,
+	}
+	return T{
+		1,
+		T{1, 2, 3},
+		3,
+	}
+	return T{
+		1,
+		T{1,
+			2, 3},
+		3,
+	}
+	return T{
+		1,
+		T{1,
+			2,
+			3},
+		3,
+	}
+	return T{
+			1,
+			2,
+		},
+		nil
+	return T{
+			1,
+			2,
+		},
+		T{
+			x: 3,
+			y: 4,
+		},
+		nil
+	return x + y +
+		z
+	return func() {}
+	return func() {
+		_ = 0
+	}, T{
+		1, 2,
+	}
+	return func() {
+		_ = 0
+	}
+	return func() T {
+		return T {
+			1, 2,
+		}
+	}
+}
+
 // Formatting of if-statement headers.
 func _() {
 	if true {}
diff --git a/src/pkg/html/template/doc.go b/src/pkg/html/template/doc.go
index 7f60f3b..3699ea1 100644
--- a/src/pkg/html/template/doc.go
+++ b/src/pkg/html/template/doc.go
@@ -19,7 +19,7 @@ to parse and execute HTML templates safely.
 
   tmpl, err := template.New("name").Parse(...)
   // Error checking elided
-  err = tmpl.Execute(out, "Foo", data)
+  err = tmpl.Execute(out, data)
 
 If successful, tmpl will now be injection-safe. Otherwise, err is an error
 defined in the docs for ErrorCode.
diff --git a/src/pkg/html/template/escape.go b/src/pkg/html/template/escape.go
index 02fa3ea..a058e20 100644
--- a/src/pkg/html/template/escape.go
+++ b/src/pkg/html/template/escape.go
@@ -593,7 +593,7 @@ func (e *escaper) escapeText(c context, n *parse.TextNode) context {
 				}
 			}
 			for j := i; j < end; j++ {
-				if s[j] == '<' && !bytes.HasPrefix(s[j:], doctypeBytes) {
+				if s[j] == '<' && !bytes.HasPrefix(bytes.ToUpper(s[j:]), doctypeBytes) {
 					b.Write(s[written:j])
 					b.WriteString("<")
 					written = j + 1
diff --git a/src/pkg/html/template/escape_test.go b/src/pkg/html/template/escape_test.go
index 70cada3..2bbb1b1 100644
--- a/src/pkg/html/template/escape_test.go
+++ b/src/pkg/html/template/escape_test.go
@@ -223,14 +223,14 @@ func TestEscape(t *testing.T) {
 			`<button onclick='alert("\x3cHello\x3e")'>`,
 		},
 		{
-			"badMarshaller",
+			"badMarshaler",
 			`<button onclick='alert(1/{{.B}}in numbers)'>`,
 			`<button onclick='alert(1/ /* json: error calling MarshalJSON for type *template.badMarshaler: invalid character 'f' looking for beginning of object key string */null in numbers)'>`,
 		},
 		{
-			"jsMarshaller",
+			"jsMarshaler",
 			`<button onclick='alert({{.M}})'>`,
-			`<button onclick='alert({"<foo>":"O'Reilly"})'>`,
+			`<button onclick='alert({"\u003cfoo\u003e":"O'Reilly"})'>`,
 		},
 		{
 			"jsStrNotUnderEscaped",
@@ -432,6 +432,11 @@ func TestEscape(t *testing.T) {
 			"<!DOCTYPE html>Hello, World!",
 		},
 		{
+			"HTML doctype not case-insensitive",
+			"<!doCtYPE htMl>Hello, World!",
+			"<!doCtYPE htMl>Hello, World!",
+		},
+		{
 			"No doctype injection",
 			`<!{{"DOCTYPE"}}`,
 			"<!DOCTYPE",
diff --git a/src/pkg/html/template/html.go b/src/pkg/html/template/html.go
index 7b77d65..36c88e2 100644
--- a/src/pkg/html/template/html.go
+++ b/src/pkg/html/template/html.go
@@ -134,7 +134,7 @@ var htmlNospaceNormReplacementTable = []string{
 	'`': "`",
 }
 
-// htmlReplacer returns s with runes replaced acccording to replacementTable
+// htmlReplacer returns s with runes replaced according to replacementTable
 // and when badRunes is true, certain bad runes are allowed through unescaped.
 func htmlReplacer(s string, replacementTable []string, badRunes bool) string {
 	written, b := 0, new(bytes.Buffer)
diff --git a/src/pkg/io/io.go b/src/pkg/io/io.go
index bbfa6c2..7074834 100644
--- a/src/pkg/io/io.go
+++ b/src/pkg/io/io.go
@@ -6,6 +6,10 @@
 // Its primary job is to wrap existing implementations of such primitives,
 // such as those in package os, into shared public interfaces that
 // abstract the functionality, plus some other related primitives.
+//
+// Because these interfaces and primitives wrap lower-level operations with
+// various implementations, unless otherwise informed clients should not
+// assume they are safe for parallel execution.
 package io
 
 import (
@@ -156,6 +160,9 @@ type WriterTo interface {
 // If ReadAt is reading from an input source with a seek offset,
 // ReadAt should not affect nor be affected by the underlying
 // seek offset.
+//
+// Clients of ReadAt can execute parallel ReadAt calls on the
+// same input source.
 type ReaderAt interface {
 	ReadAt(p []byte, off int64) (n int, err error)
 }
diff --git a/src/pkg/io/pipe.go b/src/pkg/io/pipe.go
index cf05e0c..f3f0f17 100644
--- a/src/pkg/io/pipe.go
+++ b/src/pkg/io/pipe.go
@@ -175,6 +175,10 @@ func (w *PipeWriter) CloseWithError(err error) error {
 // with code expecting an io.Writer.
 // Reads on one end are matched with writes on the other,
 // copying data directly between the two; there is no internal buffering.
+// It is safe to call Read and Write in parallel with each other or with
+// Close. Close will complete once pending I/O is done. Parallel calls to
+// Read, and parallel calls to Write, are also safe:
+// the individual calls will be gated sequentially.
 func Pipe() (*PipeReader, *PipeWriter) {
 	p := new(pipe)
 	p.rwait.L = &p.l
diff --git a/src/pkg/math/const.go b/src/pkg/math/const.go
index edb14f6..f1247c3 100644
--- a/src/pkg/math/const.go
+++ b/src/pkg/math/const.go
@@ -27,11 +27,11 @@ const (
 // Max is the largest finite value representable by the type.
 // SmallestNonzero is the smallest positive, non-zero value representable by the type.
 const (
-	MaxFloat32             = 3.40282346638528859811704183484516925440e+38  /* 2**127 * (2**24 - 1) / 2**23 */
-	SmallestNonzeroFloat32 = 1.401298464324817070923729583289916131280e-45 /* 1 / 2**(127 - 1 + 23) */
+	MaxFloat32             = 3.40282346638528859811704183484516925440e+38  // 2**127 * (2**24 - 1) / 2**23
+	SmallestNonzeroFloat32 = 1.401298464324817070923729583289916131280e-45 // 1 / 2**(127 - 1 + 23)
 
-	MaxFloat64             = 1.797693134862315708145274237317043567981e+308 /* 2**1023 * (2**53 - 1) / 2**52 */
-	SmallestNonzeroFloat64 = 4.940656458412465441765687928682213723651e-324 /* 1 / 2**(1023 - 1 + 52) */
+	MaxFloat64             = 1.797693134862315708145274237317043567981e+308 // 2**1023 * (2**53 - 1) / 2**52
+	SmallestNonzeroFloat64 = 4.940656458412465441765687928682213723651e-324 // 1 / 2**(1023 - 1 + 52)
 )
 
 // Integer limit values.
diff --git a/src/pkg/net/dial.go b/src/pkg/net/dial.go
index 61b8911..10ca5fa 100644
--- a/src/pkg/net/dial.go
+++ b/src/pkg/net/dial.go
@@ -69,7 +69,7 @@ func resolveNetAddr(op, net, addr string) (afnet string, a Addr, err error) {
 //
 // Known networks are "tcp", "tcp4" (IPv4-only), "tcp6" (IPv6-only),
 // "udp", "udp4" (IPv4-only), "udp6" (IPv6-only), "ip", "ip4"
-// (IPv4-only), "ip6" (IPv6-only), "unix", "unixgram" and "unixpacket".
+// (IPv4-only), "ip6" (IPv6-only), "unix" and "unixpacket".
 //
 // For TCP and UDP networks, addresses have the form host:port.
 // If host is a literal IPv6 address, it must be enclosed
diff --git a/src/pkg/net/dial_test.go b/src/pkg/net/dial_test.go
index e5a797e..5f5aea1 100644
--- a/src/pkg/net/dial_test.go
+++ b/src/pkg/net/dial_test.go
@@ -5,6 +5,8 @@
 package net
 
 import (
+	"flag"
+	"regexp"
 	"runtime"
 	"testing"
 	"time"
@@ -128,3 +130,82 @@ func TestSelfConnect(t *testing.T) {
 		}
 	}
 }
+
+var runErrorTest = flag.Bool("run_error_test", false, "let TestDialError check for dns errors")
+
+type DialErrorTest struct {
+	Net     string
+	Raddr   string
+	Pattern string
+}
+
+var dialErrorTests = []DialErrorTest{
+	{
+		"datakit", "mh/astro/r70",
+		"dial datakit mh/astro/r70: unknown network datakit",
+	},
+	{
+		"tcp", "127.0.0.1:☺",
+		"dial tcp 127.0.0.1:☺: unknown port tcp/☺",
+	},
+	{
+		"tcp", "no-such-name.google.com.:80",
+		"dial tcp no-such-name.google.com.:80: lookup no-such-name.google.com.( on .*)?: no (.*)",
+	},
+	{
+		"tcp", "no-such-name.no-such-top-level-domain.:80",
+		"dial tcp no-such-name.no-such-top-level-domain.:80: lookup no-such-name.no-such-top-level-domain.( on .*)?: no (.*)",
+	},
+	{
+		"tcp", "no-such-name:80",
+		`dial tcp no-such-name:80: lookup no-such-name\.(.*\.)?( on .*)?: no (.*)`,
+	},
+	{
+		"tcp", "mh/astro/r70:http",
+		"dial tcp mh/astro/r70:http: lookup mh/astro/r70: invalid domain name",
+	},
+	{
+		"unix", "/etc/file-not-found",
+		"dial unix /etc/file-not-found: no such file or directory",
+	},
+	{
+		"unix", "/etc/",
+		"dial unix /etc/: (permission denied|socket operation on non-socket|connection refused)",
+	},
+	{
+		"unixpacket", "/etc/file-not-found",
+		"dial unixpacket /etc/file-not-found: no such file or directory",
+	},
+	{
+		"unixpacket", "/etc/",
+		"dial unixpacket /etc/: (permission denied|socket operation on non-socket|connection refused)",
+	},
+}
+
+var duplicateErrorPattern = `dial (.*) dial (.*)`
+
+func TestDialError(t *testing.T) {
+	if !*runErrorTest {
+		t.Logf("test disabled; use -run_error_test to enable")
+		return
+	}
+	for i, tt := range dialErrorTests {
+		c, err := Dial(tt.Net, tt.Raddr)
+		if c != nil {
+			c.Close()
+		}
+		if err == nil {
+			t.Errorf("#%d: nil error, want match for %#q", i, tt.Pattern)
+			continue
+		}
+		s := err.Error()
+		match, _ := regexp.MatchString(tt.Pattern, s)
+		if !match {
+			t.Errorf("#%d: %q, want match for %#q", i, s, tt.Pattern)
+		}
+		match, _ = regexp.MatchString(duplicateErrorPattern, s)
+		if match {
+			t.Errorf("#%d: %q, duplicate error return from Dial", i, s)
+		}
+	}
+}
diff --git a/src/pkg/net/dialgoogle_test.go b/src/pkg/net/dialgoogle_test.go
index 14356da..03c4499 100644
--- a/src/pkg/net/dialgoogle_test.go
+++ b/src/pkg/net/dialgoogle_test.go
@@ -42,9 +42,8 @@ func doDial(t *testing.T, network, addr string) {
 }
 
 func TestLookupCNAME(t *testing.T) {
-	if testing.Short() {
-		// Don't use external network.
-		t.Logf("skipping external network test during -short")
+	if testing.Short() || !*testExternal {
+		t.Logf("skipping test to avoid external network")
 		return
 	}
 	cname, err := LookupCNAME("www.google.com")
@@ -67,9 +66,8 @@ var googleaddrsipv4 = []string{
 }
 
 func TestDialGoogleIPv4(t *testing.T) {
-	if testing.Short() {
-		// Don't use external network.
-		t.Logf("skipping external network test during -short")
+	if testing.Short() || !*testExternal {
+		t.Logf("skipping test to avoid external network")
 		return
 	}
 
@@ -124,9 +122,8 @@ var googleaddrsipv6 = []string{
 }
 
 func TestDialGoogleIPv6(t *testing.T) {
-	if testing.Short() {
-		// Don't use external network.
-		t.Logf("skipping external network test during -short")
+	if testing.Short() || !*testExternal {
+		t.Logf("skipping test to avoid external network")
 		return
 	}
 	// Only run tcp6 if the kernel will take it.
diff --git a/src/pkg/net/http/cgi/child.go b/src/pkg/net/http/cgi/child.go
index e6c3ef9..1ba7bec 100644
--- a/src/pkg/net/http/cgi/child.go
+++ b/src/pkg/net/http/cgi/child.go
@@ -144,6 +144,7 @@ func Serve(handler http.Handler) error {
 		bufw:   bufio.NewWriter(os.Stdout),
 	}
 	handler.ServeHTTP(rw, req)
+	rw.Write(nil) // make sure a response is sent
 	if err = rw.bufw.Flush(); err != nil {
 		return err
 	}
diff --git a/src/pkg/net/http/cgi/host_test.go b/src/pkg/net/http/cgi/host_test.go
index d1bb66a..4db3d85 100644
--- a/src/pkg/net/http/cgi/host_test.go
+++ b/src/pkg/net/http/cgi/host_test.go
@@ -41,6 +41,7 @@ func runCgiTest(t *testing.T, h *Handler, httpreq string, expectedMap map[string
 
 	// Make a map to hold the test map that the CGI returns.
 	m := make(map[string]string)
+	m["_body"] = rw.Body.String()
 	linesRead := 0
 readlines:
 	for {
diff --git a/src/pkg/net/http/cgi/matryoshka_test.go b/src/pkg/net/http/cgi/matryoshka_test.go
index 1a44df2..e1a78c8 100644
--- a/src/pkg/net/http/cgi/matryoshka_test.go
+++ b/src/pkg/net/http/cgi/matryoshka_test.go
@@ -51,6 +51,22 @@ func TestHostingOurselves(t *testing.T) {
 	}
 }
 
+// Test that a child handler only writing headers works.
+func TestChildOnlyHeaders(t *testing.T) {
+	h := &Handler{
+		Path: os.Args[0],
+		Root: "/test.go",
+		Args: []string{"-test.run=TestBeChildCGIProcess"},
+	}
+	expectedMap := map[string]string{
+		"_body": "",
+	}
+	replay := runCgiTest(t, h, "GET /test.go?no-body=1 HTTP/1.0\nHost: example.com\n\n", expectedMap)
+	if expected, got := "X-Test-Value", replay.Header().Get("X-Test-Header"); got != expected {
+		t.Errorf("got a X-Test-Header of %q; expected %q", got, expected)
+	}
+}
+
 // Note: not actually a test.
 func TestBeChildCGIProcess(t *testing.T) {
 	if os.Getenv("REQUEST_METHOD") == "" {
@@ -59,8 +75,11 @@ func TestBeChildCGIProcess(t *testing.T) {
 	}
 	Serve(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
 		rw.Header().Set("X-Test-Header", "X-Test-Value")
-		fmt.Fprintf(rw, "test=Hello CGI-in-CGI\n")
 		req.ParseForm()
+		if req.FormValue("no-body") == "1" {
+			return
+		}
+		fmt.Fprintf(rw, "test=Hello CGI-in-CGI\n")
 		for k, vv := range req.Form {
 			for _, v := range vv {
 				fmt.Fprintf(rw, "param-%s=%s\n", k, v)
diff --git a/src/pkg/net/http/fs_test.go b/src/pkg/net/http/fs_test.go
index 0409008..5aa93ce 100644
--- a/src/pkg/net/http/fs_test.go
+++ b/src/pkg/net/http/fs_test.go
@@ -152,12 +152,19 @@ func TestFileServerCleans(t *testing.T) {
 	}
 }
 
+func mustRemoveAll(dir string) {
+	err := os.RemoveAll(dir)
+	if err != nil {
+		panic(err)
+	}
+}
+
 func TestFileServerImplicitLeadingSlash(t *testing.T) {
 	tempDir, err := ioutil.TempDir("", "")
 	if err != nil {
 		t.Fatalf("TempDir: %v", err)
 	}
-	defer os.RemoveAll(tempDir)
+	defer mustRemoveAll(tempDir)
 	if err := ioutil.WriteFile(filepath.Join(tempDir, "foo.txt"), []byte("Hello world"), 0644); err != nil {
 		t.Fatalf("WriteFile: %v", err)
 	}
@@ -172,6 +179,7 @@ func TestFileServerImplicitLeadingSlash(t *testing.T) {
 		if err != nil {
 			t.Fatalf("ReadAll %s: %v", suffix, err)
 		}
+		res.Body.Close()
 		return string(b)
 	}
 	if s := get("/bar/"); !strings.Contains(s, ">foo.txt<") {
diff --git a/src/pkg/net/http/httptest/server.go b/src/pkg/net/http/httptest/server.go
index 8d911f7..57cf0c9 100644
--- a/src/pkg/net/http/httptest/server.go
+++ b/src/pkg/net/http/httptest/server.go
@@ -13,6 +13,7 @@ import (
 	"net"
 	"net/http"
 	"os"
+	"sync"
 )
 
 // A Server is an HTTP server listening on a system-chosen port on the
@@ -25,6 +26,10 @@ type Server struct {
 	// Config may be changed after calling NewUnstartedServer and
 	// before Start or StartTLS.
 	Config *http.Server
+
+	// wg counts the number of outstanding HTTP requests on this server.
+	// Close blocks until all requests are finished.
+	wg sync.WaitGroup
 }
 
 // historyListener keeps track of all connections that it's ever
@@ -93,6 +98,7 @@ func (s *Server) Start() {
 	}
 	s.Listener = &historyListener{s.Listener, make([]net.Conn, 0)}
 	s.URL = "http://" + s.Listener.Addr().String()
+	s.wrapHandler()
 	go s.Config.Serve(s.Listener)
 	if *serve != "" {
 		fmt.Fprintln(os.Stderr, "httptest: serving on", s.URL)
@@ -118,9 +124,21 @@ func (s *Server) StartTLS() {
 
 	s.Listener = &historyListener{tlsListener, make([]net.Conn, 0)}
 	s.URL = "https://" + s.Listener.Addr().String()
+	s.wrapHandler()
 	go s.Config.Serve(s.Listener)
 }
 
+func (s *Server) wrapHandler() {
+	h := s.Config.Handler
+	if h == nil {
+		h = http.DefaultServeMux
+	}
+	s.Config.Handler = &waitGroupHandler{
+		s: s,
+		h: h,
+	}
+}
+
 // NewTLSServer starts and returns a new Server using TLS.
 // The caller should call Close when finished, to shut it down.
 func NewTLSServer(handler http.Handler) *Server {
@@ -129,9 +147,11 @@ func NewTLSServer(handler http.Handler) *Server {
 	return ts
 }
 
-// Close shuts down the server.
+// Close shuts down the server and blocks until all outstanding
+// requests on this server have completed.
 func (s *Server) Close() {
 	s.Listener.Close()
+	s.wg.Wait()
 }
 
 // CloseClientConnections closes any currently open HTTP connections
@@ -146,6 +166,20 @@ func (s *Server) CloseClientConnections() {
 	}
 }
 
+// waitGroupHandler wraps a handler, incrementing and decrementing a
+// sync.WaitGroup on each request, to enable Server.Close to block
+// until outstanding requests are finished.
+type waitGroupHandler struct {
+	s *Server
+	h http.Handler // non-nil
+}
+
+func (h *waitGroupHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	h.s.wg.Add(1)
+	defer h.s.wg.Done() // a defer, in case ServeHTTP below panics
+	h.h.ServeHTTP(w, r)
+}
+
 // localhostCert is a PEM-encoded TLS cert with SAN DNS names
 // "127.0.0.1" and "[::1]", expiring at the last second of 2049 (the end
 // of ASN.1 time).
diff --git a/src/pkg/net/http/httputil/dump.go b/src/pkg/net/http/httputil/dump.go
index c853066..892ef4e 100644
--- a/src/pkg/net/http/httputil/dump.go
+++ b/src/pkg/net/http/httputil/dump.go
@@ -12,6 +12,7 @@ import (
 	"io/ioutil"
 	"net"
 	"net/http"
+	"net/url"
 	"strings"
 	"time"
 )
@@ -59,6 +60,19 @@ func DumpRequestOut(req *http.Request, body bool) ([]byte, error) {
 		}
 	}
 
+	// Since we're using the actual Transport code to write the request,
+	// switch to http so the Transport doesn't try to do an SSL
+	// negotiation with our dumpConn and its bytes.Buffer & pipe.
+	// The wire format for https and http are the same, anyway.
+	reqSend := req
+	if req.URL.Scheme == "https" {
+		reqSend = new(http.Request)
+		*reqSend = *req
+		reqSend.URL = new(url.URL)
+		*reqSend.URL = *req.URL
+		reqSend.URL.Scheme = "http"
+	}
+
 	// Use the actual Transport code to record what we would send
 	// on the wire, but not using TCP.  Use a Transport with a
 	// customer dialer that returns a fake net.Conn that waits
@@ -79,7 +93,7 @@ func DumpRequestOut(req *http.Request, body bool) ([]byte, error) {
 		},
 	}
 
-	_, err := t.RoundTrip(req)
+	_, err := t.RoundTrip(reqSend)
 
 	req.Body = save
 	if err != nil {
diff --git a/src/pkg/net/http/httputil/dump_test.go b/src/pkg/net/http/httputil/dump_test.go
index 819efb5..5afe9ba 100644
--- a/src/pkg/net/http/httputil/dump_test.go
+++ b/src/pkg/net/http/httputil/dump_test.go
@@ -71,6 +71,18 @@ var dumpTests = []dumpTest{
 			"User-Agent: Go http package\r\n" +
 			"Accept-Encoding: gzip\r\n\r\n",
 	},
+
+	// Test that an https URL doesn't try to do an SSL negotiation
+	// with a bytes.Buffer and hang with all goroutines not
+	// runnable.
+	{
+		Req: *mustNewRequest("GET", "https://example.com/foo", nil),
+
+		WantDumpOut: "GET /foo HTTP/1.1\r\n" +
+			"Host: example.com\r\n" +
+			"User-Agent: Go http package\r\n" +
+			"Accept-Encoding: gzip\r\n\r\n",
+	},
 }
 
 func TestDumpRequest(t *testing.T) {
diff --git a/src/pkg/net/http/httputil/persist.go b/src/pkg/net/http/httputil/persist.go
index 32f4662..507938a 100644
--- a/src/pkg/net/http/httputil/persist.go
+++ b/src/pkg/net/http/httputil/persist.go
@@ -383,7 +383,7 @@ func (cc *ClientConn) Read(req *http.Request) (resp *http.Response, err error) {
 	// Make sure body is fully consumed, even if user does not call body.Close
 	if lastbody != nil {
 		// body.Close is assumed to be idempotent and multiple calls to
-		// it should return the error that its first invokation
+		// it should return the error that its first invocation
 		// returned.
 		err = lastbody.Close()
 		if err != nil {
diff --git a/src/pkg/net/http/lex.go b/src/pkg/net/http/lex.go
index 93b67e7..ffb393c 100644
--- a/src/pkg/net/http/lex.go
+++ b/src/pkg/net/http/lex.go
@@ -14,14 +14,6 @@ func isSeparator(c byte) bool {
 	return false
 }
 
-func isSpace(c byte) bool {
-	switch c {
-	case ' ', '\t', '\r', '\n':
-		return true
-	}
-	return false
-}
-
 func isCtl(c byte) bool { return (0 <= c && c <= 31) || c == 127 }
 
 func isChar(c byte) bool { return 0 <= c && c <= 127 }
diff --git a/src/pkg/net/http/sniff_test.go b/src/pkg/net/http/sniff_test.go
index 6efa8ce..8ab72ac 100644
--- a/src/pkg/net/http/sniff_test.go
+++ b/src/pkg/net/http/sniff_test.go
@@ -129,9 +129,10 @@ func TestSniffWriteSize(t *testing.T) {
 	}))
 	defer ts.Close()
 	for _, size := range []int{0, 1, 200, 600, 999, 1000, 1023, 1024, 512 << 10, 1 << 20} {
-		_, err := Get(fmt.Sprintf("%s/?size=%d", ts.URL, size))
+		res, err := Get(fmt.Sprintf("%s/?size=%d", ts.URL, size))
 		if err != nil {
 			t.Fatalf("size %d: %v", size, err)
 		}
+		res.Body.Close()
 	}
 }
diff --git a/src/pkg/net/http/status.go b/src/pkg/net/http/status.go
index b6e2d65..5af0b77 100644
--- a/src/pkg/net/http/status.go
+++ b/src/pkg/net/http/status.go
@@ -43,6 +43,7 @@ const (
 	StatusUnsupportedMediaType         = 415
 	StatusRequestedRangeNotSatisfiable = 416
 	StatusExpectationFailed            = 417
+	StatusTeapot                       = 418
 
 	StatusInternalServerError     = 500
 	StatusNotImplemented          = 501
@@ -90,6 +91,7 @@ var statusText = map[int]string{
 	StatusUnsupportedMediaType:         "Unsupported Media Type",
 	StatusRequestedRangeNotSatisfiable: "Requested Range Not Satisfiable",
 	StatusExpectationFailed:            "Expectation Failed",
+	StatusTeapot:                       "I'm a teapot",
 
 	StatusInternalServerError:     "Internal Server Error",
 	StatusNotImplemented:          "Not Implemented",
diff --git a/src/pkg/net/http/transfer.go b/src/pkg/net/http/transfer.go
index ef9564a..3c8fe7f 100644
--- a/src/pkg/net/http/transfer.go
+++ b/src/pkg/net/http/transfer.go
@@ -383,7 +383,7 @@ func fixTransferEncoding(requestMethod string, header Header) ([]string, error)
 	// chunked encoding must always come first.
 	for _, encoding := range encodings {
 		encoding = strings.ToLower(strings.TrimSpace(encoding))
-		// "identity" encoding is not recored
+		// "identity" encoding is not recorded
 		if encoding == "identity" {
 			break
 		}
diff --git a/src/pkg/net/http/transport.go b/src/pkg/net/http/transport.go
index 3e48aba..09579f8 100644
--- a/src/pkg/net/http/transport.go
+++ b/src/pkg/net/http/transport.go
@@ -76,7 +76,9 @@ type Transport struct {
 // ProxyFromEnvironment returns the URL of the proxy to use for a
 // given request, as indicated by the environment variables
 // $HTTP_PROXY and $NO_PROXY (or $http_proxy and $no_proxy).
-// Either URL or an error is returned.
+// An error is returned if the proxy environment is invalid.
+// A nil URL and nil error are returned if no proxy is defined in the
+// environment, or a proxy should not be used for the given request.
 func ProxyFromEnvironment(req *Request) (*url.URL, error) {
 	proxy := getenvEitherCase("HTTP_PROXY")
 	if proxy == "" {
@@ -86,7 +88,7 @@ func ProxyFromEnvironment(req *Request) (*url.URL, error) {
 		return nil, nil
 	}
 	proxyURL, err := url.Parse(proxy)
-	if err != nil {
+	if err != nil || proxyURL.Scheme == "" {
 		if u, err := url.Parse("http://" + proxy); err == nil {
 			proxyURL = u
 			err = nil
diff --git a/src/pkg/net/http/transport_test.go b/src/pkg/net/http/transport_test.go
index 1a629c1..cbb3884 100644
--- a/src/pkg/net/http/transport_test.go
+++ b/src/pkg/net/http/transport_test.go
@@ -16,6 +16,7 @@ import (
 	. "net/http"
 	"net/http/httptest"
 	"net/url"
+	"os"
 	"runtime"
 	"strconv"
 	"strings"
@@ -727,6 +728,36 @@ func TestTransportAltProto(t *testing.T) {
 	}
 }
 
+var proxyFromEnvTests = []struct {
+	env     string
+	wanturl string
+	wanterr error
+}{
+	{"127.0.0.1:8080", "http://127.0.0.1:8080", nil},
+	{"http://127.0.0.1:8080", "http://127.0.0.1:8080", nil},
+	{"https://127.0.0.1:8080", "https://127.0.0.1:8080", nil},
+	{"", "<nil>", nil},
+}
+
+func TestProxyFromEnvironment(t *testing.T) {
+	os.Setenv("HTTP_PROXY", "")
+	os.Setenv("http_proxy", "")
+	os.Setenv("NO_PROXY", "")
+	os.Setenv("no_proxy", "")
+	for i, tt := range proxyFromEnvTests {
+		os.Setenv("HTTP_PROXY", tt.env)
+		req, _ := NewRequest("GET", "http://example.com", nil)
+		url, err := ProxyFromEnvironment(req)
+		if g, e := fmt.Sprintf("%v", err), fmt.Sprintf("%v", tt.wanterr); g != e {
+			t.Errorf("%d. got error = %q, want %q", i, g, e)
+			continue
+		}
+		if got := fmt.Sprintf("%s", url); got != tt.wanturl {
+			t.Errorf("%d. got URL = %q, want %q", i, url, tt.wanturl)
+		}
+	}
+}
+
 // rgz is a gzip quine that uncompresses to itself.
 var rgz = []byte{
 	0x1f, 0x8b, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
diff --git a/src/pkg/net/http/triv.go b/src/pkg/net/http/triv.go
index c88a0fb..269af0c 100644
--- a/src/pkg/net/http/triv.go
+++ b/src/pkg/net/http/triv.go
@@ -108,7 +108,6 @@ func DateServer(rw http.ResponseWriter, req *http.Request) {
 		fmt.Fprintf(rw, "fork/exec: %s\n", err)
 		return
 	}
-	defer p.Release()
 	io.Copy(rw, r)
 	wait, err := p.Wait(0)
 	if err != nil {
diff --git a/src/pkg/net/interface.go b/src/pkg/net/interface.go
index 5e7b352..f25d046 100644
--- a/src/pkg/net/interface.go
+++ b/src/pkg/net/interface.go
@@ -6,11 +6,7 @@
 
 package net
 
-import (
-	"bytes"
-	"errors"
-	"fmt"
-)
+import "errors"
 
 var (
 	errInvalidInterface         = errors.New("net: invalid interface")
@@ -20,77 +16,6 @@ var (
 	errNoSuchMulticastInterface = errors.New("net: no such multicast interface")
 )
 
-// A HardwareAddr represents a physical hardware address.
-type HardwareAddr []byte
-
-func (a HardwareAddr) String() string {
-	var buf bytes.Buffer
-	for i, b := range a {
-		if i > 0 {
-			buf.WriteByte(':')
-		}
-		fmt.Fprintf(&buf, "%02x", b)
-	}
-	return buf.String()
-}
-
-// ParseMAC parses s as an IEEE 802 MAC-48, EUI-48, or EUI-64 using one of the
-// following formats:
-//   01:23:45:67:89:ab
-//   01:23:45:67:89:ab:cd:ef
-//   01-23-45-67-89-ab
-//   01-23-45-67-89-ab-cd-ef
-//   0123.4567.89ab
-//   0123.4567.89ab.cdef
-func ParseMAC(s string) (hw HardwareAddr, err error) {
-	if len(s) < 14 {
-		goto error
-	}
-
-	if s[2] == ':' || s[2] == '-' {
-		if (len(s)+1)%3 != 0 {
-			goto error
-		}
-		n := (len(s) + 1) / 3
-		if n != 6 && n != 8 {
-			goto error
-		}
-		hw = make(HardwareAddr, n)
-		for x, i := 0, 0; i < n; i++ {
-			var ok bool
-			if hw[i], ok = xtoi2(s[x:], s[2]); !ok {
-				goto error
-			}
-			x += 3
-		}
-	} else if s[4] == '.' {
-		if (len(s)+1)%5 != 0 {
-			goto error
-		}
-		n := 2 * (len(s) + 1) / 5
-		if n != 6 && n != 8 {
-			goto error
-		}
-		hw = make(HardwareAddr, n)
-		for x, i := 0, 0; i < n; i += 2 {
-			var ok bool
-			if hw[i], ok = xtoi2(s[x:x+2], 0); !ok {
-				goto error
-			}
-			if hw[i+1], ok = xtoi2(s[x+2:], s[4]); !ok {
-				goto error
-			}
-			x += 5
-		}
-	} else {
-		goto error
-	}
-	return hw, nil
-
-error:
-	return nil, errors.New("invalid MAC address: " + s)
-}
-
 // Interface represents a mapping between network interface name
 // and index.  It also represents network interface facility
 // information.
diff --git a/src/pkg/net/interface_test.go b/src/pkg/net/interface_test.go
index 769414e..0a33bfd 100644
--- a/src/pkg/net/interface_test.go
+++ b/src/pkg/net/interface_test.go
@@ -6,8 +6,6 @@ package net
 
 import (
 	"bytes"
-	"reflect"
-	"strings"
 	"testing"
 )
 
@@ -96,46 +94,3 @@ func testMulticastAddrs(t *testing.T, ifmat []Addr) {
 		}
 	}
 }
-
-var mactests = []struct {
-	in  string
-	out HardwareAddr
-	err string
-}{
-	{"01:23:45:67:89:AB", HardwareAddr{1, 0x23, 0x45, 0x67, 0x89, 0xab}, ""},
-	{"01-23-45-67-89-AB", HardwareAddr{1, 0x23, 0x45, 0x67, 0x89, 0xab}, ""},
-	{"0123.4567.89AB", HardwareAddr{1, 0x23, 0x45, 0x67, 0x89, 0xab}, ""},
-	{"ab:cd:ef:AB:CD:EF", HardwareAddr{0xab, 0xcd, 0xef, 0xab, 0xcd, 0xef}, ""},
-	{"01.02.03.04.05.06", nil, "invalid MAC address"},
-	{"01:02:03:04:05:06:", nil, "invalid MAC address"},
-	{"x1:02:03:04:05:06", nil, "invalid MAC address"},
-	{"01002:03:04:05:06", nil, "invalid MAC address"},
-	{"01:02003:04:05:06", nil, "invalid MAC address"},
-	{"01:02:03004:05:06", nil, "invalid MAC address"},
-	{"01:02:03:04005:06", nil, "invalid MAC address"},
-	{"01:02:03:04:05006", nil, "invalid MAC address"},
-	{"01-02:03:04:05:06", nil, "invalid MAC address"},
-	{"01:02-03-04-05-06", nil, "invalid MAC address"},
-	{"0123:4567:89AF", nil, "invalid MAC address"},
-	{"0123-4567-89AF", nil, "invalid MAC address"},
-	{"01:23:45:67:89:AB:CD:EF", HardwareAddr{1, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, ""},
-	{"01-23-45-67-89-AB-CD-EF", HardwareAddr{1, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, ""},
-	{"0123.4567.89AB.CDEF", HardwareAddr{1, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, ""},
-}
-
-func match(err error, s string) bool {
-	if s == "" {
-		return err == nil
-	}
-	return err != nil && strings.Contains(err.Error(), s)
-}
-
-func TestParseMAC(t *testing.T) {
-	for _, tt := range mactests {
-		out, err := ParseMAC(tt.in)
-		if !reflect.DeepEqual(out, tt.out) || !match(err, tt.err) {
-			t.Errorf("ParseMAC(%q) = %v, %v, want %v, %v", tt.in, out, err, tt.out,
-				tt.err)
-		}
-	}
-}
diff --git a/src/pkg/net/lookup_plan9.go b/src/pkg/net/lookup_plan9.go
index b08a9fb..2c69830 100644
--- a/src/pkg/net/lookup_plan9.go
+++ b/src/pkg/net/lookup_plan9.go
@@ -76,7 +76,7 @@ func lookupProtocol(name string) (proto int, err error) {
 }
 
 func lookupHost(host string) (addrs []string, err error) {
-	// Use /net/cs insead of /net/dns because cs knows about
+	// Use /net/cs instead of /net/dns because cs knows about
 	// host names in local network (e.g. from /lib/ndb/local)
 	lines, err := queryCS("tcp", host, "1")
 	if err != nil {
diff --git a/src/pkg/net/lookup_test.go b/src/pkg/net/lookup_test.go
index 7b9ea84..3a61dfb 100644
--- a/src/pkg/net/lookup_test.go
+++ b/src/pkg/net/lookup_test.go
@@ -12,7 +12,7 @@ import (
 	"testing"
 )
 
-var testExternal = flag.Bool("external", false, "allow use of external networks during test")
+var testExternal = flag.Bool("external", true, "allow use of external networks during long test")
 
 func TestGoogleSRV(t *testing.T) {
 	if testing.Short() || !*testExternal {
@@ -78,3 +78,40 @@ func TestGoogleDNSAddr(t *testing.T) {
 		t.Errorf("no results")
 	}
 }
+
+var revAddrTests = []struct {
+	Addr      string
+	Reverse   string
+	ErrPrefix string
+}{
+	{"1.2.3.4", "4.3.2.1.in-addr.arpa.", ""},
+	{"245.110.36.114", "114.36.110.245.in-addr.arpa.", ""},
+	{"::ffff:12.34.56.78", "78.56.34.12.in-addr.arpa.", ""},
+	{"::1", "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.", ""},
+	{"1::", "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.0.0.0.ip6.arpa.", ""},
+	{"1234:567::89a:bcde", "e.d.c.b.a.9.8.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.7.6.5.0.4.3.2.1.ip6.arpa.", ""},
+	{"1234:567:fefe:bcbc:adad:9e4a:89a:bcde", "e.d.c.b.a.9.8.0.a.4.e.9.d.a.d.a.c.b.c.b.e.f.e.f.7.6.5.0.4.3.2.1.ip6.arpa.", ""},
+	{"1.2.3", "", "unrecognized address"},
+	{"1.2.3.4.5", "", "unrecognized address"},
+	{"1234:567:bcbca::89a:bcde", "", "unrecognized address"},
+	{"1234:567::bcbc:adad::89a:bcde", "", "unrecognized address"},
+}
+
+func TestReverseAddress(t *testing.T) {
+	for i, tt := range revAddrTests {
+		a, err := reverseaddr(tt.Addr)
+		if len(tt.ErrPrefix) > 0 && err == nil {
+			t.Errorf("#%d: expected %q, got <nil> (error)", i, tt.ErrPrefix)
+			continue
+		}
+		if len(tt.ErrPrefix) == 0 && err != nil {
+			t.Errorf("#%d: expected <nil>, got %q (error)", i, err)
+		}
+		if err != nil && err.(*DNSError).Err != tt.ErrPrefix {
+			t.Errorf("#%d: expected %q, got %q (mismatched error)", i, tt.ErrPrefix, err.(*DNSError).Err)
+		}
+		if a != tt.Reverse {
+			t.Errorf("#%d: expected %q, got %q (reverse address)", i, tt.Reverse, a)
+		}
+	}
+}
diff --git a/src/pkg/net/mac.go b/src/pkg/net/mac.go
new file mode 100644
index 0000000..e0637d0
--- /dev/null
+++ b/src/pkg/net/mac.go
@@ -0,0 +1,84 @@
+// 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.
+
+// MAC address manipulations
+
+package net
+
+import (
+	"bytes"
+	"errors"
+	"fmt"
+)
+
+// A HardwareAddr represents a physical hardware address.
+type HardwareAddr []byte
+
+func (a HardwareAddr) String() string {
+	var buf bytes.Buffer
+	for i, b := range a {
+		if i > 0 {
+			buf.WriteByte(':')
+		}
+		fmt.Fprintf(&buf, "%02x", b)
+	}
+	return buf.String()
+}
+
+// ParseMAC parses s as an IEEE 802 MAC-48, EUI-48, or EUI-64 using one of the
+// following formats:
+//   01:23:45:67:89:ab
+//   01:23:45:67:89:ab:cd:ef
+//   01-23-45-67-89-ab
+//   01-23-45-67-89-ab-cd-ef
+//   0123.4567.89ab
+//   0123.4567.89ab.cdef
+func ParseMAC(s string) (hw HardwareAddr, err error) {
+	if len(s) < 14 {
+		goto error
+	}
+
+	if s[2] == ':' || s[2] == '-' {
+		if (len(s)+1)%3 != 0 {
+			goto error
+		}
+		n := (len(s) + 1) / 3
+		if n != 6 && n != 8 {
+			goto error
+		}
+		hw = make(HardwareAddr, n)
+		for x, i := 0, 0; i < n; i++ {
+			var ok bool
+			if hw[i], ok = xtoi2(s[x:], s[2]); !ok {
+				goto error
+			}
+			x += 3
+		}
+	} else if s[4] == '.' {
+		if (len(s)+1)%5 != 0 {
+			goto error
+		}
+		n := 2 * (len(s) + 1) / 5
+		if n != 6 && n != 8 {
+			goto error
+		}
+		hw = make(HardwareAddr, n)
+		for x, i := 0, 0; i < n; i += 2 {
+			var ok bool
+			if hw[i], ok = xtoi2(s[x:x+2], 0); !ok {
+				goto error
+			}
+			if hw[i+1], ok = xtoi2(s[x+2:], s[4]); !ok {
+				goto error
+			}
+			x += 5
+		}
+	} else {
+		goto error
+	}
+	return hw, nil
+
+error:
+	return nil, errors.New("invalid MAC address: " + s)
+}
diff --git a/src/pkg/net/mac_test.go b/src/pkg/net/mac_test.go
new file mode 100644
index 0000000..3837e74
--- /dev/null
+++ b/src/pkg/net/mac_test.go
@@ -0,0 +1,54 @@
+// 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 net
+
+import (
+	"reflect"
+	"strings"
+	"testing"
+)
+
+var mactests = []struct {
+	in  string
+	out HardwareAddr
+	err string
+}{
+	{"01:23:45:67:89:AB", HardwareAddr{1, 0x23, 0x45, 0x67, 0x89, 0xab}, ""},
+	{"01-23-45-67-89-AB", HardwareAddr{1, 0x23, 0x45, 0x67, 0x89, 0xab}, ""},
+	{"0123.4567.89AB", HardwareAddr{1, 0x23, 0x45, 0x67, 0x89, 0xab}, ""},
+	{"ab:cd:ef:AB:CD:EF", HardwareAddr{0xab, 0xcd, 0xef, 0xab, 0xcd, 0xef}, ""},
+	{"01.02.03.04.05.06", nil, "invalid MAC address"},
+	{"01:02:03:04:05:06:", nil, "invalid MAC address"},
+	{"x1:02:03:04:05:06", nil, "invalid MAC address"},
+	{"01002:03:04:05:06", nil, "invalid MAC address"},
+	{"01:02003:04:05:06", nil, "invalid MAC address"},
+	{"01:02:03004:05:06", nil, "invalid MAC address"},
+	{"01:02:03:04005:06", nil, "invalid MAC address"},
+	{"01:02:03:04:05006", nil, "invalid MAC address"},
+	{"01-02:03:04:05:06", nil, "invalid MAC address"},
+	{"01:02-03-04-05-06", nil, "invalid MAC address"},
+	{"0123:4567:89AF", nil, "invalid MAC address"},
+	{"0123-4567-89AF", nil, "invalid MAC address"},
+	{"01:23:45:67:89:AB:CD:EF", HardwareAddr{1, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, ""},
+	{"01-23-45-67-89-AB-CD-EF", HardwareAddr{1, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, ""},
+	{"0123.4567.89AB.CDEF", HardwareAddr{1, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, ""},
+}
+
+func match(err error, s string) bool {
+	if s == "" {
+		return err == nil
+	}
+	return err != nil && strings.Contains(err.Error(), s)
+}
+
+func TestParseMAC(t *testing.T) {
+	for _, tt := range mactests {
+		out, err := ParseMAC(tt.in)
+		if !reflect.DeepEqual(out, tt.out) || !match(err, tt.err) {
+			t.Errorf("ParseMAC(%q) = %v, %v, want %v, %v", tt.in, out, err, tt.out,
+				tt.err)
+		}
+	}
+}
diff --git a/src/pkg/net/net_test.go b/src/pkg/net/net_test.go
index 9e792a1..c1a90de 100644
--- a/src/pkg/net/net_test.go
+++ b/src/pkg/net/net_test.go
@@ -5,130 +5,12 @@
 package net
 
 import (
-	"flag"
 	"io"
-	"regexp"
 	"runtime"
 	"testing"
 	"time"
 )
 
-var runErrorTest = flag.Bool("run_error_test", false, "let TestDialError check for dns errors")
-
-type DialErrorTest struct {
-	Net     string
-	Raddr   string
-	Pattern string
-}
-
-var dialErrorTests = []DialErrorTest{
-	{
-		"datakit", "mh/astro/r70",
-		"dial datakit mh/astro/r70: unknown network datakit",
-	},
-	{
-		"tcp", "127.0.0.1:☺",
-		"dial tcp 127.0.0.1:☺: unknown port tcp/☺",
-	},
-	{
-		"tcp", "no-such-name.google.com.:80",
-		"dial tcp no-such-name.google.com.:80: lookup no-such-name.google.com.( on .*)?: no (.*)",
-	},
-	{
-		"tcp", "no-such-name.no-such-top-level-domain.:80",
-		"dial tcp no-such-name.no-such-top-level-domain.:80: lookup no-such-name.no-such-top-level-domain.( on .*)?: no (.*)",
-	},
-	{
-		"tcp", "no-such-name:80",
-		`dial tcp no-such-name:80: lookup no-such-name\.(.*\.)?( on .*)?: no (.*)`,
-	},
-	{
-		"tcp", "mh/astro/r70:http",
-		"dial tcp mh/astro/r70:http: lookup mh/astro/r70: invalid domain name",
-	},
-	{
-		"unix", "/etc/file-not-found",
-		"dial unix /etc/file-not-found: no such file or directory",
-	},
-	{
-		"unix", "/etc/",
-		"dial unix /etc/: (permission denied|socket operation on non-socket|connection refused)",
-	},
-	{
-		"unixpacket", "/etc/file-not-found",
-		"dial unixpacket /etc/file-not-found: no such file or directory",
-	},
-	{
-		"unixpacket", "/etc/",
-		"dial unixpacket /etc/: (permission denied|socket operation on non-socket|connection refused)",
-	},
-}
-
-var duplicateErrorPattern = `dial (.*) dial (.*)`
-
-func TestDialError(t *testing.T) {
-	if !*runErrorTest {
-		t.Logf("test disabled; use --run_error_test to enable")
-		return
-	}
-	for i, tt := range dialErrorTests {
-		c, err := Dial(tt.Net, tt.Raddr)
-		if c != nil {
-			c.Close()
-		}
-		if err == nil {
-			t.Errorf("#%d: nil error, want match for %#q", i, tt.Pattern)
-			continue
-		}
-		s := err.Error()
-		match, _ := regexp.MatchString(tt.Pattern, s)
-		if !match {
-			t.Errorf("#%d: %q, want match for %#q", i, s, tt.Pattern)
-		}
-		match, _ = regexp.MatchString(duplicateErrorPattern, s)
-		if match {
-			t.Errorf("#%d: %q, duplicate error return from Dial", i, s)
-		}
-	}
-}
-
-var revAddrTests = []struct {
-	Addr      string
-	Reverse   string
-	ErrPrefix string
-}{
-	{"1.2.3.4", "4.3.2.1.in-addr.arpa.", ""},
-	{"245.110.36.114", "114.36.110.245.in-addr.arpa.", ""},
-	{"::ffff:12.34.56.78", "78.56.34.12.in-addr.arpa.", ""},
-	{"::1", "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.", ""},
-	{"1::", "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.0.0.0.ip6.arpa.", ""},
-	{"1234:567::89a:bcde", "e.d.c.b.a.9.8.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.7.6.5.0.4.3.2.1.ip6.arpa.", ""},
-	{"1234:567:fefe:bcbc:adad:9e4a:89a:bcde", "e.d.c.b.a.9.8.0.a.4.e.9.d.a.d.a.c.b.c.b.e.f.e.f.7.6.5.0.4.3.2.1.ip6.arpa.", ""},
-	{"1.2.3", "", "unrecognized address"},
-	{"1.2.3.4.5", "", "unrecognized address"},
-	{"1234:567:bcbca::89a:bcde", "", "unrecognized address"},
-	{"1234:567::bcbc:adad::89a:bcde", "", "unrecognized address"},
-}
-
-func TestReverseAddress(t *testing.T) {
-	for i, tt := range revAddrTests {
-		a, err := reverseaddr(tt.Addr)
-		if len(tt.ErrPrefix) > 0 && err == nil {
-			t.Errorf("#%d: expected %q, got <nil> (error)", i, tt.ErrPrefix)
-			continue
-		}
-		if len(tt.ErrPrefix) == 0 && err != nil {
-			t.Errorf("#%d: expected <nil>, got %q (error)", i, err)
-		}
-		if err != nil && err.(*DNSError).Err != tt.ErrPrefix {
-			t.Errorf("#%d: expected %q, got %q (mismatched error)", i, tt.ErrPrefix, err.(*DNSError).Err)
-		}
-		if a != tt.Reverse {
-			t.Errorf("#%d: expected %q, got %q (reverse address)", i, tt.Reverse, a)
-		}
-	}
-}
-
 func TestShutdown(t *testing.T) {
 	if runtime.GOOS == "plan9" {
 		return
diff --git a/src/pkg/net/rpc/client.go b/src/pkg/net/rpc/client.go
index 34f9ae3..f7abf21 100644
--- a/src/pkg/net/rpc/client.go
+++ b/src/pkg/net/rpc/client.go
@@ -140,7 +140,7 @@ func (client *Client) input() {
 	}
 	client.mutex.Unlock()
 	client.sending.Unlock()
-	if err != io.EOF || !closing {
+	if err != io.EOF && !closing {
 		log.Println("rpc: client protocol error:", err)
 	}
 }
diff --git a/src/pkg/net/rpc/server.go b/src/pkg/net/rpc/server.go
index 920ae91..1680e2f 100644
--- a/src/pkg/net/rpc/server.go
+++ b/src/pkg/net/rpc/server.go
@@ -13,13 +13,19 @@
 	Only methods that satisfy these criteria will be made available for remote access;
 	other methods will be ignored:
 
-		- the method name is exported, that is, begins with an upper case letter.
-		- the method receiver is exported or local (defined in the package
-		  registering the service).
-		- the method has two arguments, both exported or local types.
+		- the method is exported.
+		- the method has two arguments, both exported (or builtin) types.
 		- the method's second argument is a pointer.
 		- the method has return type error.
 
+	In effect, the method must look schematically like
+
+		func (t *T) MethodName(argType T1, replyType *T2) error
+
+	where T, T1 and T2 can be marshaled by encoding/gob.
+	These requirements apply even if a different codec is used.
+	(In future, these requirements may soften for custom codecs.)
+
 	The method's first argument represents the arguments provided by the caller; the
 	second argument represents the result parameters to be returned to the caller.
 	The method's return value, if non-nil, is passed back as a string that the client
@@ -36,10 +42,12 @@
 	call, a pointer containing the arguments, and a pointer to receive the result
 	parameters.
 
-	Call waits for the remote call to complete; Go launches the call asynchronously
-	and returns a channel that will signal completion.
+	The Call method waits for the remote call to complete while the Go method
+	launches the call asynchronously and signals completion using the Call
+	structure's Done channel.
 
-	Package "gob" is used to transport the data.
+	Unless an explicit codec is set up, package encoding/gob is used to
+	transport the data.
 
 	Here is a simple example.  A server wishes to export an object of type Arith:
 
@@ -256,6 +264,7 @@ func (server *Server) register(rcvr interface{}, name string, useName bool) erro
 		method := s.typ.Method(m)
 		mtype := method.Type
 		mname := method.Name
+		// Method must be exported.
 		if method.PkgPath != "" {
 			continue
 		}
@@ -267,7 +276,7 @@ func (server *Server) register(rcvr interface{}, name string, useName bool) erro
 		// First arg need not be a pointer.
 		argType := mtype.In(1)
 		if !isExportedOrBuiltinType(argType) {
-			log.Println(mname, "argument type not exported or local:", argType)
+			log.Println(mname, "argument type not exported:", argType)
 			continue
 		}
 		// Second arg must be a pointer.
@@ -276,15 +285,17 @@ func (server *Server) register(rcvr interface{}, name string, useName bool) erro
 			log.Println("method", mname, "reply type not a pointer:", replyType)
 			continue
 		}
+		// Reply type must be exported.
 		if !isExportedOrBuiltinType(replyType) {
-			log.Println("method", mname, "reply type not exported or local:", replyType)
+			log.Println("method", mname, "reply type not exported:", replyType)
 			continue
 		}
-		// Method needs one out: error.
+		// Method needs one out.
 		if mtype.NumOut() != 1 {
 			log.Println("method", mname, "has wrong number of outs:", mtype.NumOut())
 			continue
 		}
+		// The return type of the method must be error.
 		if returnType := mtype.Out(0); returnType != typeOfError {
 			log.Println("method", mname, "returns", returnType.String(), "not error")
 			continue
@@ -301,10 +312,10 @@ func (server *Server) register(rcvr interface{}, name string, useName bool) erro
 	return nil
 }
 
-// A value sent as a placeholder for the response when the server receives an invalid request.
-type InvalidRequest struct{}
-
-var invalidRequest = InvalidRequest{}
+// A value sent as a placeholder for the server's response value when the server
+// receives an invalid request. It is never decoded by the client since the Response
+// contains an error when it is used.
+var invalidRequest = struct{}{}
 
 func (server *Server) sendResponse(sending *sync.Mutex, req *Request, reply interface{}, codec ServerCodec, errmsg string) {
 	resp := server.getResponse()
diff --git a/src/pkg/net/sockoptip_netbsd.go b/src/pkg/net/sockoptip_netbsd.go
new file mode 100644
index 0000000..446d92a
--- /dev/null
+++ b/src/pkg/net/sockoptip_netbsd.go
@@ -0,0 +1,39 @@
+// Copyright 2012 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// IP-level socket options for NetBSD
+
+package net
+
+import "syscall"
+
+func ipv4MulticastInterface(fd *netFD) (*Interface, error) {
+	// TODO: Implement this
+	return nil, syscall.EAFNOSUPPORT
+}
+
+func setIPv4MulticastInterface(fd *netFD, ifi *Interface) error {
+	// TODO: Implement this
+	return syscall.EAFNOSUPPORT
+}
+
+func ipv4MulticastLoopback(fd *netFD) (bool, error) {
+	// TODO: Implement this
+	return false, syscall.EAFNOSUPPORT
+}
+
+func setIPv4MulticastLoopback(fd *netFD, v bool) error {
+	// TODO: Implement this
+	return syscall.EAFNOSUPPORT
+}
+
+func ipv4ReceiveInterface(fd *netFD) (bool, error) {
+	// TODO: Implement this
+	return false, syscall.EAFNOSUPPORT
+}
+
+func setIPv4ReceiveInterface(fd *netFD, v bool) error {
+	// TODO: Implement this
+	return syscall.EAFNOSUPPORT
+}
diff --git a/src/pkg/net/timeout_test.go b/src/pkg/net/timeout_test.go
index bae37c8..ef350f0 100644
--- a/src/pkg/net/timeout_test.go
+++ b/src/pkg/net/timeout_test.go
@@ -40,7 +40,7 @@ func testTimeout(t *testing.T, network, addr string, readFrom bool) {
 			errc <- fmt.Errorf("fd.%s on %s %s did not return 0, timeout: %v, %v", what, network, addr, n, err1)
 			return
 		}
-		if dt := t1.Sub(t0); dt < 50*time.Millisecond || dt > 250*time.Millisecond {
+		if dt := t1.Sub(t0); dt < 50*time.Millisecond || !testing.Short() && dt > 250*time.Millisecond {
 			errc <- fmt.Errorf("fd.%s on %s %s took %s, expected 0.1s", what, network, addr, dt)
 			return
 		}
diff --git a/src/pkg/net/udp_test.go b/src/pkg/net/udp_test.go
index 6ba762b..ea5fad4 100644
--- a/src/pkg/net/udp_test.go
+++ b/src/pkg/net/udp_test.go
@@ -38,18 +38,18 @@ func testWriteToConn(t *testing.T, raddr string) {
 
 	_, err = c.(*UDPConn).WriteToUDP([]byte("Connection-oriented mode socket"), ra)
 	if err == nil {
-		t.Fatal("WriteToUDP should be failed")
+		t.Fatal("WriteToUDP should fail")
 	}
 	if err != nil && err.(*OpError).Err != ErrWriteToConnected {
-		t.Fatalf("WriteToUDP should be failed as ErrWriteToConnected: %v", err)
+		t.Fatalf("WriteToUDP should fail as ErrWriteToConnected: %v", err)
 	}
 
 	_, err = c.(*UDPConn).WriteTo([]byte("Connection-oriented mode socket"), ra)
 	if err == nil {
-		t.Fatal("WriteTo should be failed")
+		t.Fatal("WriteTo should fail")
 	}
 	if err != nil && err.(*OpError).Err != ErrWriteToConnected {
-		t.Fatalf("WriteTo should be failed as ErrWriteToConnected: %v", err)
+		t.Fatalf("WriteTo should fail as ErrWriteToConnected: %v", err)
 	}
 
 	_, err = c.Write([]byte("Connection-oriented mode socket"))
@@ -82,6 +82,6 @@ func testWriteToPacketConn(t *testing.T, raddr string) {
 
 	_, err = c.(*UDPConn).Write([]byte("Connection-less mode socket"))
 	if err == nil {
-		t.Fatal("Write should be failed")
+		t.Fatal("Write should fail")
 	}
 }
diff --git a/src/pkg/os/doc.go b/src/pkg/os/doc.go
index ef857c0..6a531e0 100644
--- a/src/pkg/os/doc.go
+++ b/src/pkg/os/doc.go
@@ -4,6 +4,8 @@
 
 package os
 
+import "time"
+
 // FindProcess looks for a running process by its pid.
 // The Process it returns can be used to obtain information
 // about the underlying operating system process.
@@ -11,6 +13,76 @@ func FindProcess(pid int) (p *Process, err error) {
 	return findProcess(pid)
 }
 
+// StartProcess starts a new process with the program, arguments and attributes
+// specified by name, argv and attr.
+//
+// StartProcess is a low-level interface. The os/exec package provides
+// higher-level interfaces.
+//
+// If there is an error, it will be of type *PathError.
+func StartProcess(name string, argv []string, attr *ProcAttr) (*Process, error) {
+	return startProcess(name, argv, attr)
+}
+
+// Release releases any resources associated with the Process p,
+// rendering it unusable in the future.
+// Release only needs to be called if Wait is not.
+func (p *Process) Release() error {
+	return p.release()
+}
+
+// Kill causes the Process to exit immediately.
+func (p *Process) Kill() error {
+	return p.kill()
+}
+
+// Wait waits for the Process to exit, and then returns a
+// ProcessState describing its status and an error, if any.
+// Wait releases any resources associated with the Process.
+func (p *Process) Wait() (*ProcessState, error) {
+	return p.wait()
+}
+
+// Signal sends a signal to the Process.
+func (p *Process) Signal(sig Signal) error {
+	return p.signal(sig)
+}
+
+// UserTime returns the user CPU time of the exited process and its children.
+func (p *ProcessState) UserTime() time.Duration {
+	return p.userTime()
+}
+
+// SystemTime returns the system CPU time of the exited process and its children.
+func (p *ProcessState) SystemTime() time.Duration {
+	return p.systemTime()
+}
+
+// Exited returns whether the program has exited.
+func (p *ProcessState) Exited() bool {
+	return p.exited()
+}
+
+// Success reports whether the program exited successfully,
+// such as with exit status 0 on Unix.
+func (p *ProcessState) Success() bool {
+	return p.success()
+}
+
+// Sys returns system-dependent exit information about
+// the process.  Convert it to the appropriate underlying
+// type, such as syscall.WaitStatus on Unix, to access its contents.
+func (p *ProcessState) Sys() interface{} {
+	return p.sys()
+}
+
+// SysUsage returns system-dependent resource usage information about
+// the exited process.  Convert it to the appropriate underlying
+// type, such as *syscall.Rusage on Unix, to access its contents.
+func (p *ProcessState) SysUsage() interface{} {
+	return p.sysUsage()
+}
+
 // Hostname returns the host name reported by the kernel.
 func Hostname() (name string, err error) {
 	return hostname()
diff --git a/src/pkg/os/exec.go b/src/pkg/os/exec.go
index 37a0051..531b87c 100644
--- a/src/pkg/os/exec.go
+++ b/src/pkg/os/exec.go
@@ -13,7 +13,7 @@ import (
 type Process struct {
 	Pid    int
 	handle uintptr
-	done   bool // process has been successfuly waited on
+	done   bool // process has been successfully waited on
 }
 
 func newProcess(pid int, handle uintptr) *Process {
diff --git a/src/pkg/os/exec_plan9.go b/src/pkg/os/exec_plan9.go
index 1c9e2b9..41cc8c2 100644
--- a/src/pkg/os/exec_plan9.go
+++ b/src/pkg/os/exec_plan9.go
@@ -11,10 +11,7 @@ import (
 	"time"
 )
 
-// StartProcess starts a new process with the program, arguments and attributes
-// specified by name, argv and attr.
-// If there is an error, it will be of type *PathError.
-func StartProcess(name string, argv []string, attr *ProcAttr) (p *Process, err error) {
+func startProcess(name string, argv []string, attr *ProcAttr) (p *Process, err error) {
 	sysattr := &syscall.ProcAttr{
 		Dir: attr.Dir,
 		Env: attr.Env,
@@ -40,7 +37,7 @@ func (note Plan9Note) String() string {
 	return string(note)
 }
 
-func (p *Process) Signal(sig Signal) error {
+func (p *Process) signal(sig Signal) error {
 	if p.done {
 		return errors.New("os: process already finished")
 	}
@@ -54,8 +51,7 @@ func (p *Process) Signal(sig Signal) error {
 	return e
 }
 
-// Kill causes the Process to exit immediately.
-func (p *Process) Kill() error {
+func (p *Process) kill() error {
 	f, e := OpenFile("/proc/"+itoa(p.Pid)+"/ctl", O_WRONLY, 0)
 	if e != nil {
 		return NewSyscallError("kill", e)
@@ -65,9 +61,7 @@ func (p *Process) Kill() error {
 	return e
 }
 
-// Wait waits for the Process to exit or stop, and then returns a
-// ProcessState describing its status and an error, if any.
-func (p *Process) Wait() (ps *ProcessState, err error) {
+func (p *Process) wait() (ps *ProcessState, err error) {
 	var waitmsg syscall.Waitmsg
 
 	if p.Pid == -1 {
@@ -94,8 +88,7 @@ func (p *Process) Wait() (ps *ProcessState, err error) {
 	return ps, nil
 }
 
-// Release releases any resources associated with the Process.
-func (p *Process) Release() error {
+func (p *Process) release() error {
 	// NOOP for Plan 9.
 	p.Pid = -1
 	// no need for a finalizer anymore
@@ -108,7 +101,7 @@ func findProcess(pid int) (p *Process, err error) {
 	return newProcess(pid, 0), nil
 }
 
-// ProcessState stores information about process as reported by Wait.
+// ProcessState stores information about a process, as reported by Wait.
 type ProcessState struct {
 	pid    int              // The process's id.
 	status *syscall.Waitmsg // System-dependent status info.
@@ -119,40 +112,27 @@ func (p *ProcessState) Pid() int {
 	return p.pid
 }
 
-// Exited returns whether the program has exited.
-func (p *ProcessState) Exited() bool {
+func (p *ProcessState) exited() bool {
 	return p.status.Exited()
 }
 
-// Success reports whether the program exited successfully,
-// such as with exit status 0 on Unix.
-func (p *ProcessState) Success() bool {
+func (p *ProcessState) success() bool {
 	return p.status.ExitStatus() == 0
 }
 
-// Sys returns system-dependent exit information about
-// the process.  Convert it to the appropriate underlying
-// type, such as *syscall.Waitmsg on Plan 9, to access its contents.
-func (p *ProcessState) Sys() interface{} {
+func (p *ProcessState) sys() interface{} {
 	return p.status
 }
 
-// SysUsage returns system-dependent resource usage information about
-// the exited process.  Convert it to the appropriate underlying
-// type, such as *syscall.Waitmsg on Plan 9, to access its contents.
-func (p *ProcessState) SysUsage() interface{} {
+func (p *ProcessState) sysUsage() interface{} {
 	return p.status
 }
 
-// UserTime returns the user CPU time of the exited process and its children.
-// It is always reported as 0 on Windows.
-func (p *ProcessState) UserTime() time.Duration {
+func (p *ProcessState) userTime() time.Duration {
 	return time.Duration(p.status.Time[0]) * time.Millisecond
 }
 
-// SystemTime returns the system CPU time of the exited process and its children.
-// It is always reported as 0 on Windows.
-func (p *ProcessState) SystemTime() time.Duration {
+func (p *ProcessState) systemTime() time.Duration {
 	return time.Duration(p.status.Time[1]) * time.Millisecond
 }
 
diff --git a/src/pkg/os/exec_posix.go b/src/pkg/os/exec_posix.go
index 4a75cb6..70351cf 100644
--- a/src/pkg/os/exec_posix.go
+++ b/src/pkg/os/exec_posix.go
@@ -10,14 +10,17 @@ import (
 	"syscall"
 )
 
-// StartProcess starts a new process with the program, arguments and attributes
-// specified by name, argv and attr.
-//
-// StartProcess is a low-level interface. The os/exec package provides
-// higher-level interfaces.
-//
-// If there is an error, it will be of type *PathError.
-func StartProcess(name string, argv []string, attr *ProcAttr) (p *Process, err error) {
+func startProcess(name string, argv []string, attr *ProcAttr) (p *Process, err error) {
+	// Double-check existence of the directory we want
+	// to chdir into.  We can make the error clearer this way.
+	if attr != nil && attr.Dir != "" {
+		if _, err := Stat(attr.Dir); err != nil {
+			pe := err.(*PathError)
+			pe.Op = "chdir"
+			return nil, pe
+		}
+	}
+
 	sysattr := &syscall.ProcAttr{
 		Dir: attr.Dir,
 		Env: attr.Env,
@@ -37,12 +40,11 @@ func StartProcess(name string, argv []string, attr *ProcAttr) (p *Process, err e
 	return newProcess(pid, h), nil
 }
 
-// Kill causes the Process to exit immediately.
-func (p *Process) Kill() error {
+func (p *Process) kill() error {
 	return p.Signal(Kill)
 }
 
-// ProcessState stores information about process as reported by Wait.
+// ProcessState stores information about a process, as reported by Wait.
 type ProcessState struct {
 	pid    int                // The process's id.
 	status syscall.WaitStatus // System-dependent status info.
@@ -54,28 +56,19 @@ func (p *ProcessState) Pid() int {
 	return p.pid
 }
 
-// Exited returns whether the program has exited.
-func (p *ProcessState) Exited() bool {
+func (p *ProcessState) exited() bool {
 	return p.status.Exited()
 }
 
-// Success reports whether the program exited successfully,
-// such as with exit status 0 on Unix.
-func (p *ProcessState) Success() bool {
+func (p *ProcessState) success() bool {
 	return p.status.ExitStatus() == 0
 }
 
-// Sys returns system-dependent exit information about
-// the process.  Convert it to the appropriate underlying
-// type, such as syscall.WaitStatus on Unix, to access its contents.
-func (p *ProcessState) Sys() interface{} {
+func (p *ProcessState) sys() interface{} {
 	return p.status
 }
 
-// SysUsage returns system-dependent resource usage information about
-// the exited process.  Convert it to the appropriate underlying
-// type, such as *syscall.Rusage on Unix, to access its contents.
-func (p *ProcessState) SysUsage() interface{} {
+func (p *ProcessState) sysUsage() interface{} {
 	return p.rusage
 }
 
diff --git a/src/pkg/os/exec_unix.go b/src/pkg/os/exec_unix.go
index 8d000e9..ecfe535 100644
--- a/src/pkg/os/exec_unix.go
+++ b/src/pkg/os/exec_unix.go
@@ -13,9 +13,7 @@ import (
 	"time"
 )
 
-// Wait waits for the Process to exit or stop, and then returns a
-// ProcessState describing its status and an error, if any.
-func (p *Process) Wait() (ps *ProcessState, err error) {
+func (p *Process) wait() (ps *ProcessState, err error) {
 	if p.Pid == -1 {
 		return nil, syscall.EINVAL
 	}
@@ -36,8 +34,7 @@ func (p *Process) Wait() (ps *ProcessState, err error) {
 	return ps, nil
 }
 
-// Signal sends a signal to the Process.
-func (p *Process) Signal(sig Signal) error {
+func (p *Process) signal(sig Signal) error {
 	if p.done {
 		return errors.New("os: process already finished")
 	}
@@ -51,8 +48,7 @@ func (p *Process) Signal(sig Signal) error {
 	return nil
 }
 
-// Release releases any resources associated with the Process.
-func (p *Process) Release() error {
+func (p *Process) release() error {
 	// NOOP for unix.
 	p.Pid = -1
 	// no need for a finalizer anymore
@@ -65,12 +61,10 @@ func findProcess(pid int) (p *Process, err error) {
 	return newProcess(pid, 0), nil
 }
 
-// UserTime returns the user CPU time of the exited process and its children.
-func (p *ProcessState) UserTime() time.Duration {
+func (p *ProcessState) userTime() time.Duration {
 	return time.Duration(p.rusage.Utime.Nano()) * time.Nanosecond
 }
 
-// SystemTime returns the system CPU time of the exited process and its children.
-func (p *ProcessState) SystemTime() time.Duration {
+func (p *ProcessState) systemTime() time.Duration {
 	return time.Duration(p.rusage.Stime.Nano()) * time.Nanosecond
 }
diff --git a/src/pkg/os/exec_windows.go b/src/pkg/os/exec_windows.go
index dab0dc9..5beca4a 100644
--- a/src/pkg/os/exec_windows.go
+++ b/src/pkg/os/exec_windows.go
@@ -12,9 +12,7 @@ import (
 	"unsafe"
 )
 
-// Wait waits for the Process to exit or stop, and then returns a
-// ProcessState describing its status and an error, if any.
-func (p *Process) Wait() (ps *ProcessState, err error) {
+func (p *Process) wait() (ps *ProcessState, err error) {
 	s, e := syscall.WaitForSingleObject(syscall.Handle(p.handle), syscall.INFINITE)
 	switch s {
 	case syscall.WAIT_OBJECT_0:
@@ -29,12 +27,22 @@ func (p *Process) Wait() (ps *ProcessState, err error) {
 	if e != nil {
 		return nil, NewSyscallError("GetExitCodeProcess", e)
 	}
+	var u syscall.Rusage
+	e = syscall.GetProcessTimes(syscall.Handle(p.handle), &u.CreationTime, &u.ExitTime, &u.KernelTime, &u.UserTime)
+	if e != nil {
+		return nil, NewSyscallError("GetProcessTimes", e)
+	}
 	p.done = true
-	return &ProcessState{p.Pid, syscall.WaitStatus{Status: s, ExitCode: ec}, new(syscall.Rusage)}, nil
+	// NOTE(brainman): It seems that sometimes process is not dead
+	// when WaitForSingleObject returns. But we do not know any
+	// other way to wait for it. Sleeping for a while seems to do
+	// the trick sometimes. So we will sleep and smell the roses.
+	defer time.Sleep(5 * time.Millisecond)
+	defer p.Release()
+	return &ProcessState{p.Pid, syscall.WaitStatus{ExitCode: ec}, &u}, nil
 }
 
-// Signal sends a signal to the Process.
-func (p *Process) Signal(sig Signal) error {
+func (p *Process) signal(sig Signal) error {
 	if p.done {
 		return errors.New("os: process already finished")
 	}
@@ -46,8 +54,7 @@ func (p *Process) Signal(sig Signal) error {
 	return syscall.Errno(syscall.EWINDOWS)
 }
 
-// Release releases any resources associated with the Process.
-func (p *Process) Release() error {
+func (p *Process) release() error {
 	if p.handle == uintptr(syscall.InvalidHandle) {
 		return syscall.EINVAL
 	}
@@ -85,14 +92,15 @@ func init() {
 	}
 }
 
-// UserTime returns the user CPU time of the exited process and its children.
-// For now, it is always reported as 0 on Windows.
-func (p *ProcessState) UserTime() time.Duration {
-	return 0
+func ftToDuration(ft *syscall.Filetime) time.Duration {
+	n := int64(ft.HighDateTime)<<32 + int64(ft.LowDateTime) // in 100-nanosecond intervals
+	return time.Duration(n*100) * time.Nanosecond
+}
+
+func (p *ProcessState) userTime() time.Duration {
+	return ftToDuration(&p.rusage.UserTime)
 }
 
-// SystemTime returns the system CPU time of the exited process and its children.
-// For now, it is always reported as 0 on Windows.
-func (p *ProcessState) SystemTime() time.Duration {
-	return 0
+func (p *ProcessState) systemTime() time.Duration {
+	return ftToDuration(&p.rusage.KernelTime)
 }
diff --git a/src/pkg/os/file.go b/src/pkg/os/file.go
index 1c3d017..4acf35d 100644
--- a/src/pkg/os/file.go
+++ b/src/pkg/os/file.go
@@ -25,7 +25,7 @@
 //	open file.go: no such file or directory
 //
 // The file's data can then be read into a slice of bytes. Read and
-// Write take their byte counts from the length of the artument slice.
+// Write take their byte counts from the length of the argument slice.
 //
 //	data := make([]byte, 100)
 //	count, err := file.Read(data)
diff --git a/src/pkg/os/file_windows.go b/src/pkg/os/file_windows.go
index 82c7429..88fa77b 100644
--- a/src/pkg/os/file_windows.go
+++ b/src/pkg/os/file_windows.go
@@ -52,6 +52,7 @@ func NewFile(fd uintptr, name string) *File {
 type dirInfo struct {
 	data     syscall.Win32finddata
 	needdata bool
+	path     string
 }
 
 const DevNull = "NUL"
@@ -79,6 +80,11 @@ func openDir(name string) (file *File, err error) {
 	if e != nil {
 		return nil, &PathError{"open", name, e}
 	}
+	d.path = name
+	if !isAbs(d.path) {
+		cwd, _ := Getwd()
+		d.path = cwd + `\` + d.path
+	}
 	f := NewFile(uintptr(r), name)
 	f.dirinfo = d
 	return f, nil
@@ -171,7 +177,13 @@ func (file *File) readdir(n int) (fi []FileInfo, err error) {
 		if name == "." || name == ".." { // Useless names
 			continue
 		}
-		f := toFileInfo(name, d.FileAttributes, d.FileSizeHigh, d.FileSizeLow, d.CreationTime, d.LastAccessTime, d.LastWriteTime)
+		f := &fileStat{
+			name:    name,
+			size:    mkSize(d.FileSizeHigh, d.FileSizeLow),
+			modTime: mkModTime(d.LastWriteTime),
+			mode:    mkMode(d.FileAttributes),
+			sys:     mkSys(file.dirinfo.path+`\`+name, d.LastAccessTime, d.CreationTime),
+		}
 		n--
 		fi = append(fi, f)
 	}
diff --git a/src/pkg/os/os_test.go b/src/pkg/os/os_test.go
index 21e2f37..d1e241f 100644
--- a/src/pkg/os/os_test.go
+++ b/src/pkg/os/os_test.go
@@ -530,7 +530,6 @@ func exec(t *testing.T, dir, cmd string, args []string, expect string) {
 	if err != nil {
 		t.Fatalf("StartProcess: %v", err)
 	}
-	defer p.Release()
 	w.Close()
 
 	var b bytes.Buffer
@@ -848,7 +847,6 @@ func run(t *testing.T, cmd []string) string {
 	if err != nil {
 		t.Fatal(err)
 	}
-	defer p.Release()
 	w.Close()
 
 	var b bytes.Buffer
@@ -1014,3 +1012,38 @@ func TestNilProcessStateString(t *testing.T) {
 		t.Errorf("(*ProcessState)(nil).String() = %q, want %q", s, "<nil>")
 	}
 }
+
+func TestSameFile(t *testing.T) {
+	fa, err := Create("a")
+	if err != nil {
+		t.Fatalf("Create(a): %v", err)
+	}
+	defer Remove(fa.Name())
+	fa.Close()
+	fb, err := Create("b")
+	if err != nil {
+		t.Fatalf("Create(b): %v", err)
+	}
+	defer Remove(fb.Name())
+	fb.Close()
+
+	ia1, err := Stat("a")
+	if err != nil {
+		t.Fatalf("Stat(a): %v", err)
+	}
+	ia2, err := Stat("a")
+	if err != nil {
+		t.Fatalf("Stat(a): %v", err)
+	}
+	if !SameFile(ia1, ia2) {
+		t.Errorf("files should be same")
+	}
+
+	ib, err := Stat("b")
+	if err != nil {
+		t.Fatalf("Stat(b): %v", err)
+	}
+	if SameFile(ia1, ib) {
+		t.Errorf("files should be different")
+	}
+}
diff --git a/src/pkg/os/stat_netbsd.go b/src/pkg/os/stat_netbsd.go
index c58a287..00506b2 100644
--- a/src/pkg/os/stat_netbsd.go
+++ b/src/pkg/os/stat_netbsd.go
@@ -20,7 +20,7 @@ func fileInfoFromStat(st *syscall.Stat_t, name string) FileInfo {
 		name:    basename(name),
 		size:    int64(st.Size),
 		modTime: timespecToTime(st.Mtim),
-		Sys:     st,
+		sys:     st,
 	}
 	fs.mode = FileMode(st.Mode & 0777)
 	switch st.Mode & syscall.S_IFMT {
diff --git a/src/pkg/os/stat_windows.go b/src/pkg/os/stat_windows.go
index ffb679f..19e215e 100644
--- a/src/pkg/os/stat_windows.go
+++ b/src/pkg/os/stat_windows.go
@@ -5,6 +5,7 @@
 package os
 
 import (
+	"sync"
 	"syscall"
 	"time"
 	"unsafe"
@@ -25,7 +26,13 @@ func (file *File) Stat() (fi FileInfo, err error) {
 	if e != nil {
 		return nil, &PathError{"GetFileInformationByHandle", file.name, e}
 	}
-	return toFileInfo(basename(file.name), d.FileAttributes, d.FileSizeHigh, d.FileSizeLow, d.CreationTime, d.LastAccessTime, d.LastWriteTime), nil
+	return &fileStat{
+		name:    basename(file.name),
+		size:    mkSize(d.FileSizeHigh, d.FileSizeLow),
+		modTime: mkModTime(d.LastWriteTime),
+		mode:    mkMode(d.FileAttributes),
+		sys:     mkSysFromFI(&d),
+	}, nil
 }
 
 // Stat returns a FileInfo structure describing the named file.
@@ -39,7 +46,18 @@ func Stat(name string) (fi FileInfo, err error) {
 	if e != nil {
 		return nil, &PathError{"GetFileAttributesEx", name, e}
 	}
-	return toFileInfo(basename(name), d.FileAttributes, d.FileSizeHigh, d.FileSizeLow, d.CreationTime, d.LastAccessTime, d.LastWriteTime), nil
+	path := name
+	if !isAbs(path) {
+		cwd, _ := Getwd()
+		path = cwd + `\` + path
+	}
+	return &fileStat{
+		name:    basename(name),
+		size:    mkSize(d.FileSizeHigh, d.FileSizeLow),
+		modTime: mkModTime(d.LastWriteTime),
+		mode:    mkMode(d.FileAttributes),
+		sys:     mkSys(path, d.LastAccessTime, d.CreationTime),
+	}, nil
 }
 
 // Lstat returns the FileInfo structure describing the named file.
@@ -75,37 +93,144 @@ func basename(name string) string {
 	return name
 }
 
-type winTimes struct {
-	atime, ctime syscall.Filetime
+func isSlash(c uint8) bool {
+	return c == '\\' || c == '/'
+}
+
+func isAbs(path string) (b bool) {
+	v := volumeName(path)
+	if v == "" {
+		return false
+	}
+	path = path[len(v):]
+	if path == "" {
+		return false
+	}
+	return isSlash(path[0])
 }
 
-func toFileInfo(name string, fa, sizehi, sizelo uint32, ctime, atime, mtime syscall.Filetime) FileInfo {
-	fs := &fileStat{
-		name:    name,
-		size:    int64(sizehi)<<32 + int64(sizelo),
-		modTime: time.Unix(0, mtime.Nanoseconds()),
-		sys:     &winTimes{atime, ctime},
+func volumeName(path string) (v string) {
+	if len(path) < 2 {
+		return ""
 	}
+	// with drive letter
+	c := path[0]
+	if path[1] == ':' &&
+		('0' <= c && c <= '9' || 'a' <= c && c <= 'z' ||
+			'A' <= c && c <= 'Z') {
+		return path[:2]
+	}
+	// is it UNC
+	if l := len(path); l >= 5 && isSlash(path[0]) && isSlash(path[1]) &&
+		!isSlash(path[2]) && path[2] != '.' {
+		// first, leading `\\` and next shouldn't be `\`. its server name.
+		for n := 3; n < l-1; n++ {
+			// second, next '\' shouldn't be repeated.
+			if isSlash(path[n]) {
+				n++
+				// third, following something characters. its share name.
+				if !isSlash(path[n]) {
+					if path[n] == '.' {
+						break
+					}
+					for ; n < l; n++ {
+						if isSlash(path[n]) {
+							break
+						}
+					}
+					return path[:n]
+				}
+				break
+			}
+		}
+	}
+	return ""
+}
+
+type winSys struct {
+	sync.Mutex
+	path              string
+	atime, ctime      syscall.Filetime
+	vol, idxhi, idxlo uint32
+}
+
+func mkSize(hi, lo uint32) int64 {
+	return int64(hi)<<32 + int64(lo)
+}
+
+func mkModTime(mtime syscall.Filetime) time.Time {
+	return time.Unix(0, mtime.Nanoseconds())
+}
+
+func mkMode(fa uint32) (m FileMode) {
 	if fa&syscall.FILE_ATTRIBUTE_DIRECTORY != 0 {
-		fs.mode |= ModeDir
+		m |= ModeDir
 	}
 	if fa&syscall.FILE_ATTRIBUTE_READONLY != 0 {
-		fs.mode |= 0444
+		m |= 0444
 	} else {
-		fs.mode |= 0666
+		m |= 0666
 	}
-	return fs
+	return m
+}
+
+func mkSys(path string, atime, ctime syscall.Filetime) *winSys {
+	return &winSys{
+		path:  path,
+		atime: atime,
+		ctime: ctime,
+	}
+}
+
+func mkSysFromFI(i *syscall.ByHandleFileInformation) *winSys {
+	return &winSys{
+		atime: i.LastAccessTime,
+		ctime: i.CreationTime,
+		vol:   i.VolumeSerialNumber,
+		idxhi: i.FileIndexHigh,
+		idxlo: i.FileIndexLow,
+	}
+}
+
+func (s *winSys) loadFileId() error {
+	if s.path == "" {
+		// already done
+		return nil
+	}
+	s.Lock()
+	defer s.Unlock()
+	h, e := syscall.CreateFile(syscall.StringToUTF16Ptr(s.path), syscall.GENERIC_READ, syscall.FILE_SHARE_READ, nil, syscall.OPEN_EXISTING, 0, 0)
+	if e != nil {
+		return e
+	}
+	defer syscall.CloseHandle(h)
+	var i syscall.ByHandleFileInformation
+	e = syscall.GetFileInformationByHandle(syscall.Handle(h), &i)
+	if e != nil {
+		return e
+	}
+	s.path = ""
+	s.vol = i.VolumeSerialNumber
+	s.idxhi = i.FileIndexHigh
+	s.idxlo = i.FileIndexLow
+	return nil
 }
 
 func sameFile(sys1, sys2 interface{}) bool {
-	// TODO(rsc): Do better than this, but this matches what
-	// used to happen when code compared .Dev and .Ino,
-	// which were both always zero.  Obviously not all files
-	// are the same.
-	return true
+	s1 := sys1.(*winSys)
+	s2 := sys2.(*winSys)
+	e := s1.loadFileId()
+	if e != nil {
+		panic(e)
+	}
+	e = s2.loadFileId()
+	if e != nil {
+		panic(e)
+	}
+	return s1.vol == s2.vol && s1.idxhi == s2.idxhi && s1.idxlo == s2.idxlo
 }
 
 // For testing.
 func atime(fi FileInfo) time.Time {
-	return time.Unix(0, fi.Sys().(*winTimes).atime.Nanoseconds())
+	return time.Unix(0, fi.Sys().(*winSys).atime.Nanoseconds())
 }
diff --git a/src/pkg/path/filepath/path.go b/src/pkg/path/filepath/path.go
index f468d33..cfe4698 100644
--- a/src/pkg/path/filepath/path.go
+++ b/src/pkg/path/filepath/path.go
@@ -139,6 +139,7 @@ func FromSlash(path string) string {
 
 // SplitList splits a list of paths joined by the OS-specific ListSeparator,
 // usually found in PATH or GOPATH environment variables.
+// Unlike strings.Split, SplitList returns an empty slice when passed an empty string.
 func SplitList(path string) []string {
 	if path == "" {
 		return []string{}
diff --git a/src/pkg/path/filepath/path_plan9.go b/src/pkg/path/filepath/path_plan9.go
index 17b873f..cf028a7 100644
--- a/src/pkg/path/filepath/path_plan9.go
+++ b/src/pkg/path/filepath/path_plan9.go
@@ -17,7 +17,7 @@ func VolumeName(path string) string {
 	return ""
 }
 
-// HasPrefix tests whether the path p begins with prefix.
+// HasPrefix exists for historical compatibility and should not be used.
 func HasPrefix(p, prefix string) bool {
 	return strings.HasPrefix(p, prefix)
 }
diff --git a/src/pkg/path/filepath/path_unix.go b/src/pkg/path/filepath/path_unix.go
index c5ac71e..305e307 100644
--- a/src/pkg/path/filepath/path_unix.go
+++ b/src/pkg/path/filepath/path_unix.go
@@ -19,7 +19,7 @@ func VolumeName(path string) string {
 	return ""
 }
 
-// HasPrefix tests whether the path p begins with prefix.
+// HasPrefix exists for historical compatibility and should not be used.
 func HasPrefix(p, prefix string) bool {
 	return strings.HasPrefix(p, prefix)
 }
diff --git a/src/pkg/path/filepath/path_windows.go b/src/pkg/path/filepath/path_windows.go
index 9692fd9..1d1d23b 100644
--- a/src/pkg/path/filepath/path_windows.go
+++ b/src/pkg/path/filepath/path_windows.go
@@ -67,8 +67,7 @@ func VolumeName(path string) (v string) {
 	return ""
 }
 
-// HasPrefix tests whether the path p begins with prefix.
-// It ignores case while comparing.
+// HasPrefix exists for historical compatibility and should not be used.
 func HasPrefix(p, prefix string) bool {
 	if strings.HasPrefix(p, prefix) {
 		return true
diff --git a/src/pkg/reflect/all_test.go b/src/pkg/reflect/all_test.go
index ad99587..6bb0613 100644
--- a/src/pkg/reflect/all_test.go
+++ b/src/pkg/reflect/all_test.go
@@ -629,6 +629,13 @@ type DeepEqualTest struct {
 	eq   bool
 }
 
+// Simple functions for DeepEqual tests.
+var (
+	fn1 func()             // nil.
+	fn2 func()             // nil.
+	fn3 = func() { fn1() } // Not nil.
+)
+
 var deepEqualTests = []DeepEqualTest{
 	// Equalities
 	{1, 1, true},
@@ -641,6 +648,7 @@ var deepEqualTests = []DeepEqualTest{
 	{Basic{1, 0.5}, Basic{1, 0.5}, true},
 	{error(nil), error(nil), true},
 	{map[int]string{1: "one", 2: "two"}, map[int]string{2: "two", 1: "one"}, true},
+	{fn1, fn2, true},
 
 	// Inequalities
 	{1, 2, false},
@@ -658,6 +666,8 @@ var deepEqualTests = []DeepEqualTest{
 	{map[int]string{2: "two", 1: "one"}, map[int]string{1: "one"}, false},
 	{nil, 1, false},
 	{1, nil, false},
+	{fn1, fn3, false},
+	{fn3, fn3, false},
 
 	// Nil vs empty: not the same.
 	{[]int{}, []int(nil), false},
@@ -1733,3 +1743,15 @@ func isValid(v Value) {
 		panic("zero Value")
 	}
 }
+
+func TestAlias(t *testing.T) {
+	x := string("hello")
+	v := ValueOf(&x).Elem()
+	oldvalue := v.Interface()
+	v.SetString("world")
+	newvalue := v.Interface()
+
+	if oldvalue != "hello" || newvalue != "world" {
+		t.Errorf("aliasing: old=%q new=%q, want hello, world", oldvalue, newvalue)
+	}
+}
diff --git a/src/pkg/reflect/deepequal.go b/src/pkg/reflect/deepequal.go
index df5ec0a..c12e90f 100644
--- a/src/pkg/reflect/deepequal.go
+++ b/src/pkg/reflect/deepequal.go
@@ -108,6 +108,12 @@ func deepValueEqual(v1, v2 Value, visited map[uintptr]*visit, depth int) (b bool
 			}
 		}
 		return true
+	case Func:
+		if v1.IsNil() && v2.IsNil() {
+			return true
+		}
+		// Can't do better than this:
+		return false
 	default:
 		// Normal equality suffices
 		return valueInterface(v1, false) == valueInterface(v2, false)
@@ -117,8 +123,8 @@ func deepValueEqual(v1, v2 Value, visited map[uintptr]*visit, depth int) (b bool
 }
 
 // DeepEqual tests for deep equality. It uses normal == equality where possible
-// but will scan members of arrays, slices, and fields of structs. It correctly
-// handles recursive types.
+// but will scan members of arrays, slices, maps, and fields of structs. It correctly
+// handles recursive types. Functions are equal only if they are both nil.
 func DeepEqual(a1, a2 interface{}) bool {
 	if a1 == nil || a2 == nil {
 		return a1 == a2
diff --git a/src/pkg/reflect/type.go b/src/pkg/reflect/type.go
index 53638a4..6356b29 100644
--- a/src/pkg/reflect/type.go
+++ b/src/pkg/reflect/type.go
@@ -12,7 +12,7 @@
 // for that type.
 //
 // See "The Laws of Reflection" for an introduction to reflection in Go:
-// http://blog.golang.org/2011/09/laws-of-reflection.html
+// http://golang.org/doc/articles/laws_of_reflection.html
 package reflect
 
 import (
diff --git a/src/pkg/reflect/value.go b/src/pkg/reflect/value.go
index df65dcf..f3f7d63 100644
--- a/src/pkg/reflect/value.go
+++ b/src/pkg/reflect/value.go
@@ -800,13 +800,15 @@ func (v Value) CanInterface() bool {
 	return v.flag&(flagMethod|flagRO) == 0
 }
 
-// Interface returns v's value as an interface{}.
+// Interface returns v's current value as an interface{}.
+// It is equivalent to:
+//	var i interface{} = (v's underlying value)
 // If v is a method obtained by invoking Value.Method
 // (as opposed to Type.Method), Interface cannot return an
 // interface value, so it panics.
 // It also panics if the Value was obtained by accessing
 // unexported struct fields.
-func (v Value) Interface() interface{} {
+func (v Value) Interface() (i interface{}) {
 	return valueInterface(v, true)
 }
 
@@ -842,6 +844,16 @@ func valueInterface(v Value, safe bool) interface{} {
 	var eface emptyInterface
 	eface.typ = v.typ.runtimeType()
 	eface.word = v.iword()
+
+	if v.flag&flagIndir != 0 && v.typ.size > ptrSize {
+		// eface.word is a pointer to the actual data,
+		// which might be changed.  We need to return
+		// a pointer to unchanging data, so make a copy.
+		ptr := unsafe_New(v.typ)
+		memmove(ptr, unsafe.Pointer(eface.word), v.typ.size)
+		eface.word = iword(ptr)
+	}
+
 	return *(*interface{})(unsafe.Pointer(&eface))
 }
 
diff --git a/src/pkg/runtime/defs_arm_linux.go b/src/pkg/runtime/defs_arm_linux.go
index 2063efb..db0a191 100644
--- a/src/pkg/runtime/defs_arm_linux.go
+++ b/src/pkg/runtime/defs_arm_linux.go
@@ -114,7 +114,6 @@ const (
 	ITIMER_VIRTUAL = C.ITIMER_VIRTUAL
 )
 
-type Sigset C.sigset_t
 type Timespec C.struct_timespec
 type Sigaltstack C.struct_sigaltstack
 type Sigcontext C.struct_sigcontext
diff --git a/src/pkg/runtime/defs_linux_arm.h b/src/pkg/runtime/defs_linux_arm.h
index da97a84..9e5c83a 100644
--- a/src/pkg/runtime/defs_linux_arm.h
+++ b/src/pkg/runtime/defs_linux_arm.h
@@ -69,8 +69,6 @@ enum {
 // Types
 #pragma pack on
 
-typedef uint32 Sigset;
-
 typedef struct Timespec Timespec;
 struct Timespec {
 	int32 tv_sec;
diff --git a/src/pkg/runtime/lock_futex.c b/src/pkg/runtime/lock_futex.c
index 6ec4aee..b4465bf 100644
--- a/src/pkg/runtime/lock_futex.c
+++ b/src/pkg/runtime/lock_futex.c
@@ -118,8 +118,12 @@ runtime·notewakeup(Note *n)
 void
 runtime·notesleep(Note *n)
 {
+	if(m->profilehz > 0)
+		runtime·setprof(false);
 	while(runtime·atomicload(&n->key) == 0)
 		runtime·futexsleep(&n->key, 0, -1);
+	if(m->profilehz > 0)
+		runtime·setprof(true);
 }
 
 void
@@ -135,14 +139,18 @@ runtime·notetsleep(Note *n, int64 ns)
 	if(runtime·atomicload(&n->key) != 0)
 		return;
 
+	if(m->profilehz > 0)
+		runtime·setprof(false);
 	deadline = runtime·nanotime() + ns;
 	for(;;) {
 		runtime·futexsleep(&n->key, 0, ns);
 		if(runtime·atomicload(&n->key) != 0)
-			return;
+			break;
 		now = runtime·nanotime();
 		if(now >= deadline)
-			return;
+			break;
 		ns = deadline - now;
 	}
+	if(m->profilehz > 0)
+		runtime·setprof(true);
 }
diff --git a/src/pkg/runtime/lock_sema.c b/src/pkg/runtime/lock_sema.c
index 28d2c32..1d9c37f 100644
--- a/src/pkg/runtime/lock_sema.c
+++ b/src/pkg/runtime/lock_sema.c
@@ -154,7 +154,11 @@ runtime·notesleep(Note *n)
 		return;
 	}
 	// Queued.  Sleep.
+	if(m->profilehz > 0)
+		runtime·setprof(false);
 	runtime·semasleep(-1);
+	if(m->profilehz > 0)
+		runtime·setprof(true);
 }
 
 void
@@ -178,12 +182,16 @@ runtime·notetsleep(Note *n, int64 ns)
 		return;
 	}
 
+	if(m->profilehz > 0)
+		runtime·setprof(false);
 	deadline = runtime·nanotime() + ns;
 	for(;;) {
 		// Registered.  Sleep.
 		if(runtime·semasleep(ns) >= 0) {
 			// Acquired semaphore, semawakeup unregistered us.
 			// Done.
+			if(m->profilehz > 0)
+				runtime·setprof(true);
 			return;
 		}
 
@@ -196,6 +204,9 @@ runtime·notetsleep(Note *n, int64 ns)
 		ns = deadline - now;
 	}
 
+	if(m->profilehz > 0)
+		runtime·setprof(true);
+
 	// Deadline arrived.  Still registered.  Semaphore not acquired.
 	// Want to give up and return, but have to unregister first,
 	// so that any notewakeup racing with the return does not
diff --git a/src/pkg/runtime/malloc.goc b/src/pkg/runtime/malloc.goc
index 932e3d9..af03f80 100644
--- a/src/pkg/runtime/malloc.goc
+++ b/src/pkg/runtime/malloc.goc
@@ -262,6 +262,7 @@ runtime·mallocinit(void)
 	uintptr arena_size, bitmap_size;
 	extern byte end[];
 	byte *want;
+	uintptr limit;
 
 	p = nil;
 	arena_size = 0;
@@ -274,10 +275,12 @@ runtime·mallocinit(void)
 
 	runtime·InitSizes();
 
+	limit = runtime·memlimit();
+
 	// Set up the allocation arena, a contiguous area of memory where
 	// allocated data will be found.  The arena begins with a bitmap large
 	// enough to hold 4 bits per allocated word.
-	if(sizeof(void*) == 8) {
+	if(sizeof(void*) == 8 && (limit == 0 || limit > (1<<30))) {
 		// On a 64-bit machine, allocate from a single contiguous reservation.
 		// 16 GB should be big enough for now.
 		//
@@ -326,6 +329,10 @@ runtime·mallocinit(void)
 		// of address space, which is probably too much in a 32-bit world.
 		bitmap_size = MaxArena32 / (sizeof(void*)*8/4);
 		arena_size = 512<<20;
+		if(limit > 0 && arena_size+bitmap_size > limit) {
+			bitmap_size = (limit / 9) & ~((1<<PageShift) - 1);
+			arena_size = bitmap_size * 8;
+		}
 		
 		// SysReserve treats the address we ask for, end, as a hint,
 		// not as an absolute requirement.  If we ask for the end
@@ -340,6 +347,8 @@ runtime·mallocinit(void)
 		p = runtime·SysReserve(want, bitmap_size + arena_size);
 		if(p == nil)
 			runtime·throw("runtime: cannot reserve arena virtual address space");
+		if((uintptr)p & (((uintptr)1<<PageShift)-1))
+			runtime·printf("runtime: SysReserve returned unaligned address %p; asked for %p", p, bitmap_size+arena_size);
 	}
 	if((uintptr)p & (((uintptr)1<<PageShift)-1))
 		runtime·throw("runtime: SysReserve returned unaligned address");
diff --git a/src/pkg/runtime/mheap.c b/src/pkg/runtime/mheap.c
index 761246a..c877bfc 100644
--- a/src/pkg/runtime/mheap.c
+++ b/src/pkg/runtime/mheap.c
@@ -326,7 +326,7 @@ MHeap_FreeLocked(MHeap *h, MSpan *s)
 }
 
 // Release (part of) unused memory to OS.
-// Goroutine created in runtime·schedinit.
+// Goroutine created at startup.
 // Loop forever.
 void
 runtime·MHeap_Scavenger(void)
diff --git a/src/pkg/runtime/os_darwin.h b/src/pkg/runtime/os_darwin.h
index 0003b66..eb5d2da 100644
--- a/src/pkg/runtime/os_darwin.h
+++ b/src/pkg/runtime/os_darwin.h
@@ -20,6 +20,9 @@ uint32	runtime·mach_thread_self(void);
 uint32	runtime·mach_thread_self(void);
 int32	runtime·sysctl(uint32*, uint32, byte*, uintptr*, byte*, uintptr);
 
+typedef uint32 Sigset;
+void	runtime·sigprocmask(int32, Sigset*, Sigset*);
+
 struct Sigaction;
 void	runtime·sigaction(uintptr, struct Sigaction*, struct Sigaction*);
 void	runtime·setsig(int32, void(*)(int32, Siginfo*, void*, G*), bool);
@@ -35,3 +38,7 @@ void	runtime·raisesigpipe(void);
 
 #define	NSIG 32
 #define	SI_USER	0  /* empirically true, but not what headers say */
+#define	SIG_BLOCK 1
+#define	SIG_UNBLOCK 2
+#define	SIG_SETMASK 3
+
diff --git a/src/pkg/runtime/os_freebsd.h b/src/pkg/runtime/os_freebsd.h
index 194d963..5e8de54 100644
--- a/src/pkg/runtime/os_freebsd.h
+++ b/src/pkg/runtime/os_freebsd.h
@@ -9,7 +9,6 @@ struct	sigaction;
 void	runtime·sigaction(int32, struct sigaction*, struct sigaction*);
 void	runtime·sigprocmask(Sigset *, Sigset *);
 void	runtime·setsig(int32, void(*)(int32, Siginfo*, void*, G*), bool);
-void	runtiem·setitimerval(int32, Itimerval*, Itimerval*);
 void	runtime·setitimer(int32, Itimerval*, Itimerval*);
 int32	runtime·sysctl(uint32*, uint32, byte*, uintptr*, byte*, uintptr);
 
@@ -17,3 +16,11 @@ void	runtime·raisesigpipe(void);
 
 #define	NSIG 33
 #define	SI_USER	0
+
+#define RLIMIT_AS 10
+typedef struct Rlimit Rlimit;
+struct Rlimit {
+	int64	rlim_cur;
+	int64	rlim_max;
+};
+int32	runtime·getrlimit(int32, Rlimit*);
diff --git a/src/pkg/runtime/os_linux.h b/src/pkg/runtime/os_linux.h
index 82498c9..87daa3b 100644
--- a/src/pkg/runtime/os_linux.h
+++ b/src/pkg/runtime/os_linux.h
@@ -22,3 +22,22 @@ void	runtime·raisesigpipe(void);
 
 #define	NSIG	65
 #define	SI_USER 0
+
+// It's hard to tease out exactly how big a Sigset is, but
+// rt_sigprocmask crashes if we get it wrong, so if binaries
+// are running, this is right.
+typedef struct Sigset Sigset;
+struct Sigset
+{
+	uint32 mask[2];
+};
+void	runtime·rtsigprocmask(int32, Sigset*, Sigset*, int32);
+#define SIG_SETMASK 2
+
+#define RLIMIT_AS 9
+typedef struct Rlimit Rlimit;
+struct Rlimit {
+	uintptr	rlim_cur;
+	uintptr	rlim_max;
+};
+int32	runtime·getrlimit(int32, Rlimit*);
diff --git a/src/pkg/runtime/os_netbsd.h b/src/pkg/runtime/os_netbsd.h
index 67c58ec..4ecf78d 100644
--- a/src/pkg/runtime/os_netbsd.h
+++ b/src/pkg/runtime/os_netbsd.h
@@ -12,7 +12,6 @@ void	runtime·sigaltstack(Sigaltstack*, Sigaltstack*);
 void	runtime·sigaction(int32, struct sigaction*, struct sigaction*);
 void	runtime·setsig(int32, void(*)(int32, Siginfo*, void*, G*), bool);
 void	runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp);
-void	runtime·setitimerval(int32, Itimerval*, Itimerval*);
 void	runtime·setitimer(int32, Itimerval*, Itimerval*);
 int32	runtime·sysctl(uint32*, uint32, byte*, uintptr*, byte*, uintptr);
 
diff --git a/src/pkg/runtime/os_openbsd.h b/src/pkg/runtime/os_openbsd.h
index 67c58ec..4ecf78d 100644
--- a/src/pkg/runtime/os_openbsd.h
+++ b/src/pkg/runtime/os_openbsd.h
@@ -12,7 +12,6 @@ void	runtime·sigaltstack(Sigaltstack*, Sigaltstack*);
 void	runtime·sigaction(int32, struct sigaction*, struct sigaction*);
 void	runtime·setsig(int32, void(*)(int32, Siginfo*, void*, G*), bool);
 void	runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp);
-void	runtime·setitimerval(int32, Itimerval*, Itimerval*);
 void	runtime·setitimer(int32, Itimerval*, Itimerval*);
 int32	runtime·sysctl(uint32*, uint32, byte*, uintptr*, byte*, uintptr);
 
diff --git a/src/pkg/runtime/pprof/pprof.go b/src/pkg/runtime/pprof/pprof.go
index 099bb6a..f67e8a8 100644
--- a/src/pkg/runtime/pprof/pprof.go
+++ b/src/pkg/runtime/pprof/pprof.go
@@ -20,8 +20,8 @@ import (
 	"text/tabwriter"
 )
 
-// BUG(rsc): CPU profiling is broken on OS X, due to an Apple kernel bug.
-// For details, see http://code.google.com/p/go/source/detail?r=35b716c94225.
+// BUG(rsc): A bug in the OS X Snow Leopard 64-bit kernel prevents
+// CPU profiling from giving accurate results on that system.
 
 // A Profile is a collection of stack traces showing the call sequences
 // that led to instances of a particular event, such as allocation.
@@ -156,7 +156,7 @@ func (p *Profile) Count() int {
 }
 
 // Add adds the current execution stack to the profile, associated with value.
-// Add stores value in an internal map, so value must be suitable for use as 
+// Add stores value in an internal map, so value must be suitable for use as
 // a map key and will not be garbage collected until the corresponding
 // call to Remove.  Add panics if the profile already contains a stack for value.
 //
diff --git a/src/pkg/runtime/pprof/pprof_test.go b/src/pkg/runtime/pprof/pprof_test.go
index 5f128c0..2dc7aef 100644
--- a/src/pkg/runtime/pprof/pprof_test.go
+++ b/src/pkg/runtime/pprof/pprof_test.go
@@ -7,6 +7,7 @@ package pprof_test
 import (
 	"bytes"
 	"hash/crc32"
+	"os/exec"
 	"runtime"
 	. "runtime/pprof"
 	"strings"
@@ -17,8 +18,16 @@ import (
 func TestCPUProfile(t *testing.T) {
 	switch runtime.GOOS {
 	case "darwin":
-		// see Apple Bug Report #9177434 (copied into change description)
-		return
+		out, err := exec.Command("uname", "-a").CombinedOutput()
+		if err != nil {
+			t.Fatal(err)
+		}
+		vers := string(out)
+		t.Logf("uname -a: %v", vers)
+		if strings.Contains(vers, "Darwin Kernel Version 10.8.0") && strings.Contains(vers, "root:xnu-1504.15.3~1/RELEASE_X86_64") {
+			t.Logf("skipping test on known-broken kernel (64-bit Snow Leopard)")
+			return
+		}
 	case "plan9":
 		// unimplemented
 		return
diff --git a/src/pkg/runtime/proc.c b/src/pkg/runtime/proc.c
index d94bec8..de7090c 100644
--- a/src/pkg/runtime/proc.c
+++ b/src/pkg/runtime/proc.c
@@ -209,8 +209,6 @@ runtime·schedinit(void)
 
 	mstats.enablegc = 1;
 	m->nomemprof--;
-
-	scvg = runtime·newproc1((byte*)runtime·MHeap_Scavenger, nil, 0, 0, runtime·schedinit);
 }
 
 extern void main·init(void);
@@ -228,6 +226,7 @@ runtime·main(void)
 	// to preserve the lock.
 	runtime·LockOSThread();
 	runtime·sched.init = true;
+	scvg = runtime·newproc1((byte*)runtime·MHeap_Scavenger, nil, 0, 0, runtime·main);
 	main·init();
 	runtime·sched.init = false;
 	if(!runtime·sched.lockmain)
@@ -338,7 +337,7 @@ mcommoninit(M *m)
 		m->mcache = runtime·allocmcache();
 
 	runtime·callers(1, m->createstack, nelem(m->createstack));
-	
+
 	// Add to runtime·allm so garbage collector doesn't free m
 	// when it is just in a register or thread-local storage.
 	m->alllink = runtime·allm;
@@ -587,10 +586,11 @@ top:
 		mput(m);
 	}
 
-	// Look for deadlock situation: one single active g which happens to be scvg.
-	if(runtime·sched.grunning == 1 && runtime·sched.gwait == 0) {
-		if(scvg->status == Grunning || scvg->status == Gsyscall)
-			runtime·throw("all goroutines are asleep - deadlock!");
+	// Look for deadlock situation.
+	if((scvg == nil && runtime·sched.grunning == 0) ||
+	   (scvg != nil && runtime·sched.grunning == 1 && runtime·sched.gwait == 0 &&
+	    (scvg->status == Grunning || scvg->status == Gsyscall))) {
+		runtime·throw("all goroutines are asleep - deadlock!");
 	}
 
 	m->nextg = nil;
@@ -728,7 +728,6 @@ runtime·mstart(void)
 	// so other calls can reuse this stack space.
 	runtime·gosave(&m->g0->sched);
 	m->g0->sched.pc = (void*)-1;  // make sure it is never used
-
 	runtime·asminit();
 	runtime·minit();
 	schedule(nil);
@@ -916,6 +915,9 @@ runtime·entersyscall(void)
 {
 	uint32 v;
 
+	if(m->profilehz > 0)
+		runtime·setprof(false);
+
 	// Leave SP around for gc and traceback.
 	runtime·gosave(&g->sched);
 	g->gcsp = g->sched.sp;
@@ -979,6 +981,9 @@ runtime·exitsyscall(void)
 		// Garbage collector isn't running (since we are),
 		// so okay to clear gcstack.
 		g->gcstack = nil;
+
+		if(m->profilehz > 0)
+			runtime·setprof(true);
 		return;
 	}
 
diff --git a/src/pkg/runtime/runtime-gdb.py b/src/pkg/runtime/runtime-gdb.py
index dff4e2b..629c39e 100644
--- a/src/pkg/runtime/runtime-gdb.py
+++ b/src/pkg/runtime/runtime-gdb.py
@@ -5,7 +5,7 @@
 """GDB Pretty printers and convenience functions for Go's runtime structures.
 
 This script is loaded by GDB when it finds a .debug_gdb_scripts
-section in the compiled binary.  The [68]l linkers emit this with a
+section in the compiled binary. The [68]l linkers emit this with a
 path to this file based on the path to the runtime package.
 """
 
@@ -58,6 +58,8 @@ class SliceTypePrinter:
 		return str(self.val.type)[6:]  # skip 'struct '
 
 	def children(self):
+		if self.val["len"] > self.val["cap"]:
+			return
 		ptr = self.val["array"]
 		for idx in range(self.val["len"]):
 			yield ('[%d]' % idx, (ptr + idx).dereference())
@@ -85,7 +87,7 @@ class MapTypePrinter:
 		stab = self.val['st']
 		i = 0
 		for v in self.traverse_hash(stab):
-			yield ("[%d]" %  i, v['key'])
+			yield ("[%d]" % i, v['key'])
 			yield ("[%d]" % (i + 1), v['val'])
 			i += 2
 
@@ -122,10 +124,10 @@ class ChanTypePrinter:
 		return str(self.val.type)
 
 	def children(self):
-		# see chan.c chanbuf().  et is the type stolen from hchan<T>::recvq->first->elem
+		# see chan.c chanbuf(). et is the type stolen from hchan<T>::recvq->first->elem
 		et = [x.type for x in self.val['recvq']['first'].type.target().fields() if x.name == 'elem'][0]
-                ptr = (self.val.address + 1).cast(et.pointer())
-                for i in range(self.val["qcount"]):
+		ptr = (self.val.address + 1).cast(et.pointer())
+		for i in range(self.val["qcount"]):
 			j = (self.val["recvx"] + i) % self.val["dataqsiz"]
 			yield ('[%d]' % i, (ptr + j).dereference())
 
@@ -184,12 +186,10 @@ def lookup_type(name):
 	except:
 		pass
 
+_rctp_type = gdb.lookup_type("struct runtime.commonType").pointer()
+_rtp_type = gdb.lookup_type("struct runtime._type").pointer()
 
-def iface_dtype(obj):
-	"Decode type of the data field of an eface or iface struct."
-        # known issue: dtype_name decoded from runtime.commonType is "nested.Foo"
-        # but the dwarf table lists it as "full/path/to/nested.Foo"
-
+def iface_commontype(obj):
 	if is_iface(obj):
 		go_type_ptr = obj['tab']['_type']
 	elif is_eface(obj):
@@ -197,15 +197,31 @@ def iface_dtype(obj):
 	else:
 		return
 
-	ct = gdb.lookup_type("struct runtime.commonType").pointer()
-	dynamic_go_type = go_type_ptr['ptr'].cast(ct).dereference()
+	# sanity check: reflection type description ends in a loop.
+	tt = go_type_ptr['_type'].cast(_rtp_type).dereference()['_type']
+	if tt != tt.cast(_rtp_type).dereference()['_type']:
+		return
+	
+	return go_type_ptr['ptr'].cast(_rctp_type).dereference()
+	
+
+def iface_dtype(obj):
+	"Decode type of the data field of an eface or iface struct."
+	# known issue: dtype_name decoded from runtime.commonType is "nested.Foo"
+	# but the dwarf table lists it as "full/path/to/nested.Foo"
+
+	dynamic_go_type = iface_commontype(obj)
+	if dynamic_go_type is None:
+		return
 	dtype_name = dynamic_go_type['string'].dereference()['str'].string()
 
 	dynamic_gdb_type = lookup_type(dtype_name)
-        if dynamic_gdb_type:
-		type_size = int(dynamic_go_type['size'])
-                uintptr_size = int(dynamic_go_type['size'].type.sizeof)  # size is itself an uintptr
-		if type_size > uintptr_size:
+	if dynamic_gdb_type is None:
+		return
+	
+	type_size = int(dynamic_go_type['size'])
+	uintptr_size = int(dynamic_go_type['size'].type.sizeof)	 # size is itself an uintptr
+	if type_size > uintptr_size:
 			dynamic_gdb_type = dynamic_gdb_type.pointer()
 
 	return dynamic_gdb_type
@@ -213,15 +229,9 @@ def iface_dtype(obj):
 def iface_dtype_name(obj):
 	"Decode type name of the data field of an eface or iface struct."
 
-	if is_iface(obj):
-		go_type_ptr = obj['tab']['_type']
-	elif is_eface(obj):
-		go_type_ptr = obj['_type']
-	else:
+	dynamic_go_type = iface_commontype(obj)
+	if dynamic_go_type is None:
 		return
-
-	ct = gdb.lookup_type("struct runtime.commonType").pointer()
-	dynamic_go_type = go_type_ptr['ptr'].cast(ct).dereference()
 	return dynamic_go_type['string'].dereference()['str'].string()
 
 
@@ -244,7 +254,7 @@ class IfacePrinter:
 		except:
 			return "<bad dynamic type>"
 
-                if not dtype:  # trouble looking up, print something reasonable
+		if dtype is None:  # trouble looking up, print something reasonable
 			return "(%s)%s" % (iface_dtype_name(self.val), self.val['data'])
 
 		try:
@@ -267,7 +277,7 @@ goobjfile.pretty_printers.append(ifacematcher)
 class GoLenFunc(gdb.Function):
 	"Length of strings, slices, maps or channels"
 
-	how = ((StringTypePrinter, 'len' ),
+	how = ((StringTypePrinter, 'len'),
 	       (SliceTypePrinter, 'len'),
 	       (MapTypePrinter, 'count'),
 	       (ChanTypePrinter, 'qcount'))
@@ -316,7 +326,7 @@ class DTypeFunc(gdb.Function):
 #  Commands
 #
 
-sts = ( 'idle', 'runnable', 'running', 'syscall', 'waiting', 'moribund', 'dead', 'recovery')
+sts = ('idle', 'runnable', 'running', 'syscall', 'waiting', 'moribund', 'dead', 'recovery')
 
 def linked_list(ptr, linkfield):
 	while ptr:
@@ -339,8 +349,8 @@ class GoroutinesCmd(gdb.Command):
 			s = ' '
 			if ptr['m']:
 				s = '*'
-                        pc = ptr['sched']['pc'].cast(vp)
-                        sp = ptr['sched']['sp'].cast(vp)
+			pc = ptr['sched']['pc'].cast(vp)
+			sp = ptr['sched']['sp'].cast(vp)
 			blk = gdb.block_for_pc(long((pc)))
 			print s, ptr['goid'], "%8s" % sts[long((ptr['status']))], blk.function
 
@@ -382,10 +392,10 @@ class GoroutineCmd(gdb.Command):
 		gdb.parse_and_eval('$sp = 0x%x' % long(sp))
 		try:
 			gdb.execute(cmd)
-                finally:
+		finally:
 			gdb.parse_and_eval('$pc = $save_pc')
-                        gdb.parse_and_eval('$sp = $save_sp')
-                        save_frame.select()
+			gdb.parse_and_eval('$sp = $save_sp')
+			save_frame.select()
 
 
 class GoIfaceCmd(gdb.Command):
@@ -403,8 +413,12 @@ class GoIfaceCmd(gdb.Command):
 				print "Can't parse ", obj, ": ", e
 				continue
 
-			dtype = iface_dtype(obj)
-			if not dtype:
+			if obj['data'] == 0:
+				dtype = "nil"
+			else:
+				dtype = iface_dtype(obj)
+				
+			if dtype is None:
 				print "Not an interface: ", obj.type
 				continue
 
diff --git a/src/pkg/runtime/runtime.h b/src/pkg/runtime/runtime.h
index 1f4407a..f2669fd 100644
--- a/src/pkg/runtime/runtime.h
+++ b/src/pkg/runtime/runtime.h
@@ -729,3 +729,14 @@ bool	runtime·showframe(Func*);
 
 void	runtime·ifaceE2I(struct InterfaceType*, Eface, Iface*);
 
+uintptr	runtime·memlimit(void);
+
+// If appropriate, ask the operating system to control whether this
+// thread should receive profiling signals.  This is only necessary on OS X.
+// An operating system should not deliver a profiling signal to a
+// thread that is not actually executing (what good is that?), but that's
+// what OS X prefers to do.  When profiling is turned on, we mask
+// away the profiling signal when threads go to sleep, so that OS X
+// is forced to deliver the signal to a thread that's actually running.
+// This is a no-op on other systems.
+void	runtime·setprof(bool);
diff --git a/src/pkg/runtime/runtime_linux_test.go b/src/pkg/runtime/runtime_linux_test.go
new file mode 100644
index 0000000..5344ed2
--- /dev/null
+++ b/src/pkg/runtime/runtime_linux_test.go
@@ -0,0 +1,29 @@
+// Copyright 2012 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime_test
+
+import (
+	. "runtime"
+	"syscall"
+	"testing"
+)
+
+var pid, tid int
+
+func init() {
+	// Record pid and tid of init thread for use during test.
+	// The call to LockOSThread is just to exercise it;
+	// we can't test that it does anything.
+	// Instead we're testing that the conditions are good
+	// for how it is used in init (must be on main thread).
+	pid, tid = syscall.Getpid(), syscall.Gettid()
+	LockOSThread()
+}
+
+func TestLockOSThread(t *testing.T) {
+	if pid != tid {
+		t.Fatalf("pid=%d but tid=%d", pid, tid)
+	}
+}
diff --git a/src/pkg/runtime/signal_darwin_386.c b/src/pkg/runtime/signal_darwin_386.c
index 1844f68..9e98635 100644
--- a/src/pkg/runtime/signal_darwin_386.c
+++ b/src/pkg/runtime/signal_darwin_386.c
@@ -40,7 +40,8 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
 	r = &mc->ss;
 
 	if(sig == SIGPROF) {
-		runtime·sigprof((uint8*)r->eip, (uint8*)r->esp, nil, gp);
+		if(gp != m->g0 && gp != m->gsignal)
+			runtime·sigprof((uint8*)r->eip, (uint8*)r->esp, nil, gp);
 		return;
 	}
 
@@ -58,7 +59,7 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
 			if(pc[0] == 0xF6 || pc[0] == 0xF7)
 				info->si_code = FPE_INTDIV;
 		}
-		
+
 		// Make it look like a call to the signal func.
 		// Have to pass arguments out of band since
 		// augmenting the stack frame would break
diff --git a/src/pkg/runtime/signal_darwin_amd64.c b/src/pkg/runtime/signal_darwin_amd64.c
index 32c7308..d9c5f48 100644
--- a/src/pkg/runtime/signal_darwin_amd64.c
+++ b/src/pkg/runtime/signal_darwin_amd64.c
@@ -48,7 +48,8 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
 	r = &mc->ss;
 
 	if(sig == SIGPROF) {
-		runtime·sigprof((uint8*)r->rip, (uint8*)r->rsp, nil, gp);
+		if(gp != m->g0 && gp != m->gsignal)
+			runtime·sigprof((uint8*)r->rip, (uint8*)r->rsp, nil, gp);
 		return;
 	}
 
@@ -68,7 +69,7 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
 			if(pc[0] == 0xF6 || pc[0] == 0xF7)
 				info->si_code = FPE_INTDIV;
 		}
-		
+
 		// Make it look like a call to the signal func.
 		// Have to pass arguments out of band since
 		// augmenting the stack frame would break
@@ -77,7 +78,7 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
 		gp->sigcode0 = info->si_code;
 		gp->sigcode1 = (uintptr)info->si_addr;
 		gp->sigpc = r->rip;
-		
+
 		// Only push runtime·sigpanic if r->rip != 0.
 		// If r->rip == 0, probably panicked because of a
 		// call to a nil func.  Not pushing that onto sp will
@@ -92,7 +93,7 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
 		r->rip = (uintptr)runtime·sigpanic;
 		return;
 	}
-	
+
 	if(info->si_code == SI_USER || (t->flags & SigNotify))
 		if(runtime·sigsend(sig))
 			return;
diff --git a/src/pkg/runtime/signal_unix.c b/src/pkg/runtime/signal_unix.c
index 1370841..0b9d2a5 100644
--- a/src/pkg/runtime/signal_unix.c
+++ b/src/pkg/runtime/signal_unix.c
@@ -55,17 +55,17 @@ void
 runtime·resetcpuprofiler(int32 hz)
 {
 	Itimerval it;
-	
+
 	runtime·memclr((byte*)&it, sizeof it);
 	if(hz == 0) {
 		runtime·setitimer(ITIMER_PROF, &it, nil);
-		runtime·setsig(SIGPROF, SIG_IGN, true);
+		runtime·setprof(false);
 	} else {
-		runtime·setsig(SIGPROF, runtime·sighandler, true);
 		it.it_interval.tv_sec = 0;
 		it.it_interval.tv_usec = 1000000 / hz;
 		it.it_value = it.it_interval;
 		runtime·setitimer(ITIMER_PROF, &it, nil);
+		runtime·setprof(true);
 	}
 	m->profilehz = hz;
 }
diff --git a/src/pkg/runtime/sys_darwin_386.s b/src/pkg/runtime/sys_darwin_386.s
index 24eac76..c2dab89 100644
--- a/src/pkg/runtime/sys_darwin_386.s
+++ b/src/pkg/runtime/sys_darwin_386.s
@@ -100,12 +100,19 @@ TEXT runtime·nanotime(SB), 7, $32
 	IMULL	$1000, BX
 	ADDL	BX, AX
 	ADCL	$0, DX
-	
+
 	MOVL	ret+0(FP), DI
 	MOVL	AX, 0(DI)
 	MOVL	DX, 4(DI)
 	RET
 
+TEXT runtime·sigprocmask(SB),7,$0
+	MOVL	$329, AX  // pthread_sigmask (on OS X, sigprocmask==entire process)
+	INT	$0x80
+	JAE	2(PC)
+	CALL	runtime·notok(SB)
+	RET
+
 TEXT runtime·sigaction(SB),7,$0
 	MOVL	$46, AX
 	INT	$0x80
diff --git a/src/pkg/runtime/sys_darwin_amd64.s b/src/pkg/runtime/sys_darwin_amd64.s
index 9d2ecbe..4b215d0 100644
--- a/src/pkg/runtime/sys_darwin_amd64.s
+++ b/src/pkg/runtime/sys_darwin_amd64.s
@@ -92,6 +92,16 @@ TEXT runtime·nanotime(SB), 7, $32
 	ADDQ	DX, AX
 	RET
 
+TEXT runtime·sigprocmask(SB),7,$0
+	MOVL	8(SP), DI
+	MOVQ	16(SP), SI
+	MOVQ	24(SP), DX
+	MOVL	$(0x2000000+329), AX  // pthread_sigmask (on OS X, sigprocmask==entire process)
+	SYSCALL
+	JCC	2(PC)
+	CALL	runtime·notok(SB)
+	RET
+
 TEXT runtime·sigaction(SB),7,$0
 	MOVL	8(SP), DI		// arg 1 sig
 	MOVQ	16(SP), SI		// arg 2 act
diff --git a/src/pkg/runtime/sys_freebsd_386.s b/src/pkg/runtime/sys_freebsd_386.s
index 0e03eac..aab4444 100644
--- a/src/pkg/runtime/sys_freebsd_386.s
+++ b/src/pkg/runtime/sys_freebsd_386.s
@@ -60,6 +60,11 @@ TEXT runtime·write(SB),7,$-4
 	INT	$0x80
 	RET
 
+TEXT runtime·getrlimit(SB),7,$-4
+	MOVL	$194, AX
+	INT	$0x80
+	RET
+
 TEXT runtime·raisesigpipe(SB),7,$12
 	// thr_self(&8(SP))
 	LEAL	8(SP), AX
diff --git a/src/pkg/runtime/sys_freebsd_amd64.s b/src/pkg/runtime/sys_freebsd_amd64.s
index 8021a42..3984ef4 100644
--- a/src/pkg/runtime/sys_freebsd_amd64.s
+++ b/src/pkg/runtime/sys_freebsd_amd64.s
@@ -65,6 +65,13 @@ TEXT runtime·write(SB),7,$-8
 	SYSCALL
 	RET
 
+TEXT runtime·getrlimit(SB),7,$-8
+	MOVL	8(SP), DI
+	MOVQ	16(SP), SI
+	MOVL	$194, AX
+	SYSCALL
+	RET
+
 TEXT runtime·raisesigpipe(SB),7,$16
 	// thr_self(&8(SP))
 	LEAQ	8(SP), DI	// arg 1 &8(SP)
diff --git a/src/pkg/runtime/sys_linux_386.s b/src/pkg/runtime/sys_linux_386.s
index bee7854..b4cefc5 100644
--- a/src/pkg/runtime/sys_linux_386.s
+++ b/src/pkg/runtime/sys_linux_386.s
@@ -52,6 +52,13 @@ TEXT runtime·read(SB),7,$0
 	CALL	*runtime·_vdso(SB)
 	RET
 
+TEXT runtime·getrlimit(SB),7,$0
+	MOVL	$191, AX		// syscall - ugetrlimit
+	MOVL	4(SP), BX
+	MOVL	8(SP), CX
+	CALL	*runtime·_vdso(SB)
+	RET
+
 TEXT runtime·usleep(SB),7,$8
 	MOVL	$0, DX
 	MOVL	usec+0(FP), AX
@@ -136,6 +143,18 @@ TEXT runtime·nanotime(SB), 7, $32
 	MOVL	DX, 4(DI)
 	RET
 
+TEXT runtime·rtsigprocmask(SB),7,$0
+	MOVL	$175, AX		// syscall entry
+	MOVL	4(SP), BX
+	MOVL	8(SP), CX
+	MOVL	12(SP), DX
+	MOVL	16(SP), SI
+	CALL	*runtime·_vdso(SB)
+	CMPL	AX, $0xfffff001
+	JLS	2(PC)
+	INT $3
+	RET
+
 TEXT runtime·rt_sigaction(SB),7,$0
 	MOVL	$174, AX		// syscall - rt_sigaction
 	MOVL	4(SP), BX
diff --git a/src/pkg/runtime/sys_linux_amd64.s b/src/pkg/runtime/sys_linux_amd64.s
index 68c2bf0..0de5b2a 100644
--- a/src/pkg/runtime/sys_linux_amd64.s
+++ b/src/pkg/runtime/sys_linux_amd64.s
@@ -50,6 +50,13 @@ TEXT runtime·read(SB),7,$0-24
 	SYSCALL
 	RET
 
+TEXT runtime·getrlimit(SB),7,$0-24
+	MOVL	8(SP), DI
+	MOVQ	16(SP), SI
+	MOVL	$97, AX			// syscall entry
+	SYSCALL
+	RET
+
 TEXT runtime·usleep(SB),7,$16
 	MOVL	$0, DX
 	MOVL	usec+0(FP), AX
@@ -123,6 +130,18 @@ TEXT runtime·nanotime(SB), 7, $32
 	ADDQ	DX, AX
 	RET
 
+TEXT runtime·rtsigprocmask(SB),7,$0-32
+	MOVL	8(SP), DI
+	MOVQ	16(SP), SI
+	MOVQ	24(SP), DX
+	MOVL	32(SP), R10
+	MOVL	$14, AX			// syscall entry
+	SYSCALL
+	CMPQ	AX, $0xfffffffffffff001
+	JLS	2(PC)
+	CALL	runtime·notok(SB)
+	RET
+
 TEXT runtime·rt_sigaction(SB),7,$0-32
 	MOVL	8(SP), DI
 	MOVQ	16(SP), SI
diff --git a/src/pkg/runtime/sys_linux_arm.s b/src/pkg/runtime/sys_linux_arm.s
index 8f30bff..439df3a 100644
--- a/src/pkg/runtime/sys_linux_arm.s
+++ b/src/pkg/runtime/sys_linux_arm.s
@@ -8,10 +8,7 @@
 
 #include "zasm_GOOS_GOARCH.h"
 
-// OABI
-//#define SYS_BASE 0x00900000
-
-// EABI
+// for EABI, as we don't support OABI
 #define SYS_BASE 0x0
 
 #define SYS_exit (SYS_BASE + 1)
@@ -23,6 +20,7 @@
 #define SYS_clone (SYS_BASE + 120)
 #define SYS_rt_sigreturn (SYS_BASE + 173)
 #define SYS_rt_sigaction (SYS_BASE + 174)
+#define SYS_rt_sigprocmask (SYS_BASE + 175)
 #define SYS_sigaltstack (SYS_BASE + 186)
 #define SYS_mmap2 (SYS_BASE + 192)
 #define SYS_futex (SYS_BASE + 240)
@@ -35,10 +33,16 @@
 #define SYS_tkill (SYS_BASE + 238)
 #define SYS_sched_yield (SYS_BASE + 158)
 #define SYS_select (SYS_BASE + 142) // newselect
+#define SYS_ugetrlimit (SYS_BASE + 191)
 
 #define ARM_BASE (SYS_BASE + 0x0f0000)
 #define SYS_ARM_cacheflush (ARM_BASE + 2)
 
+TEXT notok<>(SB),7,$0
+	MOVW	$0, R9
+	MOVW	R9, (R9)
+	B   	0(PC)
+
 TEXT runtime·open(SB),7,$0
 	MOVW	0(FP), R0
 	MOVW	4(FP), R1
@@ -69,6 +73,13 @@ TEXT runtime·read(SB),7,$0
 	SWI	$0
 	RET
 
+TEXT runtime·getrlimit(SB),7,$0
+	MOVW	0(FP), R0
+	MOVW	4(FP), R1
+	MOVW	$SYS_ugetrlimit, R7
+	SWI	$0
+	RET
+
 TEXT runtime·exit(SB),7,$-4
 	MOVW	0(FP), R0
 	MOVW	$SYS_exit_group, R7
@@ -103,6 +114,9 @@ TEXT runtime·mmap(SB),7,$0
 	MOVW	20(FP), R5
 	MOVW	$SYS_mmap2, R7
 	SWI	$0
+	MOVW	$0xfffff001, R6
+	CMP		R6, R0
+	RSB.HI	$0, R0
 	RET
 
 TEXT runtime·munmap(SB),7,$0
@@ -110,6 +124,9 @@ TEXT runtime·munmap(SB),7,$0
 	MOVW	4(FP), R1
 	MOVW	$SYS_munmap, R7
 	SWI	$0
+	MOVW	$0xfffff001, R6
+	CMP 	R6, R0
+	BL.HI	notok<>(SB)
 	RET
 
 TEXT runtime·madvise(SB),7,$0
@@ -118,6 +135,9 @@ TEXT runtime·madvise(SB),7,$0
 	MOVW	8(FP), R2
 	MOVW	$SYS_madvise, R7
 	SWI	$0
+	MOVW	$0xfffff001, R6
+	CMP 	R6, R0
+	BL.HI	notok<>(SB)
 	RET
 
 TEXT runtime·setitimer(SB),7,$0
@@ -269,6 +289,9 @@ TEXT runtime·sigaltstack(SB),7,$0
 	MOVW	4(FP), R1
 	MOVW	$SYS_sigaltstack, R7
 	SWI	$0
+	MOVW	$0xfffff001, R6
+	CMP 	R6, R0
+	BL.HI	notok<>(SB)
 	RET
 
 TEXT runtime·sigtramp(SB),7,$24
@@ -292,6 +315,15 @@ TEXT runtime·sigtramp(SB),7,$24
 
 	RET
 
+TEXT runtime·rtsigprocmask(SB),7,$0
+	MOVW	0(FP), R0
+	MOVW	4(FP), R1
+	MOVW	8(FP), R2
+	MOVW	12(FP), R3
+	MOVW	$SYS_rt_sigprocmask, R7
+	SWI	$0
+	RET
+
 TEXT runtime·rt_sigaction(SB),7,$0
 	MOVW	0(FP), R0
 	MOVW	4(FP), R1
@@ -323,8 +355,8 @@ TEXT runtime·usleep(SB),7,$12
 	SWI	$0
 	RET
 
-// Use kernel version instead of native armcas in ../../arm.s.
-// See ../../../sync/atomic/asm_linux_arm.s for details.
+// Use kernel version instead of native armcas in asm_arm.s.
+// See ../sync/atomic/asm_linux_arm.s for details.
 TEXT cas<>(SB),7,$0
 	MOVW	$0xffff0fc0, PC
 
diff --git a/src/pkg/runtime/thread_darwin.c b/src/pkg/runtime/thread_darwin.c
index 832c74b..556fb67 100644
--- a/src/pkg/runtime/thread_darwin.c
+++ b/src/pkg/runtime/thread_darwin.c
@@ -9,6 +9,10 @@
 
 extern SigTab runtime·sigtab[];
 
+static Sigset sigset_all = ~(Sigset)0;
+static Sigset sigset_none;
+static Sigset sigset_prof = 1<<(SIGPROF-1);
+
 static void
 unimplemented(int8 *name)
 {
@@ -20,7 +24,14 @@ unimplemented(int8 *name)
 int32
 runtime·semasleep(int64 ns)
 {
-	return runtime·mach_semacquire(m->waitsema, ns);
+	int32 v;
+
+	if(m->profilehz > 0)
+		runtime·setprof(false);
+	v = runtime·mach_semacquire(m->waitsema, ns);
+	if(m->profilehz > 0)
+		runtime·setprof(true);
+	return v;
 }
 
 void
@@ -70,13 +81,19 @@ void
 runtime·newosproc(M *m, G *g, void *stk, void (*fn)(void))
 {
 	int32 errno;
+	Sigset oset;
 
 	m->tls[0] = m->id;	// so 386 asm can find it
 	if(0){
 		runtime·printf("newosproc stk=%p m=%p g=%p fn=%p id=%d/%d ostk=%p\n",
 			stk, m, g, fn, m->id, m->tls[0], &m);
 	}
-	if((errno = runtime·bsdthread_create(stk, m, g, fn)) < 0) {
+
+	runtime·sigprocmask(SIG_SETMASK, &sigset_all, &oset);
+	errno = runtime·bsdthread_create(stk, m, g, fn);
+	runtime·sigprocmask(SIG_SETMASK, &oset, nil);
+
+	if(errno < 0) {
 		runtime·printf("runtime: failed to create new OS thread (have %d already; errno=%d)\n", runtime·mcount(), -errno);
 		runtime·throw("runtime.newosproc");
 	}
@@ -89,6 +106,11 @@ runtime·minit(void)
 	// Initialize signal handling.
 	m->gsignal = runtime·malg(32*1024);	// OS X wants >=8K, Linux >=2K
 	runtime·signalstack(m->gsignal->stackguard - StackGuard, 32*1024);
+
+	if(m->profilehz > 0)
+		runtime·sigprocmask(SIG_SETMASK, &sigset_none, nil);
+	else
+		runtime·sigprocmask(SIG_SETMASK, &sigset_prof, nil);
 }
 
 // Mach IPC, to get at semaphores
@@ -414,3 +436,44 @@ void
 runtime·osyield(void)
 {
 }
+
+uintptr
+runtime·memlimit(void)
+{
+	// NOTE(rsc): Could use getrlimit here,
+	// like on FreeBSD or Linux, but Darwin doesn't enforce
+	// ulimit -v, so it's unclear why we'd try to stay within
+	// the limit.
+	return 0;
+}
+
+// NOTE(rsc): On OS X, when the CPU profiling timer expires, the SIGPROF
+// signal is not guaranteed to be sent to the thread that was executing to
+// cause it to expire.  It can and often does go to a sleeping thread, which is
+// not interesting for our profile.  This is filed Apple Bug Report #9177434,
+// copied to http://code.google.com/p/go/source/detail?r=35b716c94225.
+// To work around this bug, we disable receipt of the profiling signal on
+// a thread while in blocking system calls.  This forces the kernel to deliver
+// the profiling signal to an executing thread.
+//
+// The workaround fails on OS X machines using a 64-bit Snow Leopard kernel.
+// In that configuration, the kernel appears to want to deliver SIGPROF to the
+// sleeping threads regardless of signal mask and, worse, does not deliver
+// the signal until the thread wakes up on its own.
+//
+// If necessary, we can switch to using ITIMER_REAL for OS X and handle
+// the kernel-generated SIGALRM by generating our own SIGALRMs to deliver
+// to all the running threads.  SIGALRM does not appear to be affected by
+// the 64-bit Snow Leopard bug.  However, as of this writing Mountain Lion
+// is in preview, making Snow Leopard two versions old, so it is unclear how
+// much effort we need to spend on one buggy kernel.
+
+// Control whether profiling signal can be delivered to this thread.
+void
+runtime·setprof(bool on)
+{
+	if(on)
+		runtime·sigprocmask(SIG_UNBLOCK, &sigset_prof, nil);
+	else
+		runtime·sigprocmask(SIG_BLOCK, &sigset_prof, nil);
+}
diff --git a/src/pkg/runtime/thread_freebsd.c b/src/pkg/runtime/thread_freebsd.c
index 04de037..77e8bb3 100644
--- a/src/pkg/runtime/thread_freebsd.c
+++ b/src/pkg/runtime/thread_freebsd.c
@@ -161,3 +161,37 @@ runtime·sigpanic(void)
 	}
 	runtime·panicstring(runtime·sigtab[g->sig].name);
 }
+
+uintptr
+runtime·memlimit(void)
+{
+	Rlimit rl;
+	extern byte text[], end[];
+	uintptr used;
+	
+	if(runtime·getrlimit(RLIMIT_AS, &rl) != 0)
+		return 0;
+	if(rl.rlim_cur >= 0x7fffffff)
+		return 0;
+
+	// Estimate our VM footprint excluding the heap.
+	// Not an exact science: use size of binary plus
+	// some room for thread stacks.
+	used = end - text + (64<<20);
+	if(used >= rl.rlim_cur)
+		return 0;
+
+	// If there's not at least 16 MB left, we're probably
+	// not going to be able to do much.  Treat as no limit.
+	rl.rlim_cur -= used;
+	if(rl.rlim_cur < (16<<20))
+		return 0;
+
+	return rl.rlim_cur - used;
+}
+
+void
+runtime·setprof(bool on)
+{
+	USED(on);
+}
diff --git a/src/pkg/runtime/thread_linux.c b/src/pkg/runtime/thread_linux.c
index d185741..6b42844 100644
--- a/src/pkg/runtime/thread_linux.c
+++ b/src/pkg/runtime/thread_linux.c
@@ -13,6 +13,9 @@ int32 runtime·open(uint8*, int32, int32);
 int32 runtime·close(int32);
 int32 runtime·read(int32, void*, int32);
 
+static Sigset sigset_all = { ~(uint32)0, ~(uint32)0 };
+static Sigset sigset_none;
+
 // Linux futex.
 //
 //	futexsleep(uint32 *addr, uint32 val)
@@ -135,6 +138,7 @@ runtime·newosproc(M *m, G *g, void *stk, void (*fn)(void))
 {
 	int32 ret;
 	int32 flags;
+	Sigset oset;
 
 	/*
 	 * note: strace gets confused if we use CLONE_PTRACE here.
@@ -152,7 +156,13 @@ runtime·newosproc(M *m, G *g, void *stk, void (*fn)(void))
 			stk, m, g, fn, runtime·clone, m->id, m->tls[0], &m);
 	}
 
-	if((ret = runtime·clone(flags, stk, m, g, fn)) < 0) {
+	// Disable signals during clone, so that the new thread starts
+	// with signals disabled.  It will enable them in minit.
+	runtime·rtsigprocmask(SIG_SETMASK, &sigset_all, &oset, sizeof oset);
+	ret = runtime·clone(flags, stk, m, g, fn);
+	runtime·rtsigprocmask(SIG_SETMASK, &oset, nil, sizeof oset);
+
+	if(ret < 0) {
 		runtime·printf("runtime: failed to create new OS thread (have %d already; errno=%d)\n", runtime·mcount(), -ret);
 		runtime·throw("runtime.newosproc");
 	}
@@ -177,6 +187,7 @@ runtime·minit(void)
 	// Initialize signal handling.
 	m->gsignal = runtime·malg(32*1024);	// OS X wants >=8K, Linux >=2K
 	runtime·signalstack(m->gsignal->stackguard - StackGuard, 32*1024);
+	runtime·rtsigprocmask(SIG_SETMASK, &sigset_none, nil, sizeof sigset_none);
 }
 
 void
@@ -210,3 +221,37 @@ runtime·sigpanic(void)
 	}
 	runtime·panicstring(runtime·sigtab[g->sig].name);
 }
+
+uintptr
+runtime·memlimit(void)
+{
+	Rlimit rl;
+	extern byte text[], end[];
+	uintptr used;
+
+	if(runtime·getrlimit(RLIMIT_AS, &rl) != 0)
+		return 0;
+	if(rl.rlim_cur >= 0x7fffffff)
+		return 0;
+
+	// Estimate our VM footprint excluding the heap.
+	// Not an exact science: use size of binary plus
+	// some room for thread stacks.
+	used = end - text + (64<<20);
+	if(used >= rl.rlim_cur)
+		return 0;
+
+	// If there's not at least 16 MB left, we're probably
+	// not going to be able to do much.  Treat as no limit.
+	rl.rlim_cur -= used;
+	if(rl.rlim_cur < (16<<20))
+		return 0;
+
+	return rl.rlim_cur - used;
+}
+
+void
+runtime·setprof(bool on)
+{
+	USED(on);
+}
diff --git a/src/pkg/runtime/thread_netbsd.c b/src/pkg/runtime/thread_netbsd.c
index cba7ade..62e133c 100644
--- a/src/pkg/runtime/thread_netbsd.c
+++ b/src/pkg/runtime/thread_netbsd.c
@@ -201,3 +201,15 @@ runtime·sigpanic(void)
 	}
 	runtime·panicstring(runtime·sigtab[g->sig].name);
 }
+
+uintptr
+runtime·memlimit(void)
+{
+	return 0;
+}
+
+void
+runtime·setprof(bool on)
+{
+	USED(on);
+}
diff --git a/src/pkg/runtime/thread_openbsd.c b/src/pkg/runtime/thread_openbsd.c
index efe03e3..bee0c57 100644
--- a/src/pkg/runtime/thread_openbsd.c
+++ b/src/pkg/runtime/thread_openbsd.c
@@ -201,3 +201,15 @@ runtime·sigpanic(void)
 	}
 	runtime·panicstring(runtime·sigtab[g->sig].name);
 }
+
+uintptr
+runtime·memlimit(void)
+{
+	return 0;
+}
+
+void
+runtime·setprof(bool on)
+{
+	USED(on);
+}
diff --git a/src/pkg/runtime/thread_plan9.c b/src/pkg/runtime/thread_plan9.c
index 1180fc8..aaed505 100644
--- a/src/pkg/runtime/thread_plan9.c
+++ b/src/pkg/runtime/thread_plan9.c
@@ -87,7 +87,7 @@ runtime·nanotime(void)
 	// The naïve implementation (without the cached
 	// file descriptor) is roughly four times slower
 	// in 9vx on a 2.16 GHz Intel Core 2 Duo.
-	
+
 	if(fd < 0 && (fd = runtime·open((byte*)"/dev/bintime", OREAD|OCEXEC)) < 0)
 		return 0;
 	if(runtime·pread(fd, b, sizeof b, 0) != sizeof b)
@@ -235,3 +235,15 @@ runtime·write(int32 fd, void *buf, int32 nbytes)
 {
 	return runtime·pwrite(fd, buf, nbytes, -1LL);
 }
+
+uintptr
+runtime·memlimit(void)
+{
+	return 0;
+}
+
+void
+runtime·setprof(bool on)
+{
+	USED(on);
+}
diff --git a/src/pkg/runtime/thread_windows.c b/src/pkg/runtime/thread_windows.c
index fb3f39d..8a448bc 100644
--- a/src/pkg/runtime/thread_windows.c
+++ b/src/pkg/runtime/thread_windows.c
@@ -226,7 +226,7 @@ void
 time·now(int64 sec, int32 usec)
 {
 	int64 ns;
-	
+
 	ns = runtime·nanotime();
 	sec = ns / 1000000000LL;
 	usec = ns - sec * 1000000000LL;
@@ -425,3 +425,15 @@ os·sigpipe(void)
 {
 	runtime·throw("too many writes on closed pipe");
 }
+
+uintptr
+runtime·memlimit(void)
+{
+	return 0;
+}
+
+void
+runtime·setprof(bool on)
+{
+	USED(on);
+}
diff --git a/src/pkg/strconv/extfloat.go b/src/pkg/strconv/extfloat.go
index 64ab84f..aa5e560 100644
--- a/src/pkg/strconv/extfloat.go
+++ b/src/pkg/strconv/extfloat.go
@@ -477,7 +477,7 @@ func (f *extFloat) ShortestDecimal(d *decimal, lower, upper *extFloat) bool {
 // all data is known with a error estimate of ulpBinary*ε.
 func adjustLastDigit(d *decimal, currentDiff, targetDiff, maxDiff, ulpDecimal, ulpBinary uint64) bool {
 	if ulpDecimal < 2*ulpBinary {
-		// Appromixation is too wide.
+		// Approximation is too wide.
 		return false
 	}
 	for currentDiff+ulpDecimal/2+ulpBinary < targetDiff {
diff --git a/src/pkg/strings/example_test.go b/src/pkg/strings/example_test.go
index 0b58341..daeb85e 100644
--- a/src/pkg/strings/example_test.go
+++ b/src/pkg/strings/example_test.go
@@ -41,6 +41,7 @@ func ExampleContainsAny() {
 func ExampleCount() {
 	fmt.Println(strings.Count("cheese", "e"))
 	fmt.Println(strings.Count("five", "")) // before & after each rune
+
 	// Output:
 	// 3
 	// 5
diff --git a/src/pkg/sync/example_test.go b/src/pkg/sync/example_test.go
index 1424b1e..1564924 100644
--- a/src/pkg/sync/example_test.go
+++ b/src/pkg/sync/example_test.go
@@ -5,6 +5,7 @@
 package sync_test
 
 import (
+	"fmt"
 	"net/http"
 	"sync"
 )
@@ -32,3 +33,22 @@ func ExampleWaitGroup() {
 	// Wait for all HTTP fetches to complete.
 	wg.Wait()
 }
+
+func ExampleOnce() {
+	var once sync.Once
+	onceBody := func() {
+		fmt.Printf("Only once\n")
+	}
+	done := make(chan bool)
+	for i := 0; i < 10; i++ {
+		go func() {
+			once.Do(onceBody)
+			done <- true
+		}()
+	}
+	for i := 0; i < 10; i++ {
+		<-done
+	}
+	// Output:
+	// Only once
+}
diff --git a/src/pkg/sync/waitgroup.go b/src/pkg/sync/waitgroup.go
index 3e7d9d3..0165b1f 100644
--- a/src/pkg/sync/waitgroup.go
+++ b/src/pkg/sync/waitgroup.go
@@ -11,21 +11,6 @@ import "sync/atomic"
 // goroutines to wait for.  Then each of the goroutines
 // runs and calls Done when finished.  At the same time,
 // Wait can be used to block until all goroutines have finished.
-//
-// For example:
-//
-//   for i := 0; i < n; i++ {
-//       if !condition(i) {
-//           continue
-//       }
-//       wg.Add(1)
-//       go func() {
-//           // Do something.
-//           wg.Done()
-//       }()
-//   }
-//   wg.Wait()
-// 
 type WaitGroup struct {
 	m       Mutex
 	counter int32
diff --git a/src/pkg/syscall/exec_plan9.go b/src/pkg/syscall/exec_plan9.go
index c6c975c..7e4e180 100644
--- a/src/pkg/syscall/exec_plan9.go
+++ b/src/pkg/syscall/exec_plan9.go
@@ -71,13 +71,13 @@ func StringSlicePtr(ss []string) []*byte {
 	return bb
 }
 
-// gbit16 reads a 16-bit numeric value from a 9P protocol message strored in b,
+// gbit16 reads a 16-bit numeric value from a 9P protocol message stored in b,
 // returning the value and the remaining slice of b.
 func gbit16(b []byte) (uint16, []byte) {
 	return uint16(b[0]) | uint16(b[1])<<8, b[2:]
 }
 
-// gstring reads a string from a 9P protocol message strored in b,
+// gstring reads a string from a 9P protocol message stored in b,
 // returning the value as a Go string and the remaining slice of b.
 func gstring(b []byte) (string, []byte) {
 	n, b := gbit16(b)
diff --git a/src/pkg/syscall/syscall_windows.go b/src/pkg/syscall/syscall_windows.go
index fde3bef..7c82932 100644
--- a/src/pkg/syscall/syscall_windows.go
+++ b/src/pkg/syscall/syscall_windows.go
@@ -151,6 +151,7 @@ func NewCallback(fn interface{}) uintptr
 //sys	GetExitCodeProcess(handle Handle, exitcode *uint32) (err error)
 //sys	GetStartupInfo(startupInfo *StartupInfo) (err error) = GetStartupInfoW
 //sys	GetCurrentProcess() (pseudoHandle Handle, err error)
+//sys	GetProcessTimes(handle Handle, creationTime *Filetime, exitTime *Filetime, kernelTime *Filetime, userTime *Filetime) (err error)
 //sys	DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetProcessHandle Handle, lpTargetHandle *Handle, dwDesiredAccess uint32, bInheritHandle bool, dwOptions uint32) (err error)
 //sys	WaitForSingleObject(handle Handle, waitMilliseconds uint32) (event uint32, err error) [failretval==0xffffffff]
 //sys	GetTempPath(buflen uint32, buf *uint16) (n uint32, err error) = GetTempPathW
@@ -601,10 +602,14 @@ func WSASendto(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32
 }
 
 // Invented structures to support what package os expects.
-type Rusage struct{}
+type Rusage struct {
+	CreationTime Filetime
+	ExitTime     Filetime
+	KernelTime   Filetime
+	UserTime     Filetime
+}
 
 type WaitStatus struct {
-	Status   uint32
 	ExitCode uint32
 }
 
diff --git a/src/pkg/syscall/zsyscall_windows_386.go b/src/pkg/syscall/zsyscall_windows_386.go
index 0209463..8b1a6db 100644
--- a/src/pkg/syscall/zsyscall_windows_386.go
+++ b/src/pkg/syscall/zsyscall_windows_386.go
@@ -55,6 +55,7 @@ var (
 	procGetExitCodeProcess          = modkernel32.NewProc("GetExitCodeProcess")
 	procGetStartupInfoW             = modkernel32.NewProc("GetStartupInfoW")
 	procGetCurrentProcess           = modkernel32.NewProc("GetCurrentProcess")
+	procGetProcessTimes             = modkernel32.NewProc("GetProcessTimes")
 	procDuplicateHandle             = modkernel32.NewProc("DuplicateHandle")
 	procWaitForSingleObject         = modkernel32.NewProc("WaitForSingleObject")
 	procGetTempPathW                = modkernel32.NewProc("GetTempPathW")
@@ -597,6 +598,18 @@ func GetCurrentProcess() (pseudoHandle Handle, err error) {
 	return
 }
 
+func GetProcessTimes(handle Handle, creationTime *Filetime, exitTime *Filetime, kernelTime *Filetime, userTime *Filetime) (err error) {
+	r1, _, e1 := Syscall6(procGetProcessTimes.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(creationTime)), uintptr(unsafe.Pointer(exitTime)), uintptr(unsafe.Pointer(kernelTime)), uintptr(unsafe.Pointer(userTime)), 0)
+	if int(r1) == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
 func DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetProcessHandle Handle, lpTargetHandle *Handle, dwDesiredAccess uint32, bInheritHandle bool, dwOptions uint32) (err error) {
 	var _p0 uint32
 	if bInheritHandle {
diff --git a/src/pkg/syscall/zsyscall_windows_amd64.go b/src/pkg/syscall/zsyscall_windows_amd64.go
index 95b8b36..9d9990d 100644
--- a/src/pkg/syscall/zsyscall_windows_amd64.go
+++ b/src/pkg/syscall/zsyscall_windows_amd64.go
@@ -55,6 +55,7 @@ var (
 	procGetExitCodeProcess          = modkernel32.NewProc("GetExitCodeProcess")
 	procGetStartupInfoW             = modkernel32.NewProc("GetStartupInfoW")
 	procGetCurrentProcess           = modkernel32.NewProc("GetCurrentProcess")
+	procGetProcessTimes             = modkernel32.NewProc("GetProcessTimes")
 	procDuplicateHandle             = modkernel32.NewProc("DuplicateHandle")
 	procWaitForSingleObject         = modkernel32.NewProc("WaitForSingleObject")
 	procGetTempPathW                = modkernel32.NewProc("GetTempPathW")
@@ -597,6 +598,18 @@ func GetCurrentProcess() (pseudoHandle Handle, err error) {
 	return
 }
 
+func GetProcessTimes(handle Handle, creationTime *Filetime, exitTime *Filetime, kernelTime *Filetime, userTime *Filetime) (err error) {
+	r1, _, e1 := Syscall6(procGetProcessTimes.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(creationTime)), uintptr(unsafe.Pointer(exitTime)), uintptr(unsafe.Pointer(kernelTime)), uintptr(unsafe.Pointer(userTime)), 0)
+	if int(r1) == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
 func DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetProcessHandle Handle, lpTargetHandle *Handle, dwDesiredAccess uint32, bInheritHandle bool, dwOptions uint32) (err error) {
 	var _p0 uint32
 	if bInheritHandle {
diff --git a/src/pkg/syscall/ztypes_windows.go b/src/pkg/syscall/ztypes_windows.go
index 5a7a50c..e4881e5 100644
--- a/src/pkg/syscall/ztypes_windows.go
+++ b/src/pkg/syscall/ztypes_windows.go
@@ -252,6 +252,8 @@ type Filetime struct {
 	HighDateTime uint32
 }
 
+// Nanoseconds returns Filetime ft in nanoseconds
+// since Epoch (00:00:00 UTC, January 1, 1970).
 func (ft *Filetime) Nanoseconds() int64 {
 	// 100-nanosecond intervals since January 1, 1601
 	nsec := int64(ft.HighDateTime)<<32 + int64(ft.LowDateTime)
diff --git a/src/pkg/testing/example.go b/src/pkg/testing/example.go
index 7f8ff2d..671c798 100644
--- a/src/pkg/testing/example.go
+++ b/src/pkg/testing/example.go
@@ -19,7 +19,7 @@ type InternalExample struct {
 	Output string
 }
 
-func RunExamples(examples []InternalExample) (ok bool) {
+func RunExamples(matchString func(pat, str string) (bool, error), examples []InternalExample) (ok bool) {
 	ok = true
 
 	var eg InternalExample
@@ -27,6 +27,14 @@ func RunExamples(examples []InternalExample) (ok bool) {
 	stdout, stderr := os.Stdout, os.Stderr
 
 	for _, eg = range examples {
+		matched, err := matchString(*match, eg.Name)
+		if err != nil {
+			fmt.Fprintf(os.Stderr, "testing: invalid regexp for -test.run: %s\n", err)
+			os.Exit(1)
+		}
+		if !matched {
+			continue
+		}
 		if *chatty {
 			fmt.Printf("=== RUN: %s\n", eg.Name)
 		}
diff --git a/src/pkg/testing/testing.go b/src/pkg/testing/testing.go
index adc8c09..477d2ac 100644
--- a/src/pkg/testing/testing.go
+++ b/src/pkg/testing/testing.go
@@ -99,7 +99,7 @@ var (
 
 	// Report as tests are run; default is silent for success.
 	chatty         = flag.Bool("test.v", false, "verbose: print additional output")
-	match          = flag.String("test.run", "", "regular expression to select tests to run")
+	match          = flag.String("test.run", "", "regular expression to select tests and examples to run")
 	memProfile     = flag.String("test.memprofile", "", "write a memory profile to the named file after execution")
 	memProfileRate = flag.Int("test.memprofilerate", 0, "if >=0, sets runtime.MemProfileRate")
 	cpuProfile     = flag.String("test.cpuprofile", "", "write a cpu profile to the named file during execution")
@@ -280,7 +280,7 @@ func Main(matchString func(pat, str string) (bool, error), tests []InternalTest,
 	before()
 	startAlarm()
 	testOk := RunTests(matchString, tests)
-	exampleOk := RunExamples(examples)
+	exampleOk := RunExamples(matchString, examples)
 	if !testOk || !exampleOk {
 		fmt.Println("FAIL")
 		os.Exit(1)
diff --git a/src/pkg/text/template/doc.go b/src/pkg/text/template/doc.go
index ae91f4a..10e0f7f 100644
--- a/src/pkg/text/template/doc.go
+++ b/src/pkg/text/template/doc.go
@@ -142,11 +142,6 @@ An argument is a simple value, denoted by one of the following.
 	    .Field1.Key1.Method1.Field2.Key2.Method2
 	  Methods can also be evaluated on variables, including chaining:
 	    $x.Method1.Field
-	- The name of a niladic function-valued struct field of the data,
-	  preceded by a period, such as
-		.Function
-	  Function-valued fields behave like methods (of structs) but do not
-	  pass a receiver.
 	- The name of a niladic function, such as
 		fun
 	  The result is the value of invoking the function, fun(). The return
@@ -155,6 +150,10 @@ An argument is a simple value, denoted by one of the following.
 
 Arguments may evaluate to any type; if they are pointers the implementation
 automatically indirects to the base type when required.
+If an evaluation yields a function value, such as a function-valued
+field of a struct, the function is not invoked automatically, but it
+can be used as a truth value for an if action and the like. To invoke
+it, use the call function, defined below.
 
 A pipeline is a possibly chained sequence of "commands". A command is a simple
 value (argument) or a function or method call, possibly with multiple arguments:
@@ -167,9 +166,6 @@ value (argument) or a function or method call, possibly with multiple arguments:
 		The result is the value of calling the method with the
 		arguments:
 			dot.Method(Argument1, etc.)
-	.Function [Argument...]
-		A function-valued field of a struct works like a method but does
-		not pass the receiver.
 	functionName [Argument...]
 		The result is the value of calling the function associated
 		with the name:
@@ -257,6 +253,17 @@ Predefined global functions are named as follows.
 		first empty argument or the last argument, that is,
 		"and x y" behaves as "if x then y else x". All the
 		arguments are evaluated.
+	call
+		Returns the result of calling the first argument, which
+		must be a function, with the remaining arguments as parameters.
+		Thus "call .X.Y 1 2" is, in Go notation, dot.X.Y(1, 2) where
+		Y is a func-valued field, map entry, or the like.
+		The first argument must be the result of an evaluation
+		that yields a value of function type (as distinct from
+		a predefined function such as print). The function must
+		return either one or two result values, the second of which
+		is of type error. If the arguments don't match the function
+		or the returned error value is non-nil, execution stops.
 	html
 		Returns the escaped HTML equivalent of the textual
 		representation of its arguments.
diff --git a/src/pkg/text/template/examplefiles_test.go b/src/pkg/text/template/examplefiles_test.go
new file mode 100644
index 0000000..a15c7a6
--- /dev/null
+++ b/src/pkg/text/template/examplefiles_test.go
@@ -0,0 +1,182 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package template_test
+
+import (
+	"io"
+	"io/ioutil"
+	"log"
+	"os"
+	"path/filepath"
+	"text/template"
+)
+
+// templateFile defines the contents of a template to be stored in a file, for testing.
+type templateFile struct {
+	name     string
+	contents string
+}
+
+func createTestDir(files []templateFile) string {
+	dir, err := ioutil.TempDir("", "template")
+	if err != nil {
+		log.Fatal(err)
+	}
+	for _, file := range files {
+		f, err := os.Create(filepath.Join(dir, file.name))
+		if err != nil {
+			log.Fatal(err)
+		}
+		defer f.Close()
+		_, err = io.WriteString(f, file.contents)
+		if err != nil {
+			log.Fatal(err)
+		}
+	}
+	return dir
+}
+
+// Here we demonstrate loading a set of templates from a directory.
+func ExampleTemplate_glob() {
+	// Here we create a temporary directory and populate it with our sample
+	// template definition files; usually the template files would already
+	// exist in some location known to the program.
+	dir := createTestDir([]templateFile{
+		// T0.tmpl is a plain template file that just invokes T1.
+		{"T0.tmpl", `T0 invokes T1: ({{template "T1"}})`},
+		// T1.tmpl defines a template, T1 that invokes T2.
+		{"T1.tmpl", `{{define "T1"}}T1 invokes T2: ({{template "T2"}}){{end}}`},
+		// T2.tmpl defines a template T2.
+		{"T2.tmpl", `{{define "T2"}}This is T2{{end}}`},
+	})
+	// Clean up after the test; another quirk of running as an example.
+	defer os.RemoveAll(dir)
+
+	// pattern is the glob pattern used to find all the template files.
+	pattern := filepath.Join(dir, "*.tmpl")
+
+	// Here starts the example proper.
+	// T0.tmpl is the first name matched, so it becomes the starting template,
+	// the value returned by ParseGlob.
+	tmpl := template.Must(template.ParseGlob(pattern))
+
+	err := tmpl.Execute(os.Stdout, nil)
+	if err != nil {
+		log.Fatalf("template execution: %s", err)
+	}
+	// Output:
+	// T0 invokes T1: (T1 invokes T2: (This is T2))
+}
+
+// This example demonstrates one way to share some templates
+// and use them in different contexts. In this variant we add multiple driver
+// templates by hand to an existing bundle of templates.
+func ExampleTemplate_helpers() {
+	// Here we create a temporary directory and populate it with our sample
+	// template definition files; usually the template files would already
+	// exist in some location known to the program.
+	dir := createTestDir([]templateFile{
+		// T1.tmpl defines a template, T1 that invokes T2.
+		{"T1.tmpl", `{{define "T1"}}T1 invokes T2: ({{template "T2"}}){{end}}`},
+		// T2.tmpl defines a template T2.
+		{"T2.tmpl", `{{define "T2"}}This is T2{{end}}`},
+	})
+	// Clean up after the test; another quirk of running as an example.
+	defer os.RemoveAll(dir)
+
+	// pattern is the glob pattern used to find all the template files.
+	pattern := filepath.Join(dir, "*.tmpl")
+
+	// Here starts the example proper.
+	// Load the helpers.
+	templates := template.Must(template.ParseGlob(pattern))
+	// Add one driver template to the bunch; we do this with an explicit template definition.
+	_, err := templates.Parse("{{define `driver1`}}Driver 1 calls T1: ({{template `T1`}})\n{{end}}")
+	if err != nil {
+		log.Fatal("parsing driver1: ", err)
+	}
+	// Add another driver template.
+	_, err = templates.Parse("{{define `driver2`}}Driver 2 calls T2: ({{template `T2`}})\n{{end}}")
+	if err != nil {
+		log.Fatal("parsing driver2: ", err)
+	}
+	// We load all the templates before execution. This package does not require
+	// that behavior but html/template's escaping does, so it's a good habit.
+	err = templates.ExecuteTemplate(os.Stdout, "driver1", nil)
+	if err != nil {
+		log.Fatalf("driver1 execution: %s", err)
+	}
+	err = templates.ExecuteTemplate(os.Stdout, "driver2", nil)
+	if err != nil {
+		log.Fatalf("driver2 execution: %s", err)
+	}
+	// Output:
+	// Driver 1 calls T1: (T1 invokes T2: (This is T2))
+	// Driver 2 calls T2: (This is T2)
+}
+
+// This example demonstrates how to use one group of driver
+// templates with distinct sets of helper templates.
+func ExampleTemplate_share() {
+	// Here we create a temporary directory and populate it with our sample
+	// template definition files; usually the template files would already
+	// exist in some location known to the program.
+	dir := createTestDir([]templateFile{
+		// T0.tmpl is a plain template file that just invokes T1.
+		{"T0.tmpl", "T0 ({{.}} version) invokes T1: ({{template `T1`}})\n"},
+		// T1.tmpl defines a template, T1 that invokes T2. Note T2 is not defined
+		{"T1.tmpl", `{{define "T1"}}T1 invokes T2: ({{template "T2"}}){{end}}`},
+	})
+	// Clean up after the test; another quirk of running as an example.
+	defer os.RemoveAll(dir)
+
+	// pattern is the glob pattern used to find all the template files.
+	pattern := filepath.Join(dir, "*.tmpl")
+
+	// Here starts the example proper.
+	// Load the drivers.
+	drivers := template.Must(template.ParseGlob(pattern))
+
+	// We must define an implementation of the T2 template. First we clone
+	// the drivers, then add a definition of T2 to the template name space.
+
+	// 1. Clone the helper set to create a new name space from which to run them.
+	first, err := drivers.Clone()
+	if err != nil {
+		log.Fatal("cloning helpers: ", err)
+	}
+	// 2. Define T2, version A, and parse it.
+	_, err = first.Parse("{{define `T2`}}T2, version A{{end}}")
+	if err != nil {
+		log.Fatal("parsing T2: ", err)
+	}
+
+	// Now repeat the whole thing, using a different version of T2.
+	// 1. Clone the drivers.
+	second, err := drivers.Clone()
+	if err != nil {
+		log.Fatal("cloning drivers: ", err)
+	}
+	// 2. Define T2, version B, and parse it.
+	_, err = second.Parse("{{define `T2`}}T2, version B{{end}}")
+	if err != nil {
+		log.Fatal("parsing T2: ", err)
+	}
+
+	// Execute the templates in the reverse order to verify the
+	// first is unaffected by the second.
+	err = second.ExecuteTemplate(os.Stdout, "T0.tmpl", "second")
+	if err != nil {
+		log.Fatalf("second execution: %s", err)
+	}
+	err = first.ExecuteTemplate(os.Stdout, "T0.tmpl", "first")
+	if err != nil {
+		log.Fatalf("first: execution: %s", err)
+	}
+
+	// Output:
+	// T0 (second version) invokes T1: (T1 invokes T2: (T2, version B))
+	// T0 (first version) invokes T1: (T1 invokes T2: (T2, version A))
+}
diff --git a/src/pkg/text/template/examplefunc_test.go b/src/pkg/text/template/examplefunc_test.go
new file mode 100644
index 0000000..080b5e3
--- /dev/null
+++ b/src/pkg/text/template/examplefunc_test.go
@@ -0,0 +1,54 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package template_test
+
+import (
+	"log"
+	"os"
+	"strings"
+	"text/template"
+)
+
+// This example demonstrates a custom function to process template text.
+// It installs the strings.Title function and uses it to
+// Make Title Text Look Good In Our Template's Output.
+func ExampleTemplate_func() {
+	// First we create a FuncMap with which to register the function.
+	funcMap := template.FuncMap{
+		// The name "title" is what the function will be called in the template text.
+		"title": strings.Title,
+	}
+
+	// A simple template definition to test our function.
+	// We print the input text several ways:
+	// - the original
+	// - title-cased
+	// - title-cased and then printed with %q
+	// - printed with %q and then title-cased.
+	const templateText = `
+Input: {{printf "%q" .}}
+Output 0: {{title .}}
+Output 1: {{title . | printf "%q"}}
+Output 2: {{printf "%q" . | title}}
+`
+
+	// Create a template, add the function map, and parse the text.
+	tmpl, err := template.New("titleTest").Funcs(funcMap).Parse(templateText)
+	if err != nil {
+		log.Fatalf("parsing: %s", err)
+	}
+
+	// Run the template to verify the output.
+	err = tmpl.Execute(os.Stdout, "the go programming language")
+	if err != nil {
+		log.Fatalf("execution: %s", err)
+	}
+
+	// Output:
+	// Input: "the go programming language"
+	// Output 0: The Go Programming Language
+	// Output 1: "The Go Programming Language"
+	// Output 2: "The Go Programming Language"
+}
diff --git a/src/pkg/text/template/exec.go b/src/pkg/text/template/exec.go
index af74528..ad0118e 100644
--- a/src/pkg/text/template/exec.go
+++ b/src/pkg/text/template/exec.go
@@ -421,11 +421,8 @@ func (s *state) evalField(dot reflect.Value, fieldName string, args []parse.Node
 			field := receiver.FieldByIndex(tField.Index)
 			if tField.PkgPath == "" { // field is exported
 				// If it's a function, we must call it.
-				if field.Type().Kind() == reflect.Func {
-					return s.evalCall(dot, field, fieldName, args, final)
-				}
 				if hasArgs {
-					s.errorf("%s is not a method or function but has arguments", fieldName)
+					s.errorf("%s has arguments but cannot be invoked as function", fieldName)
 				}
 				return field
 			}
diff --git a/src/pkg/text/template/exec_test.go b/src/pkg/text/template/exec_test.go
index 159cf51..70ab39c 100644
--- a/src/pkg/text/template/exec_test.go
+++ b/src/pkg/text/template/exec_test.go
@@ -60,7 +60,9 @@ type T struct {
 	PSI *[]int
 	NIL *int
 	// Function (not method)
-	Func func(...string) string
+	BinaryFunc      func(string, string) string
+	VariadicFunc    func(...string) string
+	VariadicFuncInt func(int, ...string) string
 	// Template to test evaluation of templates.
 	Tmpl *Template
 }
@@ -120,7 +122,9 @@ var tVal = &T{
 	Err:               errors.New("erroozle"),
 	PI:                newInt(23),
 	PSI:               newIntSlice(21, 22, 23),
-	Func:              func(s ...string) string { return fmt.Sprint("<", strings.Join(s, "+"), ">") },
+	BinaryFunc:        func(a, b string) string { return fmt.Sprintf("[%s=%s]", a, b) },
+	VariadicFunc:      func(s ...string) string { return fmt.Sprint("<", strings.Join(s, "+"), ">") },
+	VariadicFuncInt:   func(a int, s ...string) string { return fmt.Sprint(a, "=<", strings.Join(s, "+"), ">") },
 	Tmpl:              Must(New("x").Parse("test template")), // "x" is the value of .X
 }
 
@@ -300,13 +304,26 @@ var execTests = []execTest{
 		"{{with $x := .}}{{with .SI}}{{$.GetU.TrueFalse $.True}}{{end}}{{end}}",
 		"true", tVal, true},
 
-	// Function call
-	{".Func", "-{{.Func}}-", "-<>-", tVal, true},
-	{".Func2", "-{{.Func `he` `llo`}}-", "-<he+llo>-", tVal, true},
+	// Function call builtin.
+	{".BinaryFunc", "{{call .BinaryFunc `1` `2`}}", "[1=2]", tVal, true},
+	{".VariadicFunc0", "{{call .VariadicFunc}}", "<>", tVal, true},
+	{".VariadicFunc2", "{{call .VariadicFunc `he` `llo`}}", "<he+llo>", tVal, true},
+	{".VariadicFuncInt", "{{call .VariadicFuncInt 33 `he` `llo`}}", "33=<he+llo>", tVal, true},
+	{"if .BinaryFunc call", "{{ if .BinaryFunc}}{{call .BinaryFunc `1` `2`}}{{end}}", "[1=2]", tVal, true},
+	{"if not .BinaryFunc call", "{{ if not .BinaryFunc}}{{call .BinaryFunc `1` `2`}}{{else}}No{{end}}", "No", tVal, true},
+
+	// Erroneous function calls (check args).
+	{".BinaryFuncTooFew", "{{call .BinaryFunc `1`}}", "", tVal, false},
+	{".BinaryFuncTooMany", "{{call .BinaryFunc `1` `2` `3`}}", "", tVal, false},
+	{".BinaryFuncBad0", "{{call .BinaryFunc 1 3}}", "", tVal, false},
+	{".BinaryFuncBad1", "{{call .BinaryFunc `1` 3}}", "", tVal, false},
+	{".VariadicFuncBad0", "{{call .VariadicFunc 3}}", "", tVal, false},
+	{".VariadicFuncIntBad0", "{{call .VariadicFuncInt}}", "", tVal, false},
+	{".VariadicFuncIntBad`", "{{call .VariadicFuncInt `x`}}", "", tVal, false},
 
 	// Pipelines.
 	{"pipeline", "-{{.Method0 | .Method2 .U16}}-", "-Method2: 16 M0-", tVal, true},
-	{"pipeline func", "-{{.Func `llo` | .Func `he` }}-", "-<he+<llo>>-", tVal, true},
+	{"pipeline func", "-{{call .VariadicFunc `llo` | call .VariadicFunc `he` }}-", "-<he+<llo>>-", tVal, true},
 
 	// If.
 	{"if true", "{{if true}}TRUE{{end}}", "TRUE", tVal, true},
diff --git a/src/pkg/text/template/funcs.go b/src/pkg/text/template/funcs.go
index d6e4bf1..525179c 100644
--- a/src/pkg/text/template/funcs.go
+++ b/src/pkg/text/template/funcs.go
@@ -24,6 +24,7 @@ type FuncMap map[string]interface{}
 
 var builtins = FuncMap{
 	"and":      and,
+	"call":     call,
 	"html":     HTMLEscaper,
 	"index":    index,
 	"js":       JSEscaper,
@@ -151,6 +152,53 @@ func length(item interface{}) (int, error) {
 	return 0, fmt.Errorf("len of type %s", v.Type())
 }
 
+// Function invocation
+
+// call returns the result of evaluating the the first argument as a function.
+// The function must return 1 result, or 2 results, the second of which is an error.
+func call(fn interface{}, args ...interface{}) (interface{}, error) {
+	v := reflect.ValueOf(fn)
+	typ := v.Type()
+	if typ.Kind() != reflect.Func {
+		return nil, fmt.Errorf("non-function of type %s", typ)
+	}
+	if !goodFunc(typ) {
+		return nil, fmt.Errorf("function called with %d args; should be 1 or 2", typ.NumOut())
+	}
+	numIn := typ.NumIn()
+	var dddType reflect.Type
+	if typ.IsVariadic() {
+		if len(args) < numIn-1 {
+			return nil, fmt.Errorf("wrong number of args: got %d want at least %d", len(args), numIn-1)
+		}
+		dddType = typ.In(numIn - 1).Elem()
+	} else {
+		if len(args) != numIn {
+			return nil, fmt.Errorf("wrong number of args: got %d want %d", len(args), numIn)
+		}
+	}
+	argv := make([]reflect.Value, len(args))
+	for i, arg := range args {
+		value := reflect.ValueOf(arg)
+		// Compute the expected type. Clumsy because of variadics.
+		var argType reflect.Type
+		if !typ.IsVariadic() || i < numIn-1 {
+			argType = typ.In(i)
+		} else {
+			argType = dddType
+		}
+		if !value.Type().AssignableTo(argType) {
+			return nil, fmt.Errorf("arg %d has type %s; should be %s", i, value.Type(), argType)
+		}
+		argv[i] = reflect.ValueOf(arg)
+	}
+	result := v.Call(argv)
+	if len(result) == 2 {
+		return result[0].Interface(), result[1].Interface().(error)
+	}
+	return result[0].Interface(), nil
+}
+
 // Boolean logic.
 
 func truth(a interface{}) bool {
diff --git a/src/pkg/text/template/multi_test.go b/src/pkg/text/template/multi_test.go
index f205e6b..22dedc4 100644
--- a/src/pkg/text/template/multi_test.go
+++ b/src/pkg/text/template/multi_test.go
@@ -265,6 +265,12 @@ func TestRedefinition(t *testing.T) {
 	if tmpl, err = New("tmpl1").Parse(`{{define "test"}}foo{{end}}`); err != nil {
 		t.Fatalf("parse 1: %v", err)
 	}
+	if _, err = tmpl.Parse(`{{define "test"}}bar{{end}}`); err == nil {
+		t.Fatal("expected error")
+	}
+	if !strings.Contains(err.Error(), "redefinition") {
+		t.Fatalf("expected redefinition error; got %v", err)
+	}
 	if _, err = tmpl.New("tmpl2").Parse(`{{define "test"}}bar{{end}}`); err == nil {
 		t.Fatal("expected error")
 	}
diff --git a/src/pkg/text/template/parse/parse.go b/src/pkg/text/template/parse/parse.go
index 35194f7..d67b388 100644
--- a/src/pkg/text/template/parse/parse.go
+++ b/src/pkg/text/template/parse/parse.go
@@ -193,6 +193,8 @@ func (t *Tree) add(treeSet map[string]*Tree) {
 // IsEmptyTree reports whether this tree (node) is empty of everything but space.
 func IsEmptyTree(n Node) bool {
 	switch n := n.(type) {
+	case nil:
+		return true
 	case *ActionNode:
 	case *IfNode:
 	case *ListNode:
diff --git a/src/pkg/text/template/parse/parse_test.go b/src/pkg/text/template/parse/parse_test.go
index efa7d8b..18c0a8b 100644
--- a/src/pkg/text/template/parse/parse_test.go
+++ b/src/pkg/text/template/parse/parse_test.go
@@ -287,6 +287,9 @@ var isEmptyTests = []isEmptyTest{
 }
 
 func TestIsEmpty(t *testing.T) {
+	if !IsEmptyTree(nil) {
+		t.Errorf("nil tree is not empty")
+	}
 	for _, test := range isEmptyTests {
 		tree, err := New("root").Parse(test.input, "", "", make(map[string]*Tree), nil)
 		if err != nil {
diff --git a/src/pkg/text/template/template.go b/src/pkg/text/template/template.go
index 7494f9d..82fc9e5 100644
--- a/src/pkg/text/template/template.go
+++ b/src/pkg/text/template/template.go
@@ -178,10 +178,11 @@ func (t *Template) Parse(text string) (*Template, error) {
 			tmpl = t.New(name)
 		}
 		// Even if t == tmpl, we need to install it in the common.tmpl map.
-		if err := t.associate(tmpl); err != nil {
+		if replace, err := t.associate(tmpl, tree); err != nil {
 			return nil, err
+		} else if replace {
+			tmpl.Tree = tree
 		}
-		tmpl.Tree = tree
 		tmpl.leftDelim = t.leftDelim
 		tmpl.rightDelim = t.rightDelim
 	}
@@ -191,22 +192,23 @@ func (t *Template) Parse(text string) (*Template, error) {
 // associate installs the new template into the group of templates associated
 // with t. It is an error to reuse a name except to overwrite an empty
 // template. The two are already known to share the common structure.
-func (t *Template) associate(new *Template) error {
+// The boolean return value reports wither to store this tree as t.Tree.
+func (t *Template) associate(new *Template, tree *parse.Tree) (bool, error) {
 	if new.common != t.common {
 		panic("internal error: associate not common")
 	}
 	name := new.name
 	if old := t.tmpl[name]; old != nil {
 		oldIsEmpty := parse.IsEmptyTree(old.Root)
-		newIsEmpty := new.Tree != nil && parse.IsEmptyTree(new.Root)
-		if !oldIsEmpty && !newIsEmpty {
-			return fmt.Errorf("template: redefinition of template %q", name)
-		}
+		newIsEmpty := parse.IsEmptyTree(tree.Root)
 		if newIsEmpty {
 			// Whether old is empty or not, new is empty; no reason to replace old.
-			return nil
+			return false, nil
+		}
+		if !oldIsEmpty {
+			return false, fmt.Errorf("template: redefinition of template %q", name)
 		}
 	}
 	t.tmpl[name] = new
-	return nil
+	return true, nil
 }
diff --git a/src/pkg/time/format.go b/src/pkg/time/format.go
index ef6f1f3..ad52bab 100644
--- a/src/pkg/time/format.go
+++ b/src/pkg/time/format.go
@@ -6,14 +6,6 @@ package time
 
 import "errors"
 
-const (
-	numeric = iota
-	alphabetic
-	separator
-	plus
-	minus
-)
-
 // These are predefined layouts for use in Time.Format.
 // The standard time used in the layouts is:
 //	Mon Jan 2 15:04:05 MST 2006
diff --git a/src/pkg/time/sleep_test.go b/src/pkg/time/sleep_test.go
index 9b0b7f7..526d58d 100644
--- a/src/pkg/time/sleep_test.go
+++ b/src/pkg/time/sleep_test.go
@@ -120,8 +120,11 @@ func TestAfterTick(t *testing.T) {
 	t1 := Now()
 	d := t1.Sub(t0)
 	target := Delta * Count
-	if d < target*9/10 || d > target*30/10 {
-		t.Fatalf("%d ticks of %s took %s, expected %s", Count, Delta, d, target)
+	if d < target*9/10 {
+		t.Fatalf("%d ticks of %s too fast: took %s, expected %s", Count, Delta, d, target)
+	}
+	if !testing.Short() && d > target*30/10 {
+		t.Fatalf("%d ticks of %s too slow: took %s, expected %s", Count, Delta, d, target)
 	}
 }
 
diff --git a/src/pkg/time/time.go b/src/pkg/time/time.go
index 709a422..f7ded24 100644
--- a/src/pkg/time/time.go
+++ b/src/pkg/time/time.go
@@ -152,7 +152,7 @@ func (d Weekday) String() string { return days[d] }
 // rely heavily on division and modulus by positive constants.  For
 // calendrical calculations we want these divisions to round down, even
 // for negative values, so that the remainder is always positive, but
-// Go's division (like most hardware divison instructions) rounds to
+// Go's division (like most hardware division instructions) rounds to
 // zero.  We can still do those computations and then adjust the result
 // for a negative numerator, but it's annoying to write the adjustment
 // over and over.  Instead, we can change to a different epoch so long
@@ -384,6 +384,15 @@ type Duration int64
 
 // Common durations.  There is no definition for units of Day or larger
 // to avoid confusion across daylight savings time zone transitions.
+//
+// To count the number of units in a Duration, divide:
+//	second := time.Second
+//	fmt.Print(int64(second/time.Millisecond)) // prints 1000
+//
+// To convert an integer number of units to a Duration, multiply:
+//	seconds := 10
+//	fmt.Print(time.Duration(seconds)*time.Second) // prints 10s
+//
 const (
 	Nanosecond  Duration = 1
 	Microsecond          = 1000 * Nanosecond
@@ -758,10 +767,6 @@ func (t Time) UnixNano() int64 {
 	return (t.sec+internalToUnix)*1e9 + int64(t.nsec)
 }
 
-type gobError string
-
-func (g gobError) Error() string { return string(g) }
-
 const timeGobVersion byte = 1
 
 // GobEncode implements the gob.GobEncoder interface.
diff --git a/src/run.bash b/src/run.bash
index d818751..fd3b1f2 100755
--- a/src/run.bash
+++ b/src/run.bash
@@ -72,7 +72,6 @@ $BROKEN ||
 ./test.bash
 ) || exit $?
 
-$BROKEN ||
 (xcd ../doc/progs
 time ./run
 ) || exit $?
diff --git a/test/bench/shootout/Makefile b/test/bench/shootout/Makefile
deleted file mode 100644
index e1c9b7b..0000000
--- a/test/bench/shootout/Makefile
+++ /dev/null
@@ -1,14 +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.
-
-include ../../../src/Make.inc
-
-all:
-	@echo "make clean or timing"
-
-timing:
-	./timing.sh
-
-clean:
-	rm -f [568].out *.[568]
diff --git a/test/bench/shootout/timing.sh b/test/bench/shootout/timing.sh
index 3e190e1..dd3e664 100755
--- a/test/bench/shootout/timing.sh
+++ b/test/bench/shootout/timing.sh
@@ -5,7 +5,11 @@
 
 set -e
 
-eval $(gomake --no-print-directory -f ../../../src/Make.inc go-env)
+eval $(go tool dist env)
+O=$GOCHAR
+GC="go tool ${O}g"
+LD="go tool ${O}l"
+
 PATH=.:$PATH
 
 havegccgo=false
diff --git a/test/bugs/424.dir/lib.go b/test/bugs/424.dir/lib.go
new file mode 100644
index 0000000..97054da
--- /dev/null
+++ b/test/bugs/424.dir/lib.go
@@ -0,0 +1,16 @@
+// Copyright 2012 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package lib
+
+type I interface {
+	m() string
+}
+
+type T struct{}
+
+// m is not accessible from outside this package.
+func (t *T) m() string {
+	return "lib.T.m"
+}
diff --git a/test/bugs/424.dir/main.go b/test/bugs/424.dir/main.go
new file mode 100644
index 0000000..64a600b
--- /dev/null
+++ b/test/bugs/424.dir/main.go
@@ -0,0 +1,61 @@
+// Copyright 2012 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Tests that method calls through an interface always
+// call the the locally defined method localT.m independent
+// at which embedding level it is and in which order
+// embedding is done.
+
+package main
+
+import "./lib"
+
+type localI interface {
+	m() string
+}
+
+type localT struct{}
+
+func (t *localT) m() string {
+	return "main.localT.m"
+}
+
+type myT1 struct {
+	localT
+}
+
+type myT2 struct {
+	localT
+	lib.T
+}
+
+type myT3 struct {
+	lib.T
+	localT
+}
+
+func main() {
+	var i localI
+
+	i = new(localT)
+	if i.m() != "main.localT.m" {
+		println("BUG: localT:", i.m(), "called")
+	}
+
+	i = new(myT1)
+	if i.m() != "main.localT.m" {
+		println("BUG: myT1:", i.m(), "called")
+	}
+
+	i = new(myT2)
+	if i.m() != "main.localT.m" {
+		println("BUG: myT2:", i.m(), "called")
+	}
+
+	i = new(myT3)
+	if i.m() != "main.localT.m" {
+		println("BUG: myT3:", i.m(), "called")
+	}
+
+}
diff --git a/test/bugs/424.go b/test/bugs/424.go
new file mode 100644
index 0000000..b227760
--- /dev/null
+++ b/test/bugs/424.go
@@ -0,0 +1,9 @@
+// $G $D/$F.dir/lib.go && $G $D/$F.dir/main.go && $L main.$A && $A.out
+
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Test case for embedded method invocation.
+
+ignored
diff --git a/test/const1.go b/test/const1.go
index f944cde..bc399c0 100644
--- a/test/const1.go
+++ b/test/const1.go
@@ -43,7 +43,9 @@ var (
 	b3        = Uint8 - Uint8         // OK
 	b4        = Uint8 - Uint8 - Uint8 // ERROR "overflow"
 	b5        = uint8(^0)             // ERROR "overflow"
+	b5a       = int64(^0)             // OK
 	b6        = ^uint8(0)             // OK
+	b6a       = ^int64(0)             // OK
 	b7        = uint8(Minus1)         // ERROR "overflow"
 	b8        = uint8(int8(-1))       // ERROR "overflow"
 	b8a       = uint8(-1)             // ERROR "overflow"
diff --git a/test/deferprint.go b/test/deferprint.go
index eab7ed4..72c98b1 100644
--- a/test/deferprint.go
+++ b/test/deferprint.go
@@ -1,4 +1,4 @@
-// $G $D/$F.go && $L $F.$A && ./$A.out 2>&1 | cmp - $D/$F.out
+// cmpout
 
 // Copyright 2010 The Go Authors.  All rights reserved.
 // Use of this source code is governed by a BSD-style
diff --git a/test/escape2.go b/test/escape2.go
index dde96bc..624ea80 100644
--- a/test/escape2.go
+++ b/test/escape2.go
@@ -5,7 +5,7 @@
 // license that can be found in the LICENSE file.
 
 // Test, using compiler diagnostic flags, that the escape analysis is working.
-// Compiles but does not run.
+// Compiles but does not run.  Inlining is disabled.
 
 package foo
 
diff --git a/test/escape4.go b/test/escape4.go
new file mode 100644
index 0000000..ab3aee2
--- /dev/null
+++ b/test/escape4.go
@@ -0,0 +1,33 @@
+// errchk -0 $G -m $D/$F.go
+
+// 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.
+
+// Test, using compiler diagnostic flags, that the escape analysis is working.
+// Compiles but does not run.  Inlining is enabled.
+
+package foo
+
+var p *int
+
+func alloc(x int) *int {  // ERROR "can inline alloc" "moved to heap: x"
+	return &x  // ERROR "&x escapes to heap"
+}
+
+var f func()
+
+func f1() {
+	p = alloc(2) // ERROR "inlining call to alloc" "&x escapes to heap" "moved to heap: x"
+
+	// Escape analysis used to miss inlined code in closures.
+
+	func() {  // ERROR "func literal does not escape"
+		p = alloc(3)  // ERROR "inlining call to alloc" "&x escapes to heap" "moved to heap: x"
+	}()
+	
+	f = func() {  // ERROR "func literal escapes to heap"
+		p = alloc(3)  // ERROR "inlining call to alloc" "&x escapes to heap" "moved to heap: x"
+	}
+	f()
+}
diff --git a/test/fixedbugs/bug328.go b/test/fixedbugs/bug328.go
index 8252983..73ab46d 100644
--- a/test/fixedbugs/bug328.go
+++ b/test/fixedbugs/bug328.go
@@ -1,4 +1,4 @@
-// $G $D/$F.go && $L $F.$A && ./$A.out 2>&1 | cmp - $D/$F.out
+// cmpout
 
 // Copyright 2011 The Go Authors.  All rights reserved.
 // Use of this source code is governed by a BSD-style
diff --git a/test/fixedbugs/bug409.go b/test/fixedbugs/bug409.go
index 884d333..1dca43b 100644
--- a/test/fixedbugs/bug409.go
+++ b/test/fixedbugs/bug409.go
@@ -1,4 +1,4 @@
-// $G $D/$F.go && $L $F.$A && ./$A.out 2>&1 | cmp - $D/$F.out
+// cmpout
 
 // Copyright 2012 The Go Authors.  All rights reserved.
 // Use of this source code is governed by a BSD-style
diff --git a/test/fixedbugs/bug425.go b/test/fixedbugs/bug425.go
new file mode 100644
index 0000000..5546bd9
--- /dev/null
+++ b/test/fixedbugs/bug425.go
@@ -0,0 +1,17 @@
+// compile
+
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// http://code.google.com/p/go/issues/detail?id=3119
+
+package main
+
+import "fmt"
+
+func main() {
+	s := "hello"
+	fmt.Println(s == "")
+	fmt.Println(s + "world" == "world")
+}
diff --git a/test/fixedbugs/bug426.go b/test/fixedbugs/bug426.go
new file mode 100644
index 0000000..a1af3cf
--- /dev/null
+++ b/test/fixedbugs/bug426.go
@@ -0,0 +1,15 @@
+// compile
+
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// gccgo crashed compiling this.
+
+package p
+
+type T *T
+
+func f(t T) {
+	println(t, *t)
+}
diff --git a/test/golden.out b/test/golden.out
index 764f561..b7d7594 100644
--- a/test/golden.out
+++ b/test/golden.out
@@ -17,5 +17,8 @@
 
 == bugs/
 
+=========== bugs/424.go
+BUG: myT3: lib.T.m called
+
 =========== bugs/bug395.go
 bug395 is broken
diff --git a/test/goprint.go b/test/goprint.go
index 3fe08f3..2f0d3c3 100644
--- a/test/goprint.go
+++ b/test/goprint.go
@@ -1,4 +1,4 @@
-// $G $D/$F.go && $L $F.$A && ./$A.out 2>&1 | cmp - $D/$F.out
+// cmpout
 
 // Copyright 2011 The Go Authors.  All rights reserved.
 // Use of this source code is governed by a BSD-style
diff --git a/test/helloworld.go b/test/helloworld.go
index 16c95f0..5025ec9 100644
--- a/test/helloworld.go
+++ b/test/helloworld.go
@@ -1,9 +1,11 @@
-// $G $F.go && $L $F.$A && ./$A.out 2>&1 | cmp - $D/$F.out
+// cmpout
 
 // 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.
 
+// Test that we can do page 1 of the C book.
+
 package main
 
 func main() {
diff --git a/test/if.go b/test/if.go
index 1395578..25cc141 100644
--- a/test/if.go
+++ b/test/if.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test if statements in various forms.
+
 package main
 
 func assertequal(is, shouldbe int, msg string) {
diff --git a/test/import.go b/test/import.go
index a02a4ad..d135cd2 100644
--- a/test/import.go
+++ b/test/import.go
@@ -4,8 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// check that when import gives multiple names
-// to a type, they're still all the same type
+// Test that when import gives multiple names
+// to a single type, they still all refer to the same type.
 
 package main
 
diff --git a/test/import1.go b/test/import1.go
index f5b8926..56b29d5 100644
--- a/test/import1.go
+++ b/test/import1.go
@@ -4,7 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// check for import conflicts
+// Verify that import conflicts are detected by the compiler.
+// Does not compile.
 
 package main
 
diff --git a/test/import2.go b/test/import2.go
index 0efc285..0acfabc 100644
--- a/test/import2.go
+++ b/test/import2.go
@@ -4,6 +4,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Various declarations of exported variables and functions.
+// Imported by import3.go.
+
 package p
 
 var C1 chan <- chan int = (chan<- (chan int))(nil)
diff --git a/test/import3.go b/test/import3.go
index e4900b9..274fcfe 100644
--- a/test/import3.go
+++ b/test/import3.go
@@ -4,7 +4,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Check that all the types from import2.go made it
+// Test that all the types from import2.go made it
 // intact and with the same meaning, by assigning to or using them.
 
 package main
diff --git a/test/import4.go b/test/import4.go
index 1ae1d0e..cbfebf7 100644
--- a/test/import4.go
+++ b/test/import4.go
@@ -4,9 +4,11 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-package main
+// Verify that various kinds of "imported and not used"
+// errors are caught by the compiler.
+// Does not compile.
 
-// various kinds of imported and not used
+package main
 
 // standard
 import "fmt"	// ERROR "imported and not used.*fmt"
diff --git a/test/import5.go b/test/import5.go
index acd03c9..6480acf 100644
--- a/test/import5.go
+++ b/test/import5.go
@@ -4,8 +4,52 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// import paths are slash-separated; reject backslash
+// Verify that invalid imports are rejected by the compiler.
+// Does not compile.
 
 package main
 
-import `net\http`  // ERROR "backslash"
+// Correct import paths.
+import _ "fmt"
+import _ `time`
+import _ "m\x61th"
+import _ "go/parser"
+
+// Correct import paths, but the packages don't exist.
+// Don't test.
+//import "a.b"
+//import "greek/αβ"
+
+// Import paths must be strings.
+import 42    // ERROR "import statement"
+import 'a'   // ERROR "import statement"
+import 3.14  // ERROR "import statement"
+import 0.25i // ERROR "import statement"
+
+// Each of these pairs tests both `` vs "" strings
+// and also use of invalid characters spelled out as
+// escape sequences and written directly.
+// For example `"\x00"` tests import "\x00"
+// while "`\x00`" tests import `<actual-NUL-byte>`.
+import ""         // ERROR "import path"
+import ``         // ERROR "import path"
+import "\x00"     // ERROR "import path"
+import `\x00`     // ERROR "import path"
+import "\x7f"     // ERROR "import path"
+import `\x7f`     // ERROR "import path"
+import "a!"       // ERROR "import path"
+import `a!`       // ERROR "import path"
+import "a b"      // ERROR "import path"
+import `a b`      // ERROR "import path"
+import "a\\b"     // ERROR "import path"
+import `a\\b`     // ERROR "import path"
+import "\"`a`\""  // ERROR "import path"
+import `\"a\"`    // ERROR "import path"
+import "\x80\x80" // ERROR "import path"
+import `\x80\x80` // ERROR "import path"
+import "\xFFFD"   // ERROR "import path"
+import `\xFFFD`   // ERROR "import path"
+
+// Invalid local imports.
+import "/foo"  // ERROR "import path cannot be absolute path"
+import "c:/foo"  // ERROR "import path contains invalid character"
diff --git a/test/index.go b/test/index.go
index 38aa33d..eb0c454 100644
--- a/test/index.go
+++ b/test/index.go
@@ -9,6 +9,7 @@
 // license that can be found in the LICENSE file.
 
 // Generate test of index and slice bounds checks.
+// The output is compiled and run.
 
 package main
 
diff --git a/test/indirect.go b/test/indirect.go
index df8d3c7..bb20f30 100644
--- a/test/indirect.go
+++ b/test/indirect.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test various safe uses of indirection.
+
 package main
 
 var m0 map[string]int
diff --git a/test/indirect1.go b/test/indirect1.go
index e49eeb0..51da4cc 100644
--- a/test/indirect1.go
+++ b/test/indirect1.go
@@ -4,6 +4,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Verify that illegal uses of indirection are caught by the compiler.
+// Does not compile.
+
 package main
 
 var m0 map[string]int
diff --git a/test/init.go b/test/init.go
index 0146f4b..f468944 100644
--- a/test/init.go
+++ b/test/init.go
@@ -4,6 +4,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Verify that erroneous use of init is detected.
+// Does not compile.
+
 package main
 
 import "runtime"
diff --git a/test/initialize.go b/test/initialize.go
index 5bab5a7..1307e02 100644
--- a/test/initialize.go
+++ b/test/initialize.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test initialization of package-level variables.
+
 package main
 
 import "fmt"
diff --git a/test/initializerr.go b/test/initializerr.go
index c2703e3..48908c3 100644
--- a/test/initializerr.go
+++ b/test/initializerr.go
@@ -4,6 +4,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Verify that erroneous initialization expressions are caught by the compiler
+// Does not compile.
+
 package main
 
 type S struct {
diff --git a/test/int_lit.go b/test/int_lit.go
index a109fa9..78deaea 100644
--- a/test/int_lit.go
+++ b/test/int_lit.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test integer literal syntax.
+
 package main
 
 import "os"
diff --git a/test/intcvt.go b/test/intcvt.go
index 81b04ef..3920528 100644
--- a/test/intcvt.go
+++ b/test/intcvt.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test implicit and explicit conversions of constants.
+
 package main
 
 const (
diff --git a/test/iota.go b/test/iota.go
index 7e9e352..7187dbe 100644
--- a/test/iota.go
+++ b/test/iota.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test iota.
+
 package main
 
 func assert(cond bool, msg string) {
diff --git a/test/ken/array.go b/test/ken/array.go
index 53f6fc8..9412e35 100644
--- a/test/ken/array.go
+++ b/test/ken/array.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test arrays and slices.
+
 package main
 
 func setpd(a []int) {
diff --git a/test/ken/chan.go b/test/ken/chan.go
index 3bfa5b2..36b18f8 100644
--- a/test/ken/chan.go
+++ b/test/ken/chan.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test communication operations including select.
+
 package main
 
 import "os"
diff --git a/test/ken/chan1.go b/test/ken/chan1.go
index ccb2619..cbd21a3 100644
--- a/test/ken/chan1.go
+++ b/test/ken/chan1.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test communication with multiple simultaneous goroutines.
+
 package main
 
 import "runtime"
diff --git a/test/ken/complit.go b/test/ken/complit.go
index cab3bca..bc50bbe 100644
--- a/test/ken/complit.go
+++ b/test/ken/complit.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test composite literals.
+
 package main
 
 type	M	map[int]int
diff --git a/test/ken/convert.go b/test/ken/convert.go
index 83e573a..33acbd8 100644
--- a/test/ken/convert.go
+++ b/test/ken/convert.go
@@ -4,7 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// near-exhaustive test of converting numbers between types.
+// Test, near-exhaustive, of converting numbers between types.
+// No complex numbers though.
 
 package main
 
diff --git a/test/ken/cplx0.go b/test/ken/cplx0.go
index f38ce5b..665e52a 100644
--- a/test/ken/cplx0.go
+++ b/test/ken/cplx0.go
@@ -1,9 +1,11 @@
-// $G $D/$F.go && $L $F.$A && ./$A.out 2>&1 | cmp - $D/$F.out
+// cmpout
 
 // 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.
 
+// Test trivial, bootstrap-level complex numbers, including printing.
+
 package main
 
 const (
diff --git a/test/ken/cplx1.go b/test/ken/cplx1.go
index 9421c53..78240a5 100644
--- a/test/ken/cplx1.go
+++ b/test/ken/cplx1.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test simple arithmetic and assignment for complex numbers.
+
 package main
 
 const (
diff --git a/test/ken/cplx2.go b/test/ken/cplx2.go
index a3c1570..eb1da7b 100644
--- a/test/ken/cplx2.go
+++ b/test/ken/cplx2.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test arithmetic on complex numbers, including multiplication and division.
+
 package main
 
 const (
diff --git a/test/ken/cplx3.go b/test/ken/cplx3.go
index 0923549..be0b864 100644
--- a/test/ken/cplx3.go
+++ b/test/ken/cplx3.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test composition, decomposition, and reflection on complex numbers.
+
 package main
 
 import "unsafe"
diff --git a/test/ken/cplx4.go b/test/ken/cplx4.go
index 8104ff1..97d5d16 100644
--- a/test/ken/cplx4.go
+++ b/test/ken/cplx4.go
@@ -4,6 +4,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test complex numbers,including fmt support.
+// Used to crash.
+
 package main
 
 import "fmt"
diff --git a/test/ken/cplx5.go b/test/ken/cplx5.go
index 0e2c882..4e8f443 100644
--- a/test/ken/cplx5.go
+++ b/test/ken/cplx5.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test compound types made of complex numbers.
+
 package main
 
 var a [12]complex128
diff --git a/test/ken/divconst.go b/test/ken/divconst.go
index 46786fb..670e074 100644
--- a/test/ken/divconst.go
+++ b/test/ken/divconst.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test integer division by constants.
+
 package main
 
 import "math/rand"
diff --git a/test/ken/divmod.go b/test/ken/divmod.go
index 02c762d..f1bd56e 100644
--- a/test/ken/divmod.go
+++ b/test/ken/divmod.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test integer division and modulus.
+
 package main
 
 const (
diff --git a/test/ken/embed.go b/test/ken/embed.go
index a3e1980..9b35c56 100644
--- a/test/ken/embed.go
+++ b/test/ken/embed.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test embedded fields of structs, including methods.
+
 package main
 
 
diff --git a/test/ken/for.go b/test/ken/for.go
index 914229b..db35548 100644
--- a/test/ken/for.go
+++ b/test/ken/for.go
@@ -4,6 +4,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test simple for loop.
 
 package main
 
diff --git a/test/ken/interbasic.go b/test/ken/interbasic.go
index 113fe3c..d8fbb95 100644
--- a/test/ken/interbasic.go
+++ b/test/ken/interbasic.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test interfaces on basic types.
+
 package main
 
 type myint int
diff --git a/test/ken/interfun.go b/test/ken/interfun.go
index ca875e8..9432181 100644
--- a/test/ken/interfun.go
+++ b/test/ken/interfun.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test interfaces and methods.
+
 package main
 
 type S struct {
diff --git a/test/ken/intervar.go b/test/ken/intervar.go
index 30815d0..8a2fca0 100644
--- a/test/ken/intervar.go
+++ b/test/ken/intervar.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test interface assignment.
+
 package main
 
 type	Iputs	interface {
diff --git a/test/ken/label.go b/test/ken/label.go
index b8867a7..fcb3e61 100644
--- a/test/ken/label.go
+++ b/test/ken/label.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test goto and labels.
+
 package main
 
 func main() {
diff --git a/test/ken/litfun.go b/test/ken/litfun.go
index 4c40ee2..e241d4e 100644
--- a/test/ken/litfun.go
+++ b/test/ken/litfun.go
@@ -4,6 +4,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test simple function literals.
 
 package main
 
diff --git a/test/ken/mfunc.go b/test/ken/mfunc.go
index 2213b81..ef24991 100644
--- a/test/ken/mfunc.go
+++ b/test/ken/mfunc.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test simple multi-argument multi-valued function.
+
 package main
 
 func
diff --git a/test/ken/modconst.go b/test/ken/modconst.go
index 3905b81..d88cf10 100644
--- a/test/ken/modconst.go
+++ b/test/ken/modconst.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test integer modulus by contstants.
+
 package main
 
 import "math/rand"
diff --git a/test/ken/ptrfun.go b/test/ken/ptrfun.go
index b115931..af806cf 100644
--- a/test/ken/ptrfun.go
+++ b/test/ken/ptrfun.go
@@ -4,6 +4,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test method invocation with pointer receivers and function-valued fields.
 
 package main
 
diff --git a/test/ken/ptrvar.go b/test/ken/ptrvar.go
index c6b4656..d78170c 100644
--- a/test/ken/ptrvar.go
+++ b/test/ken/ptrvar.go
@@ -4,6 +4,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test pointers and the . (selector) operator on structs.
 
 package main
 
diff --git a/test/ken/range.go b/test/ken/range.go
index 07d0e9a..89c14e5 100644
--- a/test/ken/range.go
+++ b/test/ken/range.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test 'for range' on arrays, slices, and maps.
+
 package main
 
 const size = 16
diff --git a/test/ken/rob1.go b/test/ken/rob1.go
index 35720c9..3042a67 100644
--- a/test/ken/rob1.go
+++ b/test/ken/rob1.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test general operation using a list implementation.
+
 package main
 
 type Item interface {
diff --git a/test/ken/rob2.go b/test/ken/rob2.go
index bd8a435..4b4410e 100644
--- a/test/ken/rob2.go
+++ b/test/ken/rob2.go
@@ -4,6 +4,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test general operation using s-list.
+// First Go program ever run (although not in this exact form).
+
 package main
 
 import "fmt"
diff --git a/test/ken/robfor.go b/test/ken/robfor.go
index 958efca..c6a420b 100644
--- a/test/ken/robfor.go
+++ b/test/ken/robfor.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test for loops of many forms.
+
 package main
 
 func assertequal(is, shouldbe int, msg string) {
diff --git a/test/ken/robfunc.go b/test/ken/robfunc.go
index 40c5b90..885267e 100644
--- a/test/ken/robfunc.go
+++ b/test/ken/robfunc.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test functions of many signatures.
+
 package main
 
 func assertequal(is, shouldbe int, msg string) {
diff --git a/test/ken/shift.go b/test/ken/shift.go
index c60143d..af87896 100644
--- a/test/ken/shift.go
+++ b/test/ken/shift.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test shift.
+
 package main
 
 var	ians	[18]int;
diff --git a/test/ken/simparray.go b/test/ken/simparray.go
index 553bc4d..0e81a34 100644
--- a/test/ken/simparray.go
+++ b/test/ken/simparray.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test simple operations on arrays.
+
 package main
 
 var b[10] float32;
diff --git a/test/ken/simpbool.go b/test/ken/simpbool.go
index 4a8324c..ab2ecc2 100644
--- a/test/ken/simpbool.go
+++ b/test/ken/simpbool.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test basic operations on bool.
+
 package main
 
 type s struct {
diff --git a/test/ken/simpconv.go b/test/ken/simpconv.go
index 9dc7ebf..22cad2a 100644
--- a/test/ken/simpconv.go
+++ b/test/ken/simpconv.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test simple arithmetic conversion.
+
 package main
 
 type vlong int64
diff --git a/test/ken/simpfun.go b/test/ken/simpfun.go
index b2c803e..e5dc2b2 100644
--- a/test/ken/simpfun.go
+++ b/test/ken/simpfun.go
@@ -4,6 +4,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test simple functions.
 
 package main
 
diff --git a/test/ken/simpswitch.go b/test/ken/simpswitch.go
index cc5f281..b28250b 100644
--- a/test/ken/simpswitch.go
+++ b/test/ken/simpswitch.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test simple switch.
+
 package main
 
 func main() {
diff --git a/test/ken/simpvar.go b/test/ken/simpvar.go
index 324008d..c6eefbb 100644
--- a/test/ken/simpvar.go
+++ b/test/ken/simpvar.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test scoping of variables.
+
 
 package main
 
diff --git a/test/ken/slicearray.go b/test/ken/slicearray.go
index e0f2d32..6cf676c 100644
--- a/test/ken/slicearray.go
+++ b/test/ken/slicearray.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test basic operations of slices and arrays.
+
 package main
 
 var bx [10]byte
diff --git a/test/ken/sliceslice.go b/test/ken/sliceslice.go
index ed1a5fe..c07c591 100644
--- a/test/ken/sliceslice.go
+++ b/test/ken/sliceslice.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test slicing and re-slicing.
+
 package main
 
 var bx []byte
diff --git a/test/ken/string.go b/test/ken/string.go
index e051082..6df8dc4 100644
--- a/test/ken/string.go
+++ b/test/ken/string.go
@@ -1,9 +1,10 @@
-// $G $D/$F.go && $L $F.$A && ./$A.out 2>&1 | cmp - $D/$F.out
+// cmpout
 
 // 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.
 
+// Test string operations including printing.
 
 package main
 
diff --git a/test/ken/strvar.go b/test/ken/strvar.go
index 34b2621..4d511fe 100644
--- a/test/ken/strvar.go
+++ b/test/ken/strvar.go
@@ -4,6 +4,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test struct-valued variables (not pointers).
 
 package main
 
diff --git a/test/label.go b/test/label.go
index 8f2df4c..b30c27e 100644
--- a/test/label.go
+++ b/test/label.go
@@ -4,7 +4,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Pass 1 label errors.
+// Verify that erroneous labels are caught by the compiler.
+// This set is caught by pass 1.
+// Does not compile.
 
 package main
 
diff --git a/test/label1.go b/test/label1.go
index 8a192c2..f923a18 100644
--- a/test/label1.go
+++ b/test/label1.go
@@ -4,7 +4,10 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Pass 2 label errors.
+
+// Verify that erroneous labels are caught by the compiler.
+// This set is caught by pass 2. That's why this file is label1.go.
+// Does not compile.
 
 package main
 
diff --git a/test/linkx.go b/test/linkx.go
index caa815a..d2c9545 100644
--- a/test/linkx.go
+++ b/test/linkx.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test the -X facility of the gc linker (6l etc.).
+
 package main
 
 var tbd string
diff --git a/test/literal.go b/test/literal.go
index 396d75c..ba185fc 100644
--- a/test/literal.go
+++ b/test/literal.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test literal syntax for basic types.
+
 package main
 
 var nbad int
diff --git a/test/mallocfin.go b/test/mallocfin.go
index 2f9f838..be6d79b 100644
--- a/test/mallocfin.go
+++ b/test/mallocfin.go
@@ -4,7 +4,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// trivial finalizer test
+// Test basic operation of finalizers.
 
 package main
 
diff --git a/test/map.go b/test/map.go
index c7f1d05..6dec0df 100644
--- a/test/map.go
+++ b/test/map.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test maps, almost exhaustively.
+
 package main
 
 import (
diff --git a/test/map1.go b/test/map1.go
index 44708c1..369e49d 100644
--- a/test/map1.go
+++ b/test/map1.go
@@ -4,6 +4,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test map declarations of many types, including erroneous ones.
+// Does not compile.
+
 package main
 
 func main() {}
diff --git a/test/method.go b/test/method.go
index 40b42ac..6080ce5 100644
--- a/test/method.go
+++ b/test/method.go
@@ -4,6 +4,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test simple methods of various types, with pointer and
+// value receivers.
+
 package main
 
 type S string
diff --git a/test/method1.go b/test/method1.go
index bbbdbfa..365b8ca 100644
--- a/test/method1.go
+++ b/test/method1.go
@@ -4,6 +4,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Verify that method redeclarations are caught by the compiler.
+// Does not compile.
+
 package main
 
 type T struct { }
diff --git a/test/method2.go b/test/method2.go
index 7db1c3a..b63da10 100644
--- a/test/method2.go
+++ b/test/method2.go
@@ -4,6 +4,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Verify that pointers and interface types cannot be method receivers.
+// Does not compile.
+
 package main
 
 type T struct {
diff --git a/test/method3.go b/test/method3.go
index 5711ffd..fd64771 100644
--- a/test/method3.go
+++ b/test/method3.go
@@ -4,7 +4,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// test that methods on slices work
+// Test methods on slices.
 
 package main
 
diff --git a/test/named1.go b/test/named1.go
index 5ff6930..62b874c 100644
--- a/test/named1.go
+++ b/test/named1.go
@@ -6,6 +6,7 @@
 
 // Test that basic operations on named types are valid
 // and preserve the type.
+// Does not compile.
 
 package main
 
diff --git a/test/nil.go b/test/nil.go
index fd93827..9f7bcbb 100644
--- a/test/nil.go
+++ b/test/nil.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test nil.
+
 package main
 
 import (
diff --git a/test/nilptr.go b/test/nilptr.go
index 1a489aa..b784914 100644
--- a/test/nilptr.go
+++ b/test/nilptr.go
@@ -4,6 +4,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test that the implementation catches nil ptr indirection
+// in a large address space.
+
 package main
 
 import "unsafe"
diff --git a/test/parentype.go b/test/parentype.go
index d7c14f3..eafa076 100644
--- a/test/parentype.go
+++ b/test/parentype.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test that types can be parenthesized.
+
 package main
 
 func f(interface{})
diff --git a/test/peano.go b/test/peano.go
index 2cc0ac2..745f515 100644
--- a/test/peano.go
+++ b/test/peano.go
@@ -4,6 +4,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test that heavy recursion works. Simple torture test for
+// segmented stacks: do math in unary by recursion.
+
 package main
 
 type Number *Number
diff --git a/test/printbig.go b/test/printbig.go
index d867bdc..5693c58 100644
--- a/test/printbig.go
+++ b/test/printbig.go
@@ -1,9 +1,11 @@
-// $G $F.go && $L $F.$A && ./$A.out 2>&1 | cmp - $D/$F.out
+// cmpout
 
 // 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.
 
+// Test that big numbers work as constants and print can print them.
+
 package main
 
 func main() {
diff --git a/test/range.go b/test/range.go
index 7921e44..b0f3ae6 100644
--- a/test/range.go
+++ b/test/range.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test the 'for range' construct.
+
 package main
 
 // test range over channels
diff --git a/test/recover.go b/test/recover.go
index d32cfdf..eea655e 100644
--- a/test/recover.go
+++ b/test/recover.go
@@ -244,3 +244,30 @@ func test7() {
 		die()
 	}
 }
+
+func varargs(s *int, a ...int) {
+	*s = 0
+	for _, v := range a {
+		*s += v
+	}
+	if recover() != nil {
+		*s += 100
+	}
+}
+
+func test8a() (r int) {
+	defer varargs(&r, 1, 2, 3)
+	panic(0)
+}
+
+func test8b() (r int) {
+	defer varargs(&r, 4, 5, 6)
+	return
+}
+
+func test8() {
+	if test8a() != 106 || test8b() != 15 {
+		println("wrong value")
+		die()
+	}
+}
diff --git a/test/recover3.go b/test/recover3.go
index f87547f..9870023 100644
--- a/test/recover3.go
+++ b/test/recover3.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test recovering from runtime errors.
+
 package main
 
 import (
diff --git a/test/rename.go b/test/rename.go
index ab61c57..e544274 100644
--- a/test/rename.go
+++ b/test/rename.go
@@ -4,70 +4,96 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test that predeclared names can be redeclared by the user.
+
 package main
 
 import "fmt"
 
 func main() {
 	n :=
-		bool +
+		append +
+			bool +
 			byte +
-			float +
+			complex +
+			complex64 +
+			complex128 +
+			cap +
+			close +
+			delete +
+			error +
+			false +
 			float32 +
 			float64 +
+			imag +
 			int +
 			int8 +
 			int16 +
 			int32 +
 			int64 +
+			len +
+			make +
+			new +
+			nil +
+			panic +
+			print +
+			println +
+			real +
+			recover +
+			rune +
+			string +
+			true +
 			uint +
 			uint8 +
 			uint16 +
 			uint32 +
 			uint64 +
 			uintptr +
-			true +
-			false +
-			iota +
-			nil +
-			cap +
-			len +
-			make +
-			new +
-			panic +
-			print +
-			println
-	if n != 27*28/2 {
-		fmt.Println("BUG: wrong n", n, 27*28/2)
+			iota
+	if n != NUM*(NUM-1)/2 {
+		fmt.Println("BUG: wrong n", n, NUM*(NUM-1)/2)
 	}
 }
 
 const (
-	bool    = 1
-	byte    = 2
-	float   = 3
-	float32 = 4
-	float64 = 5
-	int     = 6
-	int8    = 7
-	int16   = 8
-	int32   = 9
-	int64   = 10
-	uint    = 11
-	uint8   = 12
-	uint16  = 13
-	uint32  = 14
-	uint64  = 15
-	uintptr = 16
-	true    = 17
-	false   = 18
-	iota    = 19
-	nil     = 20
-	cap     = 21
-	len     = 22
-	make    = 23
-	new     = 24
-	panic   = 25
-	print   = 26
-	println = 27
+	// cannot use iota here, because iota = 38 below
+	append     = 1
+	bool       = 2
+	byte       = 3
+	complex    = 4
+	complex64  = 5
+	complex128 = 6
+	cap        = 7
+	close      = 8
+	delete     = 9
+	error      = 10
+	false      = 11
+	float32    = 12
+	float64    = 13
+	imag       = 14
+	int        = 15
+	int8       = 16
+	int16      = 17
+	int32      = 18
+	int64      = 19
+	len        = 20
+	make       = 21
+	new        = 22
+	nil        = 23
+	panic      = 24
+	print      = 25
+	println    = 26
+	real       = 27
+	recover    = 28
+	rune       = 29
+	string     = 30
+	true       = 31
+	uint       = 32
+	uint8      = 33
+	uint16     = 34
+	uint32     = 35
+	uint64     = 36
+	uintptr    = 37
+	iota       = 38
+	NUM        = 39
 )
diff --git a/test/rename1.go b/test/rename1.go
index 765fba2..53db68d 100644
--- a/test/rename1.go
+++ b/test/rename1.go
@@ -4,11 +4,14 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Verify that renamed identifiers no longer have their old meaning.
+// Does not compile.
+
 package main
 
 func main() {
 	var n byte       // ERROR "not a type|expected type"
-	var y = float(0) // ERROR "cannot call|expected function"
+	var y = float32(0) // ERROR "cannot call|expected function"
 	const (
 		a = 1 + iota // ERROR "string|incompatible types" "convert iota"
 	)
@@ -16,31 +19,42 @@ func main() {
 }
 
 const (
-	bool    = 1
-	byte    = 2
-	float   = 3
-	float32 = 4
-	float64 = 5
-	int     = 6
-	int8    = 7
-	int16   = 8
-	int32   = 9
-	int64   = 10
-	uint    = 11
-	uint8   = 12
-	uint16  = 13
-	uint32  = 14
-	uint64  = 15
-	uintptr = 16
-	true    = 17
-	false   = 18
-	iota    = "abc"
-	nil     = 20
-	cap     = 21
-	len     = 22
-	make    = 23
-	new     = 24
-	panic   = 25
-	print   = 26
-	println = 27
+	append     = 1
+	bool       = 2
+	byte       = 3
+	complex    = 4
+	complex64  = 5
+	complex128 = 6
+	cap        = 7
+	close      = 8
+	delete     = 9
+	error      = 10
+	false      = 11
+	float32    = 12
+	float64    = 13
+	imag       = 14
+	int        = 15
+	int8       = 16
+	int16      = 17
+	int32      = 18
+	int64      = 19
+	len        = 20
+	make       = 21
+	new        = 22
+	nil        = 23
+	panic      = 24
+	print      = 25
+	println    = 26
+	real       = 27
+	recover    = 28
+	rune       = 29
+	string     = 30
+	true       = 31
+	uint       = 32
+	uint8      = 33
+	uint16     = 34
+	uint32     = 35
+	uint64     = 36
+	uintptr    = 37
+	iota       = "38"
 )
diff --git a/test/reorder.go b/test/reorder.go
index a98fd8c..007039e 100644
--- a/test/reorder.go
+++ b/test/reorder.go
@@ -4,7 +4,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Check reordering of assignments.
+// Test reordering of assignments.
 
 package main
 
diff --git a/test/reorder2.go b/test/reorder2.go
index 22fefde..d91f1d8 100644
--- a/test/reorder2.go
+++ b/test/reorder2.go
@@ -4,7 +4,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// derived from fixedbugs/bug294.go
+// Test reorderings; derived from fixedbugs/bug294.go.
 
 package main
 
diff --git a/test/run.go b/test/run.go
index 67ff413..3ba35f9 100644
--- a/test/run.go
+++ b/test/run.go
@@ -32,6 +32,7 @@ var (
 	verbose     = flag.Bool("v", false, "verbose. if set, parallelism is set to 1.")
 	numParallel = flag.Int("n", 8, "number of parallel tests to run")
 	summary     = flag.Bool("summary", false, "show summary of results")
+	showSkips   = flag.Bool("show_skips", false, "show skipped tests")
 )
 
 var (
@@ -98,13 +99,10 @@ func main() {
 	for _, test := range tests {
 		<-test.donec
 		_, isSkip := test.err.(skipError)
+		errStr := "pass"
 		if isSkip {
-			resCount["skip"]++
-			if !*verbose {
-				continue
-			}
+			errStr = "skip"
 		}
-		errStr := "pass"
 		if test.err != nil {
 			errStr = test.err.Error()
 			if !isSkip {
@@ -112,9 +110,12 @@ func main() {
 			}
 		}
 		resCount[errStr]++
+		if isSkip && !*verbose && !*showSkips {
+			continue
+		}
 		if !*verbose && test.err == nil {
 			continue
-	}
+		}
 		fmt.Printf("%-10s %-20s: %s\n", test.action, test.goFileName(), errStr)
 	}
 
@@ -237,6 +238,9 @@ func (t *test) run() {
 	action = strings.TrimSpace(action)
 
 	switch action {
+	case "cmpout":
+		action = "run" // the run case already looks for <dir>/<test>.out files
+		fallthrough
 	case "compile", "build", "run", "errorcheck":
 		t.action = action
 	default:
diff --git a/test/rune.go b/test/rune.go
index 3d3823e..c013c47 100644
--- a/test/rune.go
+++ b/test/rune.go
@@ -4,6 +4,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test rune constants, expressions and types.
+// Compiles but does not run.
+
 package rune
 
 var (
diff --git a/test/runtime.go b/test/runtime.go
index 3162b3f..89f59e3 100644
--- a/test/runtime.go
+++ b/test/runtime.go
@@ -4,12 +4,13 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// make sure that even if a file imports runtime,
+// Test that even if a file imports runtime,
 // it cannot get at the low-level runtime definitions
-// known to the compiler.  for normal packages
+// known to the compiler.  For normal packages
 // the compiler doesn't even record the lower case
 // functions in its symbol table, but some functions
 // in runtime are hard-coded into the compiler.
+// Does not compile.
 
 package main
 
diff --git a/test/shift1.go b/test/shift1.go
index 393e79e..b33d22f 100644
--- a/test/shift1.go
+++ b/test/shift1.go
@@ -4,7 +4,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test illegal shifts.
 // Issue 1708, illegal cases.
+// Does not compile.
 
 package p
 
diff --git a/test/shift2.go b/test/shift2.go
index cf0a45f..88ef3c4 100644
--- a/test/shift2.go
+++ b/test/shift2.go
@@ -4,7 +4,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test legal shifts.
 // Issue 1708, legal cases.
+// Compiles but does not run.
 
 package p
 
diff --git a/test/sieve.go b/test/sieve.go
index 31c4ed5..0cd120c 100644
--- a/test/sieve.go
+++ b/test/sieve.go
@@ -1,11 +1,12 @@
 // build
 
-// don't run it - goes forever
-
 // 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.
 
+// Test basic concurrency: the classic prime sieve.
+// Do not run - loops forever.
+
 package main
 
 // Send the sequence 2, 3, 4, ... to channel 'ch'.
diff --git a/test/sigchld.go b/test/sigchld.go
index e7c3d5a..25625a6 100644
--- a/test/sigchld.go
+++ b/test/sigchld.go
@@ -5,6 +5,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test that a program can survive SIGCHLD.
+
 package main
 
 import "syscall"
diff --git a/test/simassign.go b/test/simassign.go
index 3498951..6ba5c78 100644
--- a/test/simassign.go
+++ b/test/simassign.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test simultaneous assignment.
+
 package main
 
 var a, b, c, d, e, f, g, h, i int
diff --git a/test/sinit.go b/test/sinit.go
index 5cd3a45..1bc2810 100644
--- a/test/sinit.go
+++ b/test/sinit.go
@@ -4,6 +4,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test that many initializations can be done at link time and
+// generate no executable init functions.
+
 package p
 
 // Should be no init func in the assembly.
diff --git a/test/sizeof.go b/test/sizeof.go
index 292f73a..a6abdd5 100644
--- a/test/sizeof.go
+++ b/test/sizeof.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test unsafe.Sizeof, unsafe.Alignof, and unsafe.Offsetof all return uintptr.
+
 package main
 
 import "unsafe"
diff --git a/test/solitaire.go b/test/solitaire.go
index 99c194f..ac54cec 100644
--- a/test/solitaire.go
+++ b/test/solitaire.go
@@ -1,11 +1,13 @@
 // build
 
-// don't run it - produces too much output
-
 // 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.
 
+// Test general operation by solving a peg solitaire game.
+// A version of this is in the Go playground.
+// Don't run it - produces too much output.
+
 // This program solves the (English) peg solitaire board game.
 // See also: http://en.wikipedia.org/wiki/Peg_solitaire
 
diff --git a/test/stack.go b/test/stack.go
index 2a7ce21..b62febd 100644
--- a/test/stack.go
+++ b/test/stack.go
@@ -4,6 +4,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test stack splitting code.
 // Try to tickle stack splitting bugs by doing
 // go, defer, and closure calls at different stack depths.
 
diff --git a/test/string_lit.go b/test/string_lit.go
index 7f1ca35..9563300 100644
--- a/test/string_lit.go
+++ b/test/string_lit.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test string literal syntax.
+
 package main
 
 import "os"
diff --git a/test/stringrange.go b/test/stringrange.go
index a1534c4..daaba91 100644
--- a/test/stringrange.go
+++ b/test/stringrange.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test range over strings.
+
 package main
 
 import (
diff --git a/test/struct0.go b/test/struct0.go
index 490d389..e29eb30 100644
--- a/test/struct0.go
+++ b/test/struct0.go
@@ -4,9 +4,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// zero length structs.
-// used to not be evaluated.
-// issue 2232.
+// Test zero length structs.
+// Used to not be evaluated.
+// Issue 2232.
 
 package main
 
diff --git a/test/switch.go b/test/switch.go
index 68bd117..09bf434 100644
--- a/test/switch.go
+++ b/test/switch.go
@@ -4,8 +4,12 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test switch statements.
+
 package main
 
+import "os"
+
 func assert(cond bool, msg string) {
 	if !cond {
 		print("assertion fail: ", msg, "\n")
@@ -279,4 +283,13 @@ func main() {
 		assert(false, "m should not be nil")
 	default:
 	}
+
+	i := 0
+	switch x := 5; {
+		case i < x:
+			os.Exit(0)
+		case i == x:
+		case i > x:
+			os.Exit(1)
+	}
 }
diff --git a/test/switch1.go b/test/switch1.go
deleted file mode 100644
index 484a5c3..0000000
--- a/test/switch1.go
+++ /dev/null
@@ -1,20 +0,0 @@
-// run
-
-// 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 main
-
-import "os"
-
-func main() {
-	i := 0
-	switch x := 5; {
-		case i < x:
-			os.Exit(0)
-		case i == x:
-		case i > x:
-			os.Exit(1)
-	}
-}
diff --git a/test/switch3.go b/test/switch3.go
index 404b62e..dcb6fff 100644
--- a/test/switch3.go
+++ b/test/switch3.go
@@ -4,6 +4,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Verify that erroneous switch statements are detected by the compiler.
+// Does not compile.
+
 package main
 
 type I interface {
diff --git a/test/test0.go b/test/test0.go
deleted file mode 100644
index ba88b1d..0000000
--- a/test/test0.go
+++ /dev/null
@@ -1,92 +0,0 @@
-// run
-
-// 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 main
-
-const a_const = 0
-
-const (
-	pi    = /* the usual */ 3.14159265358979323
-	e     = 2.718281828
-	mask1 int = 1 << iota
-	mask2 = 1 << iota
-	mask3 = 1 << iota
-	mask4 = 1 << iota
-)
-
-type (
-	Empty interface{}
-	Point struct {
-		x, y int
-	}
-	Point2 Point
-)
-
-func (p *Point) Initialize(x, y int) *Point {
-	p.x, p.y = x, y
-	return p
-}
-
-func (p *Point) Distance() int {
-	return p.x*p.x + p.y*p.y
-}
-
-var (
-	x1      int
-	x2      int
-	u, v, w float32
-)
-
-func foo() {}
-
-func min(x, y int) int {
-	if x < y {
-		return x
-	}
-	return y
-}
-
-func swap(x, y int) (u, v int) {
-	u = y
-	v = x
-	return
-}
-
-func control_structs() {
-	var p *Point = new(Point).Initialize(2, 3)
-	i := p.Distance()
-	var f float32 = 0.3
-	_ = f
-	for {
-	}
-	for {
-	}
-	for j := 0; j < i; j++ {
-		if i == 0 {
-		} else {
-			i = 0
-		}
-		var x float32
-		_ = x
-	}
-foo: // a label
-	var j int
-	switch y := 0; true {
-	case i < y:
-		fallthrough
-	case i < j:
-	case i == 0, i == 1, i == j:
-		i++
-		i++
-		goto foo
-	default:
-		i = -+-+i
-		break
-	}
-}
-
-func main() {
-}
diff --git a/test/testlib b/test/testlib
index ea8c5d7..2e4fefc 100644
--- a/test/testlib
+++ b/test/testlib
@@ -17,6 +17,10 @@ run() {
 	$G $D/$F.go && $L $F.$A && ./$A.out "$@"
 }
 
+cmpout() {
+	$G $D/$F.go && $L $F.$A && ./$A.out 2>&1 | cmp - $D/$F.out
+}
+
 errorcheck() {
 	errchk $G -e $D/$F.go
 }
diff --git a/test/turing.go b/test/turing.go
index f5a2be2..acbe85b 100644
--- a/test/turing.go
+++ b/test/turing.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test simulating a Turing machine, sort of.
+
 package main
 
 // brainfuck
diff --git a/test/typeswitch.go b/test/typeswitch.go
index 1f864db..30a4b49 100644
--- a/test/typeswitch.go
+++ b/test/typeswitch.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test simple type switches, including chans, maps etc.
+
 package main
 
 import "os"
diff --git a/test/typeswitch1.go b/test/typeswitch1.go
index 8b33d39..a980ce4 100644
--- a/test/typeswitch1.go
+++ b/test/typeswitch1.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test simple type switches on basic types.
+
 package main
 
 import "fmt"
diff --git a/test/typeswitch2.go b/test/typeswitch2.go
index 69088e0..6c70307 100644
--- a/test/typeswitch2.go
+++ b/test/typeswitch2.go
@@ -4,6 +4,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Verify that various erroneous type switches are caught be the compiler.
+// Does not compile.
+
 package main
 
 import "io"
diff --git a/test/typeswitch3.go b/test/typeswitch3.go
index 69a2fca..5475a8a 100644
--- a/test/typeswitch3.go
+++ b/test/typeswitch3.go
@@ -4,6 +4,10 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Verify that erroneous type switches are caught be the compiler.
+// Issue 2700, among other things.
+// Does not compile.
+
 package main
 
 import (
diff --git a/test/undef.go b/test/undef.go
index 461006d..0a77e59 100644
--- a/test/undef.go
+++ b/test/undef.go
@@ -4,7 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Check line numbers in error messages.
+// Test line numbers in error messages.
+// Does not compile.
 
 package main
 
diff --git a/test/utf.go b/test/utf.go
index 0a3a1c0..3ac7944 100644
--- a/test/utf.go
+++ b/test/utf.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test UTF-8 in strings and character constants.
+
 package main
 
 import "unicode/utf8"
diff --git a/test/varerr.go b/test/varerr.go
index 4056c16..22aa932 100644
--- a/test/varerr.go
+++ b/test/varerr.go
@@ -4,6 +4,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Verify that a couple of illegal variable declarations are caught by the compiler.
+// Does not compile.
+
 package main
 
 func main() {
diff --git a/test/varinit.go b/test/varinit.go
index 5614783..84a4a1a 100644
--- a/test/varinit.go
+++ b/test/varinit.go
@@ -4,6 +4,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Test var x = x + 1 works.
+
 package main
 
 func main() {

-- 
Packaging for Google Go



More information about the Pkg-google-commits mailing list