diff --git a/fs/fs.go b/fs/fs.go
new file mode 100644
index 0000000..c6060c0
--- /dev/null
+++ b/fs/fs.go
@@ -0,0 +1,957 @@
+// Copyright 2016 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package fs
+
+import (
+	"bytes"
+	"errors"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"os"
+	"os/user"
+	"path/filepath"
+	"sync"
+	"syscall"
+	"time"
+)
+
+var OsFs FileSystem = osFs{}
+
+func NewMockFs(files map[string][]byte) *MockFs {
+	workDir := "/cwd"
+	fs := &MockFs{
+		Clock:   NewClock(time.Unix(2, 2)),
+		workDir: workDir,
+	}
+	fs.root = *fs.newDir()
+	fs.MkDirs(workDir)
+
+	for path, bytes := range files {
+		dir := filepath.Dir(path)
+		fs.MkDirs(dir)
+		fs.WriteFile(path, bytes, 0777)
+	}
+
+	return fs
+}
+
+type FileSystem interface {
+	// getting information about files
+	Open(name string) (file io.ReadCloser, err error)
+	Lstat(path string) (stats os.FileInfo, err error)
+	ReadDir(path string) (contents []os.FileInfo, err error)
+
+	InodeNumber(info os.FileInfo) (number uint64, err error)
+	DeviceNumber(info os.FileInfo) (number uint64, err error)
+	PermTime(info os.FileInfo) (time time.Time, err error)
+
+	// changing contents of the filesystem
+	Rename(oldPath string, newPath string) (err error)
+	WriteFile(path string, data []byte, perm os.FileMode) (err error)
+	Remove(path string) (err error)
+	RemoveAll(path string) (err error)
+
+	// metadata about the filesystem
+	ViewId() (id string) // Some unique id of the user accessing the filesystem
+}
+
+// osFs implements FileSystem using the local disk.
+type osFs struct{}
+
+func (osFs) Open(name string) (io.ReadCloser, error) { return os.Open(name) }
+
+func (osFs) Lstat(path string) (stats os.FileInfo, err error) {
+	return os.Lstat(path)
+}
+
+func (osFs) InodeNumber(info os.FileInfo) (number uint64, err error) {
+	sys := info.Sys()
+	linuxStats, ok := sys.(*syscall.Stat_t)
+	if ok {
+		return linuxStats.Ino, nil
+	}
+	return 0, fmt.Errorf("%v is not a *syscall.Stat_t", sys)
+}
+
+func (osFs) DeviceNumber(info os.FileInfo) (number uint64, err error) {
+	sys := info.Sys()
+	linuxStats, ok := sys.(*syscall.Stat_t)
+	if ok {
+		return linuxStats.Dev, nil
+	}
+	return 0, fmt.Errorf("%v is not a *syscall.Stat_t", sys)
+}
+
+func (osFs) PermTime(info os.FileInfo) (when time.Time, err error) {
+	sys := info.Sys()
+	linuxStats, ok := sys.(*syscall.Stat_t)
+	if ok {
+		return time.Unix(linuxStats.Ctim.Sec, linuxStats.Ctim.Nsec), nil
+	}
+	return time.Date(0, 0, 0, 0, 0, 0, 0, nil), fmt.Errorf("%v is not a *syscall.Stat_t", sys)
+}
+
+func (osFs) ReadDir(path string) (contents []os.FileInfo, err error) {
+	return ioutil.ReadDir(path)
+}
+func (osFs) Rename(oldPath string, newPath string) error {
+	return os.Rename(oldPath, newPath)
+}
+
+func (osFs) WriteFile(path string, data []byte, perm os.FileMode) error {
+	return ioutil.WriteFile(path, data, perm)
+}
+
+func (osFs) Remove(path string) error {
+	return os.Remove(path)
+}
+
+func (osFs) RemoveAll(path string) error {
+	return os.RemoveAll(path)
+}
+
+func (osFs) ViewId() (id string) {
+	user, err := user.Current()
+	if err != nil {
+		return ""
+	}
+	username := user.Username
+
+	hostname, err := os.Hostname()
+	if err != nil {
+		return ""
+	}
+
+	return username + "@" + hostname
+}
+
+type Clock struct {
+	time time.Time
+}
+
+func NewClock(startTime time.Time) *Clock {
+	return &Clock{time: startTime}
+
+}
+
+func (c *Clock) Tick() {
+	c.time = c.time.Add(time.Microsecond)
+}
+
+func (c *Clock) Time() time.Time {
+	return c.time
+}
+
+// given "/a/b/c/d", pathSplit returns ("/a/b/c", "d")
+func pathSplit(path string) (dir string, leaf string) {
+	dir, leaf = filepath.Split(path)
+	if dir != "/" && len(dir) > 0 {
+		dir = dir[:len(dir)-1]
+	}
+	return dir, leaf
+}
+
+// MockFs supports singlethreaded writes and multithreaded reads
+type MockFs struct {
+	// configuration
+	viewId       string //
+	deviceNumber uint64
+
+	// implementation
+	root            mockDir
+	Clock           *Clock
+	workDir         string
+	nextInodeNumber uint64
+
+	// history of requests, for tests to check
+	StatCalls      []string
+	ReadDirCalls   []string
+	aggregatesLock sync.Mutex
+}
+
+type mockInode struct {
+	modTime     time.Time
+	permTime    time.Time
+	sys         interface{}
+	inodeNumber uint64
+	readable    bool
+}
+
+func (m mockInode) ModTime() time.Time {
+	return m.modTime
+}
+
+func (m mockInode) Sys() interface{} {
+	return m.sys
+}
+
+type mockFile struct {
+	bytes []byte
+
+	mockInode
+}
+
+type mockLink struct {
+	target string
+
+	mockInode
+}
+
+type mockDir struct {
+	mockInode
+
+	subdirs  map[string]*mockDir
+	files    map[string]*mockFile
+	symlinks map[string]*mockLink
+}
+
+func (m *MockFs) resolve(path string, followLastLink bool) (result string, err error) {
+	if !filepath.IsAbs(path) {
+		path = filepath.Join(m.workDir, path)
+	}
+	path = filepath.Clean(path)
+
+	return m.followLinks(path, followLastLink, 10)
+}
+
+// note that followLinks can return a file path that doesn't exist
+func (m *MockFs) followLinks(path string, followLastLink bool, count int) (canonicalPath string, err error) {
+	if path == "/" {
+		return path, nil
+	}
+
+	parentPath, leaf := pathSplit(path)
+	if parentPath == path {
+		err = fmt.Errorf("Internal error: %v yields itself as a parent", path)
+		panic(err.Error())
+		return "", fmt.Errorf("Internal error: %v yields itself as a parent", path)
+	}
+
+	parentPath, err = m.followLinks(parentPath, true, count)
+	if err != nil {
+		return "", err
+	}
+
+	parentNode, err := m.getDir(parentPath, false)
+	if err != nil {
+		return "", err
+	}
+	if !parentNode.readable {
+		return "", &os.PathError{
+			Op:   "read",
+			Path: path,
+			Err:  os.ErrPermission,
+		}
+	}
+
+	link, isLink := parentNode.symlinks[leaf]
+	if isLink && followLastLink {
+		if count <= 0 {
+			// probably a loop
+			return "", &os.PathError{
+				Op:   "read",
+				Path: path,
+				Err:  fmt.Errorf("too many levels of symbolic links"),
+			}
+		}
+
+		if !link.readable {
+			return "", &os.PathError{
+				Op:   "read",
+				Path: path,
+				Err:  os.ErrPermission,
+			}
+		}
+
+		target := m.followLink(link, parentPath)
+		return m.followLinks(target, followLastLink, count-1)
+	}
+	return path, nil
+}
+
+func (m *MockFs) followLink(link *mockLink, parentPath string) (result string) {
+	return filepath.Clean(filepath.Join(parentPath, link.target))
+}
+
+func (m *MockFs) getFile(parentDir *mockDir, fileName string) (file *mockFile, err error) {
+	file, isFile := parentDir.files[fileName]
+	if !isFile {
+		_, isDir := parentDir.subdirs[fileName]
+		_, isLink := parentDir.symlinks[fileName]
+		if isDir || isLink {
+			return nil, &os.PathError{
+				Op:   "open",
+				Path: fileName,
+				Err:  os.ErrInvalid,
+			}
+		}
+
+		return nil, &os.PathError{
+			Op:   "open",
+			Path: fileName,
+			Err:  os.ErrNotExist,
+		}
+	}
+	if !file.readable {
+		return nil, &os.PathError{
+			Op:   "open",
+			Path: fileName,
+			Err:  os.ErrPermission,
+		}
+	}
+	return file, nil
+}
+
+func (m *MockFs) getInode(parentDir *mockDir, name string) (inode *mockInode, err error) {
+	file, isFile := parentDir.files[name]
+	if isFile {
+		return &file.mockInode, nil
+	}
+	link, isLink := parentDir.symlinks[name]
+	if isLink {
+		return &link.mockInode, nil
+	}
+	dir, isDir := parentDir.subdirs[name]
+	if isDir {
+		return &dir.mockInode, nil
+	}
+	return nil, &os.PathError{
+		Op:   "stat",
+		Path: name,
+		Err:  os.ErrNotExist,
+	}
+
+}
+
+func (m *MockFs) Open(path string) (io.ReadCloser, error) {
+	path, err := m.resolve(path, true)
+	if err != nil {
+		return nil, err
+	}
+
+	if err != nil {
+		return nil, err
+	}
+
+	parentPath, base := pathSplit(path)
+	parentDir, err := m.getDir(parentPath, false)
+	if err != nil {
+		return nil, err
+	}
+	file, err := m.getFile(parentDir, base)
+	if err != nil {
+		return nil, err
+	}
+	return struct {
+		io.Closer
+		*bytes.Reader
+	}{
+		ioutil.NopCloser(nil),
+		bytes.NewReader(file.bytes),
+	}, nil
+
+}
+
+// a mockFileInfo is for exporting file stats in a way that satisfies the FileInfo interface
+type mockFileInfo struct {
+	path         string
+	size         int64
+	modTime      time.Time // time at which the inode's contents were modified
+	permTime     time.Time // time at which the inode's permissions were modified
+	isDir        bool
+	inodeNumber  uint64
+	deviceNumber uint64
+}
+
+func (m *mockFileInfo) Name() string {
+	return m.path
+}
+
+func (m *mockFileInfo) Size() int64 {
+	return m.size
+}
+
+func (m *mockFileInfo) Mode() os.FileMode {
+	return 0
+}
+
+func (m *mockFileInfo) ModTime() time.Time {
+	return m.modTime
+}
+
+func (m *mockFileInfo) IsDir() bool {
+	return m.isDir
+}
+
+func (m *mockFileInfo) Sys() interface{} {
+	return nil
+}
+
+func (m *MockFs) dirToFileInfo(d *mockDir, path string) (info *mockFileInfo) {
+	return &mockFileInfo{
+		path:         path,
+		size:         1,
+		modTime:      d.modTime,
+		permTime:     d.permTime,
+		isDir:        true,
+		inodeNumber:  d.inodeNumber,
+		deviceNumber: m.deviceNumber,
+	}
+
+}
+
+func (m *MockFs) fileToFileInfo(f *mockFile, path string) (info *mockFileInfo) {
+	return &mockFileInfo{
+		path:         path,
+		size:         1,
+		modTime:      f.modTime,
+		permTime:     f.permTime,
+		isDir:        false,
+		inodeNumber:  f.inodeNumber,
+		deviceNumber: m.deviceNumber,
+	}
+}
+
+func (m *MockFs) linkToFileInfo(l *mockLink, path string) (info *mockFileInfo) {
+	return &mockFileInfo{
+		path:         path,
+		size:         1,
+		modTime:      l.modTime,
+		permTime:     l.permTime,
+		isDir:        false,
+		inodeNumber:  l.inodeNumber,
+		deviceNumber: m.deviceNumber,
+	}
+}
+
+func (m *MockFs) Lstat(path string) (stats os.FileInfo, err error) {
+	// update aggregates
+	m.aggregatesLock.Lock()
+	m.StatCalls = append(m.StatCalls, path)
+	m.aggregatesLock.Unlock()
+
+	// resolve symlinks
+	path, err = m.resolve(path, false)
+	if err != nil {
+		return nil, err
+	}
+
+	// special case for root dir
+	if path == "/" {
+		return m.dirToFileInfo(&m.root, "/"), nil
+	}
+
+	// determine type and handle appropriately
+	parentPath, baseName := pathSplit(path)
+	dir, err := m.getDir(parentPath, false)
+	if err != nil {
+		return nil, err
+	}
+	subdir, subdirExists := dir.subdirs[baseName]
+	if subdirExists {
+		return m.dirToFileInfo(subdir, path), nil
+	}
+	file, fileExists := dir.files[baseName]
+	if fileExists {
+		return m.fileToFileInfo(file, path), nil
+	}
+	link, linkExists := dir.symlinks[baseName]
+	if linkExists {
+		return m.linkToFileInfo(link, path), nil
+	}
+	// not found
+	return nil, &os.PathError{
+		Op:   "stat",
+		Path: path,
+		Err:  os.ErrNotExist,
+	}
+}
+
+func (m *MockFs) InodeNumber(info os.FileInfo) (number uint64, err error) {
+	mockInfo, ok := info.(*mockFileInfo)
+	if ok {
+		return mockInfo.inodeNumber, nil
+	}
+	return 0, fmt.Errorf("%v is not a mockFileInfo", info)
+}
+func (m *MockFs) DeviceNumber(info os.FileInfo) (number uint64, err error) {
+	mockInfo, ok := info.(*mockFileInfo)
+	if ok {
+		return mockInfo.deviceNumber, nil
+	}
+	return 0, fmt.Errorf("%v is not a mockFileInfo", info)
+}
+func (m *MockFs) PermTime(info os.FileInfo) (when time.Time, err error) {
+	mockInfo, ok := info.(*mockFileInfo)
+	if ok {
+		return mockInfo.permTime, nil
+	}
+	return time.Date(0, 0, 0, 0, 0, 0, 0, nil),
+		fmt.Errorf("%v is not a mockFileInfo", info)
+}
+
+func (m *MockFs) ReadDir(path string) (contents []os.FileInfo, err error) {
+	// update aggregates
+	m.aggregatesLock.Lock()
+	m.ReadDirCalls = append(m.ReadDirCalls, path)
+	m.aggregatesLock.Unlock()
+
+	// locate directory
+	path, err = m.resolve(path, true)
+	if err != nil {
+		return nil, err
+	}
+	results := []os.FileInfo{}
+	dir, err := m.getDir(path, false)
+	if err != nil {
+		return nil, err
+	}
+	if !dir.readable {
+		return nil, &os.PathError{
+			Op:   "read",
+			Path: path,
+			Err:  os.ErrPermission,
+		}
+	}
+	// describe its contents
+	for name, subdir := range dir.subdirs {
+		dirInfo := m.dirToFileInfo(subdir, name)
+		results = append(results, dirInfo)
+	}
+	for name, file := range dir.files {
+		info := m.fileToFileInfo(file, name)
+		results = append(results, info)
+	}
+	for name, link := range dir.symlinks {
+		info := m.linkToFileInfo(link, name)
+		results = append(results, info)
+	}
+	return results, nil
+}
+
+func (m *MockFs) Rename(sourcePath string, destPath string) error {
+	// validate source parent exists
+	sourcePath, err := m.resolve(sourcePath, false)
+	if err != nil {
+		return err
+	}
+	sourceParentPath := filepath.Dir(sourcePath)
+	sourceParentDir, err := m.getDir(sourceParentPath, false)
+	if err != nil {
+		return err
+	}
+	if sourceParentDir == nil {
+		return &os.PathError{
+			Op:   "move",
+			Path: sourcePath,
+			Err:  os.ErrNotExist,
+		}
+	}
+	if !sourceParentDir.readable {
+		return &os.PathError{
+			Op:   "move",
+			Path: sourcePath,
+			Err:  os.ErrPermission,
+		}
+	}
+
+	// validate dest parent exists
+	destPath, err = m.resolve(destPath, false)
+	destParentPath := filepath.Dir(destPath)
+	destParentDir, err := m.getDir(destParentPath, false)
+	if err != nil {
+		return err
+	}
+	if destParentDir == nil {
+		return &os.PathError{
+			Op:   "move",
+			Path: destParentPath,
+			Err:  os.ErrNotExist,
+		}
+	}
+	if !destParentDir.readable {
+		return &os.PathError{
+			Op:   "move",
+			Path: destParentPath,
+			Err:  os.ErrPermission,
+		}
+	}
+	// check the source and dest themselves
+	sourceBase := filepath.Base(sourcePath)
+	destBase := filepath.Base(destPath)
+
+	file, sourceIsFile := sourceParentDir.files[sourceBase]
+	dir, sourceIsDir := sourceParentDir.subdirs[sourceBase]
+	link, sourceIsLink := sourceParentDir.symlinks[sourceBase]
+
+	// validate that the source exists
+	if !sourceIsFile && !sourceIsDir && !sourceIsLink {
+		return &os.PathError{
+			Op:   "move",
+			Path: sourcePath,
+			Err:  os.ErrNotExist,
+		}
+
+	}
+
+	// validate the destination doesn't already exist as an incompatible type
+	_, destWasFile := destParentDir.files[destBase]
+	_, destWasDir := destParentDir.subdirs[destBase]
+	_, destWasLink := destParentDir.symlinks[destBase]
+
+	if destWasDir {
+		return &os.PathError{
+			Op:   "move",
+			Path: destPath,
+			Err:  errors.New("destination exists as a directory"),
+		}
+	}
+
+	if sourceIsDir && (destWasFile || destWasLink) {
+		return &os.PathError{
+			Op:   "move",
+			Path: destPath,
+			Err:  errors.New("destination exists as a file"),
+		}
+	}
+
+	if destWasFile {
+		delete(destParentDir.files, destBase)
+	}
+	if destWasDir {
+		delete(destParentDir.subdirs, destBase)
+	}
+	if destWasLink {
+		delete(destParentDir.symlinks, destBase)
+	}
+
+	if sourceIsFile {
+		destParentDir.files[destBase] = file
+		delete(sourceParentDir.files, sourceBase)
+	}
+	if sourceIsDir {
+		destParentDir.subdirs[destBase] = dir
+		delete(sourceParentDir.subdirs, sourceBase)
+	}
+	if sourceIsLink {
+		destParentDir.symlinks[destBase] = link
+		delete(destParentDir.symlinks, sourceBase)
+	}
+
+	destParentDir.modTime = m.Clock.Time()
+	sourceParentDir.modTime = m.Clock.Time()
+	return nil
+}
+
+func (m *MockFs) newInodeNumber() uint64 {
+	result := m.nextInodeNumber
+	m.nextInodeNumber++
+	return result
+}
+
+func (m *MockFs) WriteFile(filePath string, data []byte, perm os.FileMode) error {
+	filePath, err := m.resolve(filePath, true)
+	if err != nil {
+		return err
+	}
+	parentPath := filepath.Dir(filePath)
+	parentDir, err := m.getDir(parentPath, false)
+	if err != nil || parentDir == nil {
+		return &os.PathError{
+			Op:   "write",
+			Path: parentPath,
+			Err:  os.ErrNotExist,
+		}
+	}
+	if !parentDir.readable {
+		return &os.PathError{
+			Op:   "write",
+			Path: parentPath,
+			Err:  os.ErrPermission,
+		}
+	}
+
+	baseName := filepath.Base(filePath)
+	_, exists := parentDir.files[baseName]
+	if !exists {
+		parentDir.modTime = m.Clock.Time()
+		parentDir.files[baseName] = m.newFile()
+	} else {
+		if !parentDir.files[baseName].readable {
+			return &os.PathError{
+				Op:   "write",
+				Path: filePath,
+				Err:  os.ErrPermission,
+			}
+		}
+	}
+	file := parentDir.files[baseName]
+	file.bytes = data
+	file.modTime = m.Clock.Time()
+	return nil
+}
+
+func (m *MockFs) newFile() *mockFile {
+	newFile := &mockFile{}
+	newFile.inodeNumber = m.newInodeNumber()
+	newFile.modTime = m.Clock.Time()
+	newFile.permTime = newFile.modTime
+	newFile.readable = true
+	return newFile
+}
+
+func (m *MockFs) newDir() *mockDir {
+	newDir := &mockDir{
+		subdirs:  make(map[string]*mockDir, 0),
+		files:    make(map[string]*mockFile, 0),
+		symlinks: make(map[string]*mockLink, 0),
+	}
+	newDir.inodeNumber = m.newInodeNumber()
+	newDir.modTime = m.Clock.Time()
+	newDir.permTime = newDir.modTime
+	newDir.readable = true
+	return newDir
+}
+
+func (m *MockFs) newLink(target string) *mockLink {
+	newLink := &mockLink{
+		target: target,
+	}
+	newLink.inodeNumber = m.newInodeNumber()
+	newLink.modTime = m.Clock.Time()
+	newLink.permTime = newLink.modTime
+	newLink.readable = true
+
+	return newLink
+}
+func (m *MockFs) MkDirs(path string) error {
+	_, err := m.getDir(path, true)
+	return err
+}
+
+// getDir doesn't support symlinks
+func (m *MockFs) getDir(path string, createIfMissing bool) (dir *mockDir, err error) {
+	cleanedPath := filepath.Clean(path)
+	if cleanedPath == "/" {
+		return &m.root, nil
+	}
+
+	parentPath, leaf := pathSplit(cleanedPath)
+	if len(parentPath) >= len(path) {
+		return &m.root, nil
+	}
+	parent, err := m.getDir(parentPath, createIfMissing)
+	if err != nil {
+		return nil, err
+	}
+	if !parent.readable {
+		return nil, &os.PathError{
+			Op:   "stat",
+			Path: path,
+			Err:  os.ErrPermission,
+		}
+	}
+	childDir, dirExists := parent.subdirs[leaf]
+	if !dirExists {
+		if createIfMissing {
+			// confirm that a file with the same name doesn't already exist
+			_, fileExists := parent.files[leaf]
+			if fileExists {
+				return nil, &os.PathError{
+					Op:   "mkdir",
+					Path: path,
+					Err:  os.ErrExist,
+				}
+			}
+			// create this directory
+			childDir = m.newDir()
+			parent.subdirs[leaf] = childDir
+			parent.modTime = m.Clock.Time()
+		} else {
+			return nil, &os.PathError{
+				Op:   "stat",
+				Path: path,
+				Err:  os.ErrNotExist,
+			}
+		}
+	}
+	return childDir, nil
+
+}
+
+func (m *MockFs) Remove(path string) (err error) {
+	path, err = m.resolve(path, false)
+	parentPath, leaf := pathSplit(path)
+	if len(leaf) == 0 {
+		return fmt.Errorf("Cannot remove %v\n", path)
+	}
+	parentDir, err := m.getDir(parentPath, false)
+	if err != nil {
+		return err
+	}
+	if parentDir == nil {
+		return &os.PathError{
+			Op:   "remove",
+			Path: path,
+			Err:  os.ErrNotExist,
+		}
+	}
+	if !parentDir.readable {
+		return &os.PathError{
+			Op:   "remove",
+			Path: path,
+			Err:  os.ErrPermission,
+		}
+	}
+	_, isDir := parentDir.subdirs[leaf]
+	if isDir {
+		return &os.PathError{
+			Op:   "remove",
+			Path: path,
+			Err:  os.ErrInvalid,
+		}
+	}
+	_, isLink := parentDir.symlinks[leaf]
+	if isLink {
+		delete(parentDir.symlinks, leaf)
+	} else {
+		_, isFile := parentDir.files[leaf]
+		if !isFile {
+			return &os.PathError{
+				Op:   "remove",
+				Path: path,
+				Err:  os.ErrNotExist,
+			}
+		}
+		delete(parentDir.files, leaf)
+	}
+	parentDir.modTime = m.Clock.Time()
+	return nil
+}
+
+func (m *MockFs) Symlink(oldPath string, newPath string) (err error) {
+	newPath, err = m.resolve(newPath, false)
+	if err != nil {
+		return err
+	}
+
+	newParentPath, leaf := pathSplit(newPath)
+	newParentDir, err := m.getDir(newParentPath, false)
+	if !newParentDir.readable {
+		return &os.PathError{
+			Op:   "link",
+			Path: newPath,
+			Err:  os.ErrPermission,
+		}
+	}
+	if err != nil {
+		return err
+	}
+	newParentDir.symlinks[leaf] = m.newLink(oldPath)
+	return nil
+}
+
+func (m *MockFs) RemoveAll(path string) (err error) {
+	path, err = m.resolve(path, false)
+	if err != nil {
+		return err
+	}
+	parentPath, leaf := pathSplit(path)
+	if len(leaf) == 0 {
+		return fmt.Errorf("Cannot remove %v\n", path)
+	}
+	parentDir, err := m.getDir(parentPath, false)
+	if err != nil {
+		return err
+	}
+	if parentDir == nil {
+		return &os.PathError{
+			Op:   "removeAll",
+			Path: path,
+			Err:  os.ErrNotExist,
+		}
+	}
+	if !parentDir.readable {
+		return &os.PathError{
+			Op:   "removeAll",
+			Path: path,
+			Err:  os.ErrPermission,
+		}
+
+	}
+	_, isFile := parentDir.files[leaf]
+	_, isLink := parentDir.symlinks[leaf]
+	if isFile || isLink {
+		return m.Remove(path)
+	}
+	_, isDir := parentDir.subdirs[leaf]
+	if !isDir {
+		if !isDir {
+			return &os.PathError{
+				Op:   "removeAll",
+				Path: path,
+				Err:  os.ErrNotExist,
+			}
+		}
+	}
+
+	delete(parentDir.subdirs, leaf)
+	parentDir.modTime = m.Clock.Time()
+	return nil
+}
+
+func (m *MockFs) SetReadable(path string, readable bool) error {
+	path, err := m.resolve(path, false)
+	if err != nil {
+		return err
+	}
+	parentPath, leaf := filepath.Split(path)
+	parentDir, err := m.getDir(parentPath, false)
+	if err != nil {
+		return err
+	}
+	if !parentDir.readable {
+		return &os.PathError{
+			Op:   "chmod",
+			Path: parentPath,
+			Err:  os.ErrPermission,
+		}
+	}
+
+	inode, err := m.getInode(parentDir, leaf)
+	if err != nil {
+		return err
+	}
+	inode.readable = readable
+	inode.permTime = m.Clock.Time()
+	return nil
+}
+
+func (m *MockFs) ClearMetrics() {
+	m.ReadDirCalls = []string{}
+	m.StatCalls = []string{}
+}
+
+func (m *MockFs) ViewId() (id string) {
+	return m.viewId
+}
+
+func (m *MockFs) SetViewId(id string) {
+	m.viewId = id
+}
+func (m *MockFs) SetDeviceNumber(deviceNumber uint64) {
+	m.deviceNumber = deviceNumber
+}
