diff --git a/ifd_builder.go b/ifd_builder.go
index 47ab37a..4854d6b 100644
--- a/ifd_builder.go
+++ b/ifd_builder.go
@@ -1111,10 +1111,7 @@ func (ib *IfdBuilder) AddTagsFromExisting(ifd *Ifd, itevr *IfdTagEntryValueResol
 
 			var value *IfdBuilderTagValue
 
-			valueContext := newValueContextFromTag(
-				ite,
-				ifd.addressableData,
-				ifd.ByteOrder)
+			valueContext := ifd.GetValueContext(ite)
 
 			var rawBytes []byte
 
diff --git a/ifd_builder_test.go b/ifd_builder_test.go
index aa87e0b..02ea53e 100644
--- a/ifd_builder_test.go
+++ b/ifd_builder_test.go
@@ -1307,8 +1307,7 @@ func TestIfdBuilder_CreateIfdBuilderFromExistingChain(t *testing.T) {
 	_, index, err := Collect(im, ti, rawExif)
 	log.PanicIf(err)
 
-	itevr := NewIfdTagEntryValueResolver(rawExif, index.RootIfd.ByteOrder)
-	ib := NewIfdBuilderFromExistingChain(index.RootIfd, itevr)
+	ib := NewIfdBuilderFromExistingChain(index.RootIfd, nil)
 
 	actual := ib.DumpToStrings()
 
@@ -1414,8 +1413,7 @@ func TestIfdBuilder_CreateIfdBuilderFromExistingChain_RealData(t *testing.T) {
 
 	ibe := NewIfdByteEncoder()
 
-	itevr := NewIfdTagEntryValueResolver(rawExif, originalIndex.RootIfd.ByteOrder)
-	rootIb := NewIfdBuilderFromExistingChain(originalIndex.RootIfd, itevr)
+	rootIb := NewIfdBuilderFromExistingChain(originalIndex.RootIfd, nil)
 
 	updatedExif, err := ibe.EncodeToExif(rootIb)
 	log.PanicIf(err)
@@ -1528,8 +1526,7 @@ func TestIfdBuilder_CreateIfdBuilderFromExistingChain_RealData(t *testing.T) {
 
 // 	ibe := NewIfdByteEncoder()
 
-// 	itevr := NewIfdTagEntryValueResolver(rawExif, originalIndex.RootIfd.ByteOrder)
-// 	rootIb := NewIfdBuilderFromExistingChain(originalIndex.RootIfd, itevr)
+// 	rootIb := NewIfdBuilderFromExistingChain(originalIndex.RootIfd, nil)
 
 // 	// Update a tag,.
 
@@ -1687,8 +1684,7 @@ func ExampleBuilderTag_SetValue() {
 
 	// Create builder.
 
-	itevr := NewIfdTagEntryValueResolver(rawExif, index.RootIfd.ByteOrder)
-	rootIb := NewIfdBuilderFromExistingChain(index.RootIfd, itevr)
+	rootIb := NewIfdBuilderFromExistingChain(index.RootIfd, nil)
 
 	// Find tag to update.
 
@@ -1745,8 +1741,7 @@ func ExampleIfdBuilder_SetStandardWithName() {
 	_, index, err := Collect(im, ti, rawExif)
 	log.PanicIf(err)
 
-	itevr := NewIfdTagEntryValueResolver(rawExif, index.RootIfd.ByteOrder)
-	ib := NewIfdBuilderFromExistingChain(index.RootIfd, itevr)
+	ib := NewIfdBuilderFromExistingChain(index.RootIfd, nil)
 
 	// Read the IFD whose tag we want to change.
 
diff --git a/ifd_enumerate.go b/ifd_enumerate.go
index 21139b7..82eef7d 100644
--- a/ifd_enumerate.go
+++ b/ifd_enumerate.go
@@ -1010,6 +1010,13 @@ func (ifd *Ifd) EnumerateTagsRecursively(visitor ParsedTagVisitor) (err error) {
 	return nil
 }
 
+func (ifd *Ifd) GetValueContext(ite *IfdTagEntry) *ValueContext {
+	return newValueContextFromTag(
+		ite,
+		ifd.addressableData,
+		ifd.ByteOrder)
+}
+
 type QueuedIfd struct {
 	Name      string
 	IfdPath   string
diff --git a/ifd_enumerate_test.go b/ifd_enumerate_test.go
index 5455b9b..020bc95 100644
--- a/ifd_enumerate_test.go
+++ b/ifd_enumerate_test.go
@@ -89,108 +89,7 @@ func TestIfdTagEntry_ValueBytes_RealData(t *testing.T) {
 	}
 }
 
-func TestIfdTagEntry_Resolver_ValueBytes(t *testing.T) {
-	defer func() {
-		if state := recover(); state != nil {
-			err := log.Wrap(state.(error))
-			log.PrintErrorf(err, "Test failure.")
-		}
-	}()
-
-	filepath := path.Join(assetsPath, "NDM_8901.jpg")
-
-	rawExif, err := SearchFileAndExtractExif(filepath)
-	log.PanicIf(err)
-
-	im := NewIfdMapping()
-
-	err = LoadStandardIfds(im)
-	log.PanicIf(err)
-
-	ti := NewTagIndex()
-
-	eh, index, err := Collect(im, ti, rawExif)
-	log.PanicIf(err)
-
-	var ite *IfdTagEntry
-	for _, thisIte := range index.RootIfd.Entries {
-		if thisIte.TagId == 0x0110 {
-			ite = thisIte
-			break
-		}
-	}
-
-	if ite == nil {
-		t.Fatalf("Tag not found.")
-	}
-
-	itevr := NewIfdTagEntryValueResolver(rawExif, eh.ByteOrder)
-
-	decodedBytes, err := itevr.ValueBytes(ite)
-	log.PanicIf(err)
-
-	expected := []byte("Canon EOS 5D Mark III")
-	expected = append(expected, 0)
-
-	if len(decodedBytes) != int(ite.UnitCount) {
-		t.Fatalf("Decoded bytes not the right count.")
-	} else if bytes.Compare(decodedBytes, expected) != 0 {
-		t.Fatalf("Decoded bytes not correct.")
-	}
-}
-
-func TestIfdTagEntry_Resolver_ValueBytes__Unknown_Field_And_Nonroot_Ifd(t *testing.T) {
-	defer func() {
-		if state := recover(); state != nil {
-			err := log.Wrap(state.(error))
-			log.PrintErrorf(err, "Test failure.")
-		}
-	}()
-
-	filepath := path.Join(assetsPath, "NDM_8901.jpg")
-
-	rawExif, err := SearchFileAndExtractExif(filepath)
-	log.PanicIf(err)
-
-	im := NewIfdMapping()
-
-	err = LoadStandardIfds(im)
-	log.PanicIf(err)
-
-	ti := NewTagIndex()
-
-	eh, index, err := Collect(im, ti, rawExif)
-	log.PanicIf(err)
-
-	ifdExif := index.Lookup[IfdPathStandardExif][0]
-
-	var ite *IfdTagEntry
-	for _, thisIte := range ifdExif.Entries {
-		if thisIte.TagId == 0x9000 {
-			ite = thisIte
-			break
-		}
-	}
-
-	if ite == nil {
-		t.Fatalf("Tag not found.")
-	}
-
-	itevr := NewIfdTagEntryValueResolver(rawExif, eh.ByteOrder)
-
-	decodedBytes, err := itevr.ValueBytes(ite)
-	log.PanicIf(err)
-
-	expected := []byte{'0', '2', '3', '0'}
-
-	if len(decodedBytes) != int(ite.UnitCount) {
-		t.Fatalf("Decoded bytes not the right count.")
-	} else if bytes.Compare(decodedBytes, expected) != 0 {
-		t.Fatalf("Recovered unknown value is not correct.")
-	}
-}
-
-func Test_Ifd_FindTagWithId_Hit(t *testing.T) {
+func TestIfd_FindTagWithId_Hit(t *testing.T) {
 	filepath := path.Join(assetsPath, "NDM_8901.jpg")
 
 	rawExif, err := SearchFileAndExtractExif(filepath)
@@ -216,7 +115,7 @@ func Test_Ifd_FindTagWithId_Hit(t *testing.T) {
 	}
 }
 
-func Test_Ifd_FindTagWithId_Miss(t *testing.T) {
+func TestIfd_FindTagWithId_Miss(t *testing.T) {
 	filepath := path.Join(assetsPath, "NDM_8901.jpg")
 
 	rawExif, err := SearchFileAndExtractExif(filepath)
@@ -242,7 +141,7 @@ func Test_Ifd_FindTagWithId_Miss(t *testing.T) {
 	}
 }
 
-func Test_Ifd_FindTagWithName_Hit(t *testing.T) {
+func TestIfd_FindTagWithName_Hit(t *testing.T) {
 	filepath := path.Join(assetsPath, "NDM_8901.jpg")
 
 	rawExif, err := SearchFileAndExtractExif(filepath)
@@ -268,7 +167,7 @@ func Test_Ifd_FindTagWithName_Hit(t *testing.T) {
 	}
 }
 
-func Test_Ifd_FindTagWithName_Miss(t *testing.T) {
+func TestIfd_FindTagWithName_Miss(t *testing.T) {
 	filepath := path.Join(assetsPath, "NDM_8901.jpg")
 
 	rawExif, err := SearchFileAndExtractExif(filepath)
@@ -294,7 +193,7 @@ func Test_Ifd_FindTagWithName_Miss(t *testing.T) {
 	}
 }
 
-func Test_Ifd_FindTagWithName_NonStandard(t *testing.T) {
+func TestIfd_FindTagWithName_NonStandard(t *testing.T) {
 	filepath := path.Join(assetsPath, "NDM_8901.jpg")
 
 	rawExif, err := SearchFileAndExtractExif(filepath)
@@ -320,7 +219,7 @@ func Test_Ifd_FindTagWithName_NonStandard(t *testing.T) {
 	}
 }
 
-func Test_Ifd_Thumbnail(t *testing.T) {
+func TestIfd_Thumbnail(t *testing.T) {
 	filepath := path.Join(assetsPath, "NDM_8901.jpg")
 
 	rawExif, err := SearchFileAndExtractExif(filepath)
diff --git a/value_context_test.go b/value_context_test.go
new file mode 100644
index 0000000..68b30ba
--- /dev/null
+++ b/value_context_test.go
@@ -0,0 +1,117 @@
+package exif
+
+import (
+	"bytes"
+	"path"
+	"testing"
+
+	"github.com/dsoprea/go-logging"
+)
+
+func TestValueContext_ReadAscii(t *testing.T) {
+	defer func() {
+		if state := recover(); state != nil {
+			err := log.Wrap(state.(error))
+			log.PrintErrorf(err, "Test failure.")
+		}
+	}()
+
+	filepath := path.Join(assetsPath, "NDM_8901.jpg")
+
+	rawExif, err := SearchFileAndExtractExif(filepath)
+	log.PanicIf(err)
+
+	im := NewIfdMapping()
+
+	err = LoadStandardIfds(im)
+	log.PanicIf(err)
+
+	ti := NewTagIndex()
+
+	_, index, err := Collect(im, ti, rawExif)
+	log.PanicIf(err)
+
+	ifd := index.RootIfd
+
+	var ite *IfdTagEntry
+	for _, thisIte := range ifd.Entries {
+		if thisIte.TagId == 0x0110 {
+			ite = thisIte
+			break
+		}
+	}
+
+	if ite == nil {
+		t.Fatalf("Tag not found.")
+	}
+
+	valueContext := ifd.GetValueContext(ite)
+
+	decodedString, err := valueContext.ReadAscii()
+	log.PanicIf(err)
+
+	decodedBytes := []byte(decodedString)
+
+	expected := []byte("Canon EOS 5D Mark III")
+
+	if bytes.Compare(decodedBytes, expected) != 0 {
+		t.Fatalf("Decoded bytes not correct.")
+	}
+}
+
+func TestValueContext_Undefined(t *testing.T) {
+	defer func() {
+		if state := recover(); state != nil {
+			err := log.Wrap(state.(error))
+			log.PrintErrorf(err, "Test failure.")
+		}
+	}()
+
+	filepath := path.Join(assetsPath, "NDM_8901.jpg")
+
+	rawExif, err := SearchFileAndExtractExif(filepath)
+	log.PanicIf(err)
+
+	im := NewIfdMapping()
+
+	err = LoadStandardIfds(im)
+	log.PanicIf(err)
+
+	ti := NewTagIndex()
+
+	_, index, err := Collect(im, ti, rawExif)
+	log.PanicIf(err)
+
+	ifdExif := index.Lookup[IfdPathStandardExif][0]
+
+	var ite *IfdTagEntry
+	for _, thisIte := range ifdExif.Entries {
+		if thisIte.TagId == 0x9000 {
+			ite = thisIte
+			break
+		}
+	}
+
+	if ite == nil {
+		t.Fatalf("Tag not found.")
+	}
+
+	valueContext := ifdExif.GetValueContext(ite)
+
+	value, err := valueContext.Undefined()
+	log.PanicIf(err)
+
+	gs, ok := value.(TagUnknownType_GeneralString)
+	if ok != true {
+		t.Fatalf("Undefined value not processed correctly.")
+	}
+
+	decodedBytes, err := gs.ValueBytes()
+	log.PanicIf(err)
+
+	expected := []byte("0230")
+
+	if bytes.Compare(decodedBytes, expected) != 0 {
+		t.Fatalf("Decoded bytes not correct.")
+	}
+}