diff --git a/src/pkg/gob/codec_test.go b/src/pkg/gob/codec_test.go
index de2c5d6bc9a02e27c6299a205ed47d67fdd5e242..848a8719473fd160d1e671e05ca971a560a731b9 100644
--- a/src/pkg/gob/codec_test.go
+++ b/src/pkg/gob/codec_test.go
@@ -36,6 +36,7 @@ var encodeT = []EncodeT {
 	EncodeT{ 1<<63,	[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81} },
 }
 
+
 // Test basic encode/decode routines for unsigned integers
 func TestUintCodec(t *testing.T) {
 	b := new(bytes.Buffer);
@@ -552,7 +553,7 @@ func TestEndToEnd(t *testing.T) {
 	b := new(bytes.Buffer);
 	encode(b, t1);
 	var _t1 T1;
-	decode(b, getTypeInfo(reflect.Typeof(_t1)).typeId, &_t1);
+	decode(b, getTypeInfo(reflect.Typeof(_t1)).id, &_t1);
 	if !reflect.DeepEqual(t1, &_t1) {
 		t.Errorf("encode expected %v got %v", *t1, _t1);
 	}
@@ -570,7 +571,7 @@ func TestNesting(t *testing.T) {
 	b := new(bytes.Buffer);
 	encode(b, rt);
 	var drt RT;
-	decode(b, getTypeInfo(reflect.Typeof(drt)).typeId, &drt);
+	decode(b, getTypeInfo(reflect.Typeof(drt)).id, &drt);
 	if drt.a != rt.a {
 		t.Errorf("nesting: encode expected %v got %v", *rt, drt);
 	}
@@ -612,7 +613,7 @@ func TestAutoIndirection(t *testing.T) {
 	b := new(bytes.Buffer);
 	encode(b, t1);
 	var t0 T0;
-	t0Id := getTypeInfo(reflect.Typeof(t0)).typeId;
+	t0Id := getTypeInfo(reflect.Typeof(t0)).id;
 	decode(b, t0Id, &t0);
 	if t0.a != 17 || t0.b != 177 || t0.c != 1777 || t0.d != 17777 {
 		t.Errorf("t1->t0: expected {17 177 1777 17777}; got %v", t0);
@@ -637,7 +638,7 @@ func TestAutoIndirection(t *testing.T) {
 	b.Reset();
 	encode(b, t0);
 	t1 = T1{};
-	t1Id := getTypeInfo(reflect.Typeof(t1)).typeId;
+	t1Id := getTypeInfo(reflect.Typeof(t1)).id;
 	decode(b, t1Id, &t1);
 	if t1.a != 17 || *t1.b != 177 || **t1.c != 1777 || ***t1.d != 17777 {
 		t.Errorf("t0->t1 expected {17 177 1777 17777}; got {%d %d %d %d}", t1.a, *t1.b, **t1.c, ***t1.d);
@@ -647,7 +648,7 @@ func TestAutoIndirection(t *testing.T) {
 	b.Reset();
 	encode(b, t0);
 	t2 = T2{};
-	t2Id := getTypeInfo(reflect.Typeof(t2)).typeId;
+	t2Id := getTypeInfo(reflect.Typeof(t2)).id;
 	decode(b, t2Id, &t2);
 	if ***t2.a != 17 || **t2.b != 177 || *t2.c != 1777 || t2.d != 17777 {
 		t.Errorf("t0->t2 expected {17 177 1777 17777}; got {%d %d %d %d}", ***t2.a, **t2.b, *t2.c, t2.d);
@@ -685,7 +686,7 @@ func TestReorderedFields(t *testing.T) {
 	rt0.c = 3.14159;
 	b := new(bytes.Buffer);
 	encode(b, rt0);
-	rt0Id := getTypeInfo(reflect.Typeof(rt0)).typeId;
+	rt0Id := getTypeInfo(reflect.Typeof(rt0)).id;
 	var rt1 RT1;
 	// Wire type is RT0, local type is RT1.
 	decode(b, rt0Id, &rt1);
@@ -723,7 +724,7 @@ func TestIgnoredFields(t *testing.T) {
 
 	b := new(bytes.Buffer);
 	encode(b, it0);
-	rt0Id := getTypeInfo(reflect.Typeof(it0)).typeId;
+	rt0Id := getTypeInfo(reflect.Typeof(it0)).id;
 	var rt1 RT1;
 	// Wire type is IT0, local type is RT1.
 	err := decode(b, rt0Id, &rt1);
diff --git a/src/pkg/gob/decode.go b/src/pkg/gob/decode.go
index 991b6f03f91907bab9ca659ca837a6ba89faf97e..a9148eb834a6488456e8d6e27fca1f2a95c90632 100644
--- a/src/pkg/gob/decode.go
+++ b/src/pkg/gob/decode.go
@@ -18,8 +18,8 @@ import (
 )
 
 var (
-	ErrRange = os.ErrorString("gob: internal error: field numbers out of bounds");
-	ErrNotStruct = os.ErrorString("gob: TODO: can only handle structs")
+	errRange = os.ErrorString("gob: internal error: field numbers out of bounds");
+	errNotStruct = os.ErrorString("gob: TODO: can only handle structs")
 )
 
 // The global execution state of an instance of the decoder.
@@ -347,7 +347,7 @@ func decodeStruct(engine *decEngine, rtyp *reflect.StructType, b *bytes.Buffer,
 		}
 		fieldnum := state.fieldnum + delta;
 		if fieldnum >= len(engine.instr) {
-			state.err = ErrRange;
+			state.err = errRange;
 			break;
 		}
 		instr := &engine.instr[fieldnum];
@@ -376,7 +376,7 @@ func ignoreStruct(engine *decEngine, b *bytes.Buffer) os.Error {
 		}
 		fieldnum := state.fieldnum + delta;
 		if fieldnum >= len(engine.instr) {
-			state.err = ErrRange;
+			state.err = errRange;
 			break;
 		}
 		instr := &engine.instr[fieldnum];
@@ -474,7 +474,7 @@ var decOpMap = map[reflect.Type] decOp {
 	reflect.Typeof((*reflect.StringType)(nil)): decString,
 }
 
-var decIgnoreOpMap = map[TypeId] decOp {
+var decIgnoreOpMap = map[typeId] decOp {
 	tBool: ignoreUint,
 	tInt: ignoreUint,
 	tUint: ignoreUint,
@@ -483,12 +483,12 @@ var decIgnoreOpMap = map[TypeId] decOp {
 	tString: ignoreUint8Array,
 }
 
-func getDecEnginePtr(wireId TypeId, rt reflect.Type) (enginePtr **decEngine, err os.Error)
-func getIgnoreEnginePtr(wireId TypeId) (enginePtr **decEngine, err os.Error)
+func getDecEnginePtr(wireId typeId, rt reflect.Type) (enginePtr **decEngine, err os.Error)
+func getIgnoreEnginePtr(wireId typeId) (enginePtr **decEngine, err os.Error)
 
 // Return the decoding op for the base type under rt and
 // the indirection count to reach it.
-func decOpFor(wireId TypeId, rt reflect.Type) (decOp, int, os.Error) {
+func decOpFor(wireId typeId, rt reflect.Type) (decOp, int, os.Error) {
 	typ, indir := indirect(rt);
 	op, ok := decOpMap[reflect.Typeof(typ)];
 	if !ok {
@@ -537,7 +537,7 @@ func decOpFor(wireId TypeId, rt reflect.Type) (decOp, int, os.Error) {
 }
 
 // Return the decoding op for a field that has no destination.
-func decIgnoreOpFor(wireId TypeId) (decOp, os.Error) {
+func decIgnoreOpFor(wireId typeId) (decOp, os.Error) {
 	op, ok := decIgnoreOpMap[wireId];
 	if !ok {
 		// Special cases
@@ -583,7 +583,7 @@ func decIgnoreOpFor(wireId TypeId) (decOp, os.Error) {
 // Are these two gob Types compatible?
 // Answers the question for basic types, arrays, and slices.
 // Structs are considered ok; fields will be checked later.
-func compatibleType(fr reflect.Type, fw TypeId) bool {
+func compatibleType(fr reflect.Type, fw typeId) bool {
 	for {
 		if pt, ok := fr.(*reflect.PtrType); ok {
 			fr = pt.Elem();
@@ -645,11 +645,11 @@ func compatibleType(fr reflect.Type, fw TypeId) bool {
 	return true;
 }
 
-func compileDec(wireId TypeId, rt reflect.Type) (engine *decEngine, err os.Error) {
+func compileDec(wireId typeId, rt reflect.Type) (engine *decEngine, err os.Error) {
 	srt, ok1 := rt.(*reflect.StructType);
 	wireStruct, ok2 := wireId.gobType().(*structType);
 	if !ok1 || !ok2 {
-		return nil, ErrNotStruct
+		return nil, errNotStruct
 	}
 	engine = new(decEngine);
 	engine.instr = make([]decInstr, len(wireStruct.field));
@@ -660,17 +660,17 @@ func compileDec(wireId TypeId, rt reflect.Type) (engine *decEngine, err os.Error
 		localField, present := srt.FieldByName(wireField.name);
 		// TODO(r): anonymous names
 		if !present || localField.Anonymous {
-			op, err := decIgnoreOpFor(wireField.typeId);
+			op, err := decIgnoreOpFor(wireField.id);
 			if err != nil {
 				return nil, err
 			}
 			engine.instr[fieldnum] = decInstr{op, fieldnum, 0, 0};
 			continue;
 		}
-		if !compatibleType(localField.Type, wireField.typeId) {
+		if !compatibleType(localField.Type, wireField.id) {
 			return nil, os.ErrorString("gob: wrong type for field " + wireField.name + " in type " + wireId.Name());
 		}
-		op, indir, err := decOpFor(wireField.typeId, localField.Type);
+		op, indir, err := decOpFor(wireField.id, localField.Type);
 		if err != nil {
 			return nil, err
 		}
@@ -680,14 +680,14 @@ func compileDec(wireId TypeId, rt reflect.Type) (engine *decEngine, err os.Error
 	return;
 }
 
-var decoderCache = make(map[reflect.Type] map[TypeId] **decEngine)
-var ignorerCache = make(map[TypeId] **decEngine)
+var decoderCache = make(map[reflect.Type] map[typeId] **decEngine)
+var ignorerCache = make(map[typeId] **decEngine)
 
 // typeLock must be held.
-func getDecEnginePtr(wireId TypeId, rt reflect.Type) (enginePtr **decEngine, err os.Error) {
+func getDecEnginePtr(wireId typeId, rt reflect.Type) (enginePtr **decEngine, err os.Error) {
 	decoderMap, ok := decoderCache[rt];
 	if !ok {
-		decoderMap = make(map[TypeId] **decEngine);
+		decoderMap = make(map[typeId] **decEngine);
 		decoderCache[rt] = decoderMap;
 	}
 	if enginePtr, ok = decoderMap[wireId]; !ok {
@@ -707,7 +707,7 @@ type emptyStruct struct {}
 var emptyStructType = reflect.Typeof(emptyStruct{})
 
 // typeLock must be held.
-func getIgnoreEnginePtr(wireId TypeId) (enginePtr **decEngine, err os.Error) {
+func getIgnoreEnginePtr(wireId typeId) (enginePtr **decEngine, err os.Error) {
 	var ok bool;
 	if enginePtr, ok = ignorerCache[wireId]; !ok {
 		// To handle recursive types, mark this engine as underway before compiling.
@@ -721,7 +721,7 @@ func getIgnoreEnginePtr(wireId TypeId) (enginePtr **decEngine, err os.Error) {
 	return
 }
 
-func decode(b *bytes.Buffer, wireId TypeId, e interface{}) os.Error {
+func decode(b *bytes.Buffer, wireId typeId, e interface{}) os.Error {
 	// Dereference down to the underlying object.
 	rt, indir := indirect(reflect.Typeof(e));
 	v := reflect.NewValue(e);
diff --git a/src/pkg/gob/decoder.go b/src/pkg/gob/decoder.go
index 609a20484c6c37246a68b5ba4760357d808fde79..7dd99a0762331341339ef708f98a6b59f7cb1b5f 100644
--- a/src/pkg/gob/decoder.go
+++ b/src/pkg/gob/decoder.go
@@ -13,27 +13,30 @@ import (
 	"sync";
 )
 
+// A Decoder manages the receipt of type and data information read from the
+// remote side of a connection.
 type Decoder struct {
-	sync.Mutex;	// each item must be received atomically
+	mutex	sync.Mutex;	// each item must be received atomically
 	r	io.Reader;	// source of the data
-	seen	map[TypeId] *wireType;	// which types we've already seen described
+	seen	map[typeId] *wireType;	// which types we've already seen described
 	state	*decodeState;	// reads data from in-memory buffer
 	countState	*decodeState;	// reads counts from wire
 	buf	[]byte;
 	oneByte	[]byte;
 }
 
+// NewDecoder returns a new decoder that reads from the io.Reader.
 func NewDecoder(r io.Reader) *Decoder {
 	dec := new(Decoder);
 	dec.r = r;
-	dec.seen = make(map[TypeId] *wireType);
+	dec.seen = make(map[typeId] *wireType);
 	dec.state = new(decodeState);	// buffer set in Decode(); rest is unimportant
 	dec.oneByte = make([]byte, 1);
 
 	return dec;
 }
 
-func (dec *Decoder) recvType(id TypeId) {
+func (dec *Decoder) recvType(id typeId) {
 	// Have we already seen this type?  That's an error
 	if wt_, alreadySeen := dec.seen[id]; alreadySeen {
 		dec.state.err = os.ErrorString("gob: duplicate type received");
@@ -47,14 +50,16 @@ func (dec *Decoder) recvType(id TypeId) {
 	dec.seen[id] = wire;
 }
 
+// Decode reads the next value from the connection and stores
+// it in the data represented by the empty interface value.
 // The value underlying e must be the correct type for the next
-// value to be received for this decoder.
+// data item received.
 func (dec *Decoder) Decode(e interface{}) os.Error {
 	rt, indir := indirect(reflect.Typeof(e));
 
 	// Make sure we're single-threaded through here.
-	dec.Lock();
-	defer dec.Unlock();
+	dec.mutex.Lock();
+	defer dec.mutex.Unlock();
 
 	dec.state.err = nil;
 	for {
@@ -81,7 +86,7 @@ func (dec *Decoder) Decode(e interface{}) os.Error {
 		}
 
 		// Receive a type id.
-		id := TypeId(decodeInt(dec.state));
+		id := typeId(decodeInt(dec.state));
 		if dec.state.err != nil {
 			break;
 		}
diff --git a/src/pkg/gob/encoder.go b/src/pkg/gob/encoder.go
index f75eccd958f54c008ca955e782951f8518cb350d..1182a70c4313b3b3dfaf5f3020296efaa2047473 100644
--- a/src/pkg/gob/encoder.go
+++ b/src/pkg/gob/encoder.go
@@ -2,6 +2,183 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+/*
+	The gob package manages streams of gobs - binary values exchanged between an
+	Encoder (transmitter) and a Decoder (receiver).  A typical use is transporting
+	arguments and results of remote procedure calls (RPCs) such as those provided by
+	package "rpc".
+
+	A stream of gobs is self-describing.  Each data item in the stream is preceded by
+	a specification of its type, expressed in terms of a small set of predefined
+	types.  Pointers are not transmitted, but the things they point to are
+	transmitted; that is, the values are flattened.  Recursive types work fine, but
+	recursive values (data with cycles) are problematic.  This may change.
+
+	To use gobs, create an Encoder and present it with a series of data items as
+	values or addresses that can be dereferenced to values.  (At the moment, these
+	items must be structs (struct, *struct, **struct etc.), but this may change.) The
+	Encoder makes sure all type information is sent before it is needed.  At the
+	receive side, a Decoder retrieves values from the encoded stream and unpacks them
+	into local variables.
+
+	The source and destination values/types need not correspond exactly.  For structs,
+	fields (identified by name) that are in the source but absent from the receiving
+	variable will be ignored.  Fields that are in the receiving variable but missing
+	from the transmitted type or value will be ignored in the destination.  If a field
+	with the same name is present in both, their types must be compatible. Both the
+	receiver and transmitter will do all necessary indirection and dereferencing to
+	convert between gobs and actual Go values.  For instance, a gob type that is
+	schematically,
+
+		struct { a, b int }
+
+	can be sent from or received into any of these Go types:
+
+		struct { a, b int }	// the same
+		*struct { a, b int }	// extra indirection of the struct
+		struct { *a, **b int }	// extra indirection of the fields
+		struct { a, b int64 }	// different concrete value type; see below
+
+	It may also be received into any of these:
+
+		struct { a, b int }	// the same
+		struct { b, a int }	// ordering doesn't matter; matching is by name
+		struct { a, b, c int }	// extra field (c) ignored
+		struct { b int }	// missing field (a) ignored; data will be dropped
+		struct { b, c int }	// missing field (a) ignored; extra field (c) ignored.
+
+	Attempting to receive into these types will draw a decode error:
+
+		struct { a int; b uint }	// change of signedness for b
+		struct { a int; b float }	// change of type for b
+		struct { }	// no field names in common
+		struct { c, d int }	// no field names in common
+
+	Integers are transmitted two ways: arbitrary precision signed integers or
+	arbitrary precision unsigned integers.  There is no int8, int16 etc.
+	discrimination in the gob format; there are only signed and unsigned integers.  As
+	described below, the transmitter sends the value in a variable-length encoding;
+	the receiver accepts the value and stores it in the destination variable.
+	Floating-point numbers are always sent using IEEE-754 64-bit precision (see
+	below).
+
+	Signed integers may be received into any signed integer variable: int, int16, etc.;
+	unsigned integers may be received into any unsigned integer variable; and floating
+	point values may be received into any floating point variable.  However,
+	the destination variable must be able to represent the value or the decode
+	operation will fail. (TODO(r): enforce this.)
+
+	Structs, arrays and slices are also supported.  Strings and arrays of bytes are
+	supported with a special, efficient representation (see below).
+
+	Maps are not supported yet, but they will be.  Interfaces, functions, and channels
+	cannot be sent in a gob.  Attempting to encode a value that contains one will
+	fail.  (TODO(r): fix this - it panics now.)
+
+	The rest of this comment documents the encoding, details that are not important
+	for most users.  Details are presented bottom-up.
+
+	An unsigned integer is encoded as an arbitrary-precision, variable-length sequence
+	of bytes.  It is sent in little-endian order (low bits first), with seven bits per
+	byte.  The high bit of each byte is zero, except that the high bit of the final
+	(highest precision) byte of the encoding will be set.  Thus 0 is transmitted as
+	(80), 7 is transmitted as (87) and 256=2*128 is transmitted as (00 82).
+
+	A boolean is encoded within an unsigned integer: 0 for false, 1 for true.
+
+	A signed integer, i, is encoded within an unsigned integer, u.  Within u, bits 1
+	upward contain the value; bit 0 says whether they should be complemented upon
+	receipt.  The encode algorithm looks like this:
+
+		uint u;
+		if i < 0 {
+			u = (^i << 1) | 1	// complement i, bit 0 is 1
+		} else {
+			u = (i << 1)	// do not complement i, bit 0 is 0
+		}
+		encodeUnsigned(u)
+
+	The low bit is therefore analogous to a sign bit, but making it the complement bit
+	instead guarantees that the largest negative integer is not a special case.  For
+	example, -129=^128=(^256>>1) encodes as (01 82).
+
+	Floating-point numbers are always sent as a representation of a float64 value.
+	That value is converted to a uint64 using math.Float64bits.  The uint64 is then
+	byte-reversed and sent as a regular unsigned integer.  The byte-reversal means the
+	exponent and high-precision part of the mantissa go first.  Since the low bits are
+	often zero, this can save encoding bytes.  For instance, 17.0 is encoded in only
+	two bytes (40 e2).
+
+	Strings and slices of bytes are sent as an unsigned count followed by that many
+	uninterpreted bytes of the value.
+
+	All other slices and arrays are sent as an unsigned count followed by that many
+	elements using the standard gob encoding for their type, recursively.
+
+	Structs are sent as a sequence of (field number, field value) pairs.  The field
+	value is sent using the standard gob encoding for its type, recursively.  If a
+	field has the zero value for its type, it is omitted from the transmission.  The
+	field number is defined by the type of the encoded struct: the first field of the
+	encoded type is field 0, the second is field 1, etc.  When encoding a value, the
+	field numbers are delta encoded for efficiency and the fields are always sent in
+	order of increasing field number; the deltas are therefore unsigned.  The
+	initialization for the delta encoding sets the field number to -1, so an unsigned
+	integer field 0 with value 7 is transmitted as unsigned delta = 1, unsigned value
+	= 7 or (81 87).  Finally, after all the fields have been sent a terminating mark
+	denotes the end of the struct.  That mark is a delta=0 value, which has
+	representation (80).
+
+	The representation of types is described below.  When a type is defined on a given
+	connection between an Encoder and Decoder, it is assigned a signed integer type
+	id.  When Encoder.Encode(v) is called, it makes sure there is an id assigned for
+	the type of v and all its elements and then it sends the pair (typeid, encoded-v)
+	where typeid is the type id of the encoded type of v and encoded-v is the gob
+	encoding of the value v.
+
+	To define a type, the encoder chooses an unused, positive type id and sends the
+	pair (-type id, encoded-type) where encoded-type is the gob encoding of a wireType
+	description, constructed from these types:
+
+		type wireType struct {
+			s	structType;
+		}
+		type fieldType struct {
+			name	string;	// the name of the field.
+			id	int;	// the type id of the field, which must be already defined
+		}
+		type commonType {
+			name	string;	// the name of the struct type
+			id	int;	// the id of the type, repeated for so it's inside the type
+		}
+		type structType struct {
+			commonType;
+			field	[]fieldType;	// the fields of the struct.
+		}
+
+	If there are nested type ids, the types for all inner type ids must be defined
+	before the top-level type id is used to describe an encoded-v.
+
+	For simplicity in setup, the connection is defined to understand these types a
+	priori, as well as the basic gob types int, uint, etc.  Their ids are:
+
+		bool	1
+		int	2
+		uint	3
+		float	4
+		[]byte	5
+		string	6
+		wireType	7
+		structType	8
+		commonType	9
+		fieldType	10
+
+	In summary, a gob stream looks like
+
+		((-type id, encoding of a wireType)* (type id, encoding of a value))*
+
+	where * signifies zero or more repetitions and the type id of a value must
+	be predefined or be defined before the value in the stream.
+*/
 package gob
 
 import (
@@ -13,19 +190,22 @@ import (
 	"sync";
 )
 
+// An Encoder manages the transmission of type and data information to the
+// other side of a connection.
 type Encoder struct {
-	sync.Mutex;	// each item must be sent atomically
+	mutex	sync.Mutex;	// each item must be sent atomically
 	w	io.Writer;	// where to send the data
-	sent	map[reflect.Type] TypeId;	// which types we've already sent
+	sent	map[reflect.Type] typeId;	// which types we've already sent
 	state	*encoderState;	// so we can encode integers, strings directly
 	countState	*encoderState;	// stage for writing counts
 	buf	[]byte;	// for collecting the output.
 }
 
+// NewEncoder returns a new encoder that will transmit on the io.Writer.
 func NewEncoder(w io.Writer) *Encoder {
 	enc := new(Encoder);
 	enc.w = w;
-	enc.sent = make(map[reflect.Type] TypeId);
+	enc.sent = make(map[reflect.Type] typeId);
 	enc.state = new(encoderState);
 	enc.state.b = new(bytes.Buffer);	// the rest isn't important; all we need is buffer and writer
 	enc.countState = new(encoderState);
@@ -91,15 +271,15 @@ func (enc *Encoder) sendType(origt reflect.Type) {
 	typeLock.Unlock();
 	// Send the pair (-id, type)
 	// Id:
-	encodeInt(enc.state, -int64(info.typeId));
+	encodeInt(enc.state, -int64(info.id));
 	// Type:
 	encode(enc.state.b, info.wire);
 	enc.send();
 
 	// Remember we've sent this type.
-	enc.sent[rt] = info.typeId;
+	enc.sent[rt] = info.id;
 	// Remember we've sent the top-level, possibly indirect type too.
-	enc.sent[origt] = info.typeId;
+	enc.sent[origt] = info.id;
 	// Now send the inner types
 	st := rt.(*reflect.StructType);
 	for i := 0; i < st.NumField(); i++ {
@@ -107,6 +287,8 @@ func (enc *Encoder) sendType(origt reflect.Type) {
 	}
 }
 
+// Encode transmits the data item represented by the empty interface value,
+// guaranteeing that all necessary type information has been transmitted first.
 func (enc *Encoder) Encode(e interface{}) os.Error {
 	if enc.state.b.Len() > 0 || enc.countState.b.Len() > 0 {
 		panicln("Encoder: buffer not empty")
@@ -114,8 +296,8 @@ func (enc *Encoder) Encode(e interface{}) os.Error {
 	rt, indir := indirect(reflect.Typeof(e));
 
 	// Make sure we're single-threaded through here.
-	enc.Lock();
-	defer enc.Unlock();
+	enc.mutex.Lock();
+	defer enc.mutex.Unlock();
 
 	// Make sure the type is known to the other side.
 	// First, have we already sent this type?
diff --git a/src/pkg/gob/encoder_test.go b/src/pkg/gob/encoder_test.go
index 4d9258345b1d1888f514947be0bcec4f21e58278..a7e66a57e39a9a0f9f13afc0c29334b3c4ad547f 100644
--- a/src/pkg/gob/encoder_test.go
+++ b/src/pkg/gob/encoder_test.go
@@ -70,7 +70,7 @@ func TestBasicEncoder(t *testing.T) {
 		t.Fatal("error decoding ET1 type:", err);
 	}
 	info := getTypeInfo(reflect.Typeof(ET1{}));
-	trueWire1 := &wireType{s: info.typeId.gobType().(*structType)};
+	trueWire1 := &wireType{s: info.id.gobType().(*structType)};
 	if !reflect.DeepEqual(wire1, trueWire1) {
 		t.Fatalf("invalid wireType for ET1: expected %+v; got %+v\n", *trueWire1, *wire1);
 	}
@@ -91,7 +91,7 @@ func TestBasicEncoder(t *testing.T) {
 		t.Fatal("error decoding ET2 type:", err);
 	}
 	info = getTypeInfo(reflect.Typeof(ET2{}));
-	trueWire2 := &wireType{s: info.typeId.gobType().(*structType)};
+	trueWire2 := &wireType{s: info.id.gobType().(*structType)};
 	if !reflect.DeepEqual(wire2, trueWire2) {
 		t.Fatalf("invalid wireType for ET2: expected %+v; got %+v\n", *trueWire2, *wire2);
 	}
@@ -107,7 +107,7 @@ func TestBasicEncoder(t *testing.T) {
 	}
 	// 8) The value of et1
 	newEt1 := new(ET1);
-	et1Id := getTypeInfo(reflect.Typeof(*newEt1)).typeId;
+	et1Id := getTypeInfo(reflect.Typeof(*newEt1)).id;
 	err = decode(b, et1Id, newEt1);
 	if err != nil {
 		t.Fatal("error decoding ET1 value:", err);
diff --git a/src/pkg/gob/type.go b/src/pkg/gob/type.go
index 006a0e442bca359d8af2b417402242e121c0a106..68d047ffd3fc29e3f2ce81e2fe177c3856a4f0ba 100644
--- a/src/pkg/gob/type.go
+++ b/src/pkg/gob/type.go
@@ -13,23 +13,23 @@ import (
 	"unicode";
 )
 
-// Types are identified by an integer TypeId.  These can be passed on the wire.
-// Internally, they are used as keys to a map to recover the underlying type info.
-type TypeId int32
+// A typeId represents a gob Type as an integer that can be passed on the wire.
+// Internally, typeIds are used as keys to a map to recover the underlying type info.
+type typeId int32
 
-var nextId	TypeId	// incremented for each new type we build
+var nextId	typeId	// incremented for each new type we build
 var typeLock	sync.Mutex	// set while building a type
 
 type gobType interface {
-	id()	TypeId;
-	setId(id TypeId);
+	id()	typeId;
+	setId(id typeId);
 	Name()	string;
 	String()	string;
-	safeString(seen map[TypeId] bool)	string;
+	safeString(seen map[typeId] bool)	string;
 }
 
 var types = make(map[reflect.Type] gobType)
-var idToType = make(map[TypeId] gobType)
+var idToType = make(map[typeId] gobType)
 
 func setTypeId(typ gobType) {
 	nextId++;
@@ -37,32 +37,34 @@ func setTypeId(typ gobType) {
 	idToType[nextId] = typ;
 }
 
-func (t TypeId) gobType() gobType {
+func (t typeId) gobType() gobType {
 	if t == 0 {
 		return nil
 	}
 	return idToType[t]
 }
 
-func (t TypeId) String() string {
+// String returns the string representation of the type associated with the typeId.
+func (t typeId) String() string {
 	return t.gobType().String()
 }
 
-func (t TypeId) Name() string {
+// Name returns the name of the type associated with the typeId.
+func (t typeId) Name() string {
 	return t.gobType().Name()
 }
 
 // Common elements of all types.
 type commonType struct {
 	name	string;
-	_id	TypeId;
+	_id	typeId;
 }
 
-func (t *commonType) id() TypeId {
+func (t *commonType) id() typeId {
 	return t._id
 }
 
-func (t *commonType) setId(id TypeId) {
+func (t *commonType) setId(id typeId) {
 	t._id = id
 }
 
@@ -79,20 +81,20 @@ func (t *commonType) Name() string {
 }
 
 // Basic type identifiers, predefined.
-var tBool TypeId
-var tInt TypeId
-var tUint TypeId
-var tFloat TypeId
-var tString TypeId
-var tBytes TypeId
+var tBool typeId
+var tInt typeId
+var tUint typeId
+var tFloat typeId
+var tString typeId
+var tBytes typeId
 
 // Predefined because it's needed by the Decoder
-var tWireType TypeId
+var tWireType typeId
 
 // Array type
 type arrayType struct {
 	commonType;
-	Elem	TypeId;
+	Elem	typeId;
 	Len	int;
 }
 
@@ -102,7 +104,7 @@ func newArrayType(name string, elem gobType, length int) *arrayType {
 	return a;
 }
 
-func (a *arrayType) safeString(seen map[TypeId] bool) string {
+func (a *arrayType) safeString(seen map[typeId] bool) string {
 	if _, ok := seen[a._id]; ok {
 		return a.name
 	}
@@ -117,7 +119,7 @@ func (a *arrayType) String() string {
 // Slice type
 type sliceType struct {
 	commonType;
-	Elem	TypeId;
+	Elem	typeId;
 }
 
 func newSliceType(name string, elem gobType) *sliceType {
@@ -126,7 +128,7 @@ func newSliceType(name string, elem gobType) *sliceType {
 	return s;
 }
 
-func (s *sliceType) safeString(seen map[TypeId] bool) string {
+func (s *sliceType) safeString(seen map[typeId] bool) string {
 	if _, ok := seen[s._id]; ok {
 		return s.name
 	}
@@ -135,13 +137,13 @@ func (s *sliceType) safeString(seen map[TypeId] bool) string {
 }
 
 func (s *sliceType) String() string {
-	return s.safeString(make(map[TypeId] bool))
+	return s.safeString(make(map[typeId] bool))
 }
 
 // Struct type
 type fieldType struct {
 	name	string;
-	typeId	TypeId;
+	id	typeId;
 }
 
 type structType struct {
@@ -149,7 +151,7 @@ type structType struct {
 	field	[]*fieldType;
 }
 
-func (s *structType) safeString(seen map[TypeId] bool) string {
+func (s *structType) safeString(seen map[typeId] bool) string {
 	if s == nil {
 		return "<nil>"
 	}
@@ -159,14 +161,14 @@ func (s *structType) safeString(seen map[TypeId] bool) string {
 	seen[s._id] = true;
 	str := s.name + " = struct { ";
 	for _, f := range s.field {
-		str += fmt.Sprintf("%s %s; ", f.name, f.typeId.gobType().safeString(seen));
+		str += fmt.Sprintf("%s %s; ", f.name, f.id.gobType().safeString(seen));
 	}
 	str += "}";
 	return str;
 }
 
 func (s *structType) String() string {
-	return s.safeString(make(map[TypeId] bool))
+	return s.safeString(make(map[typeId] bool))
 }
 
 func newStructType(name string) *structType {
@@ -294,8 +296,14 @@ func getType(name string, rt reflect.Type) gobType {
 	return t;
 }
 
+func checkId(want, got typeId) {
+	if want != got {
+		panicln("bootstrap type wrong id:", got.Name(), got, "not", want);
+	}
+}
+
 // used for building the basic types; called only from init()
-func bootstrapType(name string, e interface{}) TypeId {
+func bootstrapType(name string, e interface{}, expect typeId) typeId {
 	rt := reflect.Typeof(e);
 	_, present := types[rt];
 	if present {
@@ -304,6 +312,7 @@ func bootstrapType(name string, e interface{}) TypeId {
 	typ := &commonType{ name: name };
 	types[rt] = typ;
 	setTypeId(typ);
+	checkId(expect, nextId);
 	return nextId
 }
 
@@ -329,7 +338,7 @@ func (w *wireType) name() string {
 type decEngine struct	// defined in decode.go
 type encEngine struct	// defined in encode.go
 type typeInfo struct {
-	typeId	TypeId;
+	id	typeId;
 	encoder	*encEngine;
 	wire	*wireType;
 }
@@ -346,21 +355,26 @@ func getTypeInfo(rt reflect.Type) *typeInfo {
 	if !ok {
 		info = new(typeInfo);
 		name := rt.Name();
-		info.typeId = getType(name, rt).id();
+		info.id = getType(name, rt).id();
 		// assume it's a struct type
-		info.wire = &wireType{info.typeId.gobType().(*structType)};
+		info.wire = &wireType{info.id.gobType().(*structType)};
 		typeInfoMap[rt] = info;
 	}
 	return info;
 }
 
 func init() {
-	tBool = bootstrapType("bool", false);
-	tInt = bootstrapType("int", int(0));
-	tUint = bootstrapType("uint", uint(0));
-	tFloat = bootstrapType("float", float64(0));
+	// Create and check predefined types
+	tBool = bootstrapType("bool", false, 1);
+	tInt = bootstrapType("int", int(0), 2);
+	tUint = bootstrapType("uint", uint(0), 3);
+	tFloat = bootstrapType("float", float64(0), 4);
 	// The string for tBytes is "bytes" not "[]byte" to signify its specialness.
-	tBytes = bootstrapType("bytes", make([]byte, 0));
-	tString= bootstrapType("string", "");
-	tWireType = getTypeInfo(reflect.Typeof(wireType{})).typeId;
+	tBytes = bootstrapType("bytes", make([]byte, 0), 5);
+	tString= bootstrapType("string", "", 6);
+	tWireType = getTypeInfo(reflect.Typeof(wireType{})).id;
+	checkId(7, tWireType);
+	checkId(8, getTypeInfo(reflect.Typeof(structType{})).id);
+	checkId(9, getTypeInfo(reflect.Typeof(commonType{})).id);
+	checkId(10, getTypeInfo(reflect.Typeof(fieldType{})).id);
 }
diff --git a/src/pkg/gob/type_test.go b/src/pkg/gob/type_test.go
index d190a3045e278f5d1d30d812a56d05d39e50a9fb..2f11ba3fea3518b0d8b48525d0fa7aab412a8400 100644
--- a/src/pkg/gob/type_test.go
+++ b/src/pkg/gob/type_test.go
@@ -12,7 +12,7 @@ import (
 )
 
 type typeT struct {
-	typeId	TypeId;
+	id	typeId;
 	str	string;
 }
 var basicTypes = []typeT {
@@ -33,10 +33,10 @@ func getTypeUnlocked(name string, rt reflect.Type) gobType {
 // Sanity checks
 func TestBasic(t *testing.T) {
 	for _, tt := range basicTypes {
-		if tt.typeId.String() != tt.str {
-			t.Errorf("checkType: expected %q got %s", tt.str, tt.typeId.String())
+		if tt.id.String() != tt.str {
+			t.Errorf("checkType: expected %q got %s", tt.str, tt.id.String())
 		}
-		if tt.typeId == 0 {
+		if tt.id == 0 {
 			t.Errorf("id for %q is zero", tt.str)
 		}
 	}