diff --git a/fs/Android.bp b/fs/Android.bp
new file mode 100644
index 0000000..68cb88d
--- /dev/null
+++ b/fs/Android.bp
@@ -0,0 +1,27 @@
+// Copyright 2017 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.
+
+//
+// mock filesystem
+//
+
+bootstrap_go_package {
+    name: "soong-fs",
+    pkgPath: "android/soong/fs",
+    srcs: [
+        "fs.go",
+    ],
+}
+
+
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
+}
