diff --git a/vdl/convert_test.go b/vdl/convert_test.go
index 07bd8dc..e95d85c 100644
--- a/vdl/convert_test.go
+++ b/vdl/convert_test.go
@@ -17,6 +17,7 @@
 	"testing"
 
 	"v.io/v23/vdl"
+	"v.io/v23/vdl/vdltest"
 	"v.io/v23/verror"
 )
 
@@ -1225,3 +1226,24 @@
 		t.Errorf("got %#v, want %#v", got, want)
 	}
 }
+
+func TestConvertNew(t *testing.T) {
+	for _, entry := range vdltest.AllPass() {
+		rvTargetPtr := reflect.New(entry.Target.Type())
+		if err := vdl.Convert(rvTargetPtr.Interface(), entry.Source.Interface()); err != nil {
+			t.Errorf("%s: Convert failed: %v", entry.Name(), err)
+		}
+		if got, want := rvTargetPtr.Elem(), entry.Target; !vdl.DeepEqualReflect(got, want) {
+			t.Errorf("%s\nGOT  %v\nWANT %v", entry.Name(), got, want)
+		}
+	}
+}
+
+func TestConvertFailNew(t *testing.T) {
+	for _, entry := range vdltest.AllFail() {
+		rvTargetPtr := reflect.New(entry.Target.Type())
+		if err := vdl.Convert(rvTargetPtr.Interface(), entry.Source.Interface()); err == nil {
+			t.Errorf("%s: Convert passed, wanted failure", entry.Name())
+		}
+	}
+}
diff --git a/vdl/new_convert_test.go b/vdl/new_convert_test.go
deleted file mode 100644
index 57573a5..0000000
--- a/vdl/new_convert_test.go
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2015 The Vanadium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build newvdltests
-
-package vdl_test
-
-import (
-	"reflect"
-	"testing"
-
-	"v.io/v23/vdl"
-	"v.io/v23/vdl/vdltest"
-)
-
-func TestConvertNew(t *testing.T) {
-	for _, entry := range vdltest.AllPass() {
-		rvTargetPtr := reflect.New(entry.Target.Type())
-		if err := vdl.Convert(rvTargetPtr.Interface(), entry.Source.Interface()); err != nil {
-			t.Errorf("%s: Convert failed: %v", entry.Name(), err)
-		}
-		if got, want := rvTargetPtr.Elem(), entry.Target; !vdl.DeepEqualReflect(got, want) {
-			t.Errorf("%s\nGOT  %v\nWANT %v", entry.Name(), got, want)
-		}
-	}
-}
-
-func TestConvertFailNew(t *testing.T) {
-	for _, entry := range vdltest.AllFail() {
-		rvTargetPtr := reflect.New(entry.Target.Type())
-		if err := vdl.Convert(rvTargetPtr.Interface(), entry.Source.Interface()); err == nil {
-			t.Errorf("%s: Convert passed, wanted failure", entry.Name())
-		}
-	}
-}
diff --git a/vdl/new_value_reader_test.go b/vdl/new_value_reader_test.go
deleted file mode 100644
index fed2366..0000000
--- a/vdl/new_value_reader_test.go
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2016 The Vanadium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build newvdltests
-
-package vdl_test
-
-import (
-	"testing"
-
-	"v.io/v23/vdl"
-	"v.io/v23/vdl/vdltest"
-)
-
-func TestValueReader(t *testing.T) {
-	for _, entry := range vdltest.ToEntryValues(vdltest.AllPass()) {
-		out := vdl.ZeroValue(entry.Target.Type())
-		if err := out.VDLRead(entry.Source.Decoder()); err != nil {
-			t.Errorf("%s: VDLRead failed: %v", entry.Name(), err)
-			continue
-		}
-		if got, want := out, entry.Target; !vdl.EqualValue(got, want) {
-			t.Errorf("%s\nGOT  %v\nWANT %v", entry.Name(), got, want)
-		}
-	}
-}
diff --git a/vdl/value_reader_test.go b/vdl/value_reader_test.go
index 03bee7d..d21926c 100644
--- a/vdl/value_reader_test.go
+++ b/vdl/value_reader_test.go
@@ -8,18 +8,18 @@
 	"testing"
 
 	"v.io/v23/vdl"
-	"v.io/v23/vom/testdata/data81"
+	"v.io/v23/vdl/vdltest"
 )
 
-func TestValueRead(t *testing.T) {
-	for _, test := range data81.Tests {
-		out := vdl.ZeroValue(test.Value.Type())
-		if err := out.VDLRead(test.Value.Decoder()); err != nil {
-			t.Errorf("%s: error in ValueRead: %v", test.Name, err)
+func TestValueReader(t *testing.T) {
+	for _, entry := range vdltest.ToEntryValues(vdltest.AllPass()) {
+		out := vdl.ZeroValue(entry.Target.Type())
+		if err := out.VDLRead(entry.Source.Decoder()); err != nil {
+			t.Errorf("%s: VDLRead failed: %v", entry.Name(), err)
 			continue
 		}
-		if !vdl.EqualValue(test.Value, out) {
-			t.Errorf("%s: got %v, want %v", test.Name, out, test.Value)
+		if got, want := out, entry.Target; !vdl.EqualValue(got, want) {
+			t.Errorf("%s\nGOT  %v\nWANT %v", entry.Name(), got, want)
 		}
 	}
 }
diff --git a/vom/.api b/vom/.api
index 30322e3..f7c4048 100644
--- a/vom/.api
+++ b/vom/.api
@@ -59,7 +59,6 @@
 pkg vom, func RawBytesOf(interface{}) *RawBytes
 pkg vom, func VDLReadPrimitive(vdl.Decoder, *Primitive) error
 pkg vom, func VersionedEncode(Version, interface{}) ([]byte, error)
-pkg vom, func XRawBytesFromValue(interface{}) (*RawBytes, error)
 pkg vom, method (*ControlKind) Set(string) error
 pkg vom, method (*ControlKind) VDLRead(vdl.Decoder) error
 pkg vom, method (*Decoder) Decode(interface{}) error
diff --git a/vom/binary_util_test.go b/vom/binary_util_test.go
index 70ed50a..1d98ab1 100644
--- a/vom/binary_util_test.go
+++ b/vom/binary_util_test.go
@@ -11,14 +11,6 @@
 	"testing"
 )
 
-func hex2Bin(t *testing.T, hex string) []byte {
-	binStr, err := binFromHexPat(hex)
-	if err != nil {
-		t.Fatalf("error converting %q to binary: %v", hex, err)
-	}
-	return []byte(binStr)
-}
-
 func TestBinaryEncodeDecode(t *testing.T) {
 	tests := []struct {
 		v   interface{}
diff --git a/vom/convert_test.go b/vom/convert_test.go
index 06ffb52..f7c89e6 100644
--- a/vom/convert_test.go
+++ b/vom/convert_test.go
@@ -7,7 +7,6 @@
 import (
 	"bytes"
 	"fmt"
-	"io"
 	"reflect"
 	"strings"
 	"sync"
@@ -139,43 +138,3 @@
 	}
 	return nil
 }
-
-// In concurrent modes, one goroutine may try to read vom types before they are
-// actually sent by other goroutine. We use a simple buffered pipe to provide
-// blocking read since bytes.Buffer will return EOF in this case.
-type pipe struct {
-	b      bytes.Buffer
-	m      sync.Mutex
-	c      sync.Cond
-	closed bool
-}
-
-func newPipe() (io.ReadCloser, io.WriteCloser) {
-	p := &pipe{}
-	p.c.L = &p.m
-	return p, p
-}
-
-func (r *pipe) Read(p []byte) (n int, err error) {
-	r.m.Lock()
-	defer r.m.Unlock()
-	for r.b.Len() == 0 || r.closed {
-		r.c.Wait()
-	}
-	return r.b.Read(p)
-}
-
-func (p *pipe) Close() error {
-	p.m.Lock()
-	p.closed = true
-	p.c.Broadcast()
-	p.m.Unlock()
-	return nil
-}
-
-func (w *pipe) Write(p []byte) (n int, err error) {
-	w.m.Lock()
-	defer w.m.Unlock()
-	defer w.c.Signal()
-	return w.b.Write(p)
-}
diff --git a/vom/decoder.go b/vom/decoder.go
index 1515735..bcbb932 100644
--- a/vom/decoder.go
+++ b/vom/decoder.go
@@ -1,414 +1,800 @@
-// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Copyright 2016 The Vanadium 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 vom
 
 import (
+	"errors"
+	"fmt"
+	"io"
+	"math"
+	"os"
+
 	"v.io/v23/vdl"
 	"v.io/v23/verror"
 )
 
-// TODO(toddw): Merge this file with xdecoder.go
-
-var (
-	errDecodeZeroTypeID         = verror.Register(pkgPath+".errDecodeZeroTypeID", verror.NoRetry, "{1:}{2:} vom: zero type id{:_}")
-	errIndexOutOfRange          = verror.Register(pkgPath+".errIndexOutOfRange", verror.NoRetry, "{1:}{2:} vom: index out of range{:_}")
-	errLeftOverBytes            = verror.Register(pkgPath+".errLeftOverBytes", verror.NoRetry, "{1:}{2:} vom: {3} leftover bytes{:_}")
-	errUnexpectedControlByte    = verror.Register(pkgPath+".errUnexpectedControlByte", verror.NoRetry, "{1:}{2:} vom: unexpected control byte {3}{:_}")
-	errDecodeValueUnhandledType = verror.Register(pkgPath+".errDecodeValueUnhandledType", verror.NoRetry, "{1:}{2:} vom: decodeValue unhandled type {3}{:_}")
-	errIgnoreValueUnhandledType = verror.Register(pkgPath+".errIgnoreValueUnhandledType", verror.NoRetry, "{1:}{2:} vom: ignoreValue unhandled type {3}{:_}")
-	errInvalidTypeIdIndex       = verror.Register(pkgPath+".errInvalidTypeIdIndex", verror.NoRetry, "{1:}{2:} vom: value referenced invalid index into type id table {:_}")
-	errInvalidAnyIndex          = verror.Register(pkgPath+".errInvalidAnyIndex", verror.NoRetry, "{1:}{2:} vom: value referenced invalid index into anyLen table {:_}")
+const (
+	// IEEE 754 represents float64 using 52 bits to represent the mantissa, with
+	// an extra implied leading bit.  That gives us 53 bits to store integers
+	// without overflow - i.e. [0, (2^53)-1].  And since 2^53 is a small power of
+	// two, it can also be stored without loss via mantissa=1 exponent=53.  Thus
+	// we have our max and min values.  Ditto for float32, which uses 23 bits with
+	// an extra implied leading bit.
+	float64MaxInt = (1 << 53)
+	float64MinInt = -(1 << 53)
+	float32MaxInt = (1 << 24)
+	float32MinInt = -(1 << 24)
 )
 
-func (d *decoder81) decodeTypeDefs() error {
-	for {
-		typeNext, err := d.typeIsNext()
+var (
+	errEmptyDecoderStack          = errors.New("vom: empty decoder stack")
+	errReadRawBytesAlreadyStarted = errors.New("vom: read into vom.RawBytes after StartValue called")
+	errReadRawBytesFromNonAny     = errors.New("vom: read into vom.RawBytes only supported on any values")
+)
+
+// This is only used for debugging; add this as the first line of NewDecoder to
+// dump formatted vom bytes to stdout:
+//   r = teeDump(r)
+func teeDump(r io.Reader) io.Reader {
+	return io.TeeReader(r, NewDumper(NewDumpWriter(os.Stdout)))
+}
+
+// Decoder manages the receipt and unmarshalling of typed values from the other
+// side of a connection.
+type Decoder struct {
+	dec decoder81
+}
+
+type decoder81 struct {
+	buf        *decbuf
+	flag       decFlag
+	stack      []decStackEntry
+	refTypes   referencedTypes
+	refAnyLens referencedAnyLens
+	typeDec    *TypeDecoder
+}
+
+type decStackEntry struct {
+	Type          *vdl.Type     // Type of the value that we're decoding.
+	Index         int           // Index of the key, elem or field.
+	LenHint       int           // Length of the value, or -1 for unknown.
+	NextEntryType *vdl.Type     // type for NextEntryValue* methods
+	Flag          decStackFlag  // properties of this stack entry
+	NextEntryData nextEntryData // properties of the next entry
+}
+
+// decFlag holds properties of the decoder.
+type decFlag uint
+
+const (
+	decFlagIgnoreNextStartValue decFlag = 0x1 // ignore the next call to StartValue
+	decFlagIsParentBytes        decFlag = 0x2 // parent type is []byte or [N]byte
+	decFlagTypeIncomplete       decFlag = 0x4 // type has dependencies on unsent types
+	decFlagSeparateTypeDec      decFlag = 0x8 // type decoder is separate
+
+	// In FinishValue we need to clear both of these bits.
+	decFlagFinishValue decFlag = decFlagIgnoreNextStartValue | decFlagIsParentBytes
+)
+
+func (f decFlag) Set(bits decFlag) decFlag   { return f | bits }
+func (f decFlag) Clear(bits decFlag) decFlag { return f &^ bits }
+
+func (f decFlag) IgnoreNextStartValue() bool { return f&decFlagIgnoreNextStartValue != 0 }
+func (f decFlag) IsParentBytes() bool        { return f&decFlagIsParentBytes != 0 }
+func (f decFlag) TypeIncomplete() bool       { return f&decFlagTypeIncomplete != 0 }
+func (f decFlag) SeparateTypeDec() bool      { return f&decFlagSeparateTypeDec != 0 }
+
+// decStackFlag holds type or value properties of the stack entry.
+type decStackFlag uint
+
+const (
+	decStackFlagIsMapKey   decStackFlag = 0x1 // key or elem for dfsNextType
+	decStackFlagIsAny      decStackFlag = 0x2 // the static type is Any
+	decStackFlagIsOptional decStackFlag = 0x4 // the static type is Optional
+	decStackFlagFastRead   decStackFlag = 0x8 // subtypes use ReadValue fastpath
+)
+
+func (f decStackFlag) FlipIsMapKey() decStackFlag { return f ^ decStackFlagIsMapKey }
+func (f decStackFlag) IsMapKey() bool             { return f&decStackFlagIsMapKey != 0 }
+func (f decStackFlag) IsAny() bool                { return f&decStackFlagIsAny != 0 }
+func (f decStackFlag) IsOptional() bool           { return f&decStackFlagIsOptional != 0 }
+func (f decStackFlag) FastRead() bool             { return f&decStackFlagFastRead != 0 }
+
+// NewDecoder returns a new Decoder that reads from the given reader.  The
+// Decoder understands all formats generated by the Encoder.
+func NewDecoder(r io.Reader) *Decoder {
+	buf := newDecbuf(r)
+	typeDec := newTypeDecoderInternal(buf)
+	return &Decoder{decoder81{
+		buf:     buf,
+		typeDec: typeDec,
+	}}
+}
+
+// NewDecoderWithTypeDecoder returns a new Decoder that reads from the given
+// reader.  Types are decoded separately through the typeDec.
+func NewDecoderWithTypeDecoder(r io.Reader, typeDec *TypeDecoder) *Decoder {
+	return &Decoder{decoder81{
+		buf:     newDecbuf(r),
+		typeDec: typeDec,
+		flag:    decFlagSeparateTypeDec,
+	}}
+}
+
+// Decoder returns d as a vdl.Decoder.
+func (d *Decoder) Decoder() vdl.Decoder {
+	return &d.dec
+}
+
+// Decode reads the next value and stores it in value v.  The type of v need not
+// exactly match the type of the originally encoded value; decoding succeeds as
+// long as the values are convertible.
+func (d *Decoder) Decode(v interface{}) error {
+	return vdl.Read(&d.dec, v)
+}
+
+func (d *decoder81) IgnoreNextStartValue() {
+	d.flag = d.flag.Set(decFlagIgnoreNextStartValue)
+}
+
+func (d *decoder81) decodeWireType(wt *wireType) (TypeId, error) {
+	// Type messages are just a regularly encoded wireType, which is a union.  To
+	// decode we pre-populate the stack with an entry for the wire type, and run
+	// the code-generated __VDLRead_wireType method.
+	tid, err := d.nextMessage()
+	if err != nil {
+		return 0, err
+	}
+	d.stack = append(d.stack, decStackEntry{
+		Type:    wireTypeType,
+		Index:   -1,
+		LenHint: 1, // wireType is a union
+	})
+	d.flag = d.flag.Set(decFlagIgnoreNextStartValue)
+	if err := __VDLRead_wireType(d, wt); err != nil {
+		return 0, err
+	}
+	return tid, nil
+}
+
+// readRawBytes fills in raw with the next value.  It can be called for both
+// top-level and internal values.
+func (d *decoder81) readRawBytes(raw *RawBytes) error {
+	if d.flag.IgnoreNextStartValue() {
+		// If the user has already called StartValue on the decoder, it's harder to
+		// capture all the raw bytes, since the optional flag and length hints have
+		// already been decoded.  So we simply disallow this from happening.
+		return errReadRawBytesAlreadyStarted
+	}
+	tt, err := d.dfsNextType()
+	if err != nil {
+		return err
+	}
+	// Handle top-level values.  All types of values are supported, since we can
+	// simply copy the message bytes.
+	if len(d.stack) == 0 {
+		anyLen, err := d.peekValueByteLen(tt)
 		if err != nil {
 			return err
 		}
-		if !typeNext {
-			return nil
-		}
-		if err := d.typeDec.readSingleType(); err != nil {
+		if err := d.decodeRaw(tt, anyLen, raw); err != nil {
 			return err
 		}
+		return d.endMessage()
 	}
-}
-
-// peekValueByteLen returns the byte length of the next value.
-func (d *decoder81) peekValueByteLen(tt *vdl.Type) (int, error) {
-	if hasChunkLen(tt) {
-		// Use the explicit message length.
-		return d.buf.lim, nil
+	// Handle internal values.  Only any values are supported at the moment, since
+	// they come with a header that tells us the exact length to read.
+	//
+	// TODO(toddw): Handle other types, either by reading and skipping bytes based
+	// on the type, or by falling back to a decode / re-encode slowpath.
+	if tt.Kind() != vdl.Any {
+		return errReadRawBytesFromNonAny
 	}
-	// No explicit message length, but the length can be computed.
-	switch {
-	case tt.Kind() == vdl.Array && tt.IsBytes():
-		// Byte arrays are exactly their length and encoded with 1-byte header.
-		return tt.Len() + 1, nil
-	case tt.Kind() == vdl.String || tt.IsBytes():
-		// Strings and byte lists are encoded with a length header.
-		strlen, bytelen, err := binaryPeekUint(d.buf)
-		switch {
-		case err != nil:
-			return 0, err
-		case strlen > maxBinaryMsgLen:
-			return 0, verror.New(errMsgLen, nil, maxBinaryMsgLen)
-		}
-		return int(strlen) + bytelen, nil
-	default:
-		// Must be a primitive, which is encoded as an underlying uint.
-		return binaryPeekUintByteLen(d.buf)
-	}
-}
-
-func (d *decoder81) decodeRaw(tt *vdl.Type, valLen int, raw *RawBytes) error {
-	raw.Version = d.buf.version
-	raw.Type = tt
-	raw.Data = make([]byte, valLen)
-	if err := d.buf.ReadIntoBuf(raw.Data); err != nil {
+	ttElem, anyLen, err := d.readAnyHeader()
+	if err != nil {
 		return err
 	}
-	refTypeLen := len(d.refTypes.tids)
-	if cap(raw.RefTypes) >= refTypeLen {
-		raw.RefTypes = raw.RefTypes[:refTypeLen]
-	} else {
-		raw.RefTypes = make([]*vdl.Type, refTypeLen)
+	if ttElem == nil {
+		// This is a nil any value, which has already been read by readAnyHeader.
+		// We simply fill in RawBytes with the single WireCtrlNil byte.
+		raw.Version = d.buf.version
+		raw.Type = vdl.AnyType
+		raw.RefTypes = nil
+		raw.AnyLengths = nil
+		raw.Data = []byte{WireCtrlNil}
+		return nil
 	}
-	for i, tid := range d.refTypes.tids {
-		var err error
-		if raw.RefTypes[i], err = d.typeDec.lookupType(tid); err != nil {
-			return err
-		}
+	return d.decodeRaw(ttElem, anyLen, raw)
+}
+
+func (d *decoder81) StartValue(want *vdl.Type) error {
+	if d.flag.IgnoreNextStartValue() {
+		d.flag = d.flag.Clear(decFlagIgnoreNextStartValue)
+		return nil
 	}
-	raw.AnyLengths = d.refAnyLens.lens
+	tt, err := d.dfsNextType()
+	if err != nil {
+		return err
+	}
+	tt, lenHint, flag, err := d.setupType(tt, want)
+	if err != nil {
+		return err
+	}
+	d.stack = append(d.stack, decStackEntry{
+		Type:    tt,
+		Index:   -1,
+		LenHint: lenHint,
+		Flag:    flag,
+	})
 	return nil
 }
 
-func (d *decoder81) readAnyHeader() (*vdl.Type, int, error) {
-	// Handle WireCtrlNil.
-	switch ok, err := binaryDecodeControlOnly(d.buf, WireCtrlNil); {
-	case err != nil:
-		return nil, 0, err
-	case ok:
-		return nil, 0, nil // nil any
-	}
-	// Read the index of the referenced type id.
-	typeIndex, err := binaryDecodeUint(d.buf)
-	if err != nil {
-		return nil, 0, err
-	}
-	var tid TypeId
-	if d.buf.version == Version80 {
-		tid = TypeId(typeIndex)
-	} else if tid, err = d.refTypes.ReferencedTypeId(typeIndex); err != nil {
-		return nil, 0, err
-	}
-	// Look up the referenced type id.
-	ttElem, err := d.typeDec.lookupType(tid)
-	if err != nil {
-		return nil, 0, err
-	}
-	var anyLen int
-	if d.buf.version != Version80 {
-		// Read and lookup the index of the any byte length.  Reference the any len,
-		// even if it isn't used, to report missing references.
-		lenIndex, err := binaryDecodeUint(d.buf)
-		if err != nil {
-			return nil, 0, err
-		}
-		if anyLen, err = d.refAnyLens.ReferencedAnyLen(lenIndex); err != nil {
-			return nil, 0, err
-		}
-	}
-	return ttElem, anyLen, nil
-}
-
-func (d *decoder81) skipValue(tt *vdl.Type) error {
-	if tt.IsBytes() {
-		len, err := binaryDecodeLenOrArrayLen(d.buf, tt)
-		if err != nil {
-			return err
-		}
-		return d.buf.Skip(len)
-	}
-	switch kind := tt.Kind(); kind {
-	case vdl.Bool:
-		return d.buf.Skip(1)
-	case vdl.Byte, vdl.Uint16, vdl.Uint32, vdl.Uint64, vdl.Int8, vdl.Int16, vdl.Int32, vdl.Int64, vdl.Float32, vdl.Float64, vdl.Enum, vdl.TypeObject:
-		// The underlying encoding of all these types is based on uint.
-		return binarySkipUint(d.buf)
-	case vdl.String:
-		return binarySkipString(d.buf)
-	case vdl.Array, vdl.List, vdl.Set, vdl.Map:
-		len, err := binaryDecodeLenOrArrayLen(d.buf, tt)
-		if err != nil {
-			return err
-		}
-		for ix := 0; ix < len; ix++ {
-			if kind == vdl.Set || kind == vdl.Map {
-				if err := d.skipValue(tt.Key()); err != nil {
-					return err
-				}
-			}
-			if kind == vdl.Array || kind == vdl.List || kind == vdl.Map {
-				if err := d.skipValue(tt.Elem()); err != nil {
-					return err
-				}
-			}
-		}
-		return nil
-	case vdl.Struct:
-		// Loop through decoding the 0-based field index and corresponding field.
-		for {
-			switch ok, err := binaryDecodeControlOnly(d.buf, WireCtrlEnd); {
-			case err != nil:
-				return err
-			case ok:
-				return nil // end of struct
-			}
-			switch index, err := binaryDecodeUint(d.buf); {
-			case err != nil:
-				return err
-			case index >= uint64(tt.NumField()):
-				return verror.New(errIndexOutOfRange, nil)
-			default:
-				ttfield := tt.Field(int(index))
-				if err := d.skipValue(ttfield.Type); err != nil {
-					return err
-				}
-			}
-		}
-	case vdl.Union:
-		switch index, err := binaryDecodeUint(d.buf); {
+func (d *decoder81) setupType(tt, want *vdl.Type) (_ *vdl.Type, lenHint int, flag decStackFlag, _ error) {
+	// Handle any, which may be nil.  We "dereference" non-nil any to the inner
+	// type.  If that happens to be an optional, it's handled below.
+	if tt.Kind() == vdl.Any {
+		flag |= decStackFlagIsAny
+		var err error
+		switch tt, _, err = d.readAnyHeader(); {
 		case err != nil:
-			return err
-		case index >= uint64(tt.NumField()):
-			return verror.New(errIndexOutOfRange, nil)
-		default:
-			ttfield := tt.Field(int(index))
-			return d.skipValue(ttfield.Type)
+			return nil, 0, 0, err
+		case tt == nil:
+			tt = vdl.AnyType // nil any
 		}
-	case vdl.Optional:
+	}
+	// Handle optional, which may be nil.  Similar to any, we "dereference"
+	// non-nil optional to the inner type, which is never allowed to be another
+	// optional or any type.
+	if tt.Kind() == vdl.Optional {
+		flag |= decStackFlagIsOptional
 		// Read the WireCtrlNil code, but if it's not WireCtrlNil we need to keep
 		// the buffer as-is, since it's the first byte of the value, which may
 		// itself be another control code.
 		switch ctrl, err := binaryPeekControl(d.buf); {
 		case err != nil:
-			return err
+			return nil, 0, 0, err
 		case ctrl == WireCtrlNil:
 			d.buf.SkipAvailable(1) // nil optional
-			return nil
 		default:
-			return d.skipValue(tt.Elem()) // non-nil optional
+			tt = tt.Elem() // non-nil optional
 		}
-	case vdl.Any:
-		switch ok, err := binaryDecodeControlOnly(d.buf, WireCtrlNil); {
-		case err != nil:
-			return err
-		case ok:
-			return nil // nil any
-		}
-		switch index, err := binaryDecodeUint(d.buf); {
-		case err != nil:
-			return err
-		default:
-			tid, err := d.refTypes.ReferencedTypeId(index)
-			if err != nil {
-				return err
+	}
+	// Check compatibility between the actual type and the want type.  Since
+	// compatibility applies to the entire static type, we only need to perform
+	// this check for top-level decoded values, and subsequently for decoded any
+	// values.  We skip checking non-composite want types, since those will be
+	// naturally caught by the Decode* calls anyways.
+	if want != nil && (len(d.stack) == 0 || flag.IsAny()) {
+		switch want.Kind() {
+		case vdl.Optional, vdl.Array, vdl.List, vdl.Set, vdl.Map, vdl.Struct, vdl.Union:
+			if tt == want {
+				// Set FastRead flag, which will let us use the fastpath for ReadValue*
+				// in common cases.  We can only use this fastpath if tt and want are
+				// identical, which ensures we don't need to perform any conversions.
+				if !flag.IsAny() && isFastReadParent(tt) {
+					flag |= decStackFlagFastRead
+				}
+				// Regardless of whether we can use the fastpath, there's no need to
+				// check compatibility if tt and want are identical.
+			} else {
+				if !vdl.Compatible(tt, want) {
+					return nil, 0, 0, errIncompatibleDecode(tt, want)
+				}
 			}
-			ttElem, err := d.typeDec.lookupType(tid)
-			if err != nil {
-				return err
-			}
-			return d.skipValue(ttElem)
 		}
+	}
+	// Initialize LenHint for composite types.
+	switch tt.Kind() {
+	case vdl.Array, vdl.List, vdl.Set, vdl.Map:
+		// TODO(toddw): Handle sentry-terminated collections without a length hint.
+		len, err := binaryDecodeLenOrArrayLen(d.buf, tt)
+		if err != nil {
+			return nil, 0, 0, err
+		}
+		lenHint = len
+	case vdl.Union:
+		// Union shouldn't have a LenHint, but we abuse it in NextField as a
+		// convenience for detecting when fields are done, so we initialize it here.
+		// It has to be at least 1, since 0 will cause NextField to think that the
+		// union field has already been decoded.
+		lenHint = 1
+	case vdl.Struct:
+		// Struct shouldn't have a LenHint, but we abuse it in NextField as a
+		// convenience for detecting when fields are done, so we initialize it here.
+		lenHint = tt.NumField()
 	default:
-		return verror.New(errIgnoreValueUnhandledType, nil, tt)
+		lenHint = -1
 	}
+	if top := d.top(); top != nil && top.Type.IsBytes() {
+		d.flag = d.flag.Set(decFlagIsParentBytes)
+	} else {
+		d.flag = d.flag.Clear(decFlagIsParentBytes)
+	}
+	return tt, lenHint, flag, nil
 }
 
-func (d *decoder81) nextMessage() (TypeId, error) {
-	if leftover := d.buf.RemoveLimit(); leftover > 0 {
-		return 0, verror.New(errLeftOverBytes, nil, leftover)
-	}
-	// Decode version byte, if not already decoded.
-	if d.buf.version == 0 {
-		version, err := d.buf.ReadByte()
-		if err != nil {
-			return 0, verror.New(errEndedBeforeVersionByte, nil, err)
-		}
-		d.buf.version = Version(version)
-		if !isAllowedVersion(d.buf.version) {
-			return 0, verror.New(errBadVersionByte, nil, d.buf.version)
-		}
-	}
-	// Decode the next message id.
-	incomplete, err := binaryDecodeControlOnly(d.buf, WireCtrlTypeIncomplete)
-	if err != nil {
-		return 0, err
-	}
-	mid, err := binaryDecodeInt(d.buf)
-	if err != nil {
-		return 0, err
-	}
-	if incomplete {
-		if mid >= 0 {
-			// TypeIncomplete must be followed with a type message.
-			return 0, verror.New(errInvalid, nil)
-		}
-		d.flag = d.flag.Set(decFlagTypeIncomplete)
-	} else if mid < 0 {
-		d.flag = d.flag.Clear(decFlagTypeIncomplete)
-	}
-	// TODO(toddw): Clean up the logic below.
-	var tid TypeId
-	var hasAny, hasTypeObject, hasLength bool
-	switch {
-	case mid < 0:
-		tid = TypeId(-mid)
-		hasLength = true
-		hasAny = false
-		hasTypeObject = false
-	case mid > 0:
-		tid = TypeId(mid)
-		t, err := d.typeDec.lookupType(tid)
-		if err != nil {
-			return 0, err
-		}
-		hasLength = hasChunkLen(t)
-		hasAny = containsAny(t)
-		hasTypeObject = containsTypeObject(t)
-	default:
-		return 0, verror.New(errDecodeZeroTypeID, nil)
-	}
-
-	if (hasAny || hasTypeObject) && d.buf.version != Version80 {
-		l, err := binaryDecodeUint(d.buf)
-		if err != nil {
-			return 0, err
-		}
-		for i := 0; i < int(l); i++ {
-			refId, err := binaryDecodeUint(d.buf)
-			if err != nil {
-				return 0, err
-			}
-			d.refTypes.AddTypeID(TypeId(refId))
-		}
-	}
-	if hasAny && d.buf.version != Version80 {
-		l, err := binaryDecodeUint(d.buf)
-		if err != nil {
-			return 0, err
-		}
-		for i := 0; i < int(l); i++ {
-			refAnyLen, err := binaryDecodeLen(d.buf)
-			if err != nil {
-				return 0, err
-			}
-			d.refAnyLens.AddAnyLen(refAnyLen)
-		}
-	}
-
-	if hasLength {
-		chunkLen, err := binaryDecodeUint(d.buf)
-		if err != nil {
-			return 0, err
-		}
-		d.buf.SetLimit(int(chunkLen))
-	}
-
-	return tid, nil
+func errIncompatibleDecode(tt *vdl.Type, want interface{}) error {
+	return fmt.Errorf("vom: incompatible decode from %v into %v", tt, want)
 }
 
-func (d *decoder81) typeIsNext() (bool, error) {
-	if d.buf.version == 0 {
-		version, err := d.buf.ReadByte()
-		if err != nil {
-			return false, verror.New(errEndedBeforeVersionByte, nil, err)
-		}
-		d.buf.version = Version(version)
-		if !isAllowedVersion(d.buf.version) {
-			return false, verror.New(errBadVersionByte, nil, d.buf.version)
-		}
+func (d *decoder81) FinishValue() error {
+	d.flag = d.flag.Clear(decFlagFinishValue)
+	stackTop := len(d.stack) - 1
+	if stackTop == -1 {
+		return errEmptyDecoderStack
 	}
-	switch ctrl, err := binaryPeekControl(d.buf); {
-	case err != nil:
-		return false, err
-	case ctrl == WireCtrlTypeIncomplete:
-		return true, nil
-	case ctrl != 0:
-		return false, verror.New(errBadControlCode, nil, ctrl)
-	}
-	mid, _, err := binaryPeekInt(d.buf)
-	if err != nil {
-		return false, err
-	}
-	return mid < 0, nil
-}
-
-func (d *decoder81) endMessage() error {
-	if leftover := d.buf.RemoveLimit(); leftover > 0 {
-		return verror.New(errLeftOverBytes, nil, leftover)
-	}
-	if err := d.refTypes.Reset(); err != nil {
-		return err
-	}
-	if err := d.refAnyLens.Reset(); err != nil {
-		return err
+	d.stack = d.stack[:stackTop]
+	if stackTop == 0 {
+		return d.endMessage()
 	}
 	return nil
 }
 
-type referencedTypes struct {
-	tids   []TypeId
-	marker int
-}
-
-func (refTypes *referencedTypes) Reset() (err error) {
-	refTypes.tids = refTypes.tids[:0]
-	refTypes.marker = 0
-	return
-}
-
-func (refTypes *referencedTypes) AddTypeID(tid TypeId) {
-	refTypes.tids = append(refTypes.tids, tid)
-}
-
-func (refTypes *referencedTypes) ReferencedTypeId(index uint64) (TypeId, error) {
-	if index >= uint64(len(refTypes.tids)) {
-		return 0, verror.New(errInvalidTypeIdIndex, nil)
+func (d *decoder81) top() *decStackEntry {
+	if stackTop := len(d.stack) - 1; stackTop >= 0 {
+		return &d.stack[stackTop]
 	}
-	return refTypes.tids[index], nil
+	return nil
 }
 
-func (refTypes *referencedTypes) Mark() {
-	refTypes.marker = len(refTypes.tids)
-}
-
-type referencedAnyLens struct {
-	lens   []int
-	marker int
-}
-
-func (refAnys *referencedAnyLens) Reset() (err error) {
-	refAnys.lens = refAnys.lens[:0]
-	return
-}
-
-func (refAnys *referencedAnyLens) AddAnyLen(len int) {
-	refAnys.lens = append(refAnys.lens, len)
-}
-
-func (refAnys *referencedAnyLens) ReferencedAnyLen(index uint64) (int, error) {
-	if index >= uint64(len(refAnys.lens)) {
-		return 0, verror.New(errInvalidAnyIndex, nil)
+// dfsNextType determines the type of the next value that we will decode, by
+// walking the static type in DFS order.  To bootstrap we retrieve the top-level
+// type from the VOM value message.
+func (d *decoder81) dfsNextType() (*vdl.Type, error) {
+	top := d.top()
+	if top == nil {
+		// Bootstrap: start decoding a new top-level value.
+		if !d.flag.SeparateTypeDec() {
+			if err := d.decodeTypeDefs(); err != nil {
+				return nil, err
+			}
+		}
+		tid, err := d.nextMessage()
+		if err != nil {
+			return nil, err
+		}
+		return d.typeDec.lookupType(tid)
 	}
-	return refAnys.lens[index], nil
+	// Return the next type from our composite types.
+	tt := top.Type
+	switch tt.Kind() {
+	case vdl.Array, vdl.List:
+		return tt.Elem(), nil
+	case vdl.Set:
+		return tt.Key(), nil
+	case vdl.Map:
+		top.Flag = top.Flag.FlipIsMapKey()
+		if top.Flag.IsMapKey() {
+			return tt.Key(), nil
+		} else {
+			return tt.Elem(), nil
+		}
+	case vdl.Union, vdl.Struct:
+		return tt.Field(top.Index).Type, nil
+	}
+	return nil, fmt.Errorf("vom: can't StartValue on %v", tt)
 }
 
-func (refAnys *referencedAnyLens) Mark() {
-	refAnys.marker = len(refAnys.lens)
+func (d *decoder81) NextEntry() (bool, error) {
+	// Our strategy is to increment top.Index until it reaches top.LenHint.
+	// Currently the LenHint is always set, so it's stronger than a hint.
+	//
+	// TODO(toddw): Handle sentry-terminated collections without a LenHint.
+	top := d.top()
+	if top == nil {
+		return false, errEmptyDecoderStack
+	}
+	// Increment index and check errors.
+	top.Index++
+	switch top.Type.Kind() {
+	case vdl.Array, vdl.List, vdl.Set, vdl.Map:
+		if top.Index > top.LenHint && top.LenHint >= 0 {
+			return false, fmt.Errorf("vom: NextEntry called after done, stack: %+v", d.stack)
+		}
+	default:
+		return false, fmt.Errorf("vom: NextEntry called on invalid type, stack: %+v", d.stack)
+	}
+	return top.Index == top.LenHint, nil
+}
+
+func (d *decoder81) NextField() (int, error) {
+	top := d.top()
+	if top == nil {
+		return -1, errEmptyDecoderStack
+	}
+	// Increment index and check errors.  Note that the actual top.Index is
+	// decoded from the buf data stream; we use top.LenHint to help detect when
+	// the fields are done, and to detect invalid calls after we're done.
+	top.Index++
+	switch top.Type.Kind() {
+	case vdl.Union, vdl.Struct:
+		if top.Index > top.LenHint {
+			return -1, fmt.Errorf("vom: NextField called after done, stack: %+v", d.stack)
+		}
+	default:
+		return -1, fmt.Errorf("vom: NextField called on invalid type, stack: %+v", d.stack)
+	}
+	var field int
+	switch top.Type.Kind() {
+	case vdl.Union:
+		if top.Index == top.LenHint {
+			// We know we're done since we set LenHint=Index+1 the first time around,
+			// and we incremented the index above.
+			return -1, nil
+		}
+		// Decode the union field index.
+		switch index, err := binaryDecodeUint(d.buf); {
+		case err != nil:
+			return -1, err
+		case index >= uint64(top.Type.NumField()):
+			return -1, verror.New(errIndexOutOfRange, nil)
+		default:
+			// Set LenHint=Index+1 so that we'll know we're done next time around.
+			field = int(index)
+			top.Index = field
+			top.LenHint = field + 1
+		}
+	case vdl.Struct:
+		// Handle the end-of-struct sentry.
+		switch ok, err := binaryDecodeControlOnly(d.buf, WireCtrlEnd); {
+		case err != nil:
+			return -1, err
+		case ok:
+			// Set Index=LenHint to ensure repeated calls will fail.
+			top.Index = top.LenHint
+			return -1, nil
+		}
+		// Decode the struct field index.
+		switch index, err := binaryDecodeUint(d.buf); {
+		case err != nil:
+			return -1, err
+		case index >= uint64(top.Type.NumField()):
+			return -1, verror.New(errIndexOutOfRange, nil)
+		default:
+			field = int(index)
+			top.Index = field
+		}
+	}
+	return field, nil
+}
+
+func (d *decoder81) Type() *vdl.Type {
+	if top := d.top(); top != nil {
+		return top.Type
+	}
+	return nil
+}
+
+func (d *decoder81) IsAny() bool {
+	if top := d.top(); top != nil {
+		return top.Flag.IsAny()
+	}
+	return false
+}
+
+func (d *decoder81) IsOptional() bool {
+	if top := d.top(); top != nil {
+		return top.Flag.IsOptional()
+	}
+	return false
+}
+
+func (d *decoder81) IsNil() bool {
+	if top := d.top(); top != nil {
+		// Becuase of the "dereferencing" we do, the only time the type is any or
+		// optional is when it's nil.
+		return top.Type == vdl.AnyType || top.Type.Kind() == vdl.Optional
+	}
+	return false
+}
+
+func (d *decoder81) Index() int {
+	if top := d.top(); top != nil {
+		return top.Index
+	}
+	return -1
+}
+
+func (d *decoder81) LenHint() int {
+	if top := d.top(); top != nil {
+		// Note that union and struct shouldn't have a LenHint, but we abuse it in
+		// NextField as a convenience for detecting when fields are done, so an
+		// "arbitrary" value is returned here.  Users shouldn't be looking at it for
+		// union and struct anyways.
+		return top.LenHint
+	}
+	return -1
+}
+
+func (d *decoder81) DecodeBool() (bool, error) {
+	tt := d.Type()
+	if tt == nil {
+		return false, errEmptyDecoderStack
+	}
+	if tt.Kind() == vdl.Bool {
+		return binaryDecodeBool(d.buf)
+	}
+	return false, errIncompatibleDecode(tt, "bool")
+}
+
+func (d *decoder81) DecodeString() (string, error) {
+	tt := d.Type()
+	if tt == nil {
+		return "", errEmptyDecoderStack
+	}
+	switch tt.Kind() {
+	case vdl.String:
+		return binaryDecodeString(d.buf)
+	case vdl.Enum:
+		return d.binaryDecodeEnum(tt)
+	}
+	return "", errIncompatibleDecode(tt, "string")
+}
+
+func (d *decoder81) binaryDecodeEnum(tt *vdl.Type) (string, error) {
+	index, err := binaryDecodeUint(d.buf)
+	switch {
+	case err != nil:
+		return "", err
+	case index >= uint64(tt.NumEnumLabel()):
+		return "", fmt.Errorf("vom: enum index %d out of range, %v", index, tt)
+	}
+	return tt.EnumLabel(int(index)), nil
+}
+
+func (d *decoder81) binaryDecodeByte() (byte, error) {
+	// Handle a special-case where normally single bytes are written out as
+	// variable sized numbers, which use 2 bytes to encode bytes > 127.  But each
+	// byte contained in a list or array is written out as one byte.  E.g.
+	//   byte(0x81)         -> 0xFF81   : single byte with variable-size
+	//   []byte("\x81\x82") -> 0x028182 : each elem byte encoded as one byte
+	if d.flag.IsParentBytes() {
+		return d.buf.ReadByte()
+	}
+	x, err := binaryDecodeUint(d.buf)
+	return byte(x), err
+}
+
+func (d *decoder81) DecodeUint(bitlen int) (uint64, error) {
+	tt := d.Type()
+	if tt == nil {
+		return 0, errEmptyDecoderStack
+	}
+	return d.decodeUint(tt, uint(bitlen))
+}
+
+func (d *decoder81) decodeUint(tt *vdl.Type, ubitlen uint) (uint64, error) {
+	const errFmt = "vom: conversion from %v into uint%d loses precision: %v"
+	switch tt.Kind() {
+	case vdl.Byte:
+		x, err := d.binaryDecodeByte()
+		if err != nil {
+			return 0, err
+		}
+		return uint64(x), err
+	case vdl.Uint16, vdl.Uint32, vdl.Uint64:
+		x, err := binaryDecodeUint(d.buf)
+		if err != nil {
+			return 0, err
+		}
+		if shift := 64 - ubitlen; x != (x<<shift)>>shift {
+			return 0, fmt.Errorf(errFmt, tt, ubitlen, x)
+		}
+		return x, nil
+	case vdl.Int8, vdl.Int16, vdl.Int32, vdl.Int64:
+		x, err := binaryDecodeInt(d.buf)
+		if err != nil {
+			return 0, err
+		}
+		ux := uint64(x)
+		if shift := 64 - ubitlen; x < 0 || ux != (ux<<shift)>>shift {
+			return 0, fmt.Errorf(errFmt, tt, ubitlen, x)
+		}
+		return ux, nil
+	case vdl.Float32, vdl.Float64:
+		x, err := binaryDecodeFloat(d.buf)
+		if err != nil {
+			return 0, err
+		}
+		ux := uint64(x)
+		if shift := 64 - ubitlen; x != float64(ux) || ux != (ux<<shift)>>shift {
+			return 0, fmt.Errorf(errFmt, tt, ubitlen, x)
+		}
+		return ux, nil
+	}
+	return 0, errIncompatibleDecode(tt, fmt.Sprintf("uint%d", ubitlen))
+}
+
+func (d *decoder81) DecodeInt(bitlen int) (int64, error) {
+	tt := d.Type()
+	if tt == nil {
+		return 0, errEmptyDecoderStack
+	}
+	return d.decodeInt(tt, uint(bitlen))
+}
+
+func (d *decoder81) decodeInt(tt *vdl.Type, ubitlen uint) (int64, error) {
+	const errFmt = "vom: conversion from %v into int%d loses precision: %v"
+	switch tt.Kind() {
+	case vdl.Byte:
+		x, err := d.binaryDecodeByte()
+		if err != nil {
+			return 0, err
+		}
+		// The only case that fails is if we're converting byte(x) to int8, and x
+		// uses more than 7 bits (i.e. is greater than 127).
+		if ubitlen <= 8 && x > 0x7f {
+			return 0, fmt.Errorf(errFmt, tt, ubitlen, x)
+		}
+		return int64(x), nil
+	case vdl.Uint16, vdl.Uint32, vdl.Uint64:
+		x, err := binaryDecodeUint(d.buf)
+		if err != nil {
+			return 0, err
+		}
+		ix := int64(x)
+		// The shift uses 65 since the topmost bit is the sign bit.  I.e. 32 bit
+		// numbers should be shifted by 33 rather than 32.
+		if shift := 65 - ubitlen; ix < 0 || x != (x<<shift)>>shift {
+			return 0, fmt.Errorf(errFmt, tt, ubitlen, x)
+		}
+		return ix, nil
+	case vdl.Int8, vdl.Int16, vdl.Int32, vdl.Int64:
+		x, err := binaryDecodeInt(d.buf)
+		if err != nil {
+			return 0, err
+		}
+		if shift := 64 - ubitlen; x != (x<<shift)>>shift {
+			return 0, fmt.Errorf(errFmt, tt, ubitlen, x)
+		}
+		return x, nil
+	case vdl.Float32, vdl.Float64:
+		x, err := binaryDecodeFloat(d.buf)
+		if err != nil {
+			return 0, err
+		}
+		ix := int64(x)
+		if shift := 64 - ubitlen; x != float64(ix) || ix != (ix<<shift)>>shift {
+			return 0, fmt.Errorf(errFmt, tt, ubitlen, x)
+		}
+		return ix, nil
+	}
+	return 0, errIncompatibleDecode(tt, fmt.Sprintf("int%d", ubitlen))
+}
+
+func (d *decoder81) DecodeFloat(bitlen int) (float64, error) {
+	tt := d.Type()
+	if tt == nil {
+		return 0, errEmptyDecoderStack
+	}
+	return d.decodeFloat(tt, uint(bitlen))
+}
+
+func (d *decoder81) decodeFloat(tt *vdl.Type, ubitlen uint) (float64, error) {
+	const errFmt = "vom: conversion from %v into float%d loses precision: %v"
+	switch tt.Kind() {
+	case vdl.Byte:
+		x, err := d.binaryDecodeByte()
+		if err != nil {
+			return 0, err
+		}
+		return float64(x), nil
+	case vdl.Uint16, vdl.Uint32, vdl.Uint64:
+		x, err := binaryDecodeUint(d.buf)
+		if err != nil {
+			return 0, err
+		}
+		var max uint64
+		if ubitlen > 32 {
+			max = float64MaxInt
+		} else {
+			max = float32MaxInt
+		}
+		if x > max {
+			return 0, fmt.Errorf(errFmt, tt, ubitlen, x)
+		}
+		return float64(x), nil
+	case vdl.Int8, vdl.Int16, vdl.Int32, vdl.Int64:
+		x, err := binaryDecodeInt(d.buf)
+		if err != nil {
+			return 0, err
+		}
+		var min, max int64
+		if ubitlen > 32 {
+			min, max = float64MinInt, float64MaxInt
+		} else {
+			min, max = float32MinInt, float32MaxInt
+		}
+		if x < min || x > max {
+			return 0, fmt.Errorf(errFmt, tt, ubitlen, x)
+		}
+		return float64(x), nil
+	case vdl.Float32, vdl.Float64:
+		x, err := binaryDecodeFloat(d.buf)
+		if err != nil {
+			return 0, err
+		}
+		if ubitlen <= 32 && (x < -math.MaxFloat32 || x > math.MaxFloat32) {
+			return 0, fmt.Errorf(errFmt, tt, ubitlen, x)
+		}
+		return x, nil
+	}
+	return 0, errIncompatibleDecode(tt, fmt.Sprintf("float%d", ubitlen))
+}
+
+func (d *decoder81) DecodeBytes(fixedLen int, v *[]byte) error {
+	top := d.top()
+	if top == nil {
+		return errEmptyDecoderStack
+	}
+	tt := top.Type
+	if !tt.IsBytes() {
+		return vdl.DecodeConvertedBytes(d, fixedLen, v)
+	}
+	return d.decodeBytes(tt, top.LenHint, fixedLen, v)
+}
+
+func (d *decoder81) decodeBytes(tt *vdl.Type, lenHint, fixedLen int, v *[]byte) error {
+	switch {
+	case lenHint == -1:
+		return fmt.Errorf("vom: LenHint is currently required, %v", tt)
+	case fixedLen >= 0 && fixedLen != lenHint:
+		return fmt.Errorf("vom: got %d bytes, want fixed len %d, %v", lenHint, fixedLen, tt)
+	case lenHint == 0:
+		*v = nil
+		return nil
+	case fixedLen >= 0:
+		// Only re-use the existing buffer if we're filling in an array.  This
+		// sacrifices some performance, but also avoids bugs when repeatedly
+		// decoding into the same value.
+		*v = (*v)[:lenHint]
+	default:
+		*v = make([]byte, lenHint)
+	}
+	return d.buf.ReadIntoBuf(*v)
+}
+
+func (d *decoder81) DecodeTypeObject() (*vdl.Type, error) {
+	tt := d.Type()
+	if tt == nil {
+		return nil, errEmptyDecoderStack
+	}
+	if tt != vdl.TypeObjectType {
+		return nil, errIncompatibleDecode(tt, "typeobject")
+	}
+	return d.binaryDecodeType()
+}
+
+func (d *decoder81) binaryDecodeType() (*vdl.Type, error) {
+	typeIndex, err := binaryDecodeUint(d.buf)
+	if err != nil {
+		return nil, err
+	}
+	tid, err := d.refTypes.ReferencedTypeId(typeIndex)
+	if err != nil {
+		return nil, err
+	}
+	return d.typeDec.lookupType(tid)
+}
+
+func (d *decoder81) SkipValue() error {
+	tt, err := d.dfsNextType()
+	if err != nil {
+		return err
+	}
+	if len(d.stack) == 0 {
+		// Handle top-level values.  It's easy to determine the byte length of the
+		// value, so we can just skip the bytes.
+		valueLen, err := d.peekValueByteLen(tt)
+		if err != nil {
+			return err
+		}
+		if err := d.buf.Skip(valueLen); err != nil {
+			return err
+		}
+		return d.endMessage()
+	}
+	return d.skipValue(tt)
 }
diff --git a/vom/decoder_test.go b/vom/decoder_test.go
index 6d33e57..98317e4 100644
--- a/vom/decoder_test.go
+++ b/vom/decoder_test.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.
 
-package vom
+package vom_test
 
 import (
 	"bytes"
@@ -16,172 +16,122 @@
 	"testing"
 
 	"v.io/v23/vdl"
-	"v.io/v23/vom/testdata/data81"
+	"v.io/v23/vom"
 	"v.io/v23/vom/testdata/types"
+	"v.io/v23/vom/vomtest"
+
+	// Import verror to ensure that interface tests result in *verror.E
+	_ "v.io/v23/verror"
+)
+
+var (
+	rtIface = reflect.TypeOf((*interface{})(nil)).Elem()
+	rtValue = reflect.TypeOf(vdl.Value{})
 )
 
 func TestDecoder(t *testing.T) {
-	for _, test := range data81.Tests {
-		// Decode hex patterns into binary data.
-		binversion, err := binFromHexPat(test.HexVersion)
-		if err != nil {
-			t.Errorf("%s: couldn't convert to binary from hexversion: %q", test.Name, test.HexVersion)
-			continue
-		}
-		bintype, err := binFromHexPat(test.HexType)
-		if err != nil {
-			t.Errorf("%s: couldn't convert to binary from hextype: %q", test.Name, test.HexType)
-			continue
-		}
-		binvalue, err := binFromHexPat(test.HexValue)
-		if err != nil {
-			t.Errorf("%s: couldn't convert to binary from hexvalue: %q", test.Name, test.HexValue)
-			continue
-		}
-
-		name := test.Name + " [vdl.Value]"
-		testDecodeVDL(t, name, binversion+bintype+binvalue, test.Value)
-		name = test.Name + " [vdl.Value] (with TypeDecoder)"
-		testDecodeVDLWithTypeDecoder(t, name, binversion, bintype, binvalue, test.Value)
-		name = test.Name + " [vdl.Any]"
-		testDecodeVDL(t, name, binversion+bintype+binvalue, vdl.AnyValue(test.Value))
-		name = test.Name + " [vdl.Any] (with TypeDecoder)"
-		testDecodeVDLWithTypeDecoder(t, name, binversion, bintype, binvalue, vdl.AnyValue(test.Value))
-
-		// Convert into Go value for the rest of our tests.
-		goValue, err := toGoValue(test.Value)
-		if err != nil {
-			t.Errorf("%s: %v", test.Name, err)
-			continue
-		}
-
-		name = test.Name + " [go value]"
-		testDecodeGo(t, name, binversion+bintype+binvalue, reflect.TypeOf(goValue), goValue)
-		name = test.Name + " [go value] (with TypeDecoder)"
-		testDecodeGoWithTypeDecoder(t, name, binversion, bintype, binvalue, reflect.TypeOf(goValue), goValue)
-
-		name = test.Name + " [go interface]"
-		testDecodeGo(t, name, binversion+bintype+binvalue, reflect.TypeOf((*interface{})(nil)).Elem(), goValue)
-		name = test.Name + " [go interface] (with TypeDecoder)"
-		testDecodeGoWithTypeDecoder(t, name, binversion, bintype, binvalue, reflect.TypeOf((*interface{})(nil)).Elem(), goValue)
+	// The decoder tests take a long time, so we run them concurrently.
+	var pending sync.WaitGroup
+	for _, test := range vomtest.AllPass() {
+		pending.Add(1)
+		go func(test vomtest.Entry) {
+			defer pending.Done()
+			testDecoder(t, "[go value]", test, rvPtrValue(test.Value))
+			testDecoder(t, "[go iface]", test, rvPtrIface(test.Value))
+			vv, err := vdl.ValueFromReflect(test.Value)
+			if err != nil {
+				t.Errorf("%s: ValueFromReflect failed: %v", test.Name(), err)
+				return
+			}
+			vvWant := reflect.ValueOf(vv)
+			testDecoder(t, "[new *vdl.Value]", test, vvWant)
+			testDecoderFunc(t, "[zero vdl.Value]", test, vvWant, func() reflect.Value {
+				return reflect.ValueOf(vdl.ZeroValue(vv.Type()))
+			})
+		}(test)
 	}
+	pending.Wait()
 }
 
-func testDecodeVDL(t *testing.T, name, bin string, value *vdl.Value) {
-	for _, mode := range AllReadModes {
-		head := fmt.Sprintf("%s (%s)", name, mode)
-		decoder := NewDecoder(mode.TestReader(strings.NewReader(bin)))
-		if value == nil {
-			value = vdl.ZeroValue(vdl.AnyType)
+func rvPtrValue(rv reflect.Value) reflect.Value {
+	result := reflect.New(rv.Type())
+	result.Elem().Set(rv)
+	return result
+}
+
+func rvPtrIface(rv reflect.Value) reflect.Value {
+	result := reflect.New(rtIface)
+	result.Elem().Set(rv)
+	return result
+}
+
+func testDecoder(t *testing.T, pre string, test vomtest.Entry, rvWant reflect.Value) {
+	testDecoderFunc(t, pre, test, rvWant, func() reflect.Value {
+		return reflect.New(rvWant.Type().Elem())
+	})
+	// TODO(toddw): Add tests that start with a randomly-set value.
+}
+
+func testDecoderFunc(t *testing.T, pre string, test vomtest.Entry, rvWant reflect.Value, rvNew func() reflect.Value) {
+	readEOF := make([]byte, 1)
+	for _, mode := range vom.AllReadModes {
+		// Test vom.NewDecoder.
+		{
+			name := fmt.Sprintf("%s (%s) %s", pre, mode, test.Name())
+			rvGot := rvNew()
+			reader := mode.TestReader(bytes.NewReader(test.Bytes()))
+			dec := vom.NewDecoder(reader)
+			if err := dec.Decode(rvGot.Interface()); err != nil {
+				t.Errorf("%s: Decode failed: %v", name, err)
+				return
+			}
+			if !vdl.DeepEqualReflect(rvGot, rvWant) {
+				t.Errorf("%s\nGOT  %v\nWANT %v", name, rvGot, rvWant)
+				return
+			}
+			if n, err := reader.Read(readEOF); n != 0 || err != io.EOF {
+				t.Errorf("%s: reader got (%d,%v), want (0,EOF)", name, n, err)
+			}
 		}
-		got := vdl.ZeroValue(value.Type())
-		if err := decoder.Decode(got); err != nil {
-			t.Errorf("%s: Decode failed: %v", head, err)
-			return
-		}
-		if want := value; !vdl.EqualValue(got, want) {
-			t.Errorf("%s: Decode mismatch\nGOT  %v\nWANT %v", head, got, want)
-			return
+		// Test vom.NewDecoderWithTypeDecoder
+		{
+			name := fmt.Sprintf("%s (%s with TypeDecoder) %s", pre, mode, test.Name())
+			rvGot := rvNew()
+			readerT := mode.TestReader(bytes.NewReader(test.TypeBytes()))
+			decT := vom.NewTypeDecoder(readerT)
+			decT.Start()
+			reader := mode.TestReader(bytes.NewReader(test.ValueBytes()))
+			dec := vom.NewDecoderWithTypeDecoder(reader, decT)
+			err := dec.Decode(rvGot.Interface())
+			decT.Stop()
+			if err != nil {
+				t.Errorf("%s: Decode failed: %v", name, err)
+				return
+			}
+			if !vdl.DeepEqualReflect(rvGot, rvWant) {
+				t.Errorf("%s\nGOT  %v\nWANT %v", name, rvGot, rvWant)
+				return
+			}
+			if n, err := reader.Read(readEOF); n != 0 || err != io.EOF {
+				t.Errorf("%s: reader got (%d,%v), want (0,EOF)", name, n, err)
+			}
+			if n, err := readerT.Read(readEOF); n != 0 || err != io.EOF {
+				t.Errorf("%s: readerT got (%d,%v), want (0,EOF)", name, n, err)
+			}
 		}
 	}
 	// Test single-shot vom.Decode twice, to ensure we test the cache hit case.
-	testDecodeVDLSingleShot(t, name, bin, value)
-	testDecodeVDLSingleShot(t, name, bin, value)
-}
-
-func testDecodeVDLSingleShot(t *testing.T, name, bin string, value *vdl.Value) {
-	// Test the single-shot vom.Decode.
-	head := fmt.Sprintf("%s (single-shot)", name)
-	got := vdl.ZeroValue(value.Type())
-	if err := Decode([]byte(bin), got); err != nil {
-		t.Errorf("%s: Decode failed: %v", head, err)
-		return
-	}
-	if want := value; !vdl.EqualValue(got, want) {
-		t.Errorf("%s: Decode mismatch\nGOT  %v\nWANT %v", head, got, want)
-		return
-	}
-}
-
-func testDecodeVDLWithTypeDecoder(t *testing.T, name, binversion, bintype, binvalue string, value *vdl.Value) {
-	for _, mode := range AllReadModes {
-		head := fmt.Sprintf("%s (%s)", name, mode)
-		typedec := NewTypeDecoder(mode.TestReader(strings.NewReader(binversion + bintype)))
-		typedec.Start()
-		decoder := NewDecoderWithTypeDecoder(mode.TestReader(strings.NewReader(binversion+binvalue)), typedec)
-		if value == nil {
-			value = vdl.ZeroValue(vdl.AnyType)
-		}
-		got := vdl.ZeroValue(value.Type())
-		if err := decoder.Decode(got); err != nil {
-			t.Errorf("%s: Decode failed: %v", head, err)
+	for i := 0; i < 2; i++ {
+		name := fmt.Sprintf("%s (single-shot %d) %s", pre, i, test.Name())
+		rvGot := rvNew()
+		if err := vom.Decode(test.Bytes(), rvGot.Interface()); err != nil {
+			t.Errorf("%s: Decode failed: %v", name, err)
 			return
 		}
-		if want := value; !vdl.EqualValue(got, want) {
-			t.Errorf("%s: Decode mismatch\nGOT  %v\nWANT %v", head, got, want)
+		if !vdl.DeepEqualReflect(rvGot, rvWant) {
+			t.Errorf("%s\nGOT  %v\nWANT %v", name, rvGot, rvWant)
 			return
 		}
-		typedec.Stop()
-	}
-}
-
-func testDecodeGo(t *testing.T, name, bin string, rt reflect.Type, want interface{}) {
-	for _, mode := range AllReadModes {
-		head := fmt.Sprintf("%s (%s)", name, mode)
-		decoder := NewDecoder(mode.TestReader(strings.NewReader(bin)))
-		var got interface{}
-		if rt != nil {
-			got = reflect.New(rt).Elem().Interface()
-		}
-		if err := decoder.Decode(&got); err != nil {
-			t.Errorf("%s: Decode failed: %v", head, err)
-			return
-		}
-		if !vdl.DeepEqual(got, want) {
-			t.Errorf("%s: Decode mismatch\nGOT  %T %+v\nWANT %T %+v", head, got, got, want, want)
-			return
-		}
-	}
-	// Test single-shot vom.Decode twice, to ensure we test the cache hit case.
-	testDecodeGoSingleShot(t, name, bin, rt, want)
-	testDecodeGoSingleShot(t, name, bin, rt, want)
-}
-
-func testDecodeGoSingleShot(t *testing.T, name, bin string, rt reflect.Type, want interface{}) {
-	head := fmt.Sprintf("%s (single-shot)", name)
-	var got interface{}
-	if rt != nil {
-		got = reflect.New(rt).Elem().Interface()
-	}
-	if err := Decode([]byte(bin), &got); err != nil {
-		t.Errorf("%s: Decode failed: %v", head, err)
-		return
-	}
-	if !vdl.DeepEqual(got, want) {
-		t.Errorf("%s: Decode mismatch\nGOT  %T %+v\nWANT %T %+v", head, got, got, want, want)
-		return
-	}
-}
-
-func testDecodeGoWithTypeDecoder(t *testing.T, name, binversion, bintype, binvalue string, rt reflect.Type, want interface{}) {
-	for _, mode := range AllReadModes {
-		head := fmt.Sprintf("%s (%s)", name, mode)
-		typedec := NewTypeDecoder(mode.TestReader(strings.NewReader(binversion + bintype)))
-		typedec.Start()
-		decoder := NewDecoderWithTypeDecoder(mode.TestReader(strings.NewReader(binversion+binvalue)), typedec)
-		var got interface{}
-		if rt != nil {
-			got = reflect.New(rt).Elem().Interface()
-		}
-		if err := decoder.Decode(&got); err != nil {
-			t.Errorf("%s: Decode failed: %v", head, err)
-			return
-		}
-		if !vdl.DeepEqual(got, want) {
-			t.Errorf("%s: Decode mismatch\nGOT  %T %+v\nWANT %T %+v", head, got, got, want, want)
-			return
-		}
-		typedec.Stop()
 	}
 }
 
@@ -253,13 +203,13 @@
 	}
 
 	var (
-		typeenc *TypeEncoder
-		typedec *TypeDecoder
+		typeenc *vom.TypeEncoder
+		typedec *vom.TypeDecoder
 	)
 	if withTypeEncoderDecoder {
 		r, w := newPipe()
-		typeenc = NewTypeEncoder(w)
-		typedec = NewTypeDecoder(r)
+		typeenc = vom.NewTypeEncoder(w)
+		typedec = vom.NewTypeDecoder(r)
 		typedec.Start()
 		defer typedec.Stop()
 	}
@@ -274,16 +224,16 @@
 				name := fmt.Sprintf("[%d]:%+v,%+v", n, test.In, test.Want)
 
 				var (
-					encoder *Encoder
-					decoder *Decoder
+					encoder *vom.Encoder
+					decoder *vom.Decoder
 					buf     bytes.Buffer
 				)
 				if withTypeEncoderDecoder {
-					encoder = NewEncoderWithTypeEncoder(&buf, typeenc)
-					decoder = NewDecoderWithTypeDecoder(&buf, typedec)
+					encoder = vom.NewEncoderWithTypeEncoder(&buf, typeenc)
+					decoder = vom.NewDecoderWithTypeDecoder(&buf, typedec)
 				} else {
-					encoder = NewEncoder(&buf)
-					decoder = NewDecoder(&buf)
+					encoder = vom.NewEncoder(&buf)
+					decoder = vom.NewDecoder(&buf)
 				}
 
 				if err := encoder.Encode(test.In); err != nil {
@@ -374,6 +324,14 @@
 	return err
 }
 
+func hex2Bin(t *testing.T, hex string) []byte {
+	var bin string
+	if _, err := fmt.Sscanf(hex, "%x", &bin); err != nil {
+		t.Fatalf("error converting %q to binary: %v", hex, err)
+	}
+	return []byte(bin)
+}
+
 // Test that no EOF is returned from Decode() if the type stream finished before the value stream.
 func TestTypeStreamEndsFirst(t *testing.T) {
 	hexversion := "81"
@@ -384,10 +342,10 @@
 	binvalue := string(hex2Bin(t, hexvalue))
 	// Ensure EOF isn't returned if the type decode stream ends first
 	tr := newExtractErrReader(strings.NewReader(binversion + bintype))
-	typedec := NewTypeDecoder(tr)
+	typedec := vom.NewTypeDecoder(tr)
 	typedec.Start()
 	wr := newWaitingReader(strings.NewReader(binversion + binvalue))
-	decoder := NewDecoderWithTypeDecoder(wr, typedec)
+	decoder := vom.NewDecoderWithTypeDecoder(wr, typedec)
 	var v interface{}
 	go func() {
 		if tr.WaitForError() == nil {
@@ -415,9 +373,9 @@
 	binversion := string(hex2Bin(t, hexversion))
 	binvalue := string(hex2Bin(t, hexvalue))
 	// Ensure EOF isn't returned if the type decode stream ends first
-	typedec := NewTypeDecoder(&errorReader{})
+	typedec := vom.NewTypeDecoder(&errorReader{})
 	typedec.Start()
-	decoder := NewDecoderWithTypeDecoder(strings.NewReader(binversion+binvalue), typedec)
+	decoder := vom.NewDecoderWithTypeDecoder(strings.NewReader(binversion+binvalue), typedec)
 	var v interface{}
 	if err := decoder.Decode(&v); err == nil {
 		t.Errorf("expected error in decode, but got none")
@@ -428,7 +386,7 @@
 // in a deadlock.
 func TestFuzzTypeDecodeDeadlock(t *testing.T) {
 	var v interface{}
-	d := NewDecoder(strings.NewReader("\x81\x30"))
+	d := vom.NewDecoder(strings.NewReader("\x81\x30"))
 	// Before the fix, this line caused a deadlock and panic.
 	d.Decode(&v)
 	return
@@ -438,7 +396,7 @@
 // panic over in package vdl.
 func TestFuzzVdlPanic(t *testing.T) {
 	var v interface{}
-	d := NewDecoder(strings.NewReader("\x81S*\x00\x00$000000000000000000000000000000000000\x01*\xe1U(\x05\x00 00000000000000000000000000000000\x01*\x02+\xe1"))
+	d := vom.NewDecoder(strings.NewReader("\x81S*\x00\x00$000000000000000000000000000000000000\x01*\xe1U(\x05\x00 00000000000000000000000000000000\x01*\x02+\xe1"))
 	// Before this fix this line caused a panic.
 	d.Decode(&v)
 	return
@@ -487,7 +445,7 @@
 // Test that input found by go-fuzz cannot cause a stack overflow.
 func TestFuzzDecodeOverflow(t *testing.T) {
 	var v interface{}
-	d := NewDecoder(strings.NewReader("\x81\x51\x04\x03\x01\x29\xe1"))
+	d := vom.NewDecoder(strings.NewReader("\x81\x51\x04\x03\x01\x29\xe1"))
 
 	// Before the fix, this line caused a stack overflow.  After the fix, we
 	// expect an error.
@@ -499,7 +457,7 @@
 // Test that input discovered by go-fuzz does not result in a hang anymore.
 func TestFuzzTypeDecodeHang(t *testing.T) {
 	var v interface{}
-	d := NewDecoder(strings.NewReader(
+	d := vom.NewDecoder(strings.NewReader(
 		"\x81W&\x03\x00 v.io/v23/vom/t" +
 			"estdata/types.Rec4\x01)" +
 			"\xe1U&\x03\x00 v.io/v23/vom/t" +
@@ -530,14 +488,14 @@
 		X []byte
 		B bar
 	}
-	encoded, err := Encode(foo{"hello", 42, 3.14159265359, []byte{1, 2, 3, 4, 5, 6}, bar{[]int64{0}}})
+	encoded, err := vom.Encode(foo{"hello", 42, 3.14159265359, []byte{1, 2, 3, 4, 5, 6}, bar{[]int64{0}}})
 	if err != nil {
 		t.Fatalf("Encode failed: %v", err)
 	}
 	for x := 0; x < len(encoded)-1; x++ {
 		var f interface{}
-		if err := Decode(encoded[:x], &f); err == nil {
-			t.Errorf("Encode did not fail with x=%d", x)
+		if err := vom.Decode(encoded[:x], &f); err == nil {
+			t.Errorf("Decode did not fail with x=%d", x)
 		}
 	}
 }
diff --git a/vom/decoder_util.go b/vom/decoder_util.go
new file mode 100644
index 0000000..01753a9
--- /dev/null
+++ b/vom/decoder_util.go
@@ -0,0 +1,412 @@
+// Copyright 2015 The Vanadium 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 vom
+
+import (
+	"v.io/v23/vdl"
+	"v.io/v23/verror"
+)
+
+var (
+	errDecodeZeroTypeID         = verror.Register(pkgPath+".errDecodeZeroTypeID", verror.NoRetry, "{1:}{2:} vom: zero type id{:_}")
+	errIndexOutOfRange          = verror.Register(pkgPath+".errIndexOutOfRange", verror.NoRetry, "{1:}{2:} vom: index out of range{:_}")
+	errLeftOverBytes            = verror.Register(pkgPath+".errLeftOverBytes", verror.NoRetry, "{1:}{2:} vom: {3} leftover bytes{:_}")
+	errUnexpectedControlByte    = verror.Register(pkgPath+".errUnexpectedControlByte", verror.NoRetry, "{1:}{2:} vom: unexpected control byte {3}{:_}")
+	errDecodeValueUnhandledType = verror.Register(pkgPath+".errDecodeValueUnhandledType", verror.NoRetry, "{1:}{2:} vom: decodeValue unhandled type {3}{:_}")
+	errIgnoreValueUnhandledType = verror.Register(pkgPath+".errIgnoreValueUnhandledType", verror.NoRetry, "{1:}{2:} vom: ignoreValue unhandled type {3}{:_}")
+	errInvalidTypeIdIndex       = verror.Register(pkgPath+".errInvalidTypeIdIndex", verror.NoRetry, "{1:}{2:} vom: value referenced invalid index into type id table {:_}")
+	errInvalidAnyIndex          = verror.Register(pkgPath+".errInvalidAnyIndex", verror.NoRetry, "{1:}{2:} vom: value referenced invalid index into anyLen table {:_}")
+)
+
+func (d *decoder81) decodeTypeDefs() error {
+	for {
+		typeNext, err := d.typeIsNext()
+		if err != nil {
+			return err
+		}
+		if !typeNext {
+			return nil
+		}
+		if err := d.typeDec.readSingleType(); err != nil {
+			return err
+		}
+	}
+}
+
+// peekValueByteLen returns the byte length of the next value.
+func (d *decoder81) peekValueByteLen(tt *vdl.Type) (int, error) {
+	if hasChunkLen(tt) {
+		// Use the explicit message length.
+		return d.buf.lim, nil
+	}
+	// No explicit message length, but the length can be computed.
+	switch {
+	case tt.Kind() == vdl.Array && tt.IsBytes():
+		// Byte arrays are exactly their length and encoded with 1-byte header.
+		return tt.Len() + 1, nil
+	case tt.Kind() == vdl.String || tt.IsBytes():
+		// Strings and byte lists are encoded with a length header.
+		strlen, bytelen, err := binaryPeekUint(d.buf)
+		switch {
+		case err != nil:
+			return 0, err
+		case strlen > maxBinaryMsgLen:
+			return 0, verror.New(errMsgLen, nil, maxBinaryMsgLen)
+		}
+		return int(strlen) + bytelen, nil
+	default:
+		// Must be a primitive, which is encoded as an underlying uint.
+		return binaryPeekUintByteLen(d.buf)
+	}
+}
+
+func (d *decoder81) decodeRaw(tt *vdl.Type, valLen int, raw *RawBytes) error {
+	raw.Version = d.buf.version
+	raw.Type = tt
+	raw.Data = make([]byte, valLen)
+	if err := d.buf.ReadIntoBuf(raw.Data); err != nil {
+		return err
+	}
+	refTypeLen := len(d.refTypes.tids)
+	if cap(raw.RefTypes) >= refTypeLen {
+		raw.RefTypes = raw.RefTypes[:refTypeLen]
+	} else {
+		raw.RefTypes = make([]*vdl.Type, refTypeLen)
+	}
+	for i, tid := range d.refTypes.tids {
+		var err error
+		if raw.RefTypes[i], err = d.typeDec.lookupType(tid); err != nil {
+			return err
+		}
+	}
+	raw.AnyLengths = d.refAnyLens.lens
+	return nil
+}
+
+func (d *decoder81) readAnyHeader() (*vdl.Type, int, error) {
+	// Handle WireCtrlNil.
+	switch ok, err := binaryDecodeControlOnly(d.buf, WireCtrlNil); {
+	case err != nil:
+		return nil, 0, err
+	case ok:
+		return nil, 0, nil // nil any
+	}
+	// Read the index of the referenced type id.
+	typeIndex, err := binaryDecodeUint(d.buf)
+	if err != nil {
+		return nil, 0, err
+	}
+	var tid TypeId
+	if d.buf.version == Version80 {
+		tid = TypeId(typeIndex)
+	} else if tid, err = d.refTypes.ReferencedTypeId(typeIndex); err != nil {
+		return nil, 0, err
+	}
+	// Look up the referenced type id.
+	ttElem, err := d.typeDec.lookupType(tid)
+	if err != nil {
+		return nil, 0, err
+	}
+	var anyLen int
+	if d.buf.version != Version80 {
+		// Read and lookup the index of the any byte length.  Reference the any len,
+		// even if it isn't used, to report missing references.
+		lenIndex, err := binaryDecodeUint(d.buf)
+		if err != nil {
+			return nil, 0, err
+		}
+		if anyLen, err = d.refAnyLens.ReferencedAnyLen(lenIndex); err != nil {
+			return nil, 0, err
+		}
+	}
+	return ttElem, anyLen, nil
+}
+
+func (d *decoder81) skipValue(tt *vdl.Type) error {
+	if tt.IsBytes() {
+		len, err := binaryDecodeLenOrArrayLen(d.buf, tt)
+		if err != nil {
+			return err
+		}
+		return d.buf.Skip(len)
+	}
+	switch kind := tt.Kind(); kind {
+	case vdl.Bool:
+		return d.buf.Skip(1)
+	case vdl.Byte, vdl.Uint16, vdl.Uint32, vdl.Uint64, vdl.Int8, vdl.Int16, vdl.Int32, vdl.Int64, vdl.Float32, vdl.Float64, vdl.Enum, vdl.TypeObject:
+		// The underlying encoding of all these types is based on uint.
+		return binarySkipUint(d.buf)
+	case vdl.String:
+		return binarySkipString(d.buf)
+	case vdl.Array, vdl.List, vdl.Set, vdl.Map:
+		len, err := binaryDecodeLenOrArrayLen(d.buf, tt)
+		if err != nil {
+			return err
+		}
+		for ix := 0; ix < len; ix++ {
+			if kind == vdl.Set || kind == vdl.Map {
+				if err := d.skipValue(tt.Key()); err != nil {
+					return err
+				}
+			}
+			if kind == vdl.Array || kind == vdl.List || kind == vdl.Map {
+				if err := d.skipValue(tt.Elem()); err != nil {
+					return err
+				}
+			}
+		}
+		return nil
+	case vdl.Struct:
+		// Loop through decoding the 0-based field index and corresponding field.
+		for {
+			switch ok, err := binaryDecodeControlOnly(d.buf, WireCtrlEnd); {
+			case err != nil:
+				return err
+			case ok:
+				return nil // end of struct
+			}
+			switch index, err := binaryDecodeUint(d.buf); {
+			case err != nil:
+				return err
+			case index >= uint64(tt.NumField()):
+				return verror.New(errIndexOutOfRange, nil)
+			default:
+				ttfield := tt.Field(int(index))
+				if err := d.skipValue(ttfield.Type); err != nil {
+					return err
+				}
+			}
+		}
+	case vdl.Union:
+		switch index, err := binaryDecodeUint(d.buf); {
+		case err != nil:
+			return err
+		case index >= uint64(tt.NumField()):
+			return verror.New(errIndexOutOfRange, nil)
+		default:
+			ttfield := tt.Field(int(index))
+			return d.skipValue(ttfield.Type)
+		}
+	case vdl.Optional:
+		// Read the WireCtrlNil code, but if it's not WireCtrlNil we need to keep
+		// the buffer as-is, since it's the first byte of the value, which may
+		// itself be another control code.
+		switch ctrl, err := binaryPeekControl(d.buf); {
+		case err != nil:
+			return err
+		case ctrl == WireCtrlNil:
+			d.buf.SkipAvailable(1) // nil optional
+			return nil
+		default:
+			return d.skipValue(tt.Elem()) // non-nil optional
+		}
+	case vdl.Any:
+		switch ok, err := binaryDecodeControlOnly(d.buf, WireCtrlNil); {
+		case err != nil:
+			return err
+		case ok:
+			return nil // nil any
+		}
+		switch index, err := binaryDecodeUint(d.buf); {
+		case err != nil:
+			return err
+		default:
+			tid, err := d.refTypes.ReferencedTypeId(index)
+			if err != nil {
+				return err
+			}
+			ttElem, err := d.typeDec.lookupType(tid)
+			if err != nil {
+				return err
+			}
+			return d.skipValue(ttElem)
+		}
+	default:
+		return verror.New(errIgnoreValueUnhandledType, nil, tt)
+	}
+}
+
+func (d *decoder81) nextMessage() (TypeId, error) {
+	if leftover := d.buf.RemoveLimit(); leftover > 0 {
+		return 0, verror.New(errLeftOverBytes, nil, leftover)
+	}
+	// Decode version byte, if not already decoded.
+	if d.buf.version == 0 {
+		version, err := d.buf.ReadByte()
+		if err != nil {
+			return 0, verror.New(errEndedBeforeVersionByte, nil, err)
+		}
+		d.buf.version = Version(version)
+		if !isAllowedVersion(d.buf.version) {
+			return 0, verror.New(errBadVersionByte, nil, d.buf.version)
+		}
+	}
+	// Decode the next message id.
+	incomplete, err := binaryDecodeControlOnly(d.buf, WireCtrlTypeIncomplete)
+	if err != nil {
+		return 0, err
+	}
+	mid, err := binaryDecodeInt(d.buf)
+	if err != nil {
+		return 0, err
+	}
+	if incomplete {
+		if mid >= 0 {
+			// TypeIncomplete must be followed with a type message.
+			return 0, verror.New(errInvalid, nil)
+		}
+		d.flag = d.flag.Set(decFlagTypeIncomplete)
+	} else if mid < 0 {
+		d.flag = d.flag.Clear(decFlagTypeIncomplete)
+	}
+	// TODO(toddw): Clean up the logic below.
+	var tid TypeId
+	var hasAny, hasTypeObject, hasLength bool
+	switch {
+	case mid < 0:
+		tid = TypeId(-mid)
+		hasLength = true
+		hasAny = false
+		hasTypeObject = false
+	case mid > 0:
+		tid = TypeId(mid)
+		t, err := d.typeDec.lookupType(tid)
+		if err != nil {
+			return 0, err
+		}
+		hasLength = hasChunkLen(t)
+		hasAny = containsAny(t)
+		hasTypeObject = containsTypeObject(t)
+	default:
+		return 0, verror.New(errDecodeZeroTypeID, nil)
+	}
+
+	if (hasAny || hasTypeObject) && d.buf.version != Version80 {
+		l, err := binaryDecodeUint(d.buf)
+		if err != nil {
+			return 0, err
+		}
+		for i := 0; i < int(l); i++ {
+			refId, err := binaryDecodeUint(d.buf)
+			if err != nil {
+				return 0, err
+			}
+			d.refTypes.AddTypeID(TypeId(refId))
+		}
+	}
+	if hasAny && d.buf.version != Version80 {
+		l, err := binaryDecodeUint(d.buf)
+		if err != nil {
+			return 0, err
+		}
+		for i := 0; i < int(l); i++ {
+			refAnyLen, err := binaryDecodeLen(d.buf)
+			if err != nil {
+				return 0, err
+			}
+			d.refAnyLens.AddAnyLen(refAnyLen)
+		}
+	}
+
+	if hasLength {
+		chunkLen, err := binaryDecodeUint(d.buf)
+		if err != nil {
+			return 0, err
+		}
+		d.buf.SetLimit(int(chunkLen))
+	}
+
+	return tid, nil
+}
+
+func (d *decoder81) typeIsNext() (bool, error) {
+	if d.buf.version == 0 {
+		version, err := d.buf.ReadByte()
+		if err != nil {
+			return false, verror.New(errEndedBeforeVersionByte, nil, err)
+		}
+		d.buf.version = Version(version)
+		if !isAllowedVersion(d.buf.version) {
+			return false, verror.New(errBadVersionByte, nil, d.buf.version)
+		}
+	}
+	switch ctrl, err := binaryPeekControl(d.buf); {
+	case err != nil:
+		return false, err
+	case ctrl == WireCtrlTypeIncomplete:
+		return true, nil
+	case ctrl != 0:
+		return false, verror.New(errBadControlCode, nil, ctrl)
+	}
+	mid, _, err := binaryPeekInt(d.buf)
+	if err != nil {
+		return false, err
+	}
+	return mid < 0, nil
+}
+
+func (d *decoder81) endMessage() error {
+	if leftover := d.buf.RemoveLimit(); leftover > 0 {
+		return verror.New(errLeftOverBytes, nil, leftover)
+	}
+	if err := d.refTypes.Reset(); err != nil {
+		return err
+	}
+	if err := d.refAnyLens.Reset(); err != nil {
+		return err
+	}
+	return nil
+}
+
+type referencedTypes struct {
+	tids   []TypeId
+	marker int
+}
+
+func (refTypes *referencedTypes) Reset() (err error) {
+	refTypes.tids = refTypes.tids[:0]
+	refTypes.marker = 0
+	return
+}
+
+func (refTypes *referencedTypes) AddTypeID(tid TypeId) {
+	refTypes.tids = append(refTypes.tids, tid)
+}
+
+func (refTypes *referencedTypes) ReferencedTypeId(index uint64) (TypeId, error) {
+	if index >= uint64(len(refTypes.tids)) {
+		return 0, verror.New(errInvalidTypeIdIndex, nil)
+	}
+	return refTypes.tids[index], nil
+}
+
+func (refTypes *referencedTypes) Mark() {
+	refTypes.marker = len(refTypes.tids)
+}
+
+type referencedAnyLens struct {
+	lens   []int
+	marker int
+}
+
+func (refAnys *referencedAnyLens) Reset() (err error) {
+	refAnys.lens = refAnys.lens[:0]
+	return
+}
+
+func (refAnys *referencedAnyLens) AddAnyLen(len int) {
+	refAnys.lens = append(refAnys.lens, len)
+}
+
+func (refAnys *referencedAnyLens) ReferencedAnyLen(index uint64) (int, error) {
+	if index >= uint64(len(refAnys.lens)) {
+		return 0, verror.New(errInvalidAnyIndex, nil)
+	}
+	return refAnys.lens[index], nil
+}
+
+func (refAnys *referencedAnyLens) Mark() {
+	refAnys.marker = len(refAnys.lens)
+}
diff --git a/vom/encoder.go b/vom/encoder.go
index 6af4f26..d3e3697 100644
--- a/vom/encoder.go
+++ b/vom/encoder.go
@@ -90,7 +90,7 @@
 	return e
 }
 
-func newXEncoderForRawBytes(w io.Writer) *encoder81 {
+func newEncoderForRawBytes(w io.Writer) *encoder81 {
 	// RawBytes doesn't need the types to be encoded, since it holds the in-memory
 	// representation.  We still need a type encoder to collect the unique types,
 	// but we give it a dummy encoder that doesn't have any state set up.
diff --git a/vom/encoder_test.go b/vom/encoder_test.go
index 9baaf9a..ea9e846 100644
--- a/vom/encoder_test.go
+++ b/vom/encoder_test.go
@@ -2,95 +2,75 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-package vom
+package vom_test
 
 import (
 	"bytes"
 	"fmt"
 	"testing"
 
-	"v.io/v23/vom/testdata/data81"
-	"v.io/v23/vom/testdata/types"
+	"v.io/v23/vdl"
+	"v.io/v23/vom"
+	"v.io/v23/vom/vomtest"
 )
 
-func TestEncoder81(t *testing.T) {
-	testEncoder(t, Version81, data81.Tests)
-}
-
-func testEncoder(t *testing.T, version Version, tests []types.TestCase) {
-	for _, test := range tests {
-		name := test.Name + " [vdl.Value]"
-		testEncode(t, version, name, test.Value, test.HexVersion+test.HexType+test.HexValue)
-		name = test.Name + " [vdl.Value] (with TypeEncoder)"
-		testEncodeWithTypeEncoder(t, version, name, test.Value, test.HexVersion, test.HexType, test.HexValue)
-
-		// Convert into Go value for the rest of our tests.
-		goValue, err := toGoValue(test.Value)
+func TestEncoder(t *testing.T) {
+	for _, test := range vomtest.AllPass() {
+		testEncoder(t, "[go value]", test, test.Value.Interface())
+		vv, err := vdl.ValueFromReflect(test.Value)
 		if err != nil {
-			t.Errorf("%s: %v", name, err)
+			t.Errorf("%s: ValueFromReflect failed: %v", test.Name(), err)
 			continue
 		}
-
-		name = test.Name + " [go value]"
-		testEncode(t, version, name, goValue, test.HexVersion+test.HexType+test.HexValue)
-		name = test.Name + " [go value] (with TypeEncoder)"
-		testEncodeWithTypeEncoder(t, version, name, goValue, test.HexVersion, test.HexType, test.HexValue)
+		testEncoder(t, "[vdl.Value]", test, vv)
 	}
 }
 
-func testEncode(t *testing.T, version Version, name string, value interface{}, hex string) {
-	for _, singleShot := range []bool{false, true} {
-		var bin []byte
-		if !singleShot {
-			var buf bytes.Buffer
-			encoder := NewVersionedEncoder(version, &buf)
-			if err := encoder.Encode(value); err != nil {
-				t.Errorf("%s: Encode(%#v) failed: %v", name, value, err)
-				return
-			}
-			bin = buf.Bytes()
-		} else {
-			name += " (single-shot)"
-			var err error
-			bin, err = VersionedEncode(version, value)
-			if err != nil {
-				t.Errorf("%s: Encode(%#v) failed: %v", name, value, err)
-				return
-			}
+func testEncoder(t *testing.T, pre string, test vomtest.Entry, value interface{}) {
+	// Test vom.NewEncoder.
+	{
+		var buf bytes.Buffer
+		name := fmt.Sprintf("%s %s", pre, test.Name())
+		enc := vom.NewVersionedEncoder(test.Version, &buf)
+		if err := enc.Encode(value); err != nil {
+			t.Errorf("%s: Encode failed: %v", name, err)
+			return
 		}
-		got, want := fmt.Sprintf("%x", bin), hex
-		match, err := matchHexPat(got, want)
+		if got, want := buf.Bytes(), test.Bytes(); !bytes.Equal(got, want) {
+			t.Errorf("%s\nGOT  %x\nWANT %x", name, got, want)
+			return
+		}
+	}
+	// Test vom.NewEncoderWithTypeEncoder.
+	{
+		var buf, bufT bytes.Buffer
+		name := fmt.Sprintf("%s (with TypeEncoder) %s", pre, test.Name())
+		encT := vom.NewVersionedTypeEncoder(test.Version, &bufT)
+		enc := vom.NewVersionedEncoderWithTypeEncoder(test.Version, &buf, encT)
+		if err := enc.Encode(value); err != nil {
+			t.Errorf("%s: Encode failed: %v", name, err)
+			return
+		}
+		if got, want := bufT.Bytes(), test.TypeBytes(); !bytes.Equal(got, want) {
+			t.Errorf("%s TYPE\nGOT  %x\nWANT %x", name, got, want)
+			return
+		}
+		if got, want := buf.Bytes(), test.ValueBytes(); !bytes.Equal(got, want) {
+			t.Errorf("%s VALUE\nGOT  %x\nWANT %x", name, got, want)
+			return
+		}
+	}
+	// Test single-shot vom.Encode.
+	{
+		name := fmt.Sprintf("%s (single-shot) %s", pre, test.Name())
+		buf, err := vom.VersionedEncode(test.Version, value)
 		if err != nil {
-			t.Error(err)
+			t.Errorf("%s: Encode failed: %v", name, err)
+			return
 		}
-		if !match {
-			t.Errorf("%s: Encode(%#v)\nGOT  %s\nWANT %s", name, value, got, want)
+		if got, want := buf, test.Bytes(); !bytes.Equal(got, want) {
+			t.Errorf("%s\nGOT  %x\nWANT %x", name, got, want)
+			return
 		}
 	}
 }
-
-func testEncodeWithTypeEncoder(t *testing.T, version Version, name string, value interface{}, hexversion, hextype, hexvalue string) {
-	var buf, typebuf bytes.Buffer
-	typeenc := NewVersionedTypeEncoder(version, &typebuf)
-	encoder := NewVersionedEncoderWithTypeEncoder(version, &buf, typeenc)
-	if err := encoder.Encode(value); err != nil {
-		t.Errorf("%s: Encode(%#v) failed: %v", name, value, err)
-		return
-	}
-	got, want := fmt.Sprintf("%x", typebuf.Bytes()), hexversion+hextype
-	match, err := matchHexPat(got, want)
-	if err != nil {
-		t.Error(err)
-	}
-	if !match && len(hextype) > 0 {
-		t.Errorf("%s: EncodeType(%#v)\nGOT  %s\nWANT %s", name, value, got, want)
-	}
-	got, want = fmt.Sprintf("%x", buf.Bytes()), hexversion+hexvalue
-	match, err = matchHexPat(got, want)
-	if err != nil {
-		t.Error(err)
-	}
-	if !match {
-		t.Errorf("%s: Encode(%#v)\nGOT  %s\nWANT %s", name, value, got, want)
-	}
-}
diff --git a/vom/fuzzdump_test.go b/vom/fuzzdump_test.go
index 0cd9399..1b6e908 100644
--- a/vom/fuzzdump_test.go
+++ b/vom/fuzzdump_test.go
@@ -4,7 +4,7 @@
 
 // +build fuzzdump
 
-package vom
+package vom_test
 
 import (
 	"crypto/sha1"
@@ -13,8 +13,7 @@
 	"os"
 	"testing"
 
-	"v.io/v23/vom/testdata/data80"
-	"v.io/v23/vom/testdata/data81"
+	"v.io/v23/vom/vomtest"
 )
 
 // Add the vom tests as binary examples for the fuzzer.
@@ -27,34 +26,16 @@
 
 	seen := make(map[[sha1.Size]byte]bool)
 
-	tests := append(data80.Tests, data81.Tests...)
-
-	for _, test := range tests {
-		binversion, err := binFromHexPat(test.HexVersion)
-		if err != nil {
-			t.Fatal(err)
-		}
-
-		bintype, err := binFromHexPat(test.HexType)
-		if err != nil {
-			t.Fatal(err)
-		}
-
-		binvalue, err := binFromHexPat(test.HexValue)
-		if err != nil {
-			t.Fatal(err)
-		}
-
-		data := []byte(binversion + bintype + binvalue)
+	for _, test := range vomtest.AllPass() {
+		data := test.Bytes()
 		hash := sha1.Sum(data)
-
 		if seen[hash] {
 			continue
 		}
 		seen[hash] = true
 
-		fn := fmt.Sprintf("fuzz-workdir/corpus/%x", hash)
-		if err := ioutil.WriteFile(fn, data, 0644); err != nil {
+		name := fmt.Sprintf("fuzz-workdir/corpus/%x", hash)
+		if err := ioutil.WriteFile(name, data, 0644); err != nil {
 			t.Fatal(err)
 		}
 	}
diff --git a/vom/new_raw_bytes_test.go b/vom/new_raw_bytes_test.go
deleted file mode 100644
index 3631218..0000000
--- a/vom/new_raw_bytes_test.go
+++ /dev/null
@@ -1,138 +0,0 @@
-// Copyright 2015 The Vanadium 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 vom_test
-
-import (
-	"bytes"
-	"io"
-	"testing"
-
-	"v.io/v23/vdl"
-	"v.io/v23/vom"
-	"v.io/v23/vom/vomtest"
-)
-
-// TODO(toddw): Clean up these tests.
-
-func TestXRawBytesDecodeEncode(t *testing.T) {
-	for _, test := range vomtest.AllPass() {
-		// Interleaved
-		rb := vom.RawBytes{}
-		interleavedReader := bytes.NewReader(test.Bytes())
-		if err := vom.NewDecoder(interleavedReader).Decode(&rb); err != nil {
-			t.Errorf("%s: decode failed: %v", test.Name(), err)
-			continue
-		}
-		if _, err := interleavedReader.ReadByte(); err != io.EOF {
-			t.Errorf("%s: expected EOF, but got %v", test.Name(), err)
-			continue
-		}
-
-		var out bytes.Buffer
-		enc := vom.NewVersionedEncoder(test.Version, &out)
-		if err := enc.Encode(&rb); err != nil {
-			t.Errorf("%s: encode failed: %v\nRawBytes: %v", test.Name(), err, rb)
-			continue
-		}
-		if got, want := out.Bytes(), test.Bytes(); !bytes.Equal(got, want) {
-			t.Errorf("%s\nGOT  %x\nWANT %x", test.Name(), got, want)
-		}
-
-		// Split type and value stream.
-		rb = vom.RawBytes{}
-		typeReader := bytes.NewReader(test.TypeBytes())
-		typeDec := vom.NewTypeDecoder(typeReader)
-		typeDec.Start()
-		defer typeDec.Stop()
-		valueReader := bytes.NewReader(test.ValueBytes())
-		if err := vom.NewDecoderWithTypeDecoder(valueReader, typeDec).Decode(&rb); err != nil {
-			t.Errorf("%s: decode failed: %v", test.Name(), err)
-			continue
-		}
-		if _, err := typeReader.ReadByte(); err != io.EOF {
-			t.Errorf("%s: type reader got %v, want EOF", test.Name(), err)
-			continue
-		}
-		if _, err := valueReader.ReadByte(); err != io.EOF {
-			t.Errorf("%s: value reader got %v, want EOF", test.Name(), err)
-			continue
-		}
-
-		out.Reset()
-		var typeOut bytes.Buffer
-		typeEnc := vom.NewVersionedTypeEncoder(test.Version, &typeOut)
-		enc = vom.NewVersionedEncoderWithTypeEncoder(test.Version, &out, typeEnc)
-		if err := enc.Encode(&rb); err != nil {
-			t.Errorf("%s: encode failed: %v\nRawBytes: %v", test.Name(), err, rb)
-			continue
-		}
-		if got, want := typeOut.Bytes(), test.TypeBytes(); !bytes.Equal(got, want) {
-			t.Errorf("%s: type bytes\nGOT  %x\nWANT %x", test.Name(), got, want)
-		}
-		if got, want := out.Bytes(), test.ValueBytes(); !bytes.Equal(got, want) {
-			t.Errorf("%s: value bytes\nGOT  %x\nWANT %x", test.Name(), got, want)
-		}
-	}
-}
-
-func TestXRawBytesToFromValue(t *testing.T) {
-	for _, test := range vomtest.AllPass() {
-		rb, err := vom.XRawBytesFromValue(test.Value.Interface())
-		if err != nil {
-			t.Errorf("%v %s: XRawBytesFromValue failed: %v", test.Version, test.Name(), err)
-			continue
-		}
-		var vv *vdl.Value
-		if err := rb.ToValue(&vv); err != nil {
-			t.Errorf("%v %s: rb.ToValue failed: %v", test.Version, test.Name(), err)
-			continue
-		}
-		if got, want := vv, vdl.ValueOf(test.Value.Interface()); !vdl.EqualValue(got, want) {
-			t.Errorf("%v %s\nGOT  %v\nWANT %v", test.Version, test.Name(), got, want)
-		}
-	}
-}
-
-func TestXRawBytesDecoder(t *testing.T) {
-	for _, test := range vomtest.AllPass() {
-		tt, err := vdl.TypeFromReflect(test.Value.Type())
-		if err != nil {
-			t.Errorf("%s: TypeFromReflect failed: %v", test.Name(), err)
-			continue
-		}
-		in, err := vom.XRawBytesFromValue(test.Value.Interface())
-		if err != nil {
-			t.Errorf("%s: XRawBytesFromValue failed: %v", test.Name(), err)
-			continue
-		}
-		out := vdl.ZeroValue(tt)
-		if err := out.VDLRead(in.Decoder()); err != nil {
-			t.Errorf("%s: VDLRead failed: %v", test.Name(), err)
-			continue
-		}
-		if got, want := out, vdl.ValueOf(test.Value.Interface()); !vdl.EqualValue(got, want) {
-			t.Errorf("%s\nGOT  %v\nWANT %v", test.Name(), got, want)
-		}
-	}
-}
-
-func TestXRawBytesWriter(t *testing.T) {
-	for _, test := range vomtest.AllPass() {
-		var buf bytes.Buffer
-		enc := vom.NewEncoder(&buf)
-		rb, err := vom.XRawBytesFromValue(test.Value.Interface())
-		if err != nil {
-			t.Errorf("%s: XRawBytesFromValue failed: %v", test.Name(), err)
-			continue
-		}
-		if err := rb.VDLWrite(enc.Encoder()); err != nil {
-			t.Errorf("%s: VDLWrite failed: %v", test.Name(), err)
-			continue
-		}
-		if got, want := buf.Bytes(), test.Bytes(); !bytes.Equal(got, want) {
-			t.Errorf("%s\nGOT  %x\nWANT %x", test.Name(), got, want)
-		}
-	}
-}
diff --git a/vom/new_transcode_test.go b/vom/new_transcode_test.go
deleted file mode 100644
index 9c00e7d..0000000
--- a/vom/new_transcode_test.go
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2016 The Vanadium 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 vom_test
-
-import (
-	"bytes"
-	"testing"
-
-	"v.io/v23/vdl"
-	"v.io/v23/vom"
-	"v.io/v23/vom/vomtest"
-)
-
-func TestTranscodeXDecoderToXEncoder(t *testing.T) {
-	for _, test := range vomtest.AllPass() {
-		var buf bytes.Buffer
-		enc := vom.NewVersionedEncoder(test.Version, &buf)
-		dec := vom.NewDecoder(bytes.NewReader(test.Bytes()))
-		if err := vdl.Transcode(enc.Encoder(), dec.Decoder()); err != nil {
-			t.Errorf("%s: Transcode failed: %v", test.Name(), err)
-			continue
-		}
-		if got, want := buf.Bytes(), test.Bytes(); !bytes.Equal(got, want) {
-			t.Errorf("%s\nGOT  %x\nWANT %x", test.Name(), got, want)
-		}
-	}
-}
-
-// TODO(bprosnitz) This is probably not the right place for this test.
-func TestTranscodeVDLValueToXEncoder(t *testing.T) {
-	for _, test := range vomtest.AllPass() {
-		var buf bytes.Buffer
-		enc := vom.NewEncoder(&buf)
-		if err := vdl.Write(enc.Encoder(), test.Value.Interface()); err != nil {
-			t.Errorf("%s: vdl.Write failed: %v", test.Name(), err)
-			continue
-		}
-		if got, want := buf.Bytes(), test.Bytes(); !bytes.Equal(got, want) {
-			t.Errorf("%s\nGOT  %x\nWANT %x", test.Name(), got, want)
-		}
-	}
-}
diff --git a/vom/raw_bytes.go b/vom/raw_bytes.go
index b0794e0..e611a90 100644
--- a/vom/raw_bytes.go
+++ b/vom/raw_bytes.go
@@ -46,23 +46,6 @@
 	return rb, nil
 }
 
-// XRawBytesFromValue is a mirror of RawBytesFromValue, but uses the new
-// XEncoder and XDecoder.  It's only exposed to allow for testing.
-//
-// TODO(toddw): Remove this function after we've switched to XEncoder and
-// XDecoder, and thus it's no longer needed.
-func XRawBytesFromValue(value interface{}) (*RawBytes, error) {
-	data, err := VersionedEncode(DefaultVersion, value)
-	if err != nil {
-		return nil, err
-	}
-	rb := new(RawBytes)
-	if err := Decode(data, rb); err != nil {
-		return nil, err
-	}
-	return rb, nil
-}
-
 // String outputs a string representation of RawBytes of the form
 // RawBytes{Version81, int8, RefTypes{bool, string}, AnyLengths{4}, fa0e9dcc}
 func (rb *RawBytes) String() string {
@@ -164,7 +147,7 @@
 	}
 	// Slowpath: the bytes are not available, we must encode new bytes.
 	var buf bytes.Buffer
-	enc := newXEncoderForRawBytes(&buf)
+	enc := newEncoderForRawBytes(&buf)
 	if err := vdl.Transcode(enc, dec); err != nil {
 		return err
 	}
diff --git a/vom/raw_bytes_test.go b/vom/raw_bytes_test.go
index 0bd4016..532a12d 100644
--- a/vom/raw_bytes_test.go
+++ b/vom/raw_bytes_test.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.
 
-package vom
+package vom_test
 
 import (
 	"bytes"
@@ -11,8 +11,8 @@
 	"testing"
 
 	"v.io/v23/vdl"
-	"v.io/v23/vom/testdata/data81"
-	"v.io/v23/vom/testdata/types"
+	"v.io/v23/vom"
+	"v.io/v23/vom/vomtest"
 )
 
 type testUint64 uint64
@@ -22,27 +22,27 @@
 }
 
 type structAny struct {
-	X *RawBytes
+	X *vom.RawBytes
 }
 
 type structAnyAndTypes struct {
 	A *vdl.Type
-	B *RawBytes
+	B *vom.RawBytes
 	C *vdl.Type
-	D *RawBytes
+	D *vom.RawBytes
 }
 
 // Test various combinations of having/not having any and type object.
 var rawBytesTestCases = []struct {
 	name     string
 	goValue  interface{}
-	rawBytes RawBytes
+	rawBytes vom.RawBytes
 }{
 	{
 		name:    "testUint64(99)",
 		goValue: testUint64(99),
-		rawBytes: RawBytes{
-			Version: DefaultVersion,
+		rawBytes: vom.RawBytes{
+			Version: vom.DefaultVersion,
 			Type:    vdl.TypeOf(testUint64(0)),
 			Data:    []byte{0x63},
 		},
@@ -50,8 +50,8 @@
 	{
 		name:    "typeobject(int32)",
 		goValue: vdl.Int32Type,
-		rawBytes: RawBytes{
-			Version:  DefaultVersion,
+		rawBytes: vom.RawBytes{
+			Version:  vom.DefaultVersion,
 			Type:     vdl.TypeOf(vdl.Int32Type),
 			RefTypes: []*vdl.Type{vdl.Int32Type},
 			Data:     []byte{0x00},
@@ -60,31 +60,31 @@
 	{
 		name:    "structTypeObject{typeobject(int32)}",
 		goValue: structTypeObject{vdl.Int32Type},
-		rawBytes: RawBytes{
-			Version:  DefaultVersion,
+		rawBytes: vom.RawBytes{
+			Version:  vom.DefaultVersion,
 			Type:     vdl.TypeOf(structTypeObject{}),
 			RefTypes: []*vdl.Type{vdl.Int32Type},
-			Data:     []byte{0x00, 0x00, WireCtrlEnd},
+			Data:     []byte{0x00, 0x00, vom.WireCtrlEnd},
 		},
 	},
 	{
 		name: `structAnyAndTypes{typeobject(int32), true, typeobject(bool), "abc"}`,
 		goValue: structAnyAndTypes{
 			vdl.Int32Type,
-			&RawBytes{
-				Version: DefaultVersion,
+			&vom.RawBytes{
+				Version: vom.DefaultVersion,
 				Type:    vdl.BoolType,
 				Data:    []byte{0x01},
 			},
 			vdl.BoolType,
-			&RawBytes{
-				Version: DefaultVersion,
+			&vom.RawBytes{
+				Version: vom.DefaultVersion,
 				Type:    vdl.TypeOf(""),
 				Data:    []byte{0x03, 0x61, 0x62, 0x63},
 			},
 		},
-		rawBytes: RawBytes{
-			Version:    DefaultVersion,
+		rawBytes: vom.RawBytes{
+			Version:    vom.DefaultVersion,
 			Type:       vdl.TypeOf(structAnyAndTypes{}),
 			RefTypes:   []*vdl.Type{vdl.Int32Type, vdl.BoolType, vdl.StringType},
 			AnyLengths: []int{1, 4},
@@ -93,15 +93,15 @@
 				0x01, 0x01, 0x00, 0x01, // B
 				0x02, 0x01, // C
 				0x03, 0x02, 0x01, 0x03, 0x61, 0x62, 0x63, // D
-				WireCtrlEnd,
+				vom.WireCtrlEnd,
 			},
 		},
 	},
 	{
 		name:    "large message", // to test that multibyte length is encoded properly
 		goValue: makeLargeBytes(1000),
-		rawBytes: RawBytes{
-			Version: DefaultVersion,
+		rawBytes: vom.RawBytes{
+			Version: vom.DefaultVersion,
 			Type:    vdl.ListType(vdl.ByteType),
 			Data:    append([]byte{0xfe, 0x03, 0xe8}, makeLargeBytes(1000)...),
 		},
@@ -109,8 +109,8 @@
 	{
 		name:    "*vdl.Value",
 		goValue: vdl.ValueOf(uint16(5)),
-		rawBytes: RawBytes{
-			Version: DefaultVersion,
+		rawBytes: vom.RawBytes{
+			Version: vom.DefaultVersion,
 			Type:    vdl.Uint16Type,
 			Data:    []byte{0x05},
 		},
@@ -118,23 +118,23 @@
 	{
 		name:    "*vdl.Value - top level any",
 		goValue: vdl.ValueOf([]interface{}{uint16(5)}).Index(0),
-		rawBytes: RawBytes{
-			Version: DefaultVersion,
+		rawBytes: vom.RawBytes{
+			Version: vom.DefaultVersion,
 			Type:    vdl.Uint16Type,
 			Data:    []byte{0x05},
 		},
 	},
 	{
 		name: "any(nil)",
-		goValue: &RawBytes{
-			Version: DefaultVersion,
+		goValue: &vom.RawBytes{
+			Version: vom.DefaultVersion,
 			Type:    vdl.AnyType,
-			Data:    []byte{WireCtrlNil},
+			Data:    []byte{vom.WireCtrlNil},
 		},
-		rawBytes: RawBytes{
-			Version: DefaultVersion,
+		rawBytes: vom.RawBytes{
+			Version: vom.DefaultVersion,
 			Type:    vdl.AnyType,
-			Data:    []byte{WireCtrlNil},
+			Data:    []byte{vom.WireCtrlNil},
 		},
 	},
 }
@@ -149,13 +149,13 @@
 
 func TestDecodeToRawBytes(t *testing.T) {
 	for _, test := range rawBytesTestCases {
-		bytes, err := Encode(test.goValue)
+		bytes, err := vom.Encode(test.goValue)
 		if err != nil {
 			t.Errorf("%s: Encode failed: %v", test.name, err)
 			continue
 		}
-		var rb RawBytes
-		if err := Decode(bytes, &rb); err != nil {
+		var rb vom.RawBytes
+		if err := vom.Decode(bytes, &rb); err != nil {
 			t.Errorf("%s: Decode failed: %v", test.name, err)
 			continue
 		}
@@ -167,12 +167,12 @@
 
 func TestEncodeFromRawBytes(t *testing.T) {
 	for _, test := range rawBytesTestCases {
-		fullBytes, err := Encode(test.goValue)
+		fullBytes, err := vom.Encode(test.goValue)
 		if err != nil {
 			t.Errorf("%s: Encode goValue failed: %v", test.name, err)
 			continue
 		}
-		fullBytesFromRaw, err := Encode(&test.rawBytes)
+		fullBytesFromRaw, err := vom.Encode(&test.rawBytes)
 		if err != nil {
 			t.Errorf("%s: Encode RawBytes failed: %v", test.name, err)
 			continue
@@ -187,13 +187,13 @@
 var rawBytesWrappedTestCases = []struct {
 	name     string
 	goValue  interface{}
-	rawBytes RawBytes
+	rawBytes vom.RawBytes
 }{
 	{
 		name:    "testUint64(99)",
 		goValue: testUint64(99),
-		rawBytes: RawBytes{
-			Version:    DefaultVersion,
+		rawBytes: vom.RawBytes{
+			Version:    vom.DefaultVersion,
 			Type:       vdl.TypeOf(testUint64(0)),
 			RefTypes:   []*vdl.Type{vdl.TypeOf(testUint64(0))},
 			AnyLengths: []int{1},
@@ -203,8 +203,8 @@
 	{
 		name:    "typeobject(int32)",
 		goValue: vdl.Int32Type,
-		rawBytes: RawBytes{
-			Version:    DefaultVersion,
+		rawBytes: vom.RawBytes{
+			Version:    vom.DefaultVersion,
 			Type:       vdl.TypeOf(vdl.Int32Type),
 			RefTypes:   []*vdl.Type{vdl.TypeObjectType, vdl.Int32Type},
 			AnyLengths: []int{1},
@@ -214,8 +214,8 @@
 	{
 		name:    "structTypeObject{typeobject(int32)}",
 		goValue: structTypeObject{vdl.Int32Type},
-		rawBytes: RawBytes{
-			Version:    DefaultVersion,
+		rawBytes: vom.RawBytes{
+			Version:    vom.DefaultVersion,
 			Type:       vdl.TypeOf(structTypeObject{}),
 			RefTypes:   []*vdl.Type{vdl.TypeOf(structTypeObject{}), vdl.Int32Type},
 			AnyLengths: []int{3},
@@ -226,20 +226,20 @@
 		name: `structAnyAndTypes{typeobject(int32), true, typeobject(bool), "abc"}`,
 		goValue: structAnyAndTypes{
 			vdl.Int32Type,
-			&RawBytes{
-				Version: DefaultVersion,
+			&vom.RawBytes{
+				Version: vom.DefaultVersion,
 				Type:    vdl.BoolType,
 				Data:    []byte{0x01},
 			},
 			vdl.BoolType,
-			&RawBytes{
-				Version: DefaultVersion,
+			&vom.RawBytes{
+				Version: vom.DefaultVersion,
 				Type:    vdl.TypeOf(""),
 				Data:    []byte{0x03, 0x61, 0x62, 0x63},
 			},
 		},
-		rawBytes: RawBytes{
-			Version:    DefaultVersion,
+		rawBytes: vom.RawBytes{
+			Version:    vom.DefaultVersion,
 			Type:       vdl.TypeOf(structAnyAndTypes{}),
 			RefTypes:   []*vdl.Type{vdl.TypeOf(structAnyAndTypes{}), vdl.Int32Type, vdl.BoolType, vdl.StringType},
 			AnyLengths: []int{16, 1, 4},
@@ -255,8 +255,8 @@
 	{
 		name:    "large message", // to test that multibyte length is encoded properly
 		goValue: makeLargeBytes(1000),
-		rawBytes: RawBytes{
-			Version:    DefaultVersion,
+		rawBytes: vom.RawBytes{
+			Version:    vom.DefaultVersion,
 			Type:       vdl.ListType(vdl.ByteType),
 			RefTypes:   []*vdl.Type{vdl.ListType(vdl.ByteType)},
 			AnyLengths: []int{0x3eb},
@@ -266,8 +266,8 @@
 	{
 		name:    "*vdl.Value",
 		goValue: vdl.ValueOf(uint16(5)),
-		rawBytes: RawBytes{
-			Version:    DefaultVersion,
+		rawBytes: vom.RawBytes{
+			Version:    vom.DefaultVersion,
 			Type:       vdl.Uint16Type,
 			RefTypes:   []*vdl.Type{vdl.Uint16Type},
 			AnyLengths: []int{1},
@@ -277,8 +277,8 @@
 	{
 		name:    "*vdl.Value - top level any",
 		goValue: vdl.ValueOf([]interface{}{uint16(5)}).Index(0),
-		rawBytes: RawBytes{
-			Version:    DefaultVersion,
+		rawBytes: vom.RawBytes{
+			Version:    vom.DefaultVersion,
 			Type:       vdl.Uint16Type,
 			RefTypes:   []*vdl.Type{vdl.Uint16Type},
 			AnyLengths: []int{1},
@@ -290,13 +290,13 @@
 func TestWrappedRawBytes(t *testing.T) {
 	for i, test := range rawBytesWrappedTestCases {
 		unwrapped := rawBytesTestCases[i]
-		wrappedBytes, err := Encode(structAny{&unwrapped.rawBytes})
+		wrappedBytes, err := vom.Encode(structAny{&unwrapped.rawBytes})
 		if err != nil {
 			t.Errorf("%s: Encode failed: %v", test.name, err)
 			continue
 		}
 		var any structAny
-		if err := Decode(wrappedBytes, &any); err != nil {
+		if err := vom.Decode(wrappedBytes, &any); err != nil {
 			t.Errorf("%s: Decode failed: %v", test.name, err)
 			continue
 		}
@@ -308,11 +308,11 @@
 
 func TestEncodeNilRawBytes(t *testing.T) {
 	// Top-level
-	want, err := Encode(vdl.ZeroValue(vdl.AnyType))
+	want, err := vom.Encode(vdl.ZeroValue(vdl.AnyType))
 	if err != nil {
 		t.Fatal(err)
 	}
-	got, err := Encode((*RawBytes)(nil))
+	got, err := vom.Encode((*vom.RawBytes)(nil))
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -320,11 +320,11 @@
 		t.Errorf("top-level\nGOT  %x\nWANT %x", got, want)
 	}
 	// Within an object.
-	want, err = Encode([]*vdl.Value{vdl.ZeroValue(vdl.AnyType)})
+	want, err = vom.Encode([]*vdl.Value{vdl.ZeroValue(vdl.AnyType)})
 	if err != nil {
 		t.Fatal(err)
 	}
-	got, err = Encode([]*RawBytes{nil})
+	got, err = vom.Encode([]*vom.RawBytes{nil})
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -333,115 +333,8 @@
 	}
 }
 
-func TestRawBytesDecodeEncode(t *testing.T) {
-	versions := []struct {
-		Version Version
-		Tests   []types.TestCase
-	}{
-		{Version81, data81.Tests},
-	}
-	for _, testVersion := range versions {
-		for _, test := range testVersion.Tests {
-			// Interleaved
-			rb := RawBytes{}
-			interleavedReader := bytes.NewReader(hex2Bin(t, test.Hex))
-			if err := NewDecoder(interleavedReader).Decode(&rb); err != nil {
-				t.Errorf("unexpected error decoding %s: %v", test.Name, err)
-				continue
-			}
-			if _, err := interleavedReader.ReadByte(); err != io.EOF {
-				t.Errorf("expected EOF, but got %v", err)
-				continue
-			}
-
-			var out bytes.Buffer
-			enc := NewVersionedEncoder(testVersion.Version, &out)
-			if err := enc.Encode(&rb); err != nil {
-				t.Errorf("unexpected error encoding raw bytes %v in test %s: %v", rb, test.Name, err)
-				continue
-			}
-			if !bytes.Equal(out.Bytes(), hex2Bin(t, test.Hex)) {
-				t.Errorf("got bytes: %x but expected %s", out.Bytes(), test.Hex)
-			}
-
-			// Split type and value stream.
-			rb = RawBytes{}
-			typeReader := bytes.NewReader(hex2Bin(t, test.HexVersion+test.HexType))
-			typeDec := NewTypeDecoder(typeReader)
-			typeDec.Start()
-			defer typeDec.Stop()
-			valueReader := bytes.NewReader(hex2Bin(t, test.HexVersion+test.HexValue))
-			if err := NewDecoderWithTypeDecoder(valueReader, typeDec).Decode(&rb); err != nil {
-				t.Errorf("unexpected error decoding %s: %v", test.Name, err)
-				continue
-			}
-			if test.HexType != "" {
-				// If HexType is empty, then the type stream will just have the version byte that won't be read, so ignore
-				// that case.
-				if _, err := typeReader.ReadByte(); err != io.EOF {
-					t.Errorf("in type reader expected EOF, but got %v", err)
-					continue
-				}
-			}
-			if _, err := valueReader.ReadByte(); err != io.EOF {
-				t.Errorf("in value reader expected EOF, but got %v", err)
-				continue
-			}
-
-			out.Reset()
-			var typeOut bytes.Buffer
-			typeEnc := NewVersionedTypeEncoder(testVersion.Version, &typeOut)
-			enc = NewVersionedEncoderWithTypeEncoder(testVersion.Version, &out, typeEnc)
-			if err := enc.Encode(&rb); err != nil {
-				t.Errorf("unexpected error encoding raw value %v in test %s: %v", rb, test.Name, err)
-				continue
-			}
-			expectedType := test.HexVersion + test.HexType
-			if expectedType == "81" || expectedType == "82" {
-				expectedType = ""
-			}
-			if !bytes.Equal(typeOut.Bytes(), hex2Bin(t, expectedType)) {
-				t.Errorf("got type bytes: %x but expected %s", typeOut.Bytes(), expectedType)
-			}
-			if !bytes.Equal(out.Bytes(), hex2Bin(t, test.HexVersion+test.HexValue)) {
-				t.Errorf("got value bytes: %x but expected %s", out.Bytes(), test.HexVersion+test.HexValue)
-			}
-		}
-	}
-}
-
-func TestRawBytesToFromValue(t *testing.T) {
-	versions := []struct {
-		Version Version
-		Tests   []types.TestCase
-	}{
-		{Version81, data81.Tests},
-	}
-	for _, testVersion := range versions {
-		for _, test := range testVersion.Tests {
-			rb, err := RawBytesFromValue(test.Value)
-			if err != nil {
-				t.Fatalf("%v %s: error in RawBytesFromValue %v", testVersion.Version, test.Name, err)
-			}
-			var vv *vdl.Value
-			if err := rb.ToValue(&vv); err != nil {
-				t.Fatalf("%v %s: error in rb.ToValue %v", testVersion.Version, test.Name, err)
-			}
-			if test.Name == "any(nil)" {
-				// Skip any(nil)
-				// TODO(bprosnitz) any(nil) results in two different nil representations. This shouldn't be the case.
-				continue
-			}
-			if got, want := vv, test.Value; !vdl.EqualValue(got, want) {
-				t.Errorf("%v %s: error in converting to and from raw value. got %v, but want %v", testVersion.Version,
-					test.Name, got, want)
-			}
-		}
-	}
-}
-
 func TestVdlTypeOfRawBytes(t *testing.T) {
-	if got, want := vdl.TypeOf(&RawBytes{}), vdl.AnyType; got != want {
+	if got, want := vdl.TypeOf(&vom.RawBytes{}), vdl.AnyType; got != want {
 		t.Errorf("got %v, want %v", got, want)
 	}
 }
@@ -458,7 +351,7 @@
 
 func TestConvertRawBytes(t *testing.T) {
 	for _, test := range rawBytesTestCases {
-		var rb *RawBytes
+		var rb *vom.RawBytes
 		if err := vdl.Convert(&rb, test.goValue); err != nil {
 			t.Errorf("%s: Convert failed: %v", test.name, err)
 		}
@@ -490,7 +383,7 @@
 // are more ids in the encoder/decoder.
 func TestReusedDecoderEncoderRawBytes(t *testing.T) {
 	var buf bytes.Buffer
-	enc := NewEncoder(&buf)
+	enc := vom.NewEncoder(&buf)
 	if err := enc.Encode(structAnyInterface{int64(4)}); err != nil {
 		t.Fatalf("error on encode: %v", err)
 	}
@@ -498,7 +391,7 @@
 		t.Fatalf("error on encode: %v", err)
 	}
 
-	dec := NewDecoder(bytes.NewReader(buf.Bytes()))
+	dec := vom.NewDecoder(bytes.NewReader(buf.Bytes()))
 	var x structAny
 	if err := dec.Decode(&x); err != nil {
 		t.Fatalf("error on decode: %v", err)
@@ -525,12 +418,12 @@
 
 func TestRawBytesString(t *testing.T) {
 	tests := []struct {
-		input    *RawBytes
+		input    *vom.RawBytes
 		expected string
 	}{
 		{
-			input: &RawBytes{
-				Version81,
+			input: &vom.RawBytes{
+				vom.Version81,
 				vdl.Int8Type,
 				[]*vdl.Type{vdl.BoolType, vdl.StringType},
 				[]int{4},
@@ -538,8 +431,8 @@
 			expected: "RawBytes{Version81, int8, RefTypes{bool, string}, AnyLengths{4}, fa0e9dcc}",
 		},
 		{
-			input: &RawBytes{
-				Version81,
+			input: &vom.RawBytes{
+				vom.Version81,
 				vdl.Int8Type,
 				[]*vdl.Type{vdl.BoolType},
 				[]int{},
@@ -547,8 +440,8 @@
 			expected: "RawBytes{Version81, int8, RefTypes{bool}, fa0e9dcc}",
 		},
 		{
-			input: &RawBytes{
-				Version81,
+			input: &vom.RawBytes{
+				vom.Version81,
 				vdl.Int8Type,
 				nil,
 				nil,
@@ -564,10 +457,10 @@
 }
 
 func TestRawBytesVDLType(t *testing.T) {
-	if got, want := vdl.TypeOf(RawBytes{}), vdl.AnyType; got != want {
+	if got, want := vdl.TypeOf(vom.RawBytes{}), vdl.AnyType; got != want {
 		t.Errorf("vom.RawBytes{} got %v, want %v", got, want)
 	}
-	if got, want := vdl.TypeOf((*RawBytes)(nil)), vdl.AnyType; got != want {
+	if got, want := vdl.TypeOf((*vom.RawBytes)(nil)), vdl.AnyType; got != want {
 		t.Errorf("vom.RawBytes{} got %v, want %v", got, want)
 	}
 }
@@ -586,20 +479,20 @@
 	// of dealing with the format for describing types with any in the
 	// value message header.
 	var typeBuf, buf bytes.Buffer
-	typeEnc := NewTypeEncoder(&typeBuf)
-	if err := NewEncoderWithTypeEncoder(&buf, typeEnc).Encode(simpleStruct{5}); err != nil {
+	typeEnc := vom.NewTypeEncoder(&typeBuf)
+	if err := vom.NewEncoderWithTypeEncoder(&buf, typeEnc).Encode(simpleStruct{5}); err != nil {
 		t.Fatalf("failure when preparing type message bytes: %v", t)
 	}
 	var inputMessage []byte = typeBuf.Bytes()
-	inputMessage = append(inputMessage, byte(WireIdFirstUserType*2)) // New value message tid
-	inputMessage = append(inputMessage, 8)                           // Message length
+	inputMessage = append(inputMessage, byte(vom.WireIdFirstUserType*2)) // New value message tid
+	inputMessage = append(inputMessage, 8)                               // Message length
 	// non-vom bytes (invalid because there is no struct field at index 10)
 	dataPortion := []byte{10, 20, 30, 40, 50, 60, 70, 80}
 	inputMessage = append(inputMessage, dataPortion...)
 
 	// Now ensure decoding into a RawBytes works correctly.
-	var rb *RawBytes
-	if err := Decode(inputMessage, &rb); err != nil {
+	var rb *vom.RawBytes
+	if err := vom.Decode(inputMessage, &rb); err != nil {
 		t.Fatalf("error decoding %x into a RawBytes: %v", inputMessage, err)
 	}
 	if got, want := rb.Type, vdl.TypeOf(simpleStruct{}); got != want {
@@ -610,7 +503,7 @@
 	}
 
 	// Now re-encode and ensure that we get the original bytes.
-	encoded, err := Encode(rb)
+	encoded, err := vom.Encode(rb)
 	if err != nil {
 		t.Fatalf("error encoding RawBytes %v: %v", rb, err)
 	}
@@ -619,40 +512,123 @@
 	}
 }
 
-func TestRawBytesDecoder(t *testing.T) {
-	regex := filterRegex(t)
-	for _, test := range data81.Tests {
-		if !regex.MatchString(test.Name) {
+func TestRawBytesDecodeEncode(t *testing.T) {
+	for _, test := range vomtest.AllPass() {
+		// Interleaved
+		rb := vom.RawBytes{}
+		interleavedReader := bytes.NewReader(test.Bytes())
+		if err := vom.NewDecoder(interleavedReader).Decode(&rb); err != nil {
+			t.Errorf("%s: decode failed: %v", test.Name(), err)
+			continue
+		}
+		if _, err := interleavedReader.ReadByte(); err != io.EOF {
+			t.Errorf("%s: expected EOF, but got %v", test.Name(), err)
 			continue
 		}
 
-		in := RawBytesOf(test.Value)
-		out := vdl.ZeroValue(test.Value.Type())
-		if err := out.VDLRead(in.Decoder()); err != nil {
-			t.Errorf("%s: error in ValueRead: %v", test.Name, err)
+		var out bytes.Buffer
+		enc := vom.NewVersionedEncoder(test.Version, &out)
+		if err := enc.Encode(&rb); err != nil {
+			t.Errorf("%s: encode failed: %v\nRawBytes: %v", test.Name(), err, rb)
 			continue
 		}
-		if !vdl.EqualValue(test.Value, out) {
-			t.Errorf("%s: got %v, want %v", test.Name, out, test.Value)
+		if got, want := out.Bytes(), test.Bytes(); !bytes.Equal(got, want) {
+			t.Errorf("%s\nGOT  %x\nWANT %x", test.Name(), got, want)
+		}
+
+		// Split type and value stream.
+		rb = vom.RawBytes{}
+		typeReader := bytes.NewReader(test.TypeBytes())
+		typeDec := vom.NewTypeDecoder(typeReader)
+		typeDec.Start()
+		defer typeDec.Stop()
+		valueReader := bytes.NewReader(test.ValueBytes())
+		if err := vom.NewDecoderWithTypeDecoder(valueReader, typeDec).Decode(&rb); err != nil {
+			t.Errorf("%s: decode failed: %v", test.Name(), err)
+			continue
+		}
+		if _, err := typeReader.ReadByte(); err != io.EOF {
+			t.Errorf("%s: type reader got %v, want EOF", test.Name(), err)
+			continue
+		}
+		if _, err := valueReader.ReadByte(); err != io.EOF {
+			t.Errorf("%s: value reader got %v, want EOF", test.Name(), err)
+			continue
+		}
+
+		out.Reset()
+		var typeOut bytes.Buffer
+		typeEnc := vom.NewVersionedTypeEncoder(test.Version, &typeOut)
+		enc = vom.NewVersionedEncoderWithTypeEncoder(test.Version, &out, typeEnc)
+		if err := enc.Encode(&rb); err != nil {
+			t.Errorf("%s: encode failed: %v\nRawBytes: %v", test.Name(), err, rb)
+			continue
+		}
+		if got, want := typeOut.Bytes(), test.TypeBytes(); !bytes.Equal(got, want) {
+			t.Errorf("%s: type bytes\nGOT  %x\nWANT %x", test.Name(), got, want)
+		}
+		if got, want := out.Bytes(), test.ValueBytes(); !bytes.Equal(got, want) {
+			t.Errorf("%s: value bytes\nGOT  %x\nWANT %x", test.Name(), got, want)
+		}
+	}
+}
+
+func TestRawBytesToFromValue(t *testing.T) {
+	for _, test := range vomtest.AllPass() {
+		rb, err := vom.RawBytesFromValue(test.Value.Interface())
+		if err != nil {
+			t.Errorf("%v %s: RawBytesFromValue failed: %v", test.Version, test.Name(), err)
+			continue
+		}
+		var vv *vdl.Value
+		if err := rb.ToValue(&vv); err != nil {
+			t.Errorf("%v %s: rb.ToValue failed: %v", test.Version, test.Name(), err)
+			continue
+		}
+		if got, want := vv, vdl.ValueOf(test.Value.Interface()); !vdl.EqualValue(got, want) {
+			t.Errorf("%v %s\nGOT  %v\nWANT %v", test.Version, test.Name(), got, want)
+		}
+	}
+}
+
+func TestRawBytesDecoder(t *testing.T) {
+	for _, test := range vomtest.AllPass() {
+		tt, err := vdl.TypeFromReflect(test.Value.Type())
+		if err != nil {
+			t.Errorf("%s: TypeFromReflect failed: %v", test.Name(), err)
+			continue
+		}
+		in, err := vom.RawBytesFromValue(test.Value.Interface())
+		if err != nil {
+			t.Errorf("%s: RawBytesFromValue failed: %v", test.Name(), err)
+			continue
+		}
+		out := vdl.ZeroValue(tt)
+		if err := out.VDLRead(in.Decoder()); err != nil {
+			t.Errorf("%s: VDLRead failed: %v", test.Name(), err)
+			continue
+		}
+		if got, want := out, vdl.ValueOf(test.Value.Interface()); !vdl.EqualValue(got, want) {
+			t.Errorf("%s\nGOT  %v\nWANT %v", test.Name(), got, want)
 		}
 	}
 }
 
 func TestRawBytesWriter(t *testing.T) {
-	regex := filterRegex(t)
-	for _, test := range data81.Tests {
-		if !regex.MatchString(test.Name) {
-			continue
-		}
-
+	for _, test := range vomtest.AllPass() {
 		var buf bytes.Buffer
-		enc := NewEncoder(&buf)
-		if err := RawBytesOf(test.Value).VDLWrite(enc.Encoder()); err != nil {
-			t.Errorf("%s: error in transcode: %v", test.Name, err)
+		enc := vom.NewEncoder(&buf)
+		rb, err := vom.RawBytesFromValue(test.Value.Interface())
+		if err != nil {
+			t.Errorf("%s: RawBytesFromValue failed: %v", test.Name(), err)
 			continue
 		}
-		if got, want := buf.Bytes(), hex2Bin(t, test.Hex); !bytes.Equal(got, want) {
-			t.Errorf("%s: got %x, want %x", test.Name, got, want)
+		if err := rb.VDLWrite(enc.Encoder()); err != nil {
+			t.Errorf("%s: VDLWrite failed: %v", test.Name(), err)
+			continue
+		}
+		if got, want := buf.Bytes(), test.Bytes(); !bytes.Equal(got, want) {
+			t.Errorf("%s\nGOT  %x\nWANT %x", test.Name(), got, want)
 		}
 	}
 }
diff --git a/vom/transcode_test.go b/vom/transcode_test.go
index a91bafb..aa00779 100644
--- a/vom/transcode_test.go
+++ b/vom/transcode_test.go
@@ -2,70 +2,43 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-package vom
+package vom_test
 
 import (
 	"bytes"
-	"flag"
-	"regexp"
 	"testing"
 
 	"v.io/v23/vdl"
-	"v.io/v23/vom/testdata/data81"
+	"v.io/v23/vom"
+	"v.io/v23/vom/vomtest"
 )
 
-var filter *string = flag.String("testdata-filter", "", "regex for allowed testdata tests")
-
-func init() {
-	flag.Parse()
-}
-
-func filterRegex(t *testing.T) *regexp.Regexp {
-	pattern := ".*" + *filter + ".*"
-	regex, err := regexp.Compile(pattern)
-	if err != nil {
-		t.Fatalf("invalid regex filter %q", *filter)
-	}
-	return regex
-}
-
-func TestTranscodeXDecoderToXEncoder(t *testing.T) {
-	regex := filterRegex(t)
-	for _, test := range data81.Tests {
-		if !regex.MatchString(test.Name) {
-			continue
-		}
-
-		inBytes := hex2Bin(t, test.Hex)
+func TestTranscodeDecoderToEncoder(t *testing.T) {
+	for _, test := range vomtest.AllPass() {
 		var buf bytes.Buffer
-		enc := NewEncoder(&buf)
-		dec := NewDecoder(bytes.NewReader(inBytes))
+		enc := vom.NewVersionedEncoder(test.Version, &buf)
+		dec := vom.NewDecoder(bytes.NewReader(test.Bytes()))
 		if err := vdl.Transcode(enc.Encoder(), dec.Decoder()); err != nil {
-			t.Errorf("%s: error in transcode: %v", test.Name, err)
+			t.Errorf("%s: Transcode failed: %v", test.Name(), err)
 			continue
 		}
-		if got, want := buf.Bytes(), inBytes; !bytes.Equal(got, want) {
-			t.Errorf("%s: got %x, want %x", test.Name, got, want)
+		if got, want := buf.Bytes(), test.Bytes(); !bytes.Equal(got, want) {
+			t.Errorf("%s\nGOT  %x\nWANT %x", test.Name(), got, want)
 		}
 	}
 }
 
 // TODO(bprosnitz) This is probably not the right place for this test.
-func TestTranscodeVDLValueToXEncoder(t *testing.T) {
-	regex := filterRegex(t)
-	for _, test := range data81.Tests {
-		if !regex.MatchString(test.Name) {
-			continue
-		}
-
+func TestTranscodeVDLValueToEncoder(t *testing.T) {
+	for _, test := range vomtest.AllPass() {
 		var buf bytes.Buffer
-		enc := NewEncoder(&buf)
-		if err := test.Value.VDLWrite(enc.Encoder()); err != nil {
-			t.Errorf("%s: error in transcode: %v", test.Name, err)
+		enc := vom.NewEncoder(&buf)
+		if err := vdl.Write(enc.Encoder(), test.Value.Interface()); err != nil {
+			t.Errorf("%s: vdl.Write failed: %v", test.Name(), err)
 			continue
 		}
-		if got, want := buf.Bytes(), hex2Bin(t, test.Hex); !bytes.Equal(got, want) {
-			t.Errorf("%s: got %x, want %x", test.Name, got, want)
+		if got, want := buf.Bytes(), test.Bytes(); !bytes.Equal(got, want) {
+			t.Errorf("%s\nGOT  %x\nWANT %x", test.Name(), got, want)
 		}
 	}
 }
diff --git a/vom/xdecoder.go b/vom/xdecoder.go
deleted file mode 100644
index bcbb932..0000000
--- a/vom/xdecoder.go
+++ /dev/null
@@ -1,800 +0,0 @@
-// Copyright 2016 The Vanadium 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 vom
-
-import (
-	"errors"
-	"fmt"
-	"io"
-	"math"
-	"os"
-
-	"v.io/v23/vdl"
-	"v.io/v23/verror"
-)
-
-const (
-	// IEEE 754 represents float64 using 52 bits to represent the mantissa, with
-	// an extra implied leading bit.  That gives us 53 bits to store integers
-	// without overflow - i.e. [0, (2^53)-1].  And since 2^53 is a small power of
-	// two, it can also be stored without loss via mantissa=1 exponent=53.  Thus
-	// we have our max and min values.  Ditto for float32, which uses 23 bits with
-	// an extra implied leading bit.
-	float64MaxInt = (1 << 53)
-	float64MinInt = -(1 << 53)
-	float32MaxInt = (1 << 24)
-	float32MinInt = -(1 << 24)
-)
-
-var (
-	errEmptyDecoderStack          = errors.New("vom: empty decoder stack")
-	errReadRawBytesAlreadyStarted = errors.New("vom: read into vom.RawBytes after StartValue called")
-	errReadRawBytesFromNonAny     = errors.New("vom: read into vom.RawBytes only supported on any values")
-)
-
-// This is only used for debugging; add this as the first line of NewDecoder to
-// dump formatted vom bytes to stdout:
-//   r = teeDump(r)
-func teeDump(r io.Reader) io.Reader {
-	return io.TeeReader(r, NewDumper(NewDumpWriter(os.Stdout)))
-}
-
-// Decoder manages the receipt and unmarshalling of typed values from the other
-// side of a connection.
-type Decoder struct {
-	dec decoder81
-}
-
-type decoder81 struct {
-	buf        *decbuf
-	flag       decFlag
-	stack      []decStackEntry
-	refTypes   referencedTypes
-	refAnyLens referencedAnyLens
-	typeDec    *TypeDecoder
-}
-
-type decStackEntry struct {
-	Type          *vdl.Type     // Type of the value that we're decoding.
-	Index         int           // Index of the key, elem or field.
-	LenHint       int           // Length of the value, or -1 for unknown.
-	NextEntryType *vdl.Type     // type for NextEntryValue* methods
-	Flag          decStackFlag  // properties of this stack entry
-	NextEntryData nextEntryData // properties of the next entry
-}
-
-// decFlag holds properties of the decoder.
-type decFlag uint
-
-const (
-	decFlagIgnoreNextStartValue decFlag = 0x1 // ignore the next call to StartValue
-	decFlagIsParentBytes        decFlag = 0x2 // parent type is []byte or [N]byte
-	decFlagTypeIncomplete       decFlag = 0x4 // type has dependencies on unsent types
-	decFlagSeparateTypeDec      decFlag = 0x8 // type decoder is separate
-
-	// In FinishValue we need to clear both of these bits.
-	decFlagFinishValue decFlag = decFlagIgnoreNextStartValue | decFlagIsParentBytes
-)
-
-func (f decFlag) Set(bits decFlag) decFlag   { return f | bits }
-func (f decFlag) Clear(bits decFlag) decFlag { return f &^ bits }
-
-func (f decFlag) IgnoreNextStartValue() bool { return f&decFlagIgnoreNextStartValue != 0 }
-func (f decFlag) IsParentBytes() bool        { return f&decFlagIsParentBytes != 0 }
-func (f decFlag) TypeIncomplete() bool       { return f&decFlagTypeIncomplete != 0 }
-func (f decFlag) SeparateTypeDec() bool      { return f&decFlagSeparateTypeDec != 0 }
-
-// decStackFlag holds type or value properties of the stack entry.
-type decStackFlag uint
-
-const (
-	decStackFlagIsMapKey   decStackFlag = 0x1 // key or elem for dfsNextType
-	decStackFlagIsAny      decStackFlag = 0x2 // the static type is Any
-	decStackFlagIsOptional decStackFlag = 0x4 // the static type is Optional
-	decStackFlagFastRead   decStackFlag = 0x8 // subtypes use ReadValue fastpath
-)
-
-func (f decStackFlag) FlipIsMapKey() decStackFlag { return f ^ decStackFlagIsMapKey }
-func (f decStackFlag) IsMapKey() bool             { return f&decStackFlagIsMapKey != 0 }
-func (f decStackFlag) IsAny() bool                { return f&decStackFlagIsAny != 0 }
-func (f decStackFlag) IsOptional() bool           { return f&decStackFlagIsOptional != 0 }
-func (f decStackFlag) FastRead() bool             { return f&decStackFlagFastRead != 0 }
-
-// NewDecoder returns a new Decoder that reads from the given reader.  The
-// Decoder understands all formats generated by the Encoder.
-func NewDecoder(r io.Reader) *Decoder {
-	buf := newDecbuf(r)
-	typeDec := newTypeDecoderInternal(buf)
-	return &Decoder{decoder81{
-		buf:     buf,
-		typeDec: typeDec,
-	}}
-}
-
-// NewDecoderWithTypeDecoder returns a new Decoder that reads from the given
-// reader.  Types are decoded separately through the typeDec.
-func NewDecoderWithTypeDecoder(r io.Reader, typeDec *TypeDecoder) *Decoder {
-	return &Decoder{decoder81{
-		buf:     newDecbuf(r),
-		typeDec: typeDec,
-		flag:    decFlagSeparateTypeDec,
-	}}
-}
-
-// Decoder returns d as a vdl.Decoder.
-func (d *Decoder) Decoder() vdl.Decoder {
-	return &d.dec
-}
-
-// Decode reads the next value and stores it in value v.  The type of v need not
-// exactly match the type of the originally encoded value; decoding succeeds as
-// long as the values are convertible.
-func (d *Decoder) Decode(v interface{}) error {
-	return vdl.Read(&d.dec, v)
-}
-
-func (d *decoder81) IgnoreNextStartValue() {
-	d.flag = d.flag.Set(decFlagIgnoreNextStartValue)
-}
-
-func (d *decoder81) decodeWireType(wt *wireType) (TypeId, error) {
-	// Type messages are just a regularly encoded wireType, which is a union.  To
-	// decode we pre-populate the stack with an entry for the wire type, and run
-	// the code-generated __VDLRead_wireType method.
-	tid, err := d.nextMessage()
-	if err != nil {
-		return 0, err
-	}
-	d.stack = append(d.stack, decStackEntry{
-		Type:    wireTypeType,
-		Index:   -1,
-		LenHint: 1, // wireType is a union
-	})
-	d.flag = d.flag.Set(decFlagIgnoreNextStartValue)
-	if err := __VDLRead_wireType(d, wt); err != nil {
-		return 0, err
-	}
-	return tid, nil
-}
-
-// readRawBytes fills in raw with the next value.  It can be called for both
-// top-level and internal values.
-func (d *decoder81) readRawBytes(raw *RawBytes) error {
-	if d.flag.IgnoreNextStartValue() {
-		// If the user has already called StartValue on the decoder, it's harder to
-		// capture all the raw bytes, since the optional flag and length hints have
-		// already been decoded.  So we simply disallow this from happening.
-		return errReadRawBytesAlreadyStarted
-	}
-	tt, err := d.dfsNextType()
-	if err != nil {
-		return err
-	}
-	// Handle top-level values.  All types of values are supported, since we can
-	// simply copy the message bytes.
-	if len(d.stack) == 0 {
-		anyLen, err := d.peekValueByteLen(tt)
-		if err != nil {
-			return err
-		}
-		if err := d.decodeRaw(tt, anyLen, raw); err != nil {
-			return err
-		}
-		return d.endMessage()
-	}
-	// Handle internal values.  Only any values are supported at the moment, since
-	// they come with a header that tells us the exact length to read.
-	//
-	// TODO(toddw): Handle other types, either by reading and skipping bytes based
-	// on the type, or by falling back to a decode / re-encode slowpath.
-	if tt.Kind() != vdl.Any {
-		return errReadRawBytesFromNonAny
-	}
-	ttElem, anyLen, err := d.readAnyHeader()
-	if err != nil {
-		return err
-	}
-	if ttElem == nil {
-		// This is a nil any value, which has already been read by readAnyHeader.
-		// We simply fill in RawBytes with the single WireCtrlNil byte.
-		raw.Version = d.buf.version
-		raw.Type = vdl.AnyType
-		raw.RefTypes = nil
-		raw.AnyLengths = nil
-		raw.Data = []byte{WireCtrlNil}
-		return nil
-	}
-	return d.decodeRaw(ttElem, anyLen, raw)
-}
-
-func (d *decoder81) StartValue(want *vdl.Type) error {
-	if d.flag.IgnoreNextStartValue() {
-		d.flag = d.flag.Clear(decFlagIgnoreNextStartValue)
-		return nil
-	}
-	tt, err := d.dfsNextType()
-	if err != nil {
-		return err
-	}
-	tt, lenHint, flag, err := d.setupType(tt, want)
-	if err != nil {
-		return err
-	}
-	d.stack = append(d.stack, decStackEntry{
-		Type:    tt,
-		Index:   -1,
-		LenHint: lenHint,
-		Flag:    flag,
-	})
-	return nil
-}
-
-func (d *decoder81) setupType(tt, want *vdl.Type) (_ *vdl.Type, lenHint int, flag decStackFlag, _ error) {
-	// Handle any, which may be nil.  We "dereference" non-nil any to the inner
-	// type.  If that happens to be an optional, it's handled below.
-	if tt.Kind() == vdl.Any {
-		flag |= decStackFlagIsAny
-		var err error
-		switch tt, _, err = d.readAnyHeader(); {
-		case err != nil:
-			return nil, 0, 0, err
-		case tt == nil:
-			tt = vdl.AnyType // nil any
-		}
-	}
-	// Handle optional, which may be nil.  Similar to any, we "dereference"
-	// non-nil optional to the inner type, which is never allowed to be another
-	// optional or any type.
-	if tt.Kind() == vdl.Optional {
-		flag |= decStackFlagIsOptional
-		// Read the WireCtrlNil code, but if it's not WireCtrlNil we need to keep
-		// the buffer as-is, since it's the first byte of the value, which may
-		// itself be another control code.
-		switch ctrl, err := binaryPeekControl(d.buf); {
-		case err != nil:
-			return nil, 0, 0, err
-		case ctrl == WireCtrlNil:
-			d.buf.SkipAvailable(1) // nil optional
-		default:
-			tt = tt.Elem() // non-nil optional
-		}
-	}
-	// Check compatibility between the actual type and the want type.  Since
-	// compatibility applies to the entire static type, we only need to perform
-	// this check for top-level decoded values, and subsequently for decoded any
-	// values.  We skip checking non-composite want types, since those will be
-	// naturally caught by the Decode* calls anyways.
-	if want != nil && (len(d.stack) == 0 || flag.IsAny()) {
-		switch want.Kind() {
-		case vdl.Optional, vdl.Array, vdl.List, vdl.Set, vdl.Map, vdl.Struct, vdl.Union:
-			if tt == want {
-				// Set FastRead flag, which will let us use the fastpath for ReadValue*
-				// in common cases.  We can only use this fastpath if tt and want are
-				// identical, which ensures we don't need to perform any conversions.
-				if !flag.IsAny() && isFastReadParent(tt) {
-					flag |= decStackFlagFastRead
-				}
-				// Regardless of whether we can use the fastpath, there's no need to
-				// check compatibility if tt and want are identical.
-			} else {
-				if !vdl.Compatible(tt, want) {
-					return nil, 0, 0, errIncompatibleDecode(tt, want)
-				}
-			}
-		}
-	}
-	// Initialize LenHint for composite types.
-	switch tt.Kind() {
-	case vdl.Array, vdl.List, vdl.Set, vdl.Map:
-		// TODO(toddw): Handle sentry-terminated collections without a length hint.
-		len, err := binaryDecodeLenOrArrayLen(d.buf, tt)
-		if err != nil {
-			return nil, 0, 0, err
-		}
-		lenHint = len
-	case vdl.Union:
-		// Union shouldn't have a LenHint, but we abuse it in NextField as a
-		// convenience for detecting when fields are done, so we initialize it here.
-		// It has to be at least 1, since 0 will cause NextField to think that the
-		// union field has already been decoded.
-		lenHint = 1
-	case vdl.Struct:
-		// Struct shouldn't have a LenHint, but we abuse it in NextField as a
-		// convenience for detecting when fields are done, so we initialize it here.
-		lenHint = tt.NumField()
-	default:
-		lenHint = -1
-	}
-	if top := d.top(); top != nil && top.Type.IsBytes() {
-		d.flag = d.flag.Set(decFlagIsParentBytes)
-	} else {
-		d.flag = d.flag.Clear(decFlagIsParentBytes)
-	}
-	return tt, lenHint, flag, nil
-}
-
-func errIncompatibleDecode(tt *vdl.Type, want interface{}) error {
-	return fmt.Errorf("vom: incompatible decode from %v into %v", tt, want)
-}
-
-func (d *decoder81) FinishValue() error {
-	d.flag = d.flag.Clear(decFlagFinishValue)
-	stackTop := len(d.stack) - 1
-	if stackTop == -1 {
-		return errEmptyDecoderStack
-	}
-	d.stack = d.stack[:stackTop]
-	if stackTop == 0 {
-		return d.endMessage()
-	}
-	return nil
-}
-
-func (d *decoder81) top() *decStackEntry {
-	if stackTop := len(d.stack) - 1; stackTop >= 0 {
-		return &d.stack[stackTop]
-	}
-	return nil
-}
-
-// dfsNextType determines the type of the next value that we will decode, by
-// walking the static type in DFS order.  To bootstrap we retrieve the top-level
-// type from the VOM value message.
-func (d *decoder81) dfsNextType() (*vdl.Type, error) {
-	top := d.top()
-	if top == nil {
-		// Bootstrap: start decoding a new top-level value.
-		if !d.flag.SeparateTypeDec() {
-			if err := d.decodeTypeDefs(); err != nil {
-				return nil, err
-			}
-		}
-		tid, err := d.nextMessage()
-		if err != nil {
-			return nil, err
-		}
-		return d.typeDec.lookupType(tid)
-	}
-	// Return the next type from our composite types.
-	tt := top.Type
-	switch tt.Kind() {
-	case vdl.Array, vdl.List:
-		return tt.Elem(), nil
-	case vdl.Set:
-		return tt.Key(), nil
-	case vdl.Map:
-		top.Flag = top.Flag.FlipIsMapKey()
-		if top.Flag.IsMapKey() {
-			return tt.Key(), nil
-		} else {
-			return tt.Elem(), nil
-		}
-	case vdl.Union, vdl.Struct:
-		return tt.Field(top.Index).Type, nil
-	}
-	return nil, fmt.Errorf("vom: can't StartValue on %v", tt)
-}
-
-func (d *decoder81) NextEntry() (bool, error) {
-	// Our strategy is to increment top.Index until it reaches top.LenHint.
-	// Currently the LenHint is always set, so it's stronger than a hint.
-	//
-	// TODO(toddw): Handle sentry-terminated collections without a LenHint.
-	top := d.top()
-	if top == nil {
-		return false, errEmptyDecoderStack
-	}
-	// Increment index and check errors.
-	top.Index++
-	switch top.Type.Kind() {
-	case vdl.Array, vdl.List, vdl.Set, vdl.Map:
-		if top.Index > top.LenHint && top.LenHint >= 0 {
-			return false, fmt.Errorf("vom: NextEntry called after done, stack: %+v", d.stack)
-		}
-	default:
-		return false, fmt.Errorf("vom: NextEntry called on invalid type, stack: %+v", d.stack)
-	}
-	return top.Index == top.LenHint, nil
-}
-
-func (d *decoder81) NextField() (int, error) {
-	top := d.top()
-	if top == nil {
-		return -1, errEmptyDecoderStack
-	}
-	// Increment index and check errors.  Note that the actual top.Index is
-	// decoded from the buf data stream; we use top.LenHint to help detect when
-	// the fields are done, and to detect invalid calls after we're done.
-	top.Index++
-	switch top.Type.Kind() {
-	case vdl.Union, vdl.Struct:
-		if top.Index > top.LenHint {
-			return -1, fmt.Errorf("vom: NextField called after done, stack: %+v", d.stack)
-		}
-	default:
-		return -1, fmt.Errorf("vom: NextField called on invalid type, stack: %+v", d.stack)
-	}
-	var field int
-	switch top.Type.Kind() {
-	case vdl.Union:
-		if top.Index == top.LenHint {
-			// We know we're done since we set LenHint=Index+1 the first time around,
-			// and we incremented the index above.
-			return -1, nil
-		}
-		// Decode the union field index.
-		switch index, err := binaryDecodeUint(d.buf); {
-		case err != nil:
-			return -1, err
-		case index >= uint64(top.Type.NumField()):
-			return -1, verror.New(errIndexOutOfRange, nil)
-		default:
-			// Set LenHint=Index+1 so that we'll know we're done next time around.
-			field = int(index)
-			top.Index = field
-			top.LenHint = field + 1
-		}
-	case vdl.Struct:
-		// Handle the end-of-struct sentry.
-		switch ok, err := binaryDecodeControlOnly(d.buf, WireCtrlEnd); {
-		case err != nil:
-			return -1, err
-		case ok:
-			// Set Index=LenHint to ensure repeated calls will fail.
-			top.Index = top.LenHint
-			return -1, nil
-		}
-		// Decode the struct field index.
-		switch index, err := binaryDecodeUint(d.buf); {
-		case err != nil:
-			return -1, err
-		case index >= uint64(top.Type.NumField()):
-			return -1, verror.New(errIndexOutOfRange, nil)
-		default:
-			field = int(index)
-			top.Index = field
-		}
-	}
-	return field, nil
-}
-
-func (d *decoder81) Type() *vdl.Type {
-	if top := d.top(); top != nil {
-		return top.Type
-	}
-	return nil
-}
-
-func (d *decoder81) IsAny() bool {
-	if top := d.top(); top != nil {
-		return top.Flag.IsAny()
-	}
-	return false
-}
-
-func (d *decoder81) IsOptional() bool {
-	if top := d.top(); top != nil {
-		return top.Flag.IsOptional()
-	}
-	return false
-}
-
-func (d *decoder81) IsNil() bool {
-	if top := d.top(); top != nil {
-		// Becuase of the "dereferencing" we do, the only time the type is any or
-		// optional is when it's nil.
-		return top.Type == vdl.AnyType || top.Type.Kind() == vdl.Optional
-	}
-	return false
-}
-
-func (d *decoder81) Index() int {
-	if top := d.top(); top != nil {
-		return top.Index
-	}
-	return -1
-}
-
-func (d *decoder81) LenHint() int {
-	if top := d.top(); top != nil {
-		// Note that union and struct shouldn't have a LenHint, but we abuse it in
-		// NextField as a convenience for detecting when fields are done, so an
-		// "arbitrary" value is returned here.  Users shouldn't be looking at it for
-		// union and struct anyways.
-		return top.LenHint
-	}
-	return -1
-}
-
-func (d *decoder81) DecodeBool() (bool, error) {
-	tt := d.Type()
-	if tt == nil {
-		return false, errEmptyDecoderStack
-	}
-	if tt.Kind() == vdl.Bool {
-		return binaryDecodeBool(d.buf)
-	}
-	return false, errIncompatibleDecode(tt, "bool")
-}
-
-func (d *decoder81) DecodeString() (string, error) {
-	tt := d.Type()
-	if tt == nil {
-		return "", errEmptyDecoderStack
-	}
-	switch tt.Kind() {
-	case vdl.String:
-		return binaryDecodeString(d.buf)
-	case vdl.Enum:
-		return d.binaryDecodeEnum(tt)
-	}
-	return "", errIncompatibleDecode(tt, "string")
-}
-
-func (d *decoder81) binaryDecodeEnum(tt *vdl.Type) (string, error) {
-	index, err := binaryDecodeUint(d.buf)
-	switch {
-	case err != nil:
-		return "", err
-	case index >= uint64(tt.NumEnumLabel()):
-		return "", fmt.Errorf("vom: enum index %d out of range, %v", index, tt)
-	}
-	return tt.EnumLabel(int(index)), nil
-}
-
-func (d *decoder81) binaryDecodeByte() (byte, error) {
-	// Handle a special-case where normally single bytes are written out as
-	// variable sized numbers, which use 2 bytes to encode bytes > 127.  But each
-	// byte contained in a list or array is written out as one byte.  E.g.
-	//   byte(0x81)         -> 0xFF81   : single byte with variable-size
-	//   []byte("\x81\x82") -> 0x028182 : each elem byte encoded as one byte
-	if d.flag.IsParentBytes() {
-		return d.buf.ReadByte()
-	}
-	x, err := binaryDecodeUint(d.buf)
-	return byte(x), err
-}
-
-func (d *decoder81) DecodeUint(bitlen int) (uint64, error) {
-	tt := d.Type()
-	if tt == nil {
-		return 0, errEmptyDecoderStack
-	}
-	return d.decodeUint(tt, uint(bitlen))
-}
-
-func (d *decoder81) decodeUint(tt *vdl.Type, ubitlen uint) (uint64, error) {
-	const errFmt = "vom: conversion from %v into uint%d loses precision: %v"
-	switch tt.Kind() {
-	case vdl.Byte:
-		x, err := d.binaryDecodeByte()
-		if err != nil {
-			return 0, err
-		}
-		return uint64(x), err
-	case vdl.Uint16, vdl.Uint32, vdl.Uint64:
-		x, err := binaryDecodeUint(d.buf)
-		if err != nil {
-			return 0, err
-		}
-		if shift := 64 - ubitlen; x != (x<<shift)>>shift {
-			return 0, fmt.Errorf(errFmt, tt, ubitlen, x)
-		}
-		return x, nil
-	case vdl.Int8, vdl.Int16, vdl.Int32, vdl.Int64:
-		x, err := binaryDecodeInt(d.buf)
-		if err != nil {
-			return 0, err
-		}
-		ux := uint64(x)
-		if shift := 64 - ubitlen; x < 0 || ux != (ux<<shift)>>shift {
-			return 0, fmt.Errorf(errFmt, tt, ubitlen, x)
-		}
-		return ux, nil
-	case vdl.Float32, vdl.Float64:
-		x, err := binaryDecodeFloat(d.buf)
-		if err != nil {
-			return 0, err
-		}
-		ux := uint64(x)
-		if shift := 64 - ubitlen; x != float64(ux) || ux != (ux<<shift)>>shift {
-			return 0, fmt.Errorf(errFmt, tt, ubitlen, x)
-		}
-		return ux, nil
-	}
-	return 0, errIncompatibleDecode(tt, fmt.Sprintf("uint%d", ubitlen))
-}
-
-func (d *decoder81) DecodeInt(bitlen int) (int64, error) {
-	tt := d.Type()
-	if tt == nil {
-		return 0, errEmptyDecoderStack
-	}
-	return d.decodeInt(tt, uint(bitlen))
-}
-
-func (d *decoder81) decodeInt(tt *vdl.Type, ubitlen uint) (int64, error) {
-	const errFmt = "vom: conversion from %v into int%d loses precision: %v"
-	switch tt.Kind() {
-	case vdl.Byte:
-		x, err := d.binaryDecodeByte()
-		if err != nil {
-			return 0, err
-		}
-		// The only case that fails is if we're converting byte(x) to int8, and x
-		// uses more than 7 bits (i.e. is greater than 127).
-		if ubitlen <= 8 && x > 0x7f {
-			return 0, fmt.Errorf(errFmt, tt, ubitlen, x)
-		}
-		return int64(x), nil
-	case vdl.Uint16, vdl.Uint32, vdl.Uint64:
-		x, err := binaryDecodeUint(d.buf)
-		if err != nil {
-			return 0, err
-		}
-		ix := int64(x)
-		// The shift uses 65 since the topmost bit is the sign bit.  I.e. 32 bit
-		// numbers should be shifted by 33 rather than 32.
-		if shift := 65 - ubitlen; ix < 0 || x != (x<<shift)>>shift {
-			return 0, fmt.Errorf(errFmt, tt, ubitlen, x)
-		}
-		return ix, nil
-	case vdl.Int8, vdl.Int16, vdl.Int32, vdl.Int64:
-		x, err := binaryDecodeInt(d.buf)
-		if err != nil {
-			return 0, err
-		}
-		if shift := 64 - ubitlen; x != (x<<shift)>>shift {
-			return 0, fmt.Errorf(errFmt, tt, ubitlen, x)
-		}
-		return x, nil
-	case vdl.Float32, vdl.Float64:
-		x, err := binaryDecodeFloat(d.buf)
-		if err != nil {
-			return 0, err
-		}
-		ix := int64(x)
-		if shift := 64 - ubitlen; x != float64(ix) || ix != (ix<<shift)>>shift {
-			return 0, fmt.Errorf(errFmt, tt, ubitlen, x)
-		}
-		return ix, nil
-	}
-	return 0, errIncompatibleDecode(tt, fmt.Sprintf("int%d", ubitlen))
-}
-
-func (d *decoder81) DecodeFloat(bitlen int) (float64, error) {
-	tt := d.Type()
-	if tt == nil {
-		return 0, errEmptyDecoderStack
-	}
-	return d.decodeFloat(tt, uint(bitlen))
-}
-
-func (d *decoder81) decodeFloat(tt *vdl.Type, ubitlen uint) (float64, error) {
-	const errFmt = "vom: conversion from %v into float%d loses precision: %v"
-	switch tt.Kind() {
-	case vdl.Byte:
-		x, err := d.binaryDecodeByte()
-		if err != nil {
-			return 0, err
-		}
-		return float64(x), nil
-	case vdl.Uint16, vdl.Uint32, vdl.Uint64:
-		x, err := binaryDecodeUint(d.buf)
-		if err != nil {
-			return 0, err
-		}
-		var max uint64
-		if ubitlen > 32 {
-			max = float64MaxInt
-		} else {
-			max = float32MaxInt
-		}
-		if x > max {
-			return 0, fmt.Errorf(errFmt, tt, ubitlen, x)
-		}
-		return float64(x), nil
-	case vdl.Int8, vdl.Int16, vdl.Int32, vdl.Int64:
-		x, err := binaryDecodeInt(d.buf)
-		if err != nil {
-			return 0, err
-		}
-		var min, max int64
-		if ubitlen > 32 {
-			min, max = float64MinInt, float64MaxInt
-		} else {
-			min, max = float32MinInt, float32MaxInt
-		}
-		if x < min || x > max {
-			return 0, fmt.Errorf(errFmt, tt, ubitlen, x)
-		}
-		return float64(x), nil
-	case vdl.Float32, vdl.Float64:
-		x, err := binaryDecodeFloat(d.buf)
-		if err != nil {
-			return 0, err
-		}
-		if ubitlen <= 32 && (x < -math.MaxFloat32 || x > math.MaxFloat32) {
-			return 0, fmt.Errorf(errFmt, tt, ubitlen, x)
-		}
-		return x, nil
-	}
-	return 0, errIncompatibleDecode(tt, fmt.Sprintf("float%d", ubitlen))
-}
-
-func (d *decoder81) DecodeBytes(fixedLen int, v *[]byte) error {
-	top := d.top()
-	if top == nil {
-		return errEmptyDecoderStack
-	}
-	tt := top.Type
-	if !tt.IsBytes() {
-		return vdl.DecodeConvertedBytes(d, fixedLen, v)
-	}
-	return d.decodeBytes(tt, top.LenHint, fixedLen, v)
-}
-
-func (d *decoder81) decodeBytes(tt *vdl.Type, lenHint, fixedLen int, v *[]byte) error {
-	switch {
-	case lenHint == -1:
-		return fmt.Errorf("vom: LenHint is currently required, %v", tt)
-	case fixedLen >= 0 && fixedLen != lenHint:
-		return fmt.Errorf("vom: got %d bytes, want fixed len %d, %v", lenHint, fixedLen, tt)
-	case lenHint == 0:
-		*v = nil
-		return nil
-	case fixedLen >= 0:
-		// Only re-use the existing buffer if we're filling in an array.  This
-		// sacrifices some performance, but also avoids bugs when repeatedly
-		// decoding into the same value.
-		*v = (*v)[:lenHint]
-	default:
-		*v = make([]byte, lenHint)
-	}
-	return d.buf.ReadIntoBuf(*v)
-}
-
-func (d *decoder81) DecodeTypeObject() (*vdl.Type, error) {
-	tt := d.Type()
-	if tt == nil {
-		return nil, errEmptyDecoderStack
-	}
-	if tt != vdl.TypeObjectType {
-		return nil, errIncompatibleDecode(tt, "typeobject")
-	}
-	return d.binaryDecodeType()
-}
-
-func (d *decoder81) binaryDecodeType() (*vdl.Type, error) {
-	typeIndex, err := binaryDecodeUint(d.buf)
-	if err != nil {
-		return nil, err
-	}
-	tid, err := d.refTypes.ReferencedTypeId(typeIndex)
-	if err != nil {
-		return nil, err
-	}
-	return d.typeDec.lookupType(tid)
-}
-
-func (d *decoder81) SkipValue() error {
-	tt, err := d.dfsNextType()
-	if err != nil {
-		return err
-	}
-	if len(d.stack) == 0 {
-		// Handle top-level values.  It's easy to determine the byte length of the
-		// value, so we can just skip the bytes.
-		valueLen, err := d.peekValueByteLen(tt)
-		if err != nil {
-			return err
-		}
-		if err := d.buf.Skip(valueLen); err != nil {
-			return err
-		}
-		return d.endMessage()
-	}
-	return d.skipValue(tt)
-}
diff --git a/vom/xdecoder_test.go b/vom/xdecoder_test.go
deleted file mode 100644
index 90fd789..0000000
--- a/vom/xdecoder_test.go
+++ /dev/null
@@ -1,134 +0,0 @@
-// Copyright 2015 The Vanadium 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 vom_test
-
-import (
-	"bytes"
-	"fmt"
-	"io"
-	"reflect"
-	"sync"
-	"testing"
-
-	"v.io/v23/vdl"
-	"v.io/v23/vom"
-	"v.io/v23/vom/vomtest"
-
-	// Import verror to ensure that interface tests result in *verror.E
-	_ "v.io/v23/verror"
-)
-
-// TODO(toddw): Add all useful tests from decoder_test.go
-
-var (
-	rtIface = reflect.TypeOf((*interface{})(nil)).Elem()
-	rtValue = reflect.TypeOf(vdl.Value{})
-)
-
-func TestXDecoder(t *testing.T) {
-	// The decoder tests take a long time, so we run them concurrently.
-	var pending sync.WaitGroup
-	for _, test := range vomtest.AllPass() {
-		pending.Add(1)
-		go func(test vomtest.Entry) {
-			defer pending.Done()
-			testXDecoder(t, "[go value]", test, rvPtrValue(test.Value))
-			testXDecoder(t, "[go iface]", test, rvPtrIface(test.Value))
-			vv, err := vdl.ValueFromReflect(test.Value)
-			if err != nil {
-				t.Errorf("%s: ValueFromReflect failed: %v", test.Name(), err)
-				return
-			}
-			vvWant := reflect.ValueOf(vv)
-			testXDecoder(t, "[new *vdl.Value]", test, vvWant)
-			testXDecoderFunc(t, "[zero vdl.Value]", test, vvWant, func() reflect.Value {
-				return reflect.ValueOf(vdl.ZeroValue(vv.Type()))
-			})
-		}(test)
-	}
-	pending.Wait()
-}
-
-func rvPtrValue(rv reflect.Value) reflect.Value {
-	result := reflect.New(rv.Type())
-	result.Elem().Set(rv)
-	return result
-}
-
-func rvPtrIface(rv reflect.Value) reflect.Value {
-	result := reflect.New(rtIface)
-	result.Elem().Set(rv)
-	return result
-}
-
-func testXDecoder(t *testing.T, pre string, test vomtest.Entry, rvWant reflect.Value) {
-	testXDecoderFunc(t, pre, test, rvWant, func() reflect.Value {
-		return reflect.New(rvWant.Type().Elem())
-	})
-	// TODO(toddw): Add tests that start with a randomly-set value.
-}
-
-func testXDecoderFunc(t *testing.T, pre string, test vomtest.Entry, rvWant reflect.Value, rvNew func() reflect.Value) {
-	readEOF := make([]byte, 1)
-	for _, mode := range vom.AllReadModes {
-		// Test vom.NewXDecoder.
-		{
-			name := fmt.Sprintf("%s (%s) %s", pre, mode, test.Name())
-			rvGot := rvNew()
-			reader := mode.TestReader(bytes.NewReader(test.Bytes()))
-			dec := vom.NewDecoder(reader)
-			if err := dec.Decode(rvGot.Interface()); err != nil {
-				t.Errorf("%s: Decode failed: %v", name, err)
-				return
-			}
-			if !vdl.DeepEqualReflect(rvGot, rvWant) {
-				t.Errorf("%s\nGOT  %v\nWANT %v", name, rvGot, rvWant)
-				return
-			}
-			if n, err := reader.Read(readEOF); n != 0 || err != io.EOF {
-				t.Errorf("%s: reader got (%d,%v), want (0,EOF)", name, n, err)
-			}
-		}
-		// Test vom.NewXDecoderWithTypeDecoder
-		{
-			name := fmt.Sprintf("%s (%s with TypeDecoder) %s", pre, mode, test.Name())
-			rvGot := rvNew()
-			readerT := mode.TestReader(bytes.NewReader(test.TypeBytes()))
-			decT := vom.NewTypeDecoder(readerT)
-			decT.Start()
-			reader := mode.TestReader(bytes.NewReader(test.ValueBytes()))
-			dec := vom.NewDecoderWithTypeDecoder(reader, decT)
-			err := dec.Decode(rvGot.Interface())
-			decT.Stop()
-			if err != nil {
-				t.Errorf("%s: Decode failed: %v", name, err)
-				return
-			}
-			if !vdl.DeepEqualReflect(rvGot, rvWant) {
-				t.Errorf("%s\nGOT  %v\nWANT %v", name, rvGot, rvWant)
-				return
-			}
-			if n, err := reader.Read(readEOF); n != 0 || err != io.EOF {
-				t.Errorf("%s: reader got (%d,%v), want (0,EOF)", name, n, err)
-			}
-			if n, err := readerT.Read(readEOF); n != 0 || err != io.EOF {
-				t.Errorf("%s: readerT got (%d,%v), want (0,EOF)", name, n, err)
-			}
-		}
-	}
-	// Test single-shot vom.Decode twice, to ensure we test the cache hit case.
-	for i := 0; i < 2; i++ {
-		name := fmt.Sprintf("%s (single-shot %d) %s", pre, i, test.Name())
-		rvGot := rvNew()
-		if err := vom.Decode(test.Bytes(), rvGot.Interface()); err != nil {
-			t.Errorf("%s: Decode failed: %v", name, err)
-			return
-		}
-		if !vdl.DeepEqualReflect(rvGot, rvWant) {
-			t.Errorf("%s\nGOT  %v\nWANT %v", name, rvGot, rvWant)
-			return
-		}
-	}
-}
diff --git a/vom/xencoder_test.go b/vom/xencoder_test.go
deleted file mode 100644
index 2b9d013..0000000
--- a/vom/xencoder_test.go
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2015 The Vanadium 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 vom_test
-
-import (
-	"bytes"
-	"fmt"
-	"testing"
-
-	"v.io/v23/vdl"
-	"v.io/v23/vom"
-	"v.io/v23/vom/vomtest"
-)
-
-func TestXEncoder(t *testing.T) {
-	for _, test := range vomtest.AllPass() {
-		testXEncoder(t, "[go value]", test, test.Value.Interface())
-		vv, err := vdl.ValueFromReflect(test.Value)
-		if err != nil {
-			t.Errorf("%s: ValueFromReflect failed: %v", test.Name(), err)
-			continue
-		}
-		testXEncoder(t, "[vdl.Value]", test, vv)
-	}
-}
-
-func testXEncoder(t *testing.T, pre string, test vomtest.Entry, value interface{}) {
-	// Test vom.NewXEncoder.
-	{
-		var buf bytes.Buffer
-		name := fmt.Sprintf("%s %s", pre, test.Name())
-		enc := vom.NewVersionedEncoder(test.Version, &buf)
-		if err := enc.Encode(value); err != nil {
-			t.Errorf("%s: Encode failed: %v", name, err)
-			return
-		}
-		if got, want := buf.Bytes(), test.Bytes(); !bytes.Equal(got, want) {
-			t.Errorf("%s\nGOT  %x\nWANT %x", name, got, want)
-			return
-		}
-	}
-	// Test vom.NewXEncoderWithTypeEncoder.
-	{
-		var buf, bufT bytes.Buffer
-		name := fmt.Sprintf("%s (with TypeEncoder) %s", pre, test.Name())
-		encT := vom.NewVersionedTypeEncoder(test.Version, &bufT)
-		enc := vom.NewVersionedEncoderWithTypeEncoder(test.Version, &buf, encT)
-		if err := enc.Encode(value); err != nil {
-			t.Errorf("%s: Encode failed: %v", name, err)
-			return
-		}
-		if got, want := bufT.Bytes(), test.TypeBytes(); !bytes.Equal(got, want) {
-			t.Errorf("%s TYPE\nGOT  %x\nWANT %x", name, got, want)
-			return
-		}
-		if got, want := buf.Bytes(), test.ValueBytes(); !bytes.Equal(got, want) {
-			t.Errorf("%s VALUE\nGOT  %x\nWANT %x", name, got, want)
-			return
-		}
-	}
-	// Test single-shot vom.XEncode.
-	{
-		name := fmt.Sprintf("%s (single-shot) %s", pre, test.Name())
-		buf, err := vom.VersionedEncode(test.Version, value)
-		if err != nil {
-			t.Errorf("%s: Encode failed: %v", name, err)
-			return
-		}
-		if got, want := buf, test.Bytes(); !bytes.Equal(got, want) {
-			t.Errorf("%s\nGOT  %x\nWANT %x", name, got, want)
-			return
-		}
-	}
-}
