diff --git a/filetree/node.go b/filetree/node.go
index 898fd9e..7acd9d4 100644
--- a/filetree/node.go
+++ b/filetree/node.go
@@ -5,6 +5,7 @@ import (
 	"strings"
 
 	"github.com/fatih/color"
+	"fmt"
 )
 
 type FileNode struct {
@@ -30,10 +31,12 @@ func NewNode(parent *FileNode, name string, data *FileInfo) (node *FileNode) {
 	return node
 }
 
-func (node *FileNode) Copy() *FileNode {
-	newNode := NewNode(node.Parent, node.Name, node.Data.FileInfo)
+func (node *FileNode) Copy(parent *FileNode) *FileNode {
+	newNode := NewNode(parent, node.Name, node.Data.FileInfo)
+	newNode.Data.ViewInfo = node.Data.ViewInfo
+	newNode.Data.DiffType = node.Data.DiffType
 	for name, child := range node.Children {
-		newNode.Children[name] = child.Copy()
+		newNode.Children[name] = child.Copy(newNode)
 		child.Parent = newNode
 	}
 	return newNode
@@ -52,6 +55,9 @@ func (node *FileNode) AddChild(name string, data *FileInfo) (child *FileNode) {
 }
 
 func (node *FileNode) Remove() error {
+	if node == node.Tree.Root {
+		return fmt.Errorf("cannot remove the tree root")
+	}
 	for _, child := range node.Children {
 		child.Remove()
 	}
@@ -87,24 +93,37 @@ func (node *FileNode) VisitDepthChildFirst(visiter Visiter, evaluator VisitEvalu
 	}
 	sort.Strings(keys)
 	for _, name := range keys {
-		if evaluator != nil {
-			if !evaluator(node) {
-				continue
-			}
-		}
 		child := node.Children[name]
 		err := child.VisitDepthChildFirst(visiter, evaluator)
 		if err != nil {
 			return err
 		}
 	}
-	return visiter(node)
+	// never visit the root node
+	if node == node.Tree.Root {
+		return nil
+	} else if evaluator != nil && evaluator(node) || evaluator == nil {
+		return visiter(node)
+	}
+
+	return nil
 }
 
 func (node *FileNode) VisitDepthParentFirst(visiter Visiter, evaluator VisitEvaluator) error {
-	err := visiter(node)
-	if err != nil {
-		return err
+	var err error
+
+	doVisit := evaluator != nil && evaluator(node) || evaluator == nil
+
+	if !doVisit {
+		return nil
+	}
+
+	// never visit the root node
+	if node != node.Tree.Root{
+		err = visiter(node)
+		if err != nil {
+			return err
+		}
 	}
 
 	var keys []string
@@ -113,11 +132,6 @@ func (node *FileNode) VisitDepthParentFirst(visiter Visiter, evaluator VisitEval
 	}
 	sort.Strings(keys)
 	for _, name := range keys {
-		if evaluator != nil {
-			if !evaluator(node) {
-				continue
-			}
-		}
 		child := node.Children[name]
 		err = child.VisitDepthParentFirst(visiter, evaluator)
 		if err != nil {
diff --git a/filetree/tree.go b/filetree/tree.go
index 47b6a6b..e1b4efe 100644
--- a/filetree/tree.go
+++ b/filetree/tree.go
@@ -1,7 +1,6 @@
 package filetree
 
 import (
-	"errors"
 	"fmt"
 	"sort"
 	"strings"
@@ -88,8 +87,10 @@ func (tree *FileTree) String() string {
 
 func (tree *FileTree) Copy() *FileTree {
 	newTree := NewFileTree()
-	*newTree = *tree
-	newTree.Root = tree.Root.Copy()
+	newTree.Size = tree.Size
+	newTree.Root = tree.Root.Copy(newTree.Root)
+
+	// update the tree pointers
 	newTree.VisitDepthChildFirst(func(node *FileNode) error {
 		node.Tree = newTree
 		return nil
@@ -116,12 +117,12 @@ func (tree *FileTree) Stack(upper *FileTree) error {
 		if node.IsWhiteout() {
 			err := tree.RemovePath(node.Path())
 			if err != nil {
-				return fmt.Errorf("Cannot remove node %s: %v", node.Path(), err.Error())
+				return fmt.Errorf("cannot remove node %s: %v", node.Path(), err.Error())
 			}
 		} else {
 			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 fmt.Errorf("cannot add node %s: %v", newNode.Path(), err.Error())
 			}
 		}
 		return nil
@@ -137,7 +138,7 @@ func (tree *FileTree) GetNode(path string) (*FileNode, error) {
 			continue
 		}
 		if node.Children[name] == nil {
-			return nil, errors.New("Path does not exist")
+			return nil, fmt.Errorf("path does not exist: %s", path)
 		}
 		node = node.Children[name]
 	}
@@ -183,7 +184,7 @@ func (tree *FileTree) Compare(upper *FileTree) error {
 		if upperNode.IsWhiteout() {
 			err := tree.MarkRemoved(upperNode.Path())
 			if err != nil {
-				 return fmt.Errorf("Cannot remove upperNode %s: %v", upperNode.Path(), err.Error())
+				 return fmt.Errorf("cannot remove upperNode %s: %v", upperNode.Path(), err.Error())
 			}
 		} else {
 			lowerNode, _ := tree.GetNode(upperNode.Path())
@@ -191,7 +192,7 @@ func (tree *FileTree) Compare(upper *FileTree) error {
 				newNode, err := tree.AddPath(upperNode.Path(), upperNode.Data.FileInfo)
 				// fmt.Printf("added new upperNode at %s\n", newNode.Path())
 				if err != nil {
-					 return fmt.Errorf("Cannot add new upperNode %s: %v", upperNode.Path(), err.Error())
+					 return fmt.Errorf("cannot add new upperNode %s: %v", upperNode.Path(), err.Error())
 				}
 				newNode.AssignDiffType(Added)
 			} else {
diff --git a/filetree/tree_test.go b/filetree/tree_test.go
index 1010124..283bd39 100644
--- a/filetree/tree_test.go
+++ b/filetree/tree_test.go
@@ -432,3 +432,41 @@ func TestStackRange(t *testing.T) {
 	trees := []*FileTree{lowerTree, upperTree, tree}
 	StackRange(trees, 2)
 }
+
+
+func TestRemoveOnIterate(t *testing.T) {
+
+	tree := NewFileTree()
+	paths := [...]string{"/etc", "/usr", "/etc/hosts", "/etc/sudoers", "/usr/bin", "/usr/something"}
+
+	for _, value := range paths {
+		fakeData := FileInfo{
+			Path:     value,
+			Typeflag: 1,
+			MD5sum:   [16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+		}
+		node, err := tree.AddPath(value, &fakeData)
+		if err == nil && stringInSlice(node.Path(), []string{"/etc"}) {
+			node.Data.ViewInfo.Hidden = true
+		}
+	}
+
+	tree.VisitDepthChildFirst(func(node *FileNode) error {
+		if node.Data.ViewInfo.Hidden {
+			tree.RemovePath(node.Path())
+		}
+		return nil
+	}, nil)
+
+	expected := `.
+└── usr
+    ├── bin
+    └── something
+`
+	actual := tree.String()
+	if expected != actual {
+		t.Errorf("Expected tree string:\n--->%s<---\nGot:\n--->%s<---", expected, actual)
+	}
+
+}
+
diff --git a/ui/filetreeview.go b/ui/filetreeview.go
index b72b99d..ce2fa98 100644
--- a/ui/filetreeview.go
+++ b/ui/filetreeview.go
@@ -13,7 +13,8 @@ type FileTreeView struct {
 	gui             *gocui.Gui
 	view            *gocui.View
 	TreeIndex       int
-	Tree            *filetree.FileTree
+	ModelTree       *filetree.FileTree
+	ViewTree        *filetree.FileTree
 	RefTrees        []*filetree.FileTree
 	HiddenDiffTypes []bool
 }
@@ -24,7 +25,7 @@ func NewFileTreeView(name string, gui *gocui.Gui, tree *filetree.FileTree, refTr
 	// populate main fields
 	treeview.Name = name
 	treeview.gui = gui
-	treeview.Tree = tree
+	treeview.ModelTree = tree
 	treeview.RefTrees = refTrees
 	treeview.HiddenDiffTypes = make([]bool, 4)
 
@@ -65,6 +66,7 @@ func (view *FileTreeView) Setup(v *gocui.View) error {
 		return err
 	}
 
+	view.updateViewTree()
 	view.Render()
 
 	return nil
@@ -81,14 +83,11 @@ func (view *FileTreeView) setLayer(layerIndex int) error {
 	visitor := func(node *filetree.FileNode) error {
 		newNode, err := newTree.GetNode(node.Path())
 		if err == nil {
-			newNode.Data.ViewInfo.Collapsed = node.Data.ViewInfo.Collapsed
+			newNode.Data.ViewInfo = node.Data.ViewInfo
 		}
 		return nil
 	}
-	view.Tree.VisitDepthChildFirst(visitor, nil)
-
-	// now that the tree has been rebuilt, keep the view seleciton in parity with the previous selection
-	view.setHiddenFromDiffTypes()
+	view.ModelTree.VisitDepthChildFirst(visitor, nil)
 
 	if debug {
 		v, _ := view.gui.View("debug")
@@ -96,9 +95,11 @@ func (view *FileTreeView) setLayer(layerIndex int) error {
 		_, _ = fmt.Fprintln(v, view.RefTrees[layerIndex])
 	}
 
+
 	view.view.SetCursor(0, 0)
 	view.TreeIndex = 0
-	view.Tree = newTree
+	view.ModelTree = newTree
+	view.updateViewTree()
 	return view.Render()
 }
 
@@ -115,6 +116,8 @@ func (view *FileTreeView) CursorUp() error {
 	if err == nil {
 		view.TreeIndex--
 	}
+	// tmp tmp tmp
+	view.getAbsPositionNode()
 	return nil
 }
 
@@ -123,21 +126,26 @@ func (view *FileTreeView) getAbsPositionNode() (node *filetree.FileNode) {
 	var evaluator func(*filetree.FileNode) bool
 	var dfsCounter int
 
+	// special case: the root node is never visited
+	if view.TreeIndex == 0 {
+		return view.ModelTree.Root
+	}
+
 	visiter = func(curNode *filetree.FileNode) error {
+		dfsCounter++
 		if dfsCounter == view.TreeIndex {
 			node = curNode
 		}
-		dfsCounter++
 		return nil
 	}
 
 	evaluator = func(curNode *filetree.FileNode) bool {
-		return !curNode.Data.ViewInfo.Collapsed && !curNode.Data.ViewInfo.Hidden
+		return !curNode.Parent.Data.ViewInfo.Collapsed && !curNode.Data.ViewInfo.Hidden
 	}
 
-	err := view.Tree.VisitDepthParentFirst(visiter, evaluator)
+	err := view.ModelTree.VisitDepthParentFirst(visiter, evaluator)
 	if err != nil {
-		// todo: you guessed it, check errors
+		panic(err)
 	}
 
 	return node
@@ -146,25 +154,39 @@ func (view *FileTreeView) getAbsPositionNode() (node *filetree.FileNode) {
 func (view *FileTreeView) toggleCollapse() error {
 	node := view.getAbsPositionNode()
 	node.Data.ViewInfo.Collapsed = !node.Data.ViewInfo.Collapsed
-	return view.Render()
-}
-
-func (view *FileTreeView) setHiddenFromDiffTypes() error {
-	visitor := func(node *filetree.FileNode) error {
-		node.Data.ViewInfo.Hidden = view.HiddenDiffTypes[node.Data.DiffType]
-		return nil
-	}
-	view.Tree.VisitDepthChildFirst(visitor, nil)
+	view.updateViewTree()
 	return view.Render()
 }
 
 func (view *FileTreeView) toggleShowDiffType(diffType filetree.DiffType) error {
 	view.HiddenDiffTypes[diffType] = !view.HiddenDiffTypes[diffType]
-	return view.setHiddenFromDiffTypes()
+
+	view.view.SetCursor(0, 0)
+	view.TreeIndex = 0
+	view.updateViewTree()
+	return view.Render()
+}
+
+func (view *FileTreeView) updateViewTree() {
+	// keep the view selection in parity with the current DiffType selection
+	view.ModelTree.VisitDepthChildFirst(func(node *filetree.FileNode) error {
+		node.Data.ViewInfo.Hidden = view.HiddenDiffTypes[node.Data.DiffType]
+		return nil
+	}, nil)
+
+	// make a new tree with only visible nodes
+	view.ViewTree = view.ModelTree.Copy()
+	view.ViewTree.VisitDepthParentFirst(func(node *filetree.FileNode) error {
+		if node.Data.ViewInfo.Hidden {
+			view.ViewTree.RemovePath(node.Path())
+		}
+		return nil
+	}, nil)
 }
 
 func (view *FileTreeView) Render() error {
-	renderString := view.Tree.String()
+	// print the tree to the view
+	renderString := view.ViewTree.String()
 	view.gui.Update(func(g *gocui.Gui) error {
 		view.view.Clear()
 		_, err := fmt.Fprintln(view.view, renderString)