diff --git a/filetree/changeinfo.go b/filetree/changeinfo.go
deleted file mode 100644
index 95a6529..0000000
--- a/filetree/changeinfo.go
+++ /dev/null
@@ -1,84 +0,0 @@
-package filetree
-
-import (
-	"archive/tar"
-	"bytes"
-	"crypto/md5"
-	"fmt"
-	"io"
-)
-
-type FileChangeInfo struct {
-	Path     string
-	Typeflag byte
-	MD5sum   [16]byte
-	DiffType DiffType
-}
-
-type DiffType int
-
-// enum to show whether a file has changed
-const (
-	Unchanged DiffType = iota
-	Changed
-	Added
-	Removed
-)
-
-func NewFileChangeInfo(reader *tar.Reader, header *tar.Header, path string) FileChangeInfo {
-	if header.Typeflag == tar.TypeDir {
-		return FileChangeInfo{
-			Path:     path,
-			Typeflag: header.Typeflag,
-			MD5sum:   [16]byte{},
-		}
-	}
-	fileBytes := make([]byte, header.Size)
-	_, err := reader.Read(fileBytes)
-	if err != nil && err != io.EOF {
-		panic(err)
-	}
-	return FileChangeInfo{
-		Path:     path,
-		Typeflag: header.Typeflag,
-		MD5sum:   md5.Sum(fileBytes),
-		DiffType: Unchanged,
-	}
-}
-
-func (d DiffType) String() string {
-	switch d {
-	case Unchanged:
-		return "Unchanged"
-	case Changed:
-		return "Changed"
-	case Added:
-		return "Added"
-	case Removed:
-		return "Removed"
-	default:
-		return fmt.Sprintf("%d", int(d))
-	}
-}
-
-func (a DiffType) merge(b DiffType) DiffType {
-	if a == b {
-		return a
-	}
-	return Changed
-}
-
-func (a *FileChangeInfo) getDiffType(b *FileChangeInfo) DiffType {
-	if a == nil && b == nil {
-		return Unchanged
-	}
-	if a == nil || b == nil {
-		return Changed
-	}
-	if a.Typeflag == b.Typeflag {
-		if bytes.Compare(a.MD5sum[:], b.MD5sum[:]) == 0 {
-			return Unchanged
-		}
-	}
-	return Changed
-}
diff --git a/filetree/data.go b/filetree/data.go
new file mode 100644
index 0000000..05114b9
--- /dev/null
+++ b/filetree/data.go
@@ -0,0 +1,134 @@
+package filetree
+
+import (
+	"archive/tar"
+	"bytes"
+	"crypto/md5"
+	"fmt"
+	"io"
+)
+
+// enum to show whether a file has changed
+const (
+	Unchanged DiffType = iota
+	Changed
+	Added
+	Removed
+)
+
+type NodeData struct {
+	ViewInfo  ViewInfo
+	FileInfo  *FileInfo
+	DiffType  DiffType
+}
+
+type ViewInfo struct {
+	Collapsed bool
+	Hidden    bool
+}
+
+type FileInfo struct {
+	Path     string
+	Typeflag byte
+	MD5sum   [16]byte
+}
+
+type DiffType int
+
+func NewNodeData() (*NodeData) {
+	return &NodeData{
+		ViewInfo: *NewViewInfo(),
+		FileInfo: nil,
+		DiffType: Unchanged,
+	}
+}
+
+func (data *NodeData) Copy() (*NodeData) {
+	return &NodeData{
+		ViewInfo: *data.ViewInfo.Copy(),
+		FileInfo: data.FileInfo.Copy(),
+		DiffType: data.DiffType,
+	}
+}
+
+
+func NewViewInfo() (view *ViewInfo) {
+	return &ViewInfo{
+		Collapsed: false,
+		Hidden: false,
+	}
+}
+
+func (view *ViewInfo) Copy() (newView *ViewInfo) {
+	newView = NewViewInfo()
+	*newView = *view
+	return newView
+}
+
+func NewFileInfo(reader *tar.Reader, header *tar.Header, path string) FileInfo {
+	if header.Typeflag == tar.TypeDir {
+		return FileInfo{
+			Path:     path,
+			Typeflag: header.Typeflag,
+			MD5sum:   [16]byte{},
+		}
+	}
+	fileBytes := make([]byte, header.Size)
+	_, err := reader.Read(fileBytes)
+	if err != nil && err != io.EOF {
+		panic(err)
+	}
+	return FileInfo{
+		Path:     path,
+		Typeflag: header.Typeflag,
+		MD5sum:   md5.Sum(fileBytes),
+	}
+}
+
+func (d DiffType) String() string {
+	switch d {
+	case Unchanged:
+		return "Unchanged"
+	case Changed:
+		return "Changed"
+	case Added:
+		return "Added"
+	case Removed:
+		return "Removed"
+	default:
+		return fmt.Sprintf("%d", int(d))
+	}
+}
+
+func (a DiffType) merge(b DiffType) DiffType {
+	if a == b {
+		return a
+	}
+	return Changed
+}
+
+func (data *FileInfo) Copy() *FileInfo {
+	if data == nil {
+		return nil
+	}
+	return &FileInfo{
+		Path:     data.Path,
+		Typeflag: data.Typeflag,
+		MD5sum:   data.MD5sum,
+	}
+}
+
+func (data *FileInfo) getDiffType(other *FileInfo) DiffType {
+	if data == nil && other == nil {
+		return Unchanged
+	}
+	if data == nil || other == nil {
+		return Changed
+	}
+	if data.Typeflag == other.Typeflag {
+		if bytes.Compare(data.MD5sum[:], other.MD5sum[:]) == 0 {
+			return Unchanged
+		}
+	}
+	return Changed
+}
diff --git a/filetree/changeinfo_test.go b/filetree/data_test.go
similarity index 58%
rename from filetree/changeinfo_test.go
rename to filetree/data_test.go
index 1892ac7..0d6fcbd 100644
--- a/filetree/changeinfo_test.go
+++ b/filetree/data_test.go
@@ -28,23 +28,10 @@ func TestMergeDiffTypes(t *testing.T) {
 	}
 }
 
-func TestDiffTypeFromChildren(t *testing.T) {
-	tree := NewFileTree()
-	tree.AddPath("/usr", BlankFileChangeInfo("/usr", Unchanged))
-	info1 := BlankFileChangeInfo("/usr/bin", Added)
-	tree.AddPath("/usr/bin", info1)
-	info2 := BlankFileChangeInfo("/usr/bin2", Removed)
-	tree.AddPath("/usr/bin2", info2)
-	tree.Root.Children["usr"].deriveDiffType(Unchanged)
-	if tree.Root.Children["usr"].Data.DiffType != Changed {
-		t.Errorf("Expected Changed but got %v", tree.Root.Children["usr"].Data.DiffType)
-	}
-}
-
 func AssertDiffType(node *FileNode, expectedDiffType DiffType, t *testing.T) error {
-	if node.Data == nil {
-		t.Errorf("Expected *FileChangeInfo but got nil at Path %s", node.Path())
-		return fmt.Errorf("expected *FileChangeInfo but got nil at Path %s", node.Path())
+	if node.Data.FileInfo == nil {
+		t.Errorf("Expected *FileInfo but got nil at Path %s", node.Path())
+		return fmt.Errorf("expected *FileInfo but got nil at Path %s", node.Path())
 	}
 	if node.Data.DiffType != expectedDiffType {
 		t.Errorf("Expecting node at %s to have DiffType %v, but had %v", node.Path(), expectedDiffType, node.Data.DiffType)
@@ -53,12 +40,11 @@ func AssertDiffType(node *FileNode, expectedDiffType DiffType, t *testing.T) err
 	return nil
 }
 
-func BlankFileChangeInfo(path string, diffType DiffType) (f *FileChangeInfo) {
-	result := FileChangeInfo{
+func BlankFileChangeInfo(path string, diffType DiffType) (f *FileInfo) {
+	result := FileInfo{
 		Path:     path,
 		Typeflag: 1,
 		MD5sum:   [16]byte{1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0},
-		DiffType: diffType,
 	}
 	return &result
 }
diff --git a/filetree/node.go b/filetree/node.go
index 61a7abb..2239b62 100644
--- a/filetree/node.go
+++ b/filetree/node.go
@@ -11,19 +11,17 @@ type FileNode struct {
 	Tree      *FileTree
 	Parent    *FileNode
 	Name      string
-	Collapsed bool
-	Hidden    bool
-	Data      *FileChangeInfo
+	Data      NodeData
 	Children  map[string]*FileNode
 }
 
-func NewNode(parent *FileNode, name string, data *FileChangeInfo) (node *FileNode) {
+func NewNode(parent *FileNode, name string, data *FileInfo) (node *FileNode) {
 	node = new(FileNode)
 	node.Name = name
-	if data == nil {
-		data = &FileChangeInfo{}
+	node.Data = *NewNodeData()
+	if data != nil {
+		node.Data.FileInfo = data.Copy()
 	}
-	node.Data = data
 	node.Children = make(map[string]*FileNode)
 	node.Parent = parent
 	if parent != nil {
@@ -33,21 +31,19 @@ func NewNode(parent *FileNode, name string, data *FileChangeInfo) (node *FileNod
 }
 
 func (node *FileNode) Copy() *FileNode {
-	// newNode := new(FileNode)
-	// *newNode = *node
-	// return newNode
-	newNode := NewNode(node.Parent, node.Name, node.Data)
+	newNode := NewNode(node.Parent, node.Name, node.Data.FileInfo)
 	for name, child := range node.Children {
 		newNode.Children[name] = child.Copy()
+		child.Parent = newNode
 	}
 	return newNode
 }
 
-func (node *FileNode) AddChild(name string, data *FileChangeInfo) (child *FileNode) {
+func (node *FileNode) AddChild(name string, data *FileInfo) (child *FileNode) {
 	child = NewNode(node, name, data)
 	if node.Children[name] != nil {
 		// tree node already exists, replace the payload, keep the children
-		node.Children[name].Data = data
+		node.Children[name].Data.FileInfo = data.Copy()
 	} else {
 		node.Children[name] = child
 		node.Tree.Size++
@@ -68,7 +64,7 @@ func (node *FileNode) String() string {
 	var style *color.Color
 	if node == nil {
 		return ""
-	} else if node.Data == nil {
+	} else if node.Data.FileInfo == nil {
 		return node.Name
 	}
 	switch node.Data.DiffType {
@@ -86,7 +82,7 @@ func (node *FileNode) String() string {
 	return style.Sprint(node.Name)
 }
 
-func (node *FileNode) Visit(visiter Visiter) error {
+func (node *FileNode) VisitDepthChildFirst(visiter Visiter) error {
 	var keys []string
 	for key := range node.Children {
 		keys = append(keys, key)
@@ -94,7 +90,7 @@ func (node *FileNode) Visit(visiter Visiter) error {
 	sort.Strings(keys)
 	for _, name := range keys {
 		child := node.Children[name]
-		err := child.Visit(visiter)
+		err := child.VisitDepthChildFirst(visiter)
 		if err != nil {
 			return err
 		}
@@ -165,8 +161,7 @@ func (node *FileNode) deriveDiffType(diffType DiffType) error {
 	myDiffType := diffType
 
 	for _, v := range node.Children {
-		vData := v.Data
-		myDiffType = myDiffType.merge(vData.DiffType)
+		myDiffType = myDiffType.merge(v.Data.DiffType)
 
 	}
 	node.AssignDiffType(myDiffType)
@@ -217,5 +212,5 @@ func (a *FileNode) compare(b *FileNode) DiffType {
 	}
 	// TODO: fails on nil
 
-	return a.Data.getDiffType(b.Data)
+	return a.Data.FileInfo.getDiffType(b.Data.FileInfo)
 }
diff --git a/filetree/node_test.go b/filetree/node_test.go
index 03a262d..18bdb27 100644
--- a/filetree/node_test.go
+++ b/filetree/node_test.go
@@ -1,12 +1,14 @@
 package filetree
 
-import "testing"
+import (
+	"testing"
+)
 
 func TestAddChild(t *testing.T) {
 	var expected, actual int
 	tree := NewFileTree()
 
-	payload := FileChangeInfo{
+	payload := FileInfo{
 		Path: "stufffffs",
 	}
 
@@ -34,16 +36,16 @@ func TestAddChild(t *testing.T) {
 		t.Errorf("Expected 'twos' number of children to be %d got %d.", expected, actual)
 	}
 
-	expectedFC := &FileChangeInfo{
+	expectedFC := &FileInfo{
 		Path: "stufffffs",
 	}
-	actualFC := one.Data
+	actualFC := one.Data.FileInfo
 	if *expectedFC != *actualFC {
 		t.Errorf("Expected 'ones' payload to be %+v got %+v.", expectedFC, actualFC)
 	}
 
-	if *two.Data != *new(FileChangeInfo) {
-		t.Errorf("Expected 'twos' payload to be nil got %+v.", two.Data)
+	if two.Data.FileInfo != nil {
+		t.Errorf("Expected 'twos' payload to be nil got %+v.", two.Data.FileInfo)
 	}
 
 }
@@ -106,3 +108,20 @@ func TestIsWhiteout(t *testing.T) {
 		t.Errorf("Expected Path '%s' to be a whiteout file", p2.Name)
 	}
 }
+
+func TestDiffTypeFromChildren(t *testing.T) {
+	tree := NewFileTree()
+	tree.AddPath("/usr", BlankFileChangeInfo("/usr", Unchanged))
+
+	info1 := BlankFileChangeInfo("/usr/bin", Added)
+	tree.AddPath("/usr/bin", info1)
+
+	info2 := BlankFileChangeInfo("/usr/bin2", Removed)
+	tree.AddPath("/usr/bin2", info2)
+
+	tree.Root.Children["usr"].deriveDiffType(Unchanged)
+
+	if tree.Root.Children["usr"].Data.DiffType != Changed {
+		t.Errorf("Expected Changed but got %v", tree.Root.Children["usr"].Data.DiffType)
+	}
+}
diff --git a/filetree/tree.go b/filetree/tree.go
index 9ee443f..8879862 100644
--- a/filetree/tree.go
+++ b/filetree/tree.go
@@ -69,13 +69,13 @@ func (tree *FileTree) String() string {
 		sort.Strings(keys)
 		for idx, name := range keys {
 			child := node.Children[name]
-			if child.Hidden {
+			if child.Data.ViewInfo.Hidden {
 				continue
 			}
 			last := idx == (len(node.Children) - 1)
-			showCollapsed := child.Collapsed && len(child.Children) > 0
+			showCollapsed := child.Data.ViewInfo.Collapsed && len(child.Children) > 0
 			result += renderLine(child.String(), spaces, last, showCollapsed)
-			if len(child.Children) > 0 && !child.Collapsed {
+			if len(child.Children) > 0 && !child.Data.ViewInfo.Collapsed {
 				spacesChild := append(spaces, last)
 				result += walkTree(child, spacesChild, depth+1)
 			}
@@ -90,7 +90,7 @@ func (tree *FileTree) Copy() *FileTree {
 	newTree := NewFileTree()
 	*newTree = *tree
 	newTree.Root = tree.Root.Copy()
-	newTree.Visit(func(node *FileNode) error {
+	newTree.VisitDepthChildFirst(func(node *FileNode) error {
 		node.Tree = newTree
 		return nil
 	})
@@ -101,10 +101,12 @@ func (tree *FileTree) Copy() *FileTree {
 type Visiter func(*FileNode) error
 type VisitEvaluator func(*FileNode) bool
 
-func (tree *FileTree) Visit(visiter Visiter) error {
-	return tree.Root.Visit(visiter)
+// DFS bubble up
+func (tree *FileTree) VisitDepthChildFirst(visiter Visiter) error {
+	return tree.Root.VisitDepthChildFirst(visiter)
 }
 
+// DFS sink down
 func (tree *FileTree) VisitDepthParentFirst(visiter Visiter, evaluator VisitEvaluator) error {
 	return tree.Root.VisitDepthParentFirst(visiter, evaluator)
 }
@@ -117,14 +119,14 @@ func (tree *FileTree) Stack(upper *FileTree) error {
 				return fmt.Errorf("Cannot remove node %s: %v", node.Path(), err.Error())
 			}
 		} else {
-			newNode, err := tree.AddPath(node.Path(), node.Data)
+			newNode, err := tree.AddPath(node.Path(), node.Data.FileInfo)
 			if err != nil {
 				return fmt.Errorf("Cannot add node %s: %v", newNode.Path(), err.Error())
 			}
 		}
 		return nil
 	}
-	return upper.Visit(graft)
+	return upper.VisitDepthChildFirst(graft)
 }
 
 func (tree *FileTree) GetNode(path string) (*FileNode, error) {
@@ -142,7 +144,7 @@ func (tree *FileTree) GetNode(path string) (*FileNode, error) {
 	return node, nil
 }
 
-func (tree *FileTree) AddPath(path string, data *FileChangeInfo) (*FileNode, error) {
+func (tree *FileTree) AddPath(path string, data *FileInfo) (*FileNode, error) {
 	// fmt.Printf("ADDPATH: %s %+v\n", path, data)
 	nodeNames := strings.Split(path, "/")
 	node := tree.Root
@@ -161,7 +163,7 @@ func (tree *FileTree) AddPath(path string, data *FileChangeInfo) (*FileNode, err
 
 		// attach payload to the last specified node
 		if idx == len(nodeNames)-1 {
-			node.Data = data
+			node.Data.FileInfo = data
 		}
 
 	}
@@ -186,7 +188,7 @@ func (tree *FileTree) Compare(upper *FileTree) error {
 		} else {
 			existingNode, _ := tree.GetNode(node.Path())
 			if existingNode == nil {
-				newNode, err := tree.AddPath(node.Path(), node.Data)
+				newNode, err := tree.AddPath(node.Path(), node.Data.FileInfo)
 				// fmt.Printf("added new node at %s\n", newNode.Path())
 				if err != nil {
 					return fmt.Errorf("Cannot add new node %s: %v", node.Path(), err.Error())
@@ -200,7 +202,7 @@ func (tree *FileTree) Compare(upper *FileTree) error {
 		}
 		return nil
 	}
-	return upper.Visit(graft)
+	return upper.VisitDepthChildFirst(graft)
 }
 
 func (tree *FileTree) MarkRemoved(path string) error {
diff --git a/filetree/tree_test.go b/filetree/tree_test.go
index 14cb61b..a9c6652 100644
--- a/filetree/tree_test.go
+++ b/filetree/tree_test.go
@@ -86,7 +86,7 @@ func TestRemovePath(t *testing.T) {
 
 func TestStack(t *testing.T) {
 	payloadKey := "/var/run/systemd"
-	payloadValue := FileChangeInfo{
+	payloadValue := FileInfo{
 		Path: "yup",
 	}
 
@@ -128,8 +128,8 @@ func TestStack(t *testing.T) {
 		t.Errorf("Expected '%s' to still exist, but it doesn't", payloadKey)
 	}
 
-	if *node.Data != payloadValue {
-		t.Errorf("Expected '%s' value to be %+v but got %+v", payloadKey, payloadValue, node.Data)
+	if *node.Data.FileInfo != payloadValue {
+		t.Errorf("Expected '%s' value to be %+v but got %+v", payloadKey, payloadValue, node.Data.FileInfo)
 	}
 
 	actual := tree1.String()
@@ -177,11 +177,10 @@ func TestCompareWithNoChanges(t *testing.T) {
 	paths := [...]string{"/etc", "/etc/sudoers", "/etc/hosts", "/usr/bin", "/usr/bin/bash", "/usr"}
 
 	for _, value := range paths {
-		fakeData := FileChangeInfo{
+		fakeData := FileInfo{
 			Path:     value,
 			Typeflag: 1,
 			MD5sum:   [16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-			DiffType: Unchanged,
 		}
 		lowerTree.AddPath(value, &fakeData)
 		upperTree.AddPath(value, &fakeData)
@@ -191,16 +190,16 @@ func TestCompareWithNoChanges(t *testing.T) {
 		if n.Path() == "/" {
 			return nil
 		}
-		if n.Data == nil {
-			t.Errorf("Expected *FileChangeInfo but got nil")
-			return fmt.Errorf("expected *FileChangeInfo but got nil")
+		if n.Data.FileInfo == nil {
+			t.Errorf("Expected *FileInfo but got nil")
+			return fmt.Errorf("expected *FileInfo but got nil")
 		}
 		if (n.Data.DiffType) != Unchanged {
 			t.Errorf("Expecting node at %s to have DiffType unchanged, but had %v", n.Path(), n.Data.DiffType)
 		}
 		return nil
 	}
-	err := lowerTree.Visit(asserter)
+	err := lowerTree.VisitDepthChildFirst(asserter)
 	if err != nil {
 		t.Error(err)
 	}
@@ -213,21 +212,19 @@ func TestCompareWithAdds(t *testing.T) {
 	upperPaths := [...]string{"/etc", "/etc/sudoers", "/usr", "/etc/hosts", "/usr/bin", "/usr/bin/bash"}
 
 	for _, value := range lowerPaths {
-		fakeData := FileChangeInfo{
+		fakeData := FileInfo{
 			Path:     value,
 			Typeflag: 1,
 			MD5sum:   [16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-			DiffType: Unchanged,
 		}
 		lowerTree.AddPath(value, &fakeData)
 	}
 
 	for _, value := range upperPaths {
-		fakeData := FileChangeInfo{
+		fakeData := FileInfo{
 			Path:     value,
 			Typeflag: 1,
 			MD5sum:   [16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-			DiffType: Unchanged,
 		}
 		upperTree.AddPath(value, &fakeData)
 	}
@@ -251,7 +248,7 @@ func TestCompareWithAdds(t *testing.T) {
 		}
 		return AssertDiffType(n, Unchanged, t)
 	}
-	err := lowerTree.Visit(asserter)
+	err := lowerTree.VisitDepthChildFirst(asserter)
 	if err != nil {
 		t.Error(err)
 	}
@@ -264,21 +261,19 @@ func TestCompareWithChanges(t *testing.T) {
 	upperPaths := [...]string{"/etc", "/usr", "/etc/hosts", "/etc/sudoers", "/usr/bin"}
 
 	for _, value := range lowerPaths {
-		fakeData := FileChangeInfo{
+		fakeData := FileInfo{
 			Path:     value,
 			Typeflag: 1,
 			MD5sum:   [16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-			DiffType: Unchanged,
 		}
 		lowerTree.AddPath(value, &fakeData)
 	}
 
 	for _, value := range upperPaths {
-		fakeData := FileChangeInfo{
+		fakeData := FileInfo{
 			Path:     value,
 			Typeflag: 1,
 			MD5sum:   [16]byte{1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0},
-			DiffType: Unchanged,
 		}
 		upperTree.AddPath(value, &fakeData)
 	}
@@ -291,7 +286,7 @@ func TestCompareWithChanges(t *testing.T) {
 		}
 		return AssertDiffType(n, Changed, t)
 	}
-	err := lowerTree.Visit(asserter)
+	err := lowerTree.VisitDepthChildFirst(asserter)
 	if err != nil {
 		t.Error(err)
 	}
@@ -315,21 +310,19 @@ func TestStackRange(t *testing.T) {
 	upperPaths := [...]string{"/etc", "/usr", "/etc/hosts", "/etc/sudoers", "/usr/bin"}
 
 	for _, value := range lowerPaths {
-		fakeData := FileChangeInfo{
+		fakeData := FileInfo{
 			Path:     value,
 			Typeflag: 1,
 			MD5sum:   [16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-			DiffType: Unchanged,
 		}
 		lowerTree.AddPath(value, &fakeData)
 	}
 
 	for _, value := range upperPaths {
-		fakeData := FileChangeInfo{
+		fakeData := FileInfo{
 			Path:     value,
 			Typeflag: 1,
 			MD5sum:   [16]byte{1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0},
-			DiffType: Unchanged,
 		}
 		upperTree.AddPath(value, &fakeData)
 	}
diff --git a/image/image.go b/image/image.go
index 140f4ba..96bc0cd 100644
--- a/image/image.go
+++ b/image/image.go
@@ -184,8 +184,8 @@ func saveImage(imageID string) (string, string) {
 	return imageTarPath, tmpDir
 }
 
-func getFileList(parentReader *tar.Reader, h *tar.Header) []filetree.FileChangeInfo {
-	var files []filetree.FileChangeInfo
+func getFileList(parentReader *tar.Reader, h *tar.Header) []filetree.FileInfo {
+	var files []filetree.FileInfo
 	var tarredBytes = make([]byte, h.Size)
 
 	_, err := parentReader.Read(tarredBytes)
@@ -214,7 +214,7 @@ func getFileList(parentReader *tar.Reader, h *tar.Header) []filetree.FileChangeI
 		case tar.TypeXHeader:
 			fmt.Printf("ERRG: XHeader: %v: %s\n", header.Typeflag, name)
 		default:
-			files = append(files, filetree.NewFileChangeInfo(tarReader, header, name))
+			files = append(files, filetree.NewFileInfo(tarReader, header, name))
 		}
 	}
 	return files
diff --git a/ui/filetreeview.go b/ui/filetreeview.go
index 9d81cf8..85dadeb 100644
--- a/ui/filetreeview.go
+++ b/ui/filetreeview.go
@@ -81,11 +81,11 @@ func (view *FileTreeView) setLayer(layerIndex int) error {
 	visitor := func(node *filetree.FileNode) error {
 		newNode, err := newTree.GetNode(node.Path())
 		if err == nil {
-			newNode.Collapsed = node.Collapsed
+			newNode.Data.ViewInfo.Collapsed = node.Data.ViewInfo.Collapsed
 		}
 		return nil
 	}
-	view.Tree.Visit(visitor)
+	view.Tree.VisitDepthChildFirst(visitor)
 
 	// now that the tree has been rebuilt, keep the view seleciton in parity with the previous selection
 	view.setHiddenFromDiffTypes()
@@ -132,7 +132,7 @@ func (view *FileTreeView) getAbsPositionNode() (node *filetree.FileNode) {
 	}
 
 	evaluator = func(curNode *filetree.FileNode) bool {
-		return !curNode.Collapsed && !curNode.Hidden
+		return !curNode.Data.ViewInfo.Collapsed && !curNode.Data.ViewInfo.Hidden
 	}
 
 	err := view.Tree.VisitDepthParentFirst(visiter, evaluator)
@@ -145,16 +145,16 @@ func (view *FileTreeView) getAbsPositionNode() (node *filetree.FileNode) {
 
 func (view *FileTreeView) toggleCollapse() error {
 	node := view.getAbsPositionNode()
-	node.Collapsed = !node.Collapsed
+	node.Data.ViewInfo.Collapsed = !node.Data.ViewInfo.Collapsed
 	return view.Render()
 }
 
 func (view *FileTreeView) setHiddenFromDiffTypes() error {
 	visitor := func(node *filetree.FileNode) error {
-		node.Hidden = view.HiddenDiffTypes[node.Data.DiffType]
+		node.Data.ViewInfo.Hidden = view.HiddenDiffTypes[node.Data.DiffType]
 		return nil
 	}
-	view.Tree.Visit(visitor)
+	view.Tree.VisitDepthChildFirst(visitor)
 	return view.Render()
 }