diff --git a/src/com/google/enterprise/adaptor/fs/FsAdaptor.java b/src/com/google/enterprise/adaptor/fs/FsAdaptor.java
index 972cc84..d8a6103 100644
--- a/src/com/google/enterprise/adaptor/fs/FsAdaptor.java
+++ b/src/com/google/enterprise/adaptor/fs/FsAdaptor.java
@@ -134,13 +134,15 @@
   /** The namespace applied to ACL Principals. */
   private String namespace;
 
+  /** The filesystem change monitor. */
+  private FsMonitor monitor;
+
   private AdaptorContext context;
   private Path rootPath;
   private boolean isDfsUnc;
   private DocId rootPathDocId;
   private FileDelegate delegate;
-  private FsMonitor monitor;
-  private ShareAcls lastPushedShareAcls = new ShareAcls(null, null);
+  private ShareAcls lastPushedShareAcls = null;
 
   public FsAdaptor() {
     // At the moment, we only support Windows.
@@ -152,6 +154,31 @@
     }
   }
 
+  @VisibleForTesting
+  FsAdaptor(FileDelegate delegate) {
+    this.delegate = delegate;
+  }
+
+  @VisibleForTesting
+  Set<String> getSupportedWindowsAccounts() {
+    return supportedWindowsAccounts;
+  }
+
+  @VisibleForTesting
+  String getBuiltinPrefix() {
+    return builtinPrefix;
+  }
+
+  @VisibleForTesting
+  String getNamespace() {
+    return namespace;
+  }
+
+  @VisibleForTesting
+  BlockingQueue<Path> getFsMonitorQueue() {
+    return monitor.getQueue();
+  }
+
   @Override
   public void initConfig(Config config) {
     config.addKey(CONFIG_SRC, null);
@@ -238,11 +265,16 @@
   @Override
   public void destroy() {
     delegate.destroy();
-    monitor.destroy();
-    monitor = null;
+    // TODO (bmj): The check for null monitor is strictly for the tests,
+    // some of which may not have fully initialized the adaptor.  Maybe
+    // look into handling this less obtrusively in the future.
+    if (monitor != null) {
+      monitor.destroy();
+      monitor = null;
+    }
   }
 
-  private ShareAcls getShareAcls() throws IOException {
+  private ShareAcls readShareAcls() throws IOException {
     Acl shareAcl;
     Acl dfsShareAcl;
 
@@ -305,14 +337,14 @@
     // The pusher does not support fragments in named resources.
     // Feed a DocId that is just the SHARE_ACL fragment to avoid
     // collisions with the root docid.
-    ShareAcls shareAcls = getShareAcls();
+    ShareAcls shareAcls = readShareAcls();
     Map<DocId, Acl> namedResources = new HashMap<DocId, Acl>();
-    if (forcePush || ((shareAcls.dfsShareAcl != null)
-        && !shareAcls.dfsShareAcl.equals(lastPushedShareAcls.dfsShareAcl))) {
+    if ((shareAcls.dfsShareAcl != null) && (forcePush ||
+        !shareAcls.dfsShareAcl.equals(lastPushedShareAcls.dfsShareAcl))) {
       namedResources.put(DFS_SHARE_ACL_DOCID, shareAcls.dfsShareAcl);
     }
-    if (forcePush || ((shareAcls.shareAcl != null)
-        && !shareAcls.shareAcl.equals(lastPushedShareAcls.shareAcl))) {
+    if ((shareAcls.shareAcl != null) && (forcePush ||
+        !shareAcls.shareAcl.equals(lastPushedShareAcls.shareAcl))) {
       namedResources.put(SHARE_ACL_DOCID, shareAcls.shareAcl);
     }
     if (namedResources.size() > 0) {
@@ -443,10 +475,10 @@
     // Populate the document content.
     if (docIsDirectory) {
       HtmlResponseWriter writer = createHtmlResponseWriter(resp);
-      writer.start(id, getPathName(doc));
+      writer.start(id, getFileName(doc));
       for (Path file : delegate.newDirectoryStream(doc)) {
         if (isSupportedPath(file)) {
-          writer.addLink(delegate.newDocId(file), getPathName(file));
+          writer.addLink(delegate.newDocId(file), getFileName(file));
         }
       }
       writer.finish();
@@ -483,12 +515,14 @@
   }
 
   @VisibleForTesting
-  String getPathName(Path file) {
+  String getFileName(Path file) {
     // NOTE: file.getFileName() fails for UNC paths. Use file.toFile() instead.
-    return file.toFile().getName();
+    String name = file.toFile().getName();
+    return name.isEmpty() ? file.getRoot().toString() : name;
   }
 
-  private boolean isSupportedPath(Path p) throws IOException {
+  @VisibleForTesting
+  boolean isSupportedPath(Path p) throws IOException {
     return delegate.isRegularFile(p) || delegate.isDirectory(p);
   }
 
@@ -496,7 +530,8 @@
    * Verifies that the file is a descendant of the root directory,
    * and that it, nor none of its ancestors, is hidden.
    */
-  private boolean isVisibleDescendantOfRoot(Path doc) throws IOException {
+  @VisibleForTesting
+  boolean isVisibleDescendantOfRoot(Path doc) throws IOException {
     for (Path file = doc; file != null; file = file.getParent()) {
       if (delegate.isHidden(file)) {
         if (doc.equals(file)) {
@@ -531,8 +566,8 @@
       Preconditions.checkNotNull(pusher, "the DocId pusher may not be null");
       Preconditions.checkArgument(maxFeedSize > 0,
           "the maxFeedSize must be greater than zero");
-      Preconditions.checkArgument(maxLatencyMillis > 0,
-          "the maxLatencyMillis must be greater than zero");
+      Preconditions.checkArgument(maxLatencyMillis >= 0,
+          "the maxLatencyMillis must be greater than or equal to zero");
       this.pusher = pusher;
       this.maxFeedSize = maxFeedSize;
       this.maxLatencyMillis = maxLatencyMillis;
diff --git a/src/com/google/enterprise/adaptor/fs/HtmlResponseWriter.java b/src/com/google/enterprise/adaptor/fs/HtmlResponseWriter.java
index 3cf0f47..e0d50f3 100644
--- a/src/com/google/enterprise/adaptor/fs/HtmlResponseWriter.java
+++ b/src/com/google/enterprise/adaptor/fs/HtmlResponseWriter.java
@@ -15,6 +15,7 @@
 package com.google.enterprise.adaptor.fs;
 
 import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Strings;
 import com.google.enterprise.adaptor.DocId;
 import com.google.enterprise.adaptor.DocIdEncoder;
 
@@ -213,10 +214,10 @@
   }
 
   private String computeLabel(String label, DocId doc) {
-    if (label == null || "".equals(label)) {
+    if (Strings.isNullOrEmpty(label)) {
       // Use the last part of the URL if an item doesn't have a title. The last
       // part of the URL will generally be a filename in this case.
-      String[] parts = doc.getUniqueId().split("/");
+      String[] parts = doc.getUniqueId().split("/", 0);
       label = parts[parts.length - 1];
     }
     return label;
diff --git a/src/com/google/enterprise/adaptor/fs/WindowsAclFileAttributeViews.java b/src/com/google/enterprise/adaptor/fs/WindowsAclFileAttributeViews.java
index 199b568..b70e455 100644
--- a/src/com/google/enterprise/adaptor/fs/WindowsAclFileAttributeViews.java
+++ b/src/com/google/enterprise/adaptor/fs/WindowsAclFileAttributeViews.java
@@ -14,6 +14,7 @@
 
 package com.google.enterprise.adaptor.fs;
 
+import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Strings;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Sets;
@@ -67,12 +68,9 @@
  */
 class WindowsAclFileAttributeViews {
 
-  private static final Logger log = 
+  private static final Logger log =
       Logger.getLogger(WindowsAclFileAttributeViews.class.getName());
 
-  private static final Kernel32 KERNEL32 = Kernel32.INSTANCE;
-  private static final Advapi32 ADVAPI32 = Advapi32.INSTANCE; 
-
   /** This pattern parses a UNC path to get the host and share details. */
   private static final Pattern UNC_PATTERN =
       Pattern.compile("^\\\\\\\\([^\\\\]+)\\\\([^\\\\]+)");
@@ -88,7 +86,7 @@
       Collections.unmodifiableSet(Sets.newHashSet(SID_NAME_USE.SidTypeUser));
 
   /** Map of NT GENERIC permissions to NT FILE permissions. */
-  private static final Map<Integer, Integer> GENERIC_PERMS_MAP = 
+  private static final Map<Integer, Integer> GENERIC_PERMS_MAP =
       Collections.unmodifiableMap(new HashMap<Integer, Integer>() {
           {
             put(WinNT.GENERIC_READ, WinNT.FILE_GENERIC_READ);
@@ -142,6 +140,28 @@
           }
       });
 
+  private final Advapi32 advapi32;
+  private final Kernel32 kernel32;
+  private final Mpr mpr;
+  private final Netapi32Ex netapi32;
+  private final Shlwapi shlwapi;
+
+  /** Constructor used for production. */
+  public WindowsAclFileAttributeViews() {
+    this(Advapi32.INSTANCE, Kernel32.INSTANCE, Mpr.INSTANCE,
+         Netapi32Ex.INSTANCE,Shlwapi.INSTANCE);
+  }
+
+  /** Constructor used by the tests. */
+  @VisibleForTesting
+  WindowsAclFileAttributeViews(Advapi32 advapi32, Kernel32 kernel32,
+      Mpr mpr, Netapi32Ex netapi32, Shlwapi shlwapi) {
+    this.advapi32 = advapi32;
+    this.kernel32 = kernel32;
+    this.mpr = mpr;
+    this.netapi32 = netapi32;
+    this.shlwapi = shlwapi;
+  }
 
   /**
    * Returns a container for the direct and inherited ACLs for
@@ -152,7 +172,7 @@
    */
   public AclFileAttributeViews getAclViews(Path path) throws IOException {
     String pathname = path.toRealPath(LinkOption.NOFOLLOW_LINKS).toString();
-    WinNT.ACCESS_ACEStructure[] aces = getFileSecurity(pathname, 
+    WinNT.ACCESS_ACEStructure[] aces = getFileSecurity(pathname,
         WinNT.DACL_SECURITY_INFORMATION |
         WinNT.PROTECTED_DACL_SECURITY_INFORMATION |
         WinNT.UNPROTECTED_DACL_SECURITY_INFORMATION);
@@ -160,7 +180,7 @@
     ImmutableList.Builder<AclEntry> direct = ImmutableList.builder();
 
     for (WinNT.ACCESS_ACEStructure ace : aces) {
-      AclEntry aclEntry = newAclEntry(ace);      
+      AclEntry aclEntry = newAclEntry(ace);
       if (aclEntry != null) {
         if ((ace.AceFlags & WinNT.INHERITED_ACE) == WinNT.INHERITED_ACE) {
           inherited.add(aclEntry);
@@ -192,23 +212,22 @@
    */
   public AclFileAttributeView getShareAclView(Path path)
       throws IOException, UnsupportedOperationException {
-    if (Shlwapi.INSTANCE.PathIsUNC(path.toString())) {
+    if (shlwapi.PathIsUNC(path.toString())) {
       log.log(Level.FINEST, "Using a UNC path.");
       return getUncShareAclView(path.toString());
-    } else if (Shlwapi.INSTANCE.PathIsNetworkPath(path.toString())) {
+    } else if (shlwapi.PathIsNetworkPath(path.toString())) {
       log.log(Level.FINEST, "Using a mapped drive.");
-      // Call WNetGetUniversalNameW with the size needed for 
+      // Call WNetGetUniversalNameW with the size needed for
       // UNIVERSAL_NAME_INFO. If WNetGetUniversalNameW returns ERROR_MORE_DATA
       // that indicates that a larger buffer is needed. If this happens, make
       // a second call to WNetGetUniversalNameW with a buffer big enough.
-      Mpr mprlib = Mpr.INSTANCE;
       Memory buf = new Memory(1024);
       IntByReference bufSize = new IntByReference((int) buf.size());
-      int result = mprlib.WNetGetUniversalNameW(path.getRoot().toString(),
+      int result = mpr.WNetGetUniversalNameW(path.getRoot().toString(),
           Mpr.UNIVERSAL_NAME_INFO_LEVEL, buf, bufSize);
       if (result == WinNT.ERROR_MORE_DATA) {
         buf = new Memory(bufSize.getValue());
-        result = Mpr.INSTANCE.WNetGetUniversalNameW(path.getRoot().toString(),
+        result = mpr.WNetGetUniversalNameW(path.getRoot().toString(),
             Mpr.UNIVERSAL_NAME_INFO_LEVEL, buf, bufSize);
       }
       if (result != WinNT.NO_ERROR) {
@@ -239,12 +258,11 @@
         new Object[] { host, share });
     return getShareAclView(host, share);
   }
-  
+
   private AclFileAttributeView getShareAclView(String host, String share)
       throws IOException {
-    Netapi32Ex netapi32 = Netapi32Ex.INSTANCE;
     PointerByReference buf = new PointerByReference();
-    
+
     // Call NetShareGetInfo with a 502 to get the security descriptor of the
     // share. The security descriptor contains the Acl details for the share
     // that the adaptor needs.
@@ -299,7 +317,7 @@
    * @return AclEntry representing the ace, or {@code null} if a valid
    *         AclEntry could not be created from the ace.
    */
-  public static AclEntry newAclEntry(WinNT.ACCESS_ACEStructure ace) {
+  public AclEntry newAclEntry(WinNT.ACCESS_ACEStructure ace) {
     // Map the type.
     AclEntryType aclType = ACL_TYPE_MAP.get(ace.AceType);
     if (aclType == null) {
@@ -311,7 +329,7 @@
     // Map the user.
     Account account;
     try {
-      account = Advapi32Util.getAccountBySid(ace.getSID());
+      account = getAccountBySid(ace.getSID());
     } catch (Win32Exception e) {
       // Only the least significant 16-bits signifies the HR code.
       if ((e.getHR().intValue() & 0xFFFF) == WinError.ERROR_NONE_MAPPED) {
@@ -336,7 +354,7 @@
           new Object[] { accountName, accountType });
       return null;
     }
-    
+
     // Expand NT GENERIC_* permissions to their FILE_GENERIC_* equivalents.
     int aceMask = ace.Mask;
     for (Map.Entry<Integer, Integer> e : GENERIC_PERMS_MAP.entrySet()) {
@@ -352,7 +370,7 @@
         aclPerms.add(e.getValue());
       }
     }
-    
+
     // Map the flags.
     Set<AclEntryFlag> aclFlags = EnumSet.noneOf(AclEntryFlag.class);
     for (Map.Entry<Byte, AclEntryFlag> e : ACL_FLAGS_MAP.entrySet()) {
@@ -369,6 +387,11 @@
         .build();
   }
 
+  @VisibleForTesting
+  Account getAccountBySid(WinNT.PSID sid) throws Win32Exception {
+    return Advapi32Util.getAccountBySid(sid);
+  }
+
   // One-to-one corresponance to WinNT.SID_NAME_USE "enumeration".
   private static final List<String> SID_TYPE_NAMES = ImmutableList.of(
       "Unknown", "User", "Group", "Domain", "Alias", "Well-known Group",
@@ -408,7 +431,8 @@
     }
   }
 
-  private interface Mpr extends StdCallLibrary {
+  @VisibleForTesting
+  interface Mpr extends StdCallLibrary {
     Mpr INSTANCE = (Mpr) Native.loadLibrary("Mpr", Mpr.class,
         W32APIOptions.UNICODE_OPTIONS);
 
@@ -442,21 +466,21 @@
     WString wpath = new WString(pathname);
     IntByReference lengthNeeded = new IntByReference();
 
-    if (ADVAPI32.GetFileSecurity(wpath, daclType, null, 0, lengthNeeded)) {
+    if (advapi32.GetFileSecurity(wpath, daclType, null, 0, lengthNeeded)) {
       throw new RuntimeException("GetFileSecurity was expected to fail with "
           + "ERROR_INSUFFICIENT_BUFFER");
     }
 
-    int rc = KERNEL32.GetLastError();
+    int rc = kernel32.GetLastError();
     if (rc != W32Errors.ERROR_INSUFFICIENT_BUFFER) {
       throw new IOException("Failed GetFileSecurity", new Win32Exception(rc));
     }
 
     Memory memory = new Memory(lengthNeeded.getValue());
-    if (!ADVAPI32.GetFileSecurity(wpath, daclType, memory, (int) memory.size(),
+    if (!advapi32.GetFileSecurity(wpath, daclType, memory, (int) memory.size(),
                                   lengthNeeded)) {
       throw new IOException("Failed GetFileSecurity",
-          new Win32Exception(KERNEL32.GetLastError()));
+          new Win32Exception(kernel32.GetLastError()));
     }
 
     WinNT.SECURITY_DESCRIPTOR_RELATIVE securityDescriptor =
diff --git a/src/com/google/enterprise/adaptor/fs/WindowsFileDelegate.java b/src/com/google/enterprise/adaptor/fs/WindowsFileDelegate.java
index 18b139b..07c106d 100644
--- a/src/com/google/enterprise/adaptor/fs/WindowsFileDelegate.java
+++ b/src/com/google/enterprise/adaptor/fs/WindowsFileDelegate.java
@@ -99,7 +99,7 @@
 
     ImmutableList.Builder<AclEntry> builder = ImmutableList.builder();
     for (WinNT.ACCESS_ACEStructure ace : dacl.getACEStructures()) {
-      AclEntry entry = WindowsAclFileAttributeViews.newAclEntry(ace);
+      AclEntry entry = aclViews.newAclEntry(ace);
       if (entry != null) {
         builder.add(entry);
       }
diff --git a/test/com/google/enterprise/adaptor/fs/AccumulatingDocIdPusher.java b/test/com/google/enterprise/adaptor/fs/AccumulatingDocIdPusher.java
new file mode 100644
index 0000000..5c38e25
--- /dev/null
+++ b/test/com/google/enterprise/adaptor/fs/AccumulatingDocIdPusher.java
@@ -0,0 +1,96 @@
+// Copyright 2012 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 com.google.enterprise.adaptor.fs;
+
+import com.google.enterprise.adaptor.Acl;
+import com.google.enterprise.adaptor.DocId;
+import com.google.enterprise.adaptor.ExceptionHandler;
+import com.google.enterprise.adaptor.GroupPrincipal;
+import com.google.enterprise.adaptor.Principal;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+class AccumulatingDocIdPusher extends UnsupportedDocIdPusher {
+  private List<Record> records = new ArrayList<Record>();
+  private List<Map<DocId, Acl>> namedResouces
+      = new ArrayList<Map<DocId, Acl>>();
+
+  @Override
+  public DocId pushDocIds(Iterable<DocId> docIds)
+      throws InterruptedException {
+    return pushDocIds(docIds, null);
+  }
+
+  @Override
+  public DocId pushDocIds(Iterable<DocId> docIds,
+                          ExceptionHandler handler)
+      throws InterruptedException {
+    List<Record> records = new ArrayList<Record>();
+    for (DocId docId : docIds) {
+      records.add(new Record.Builder(docId).build());
+    }
+    Record record = pushRecords(records, handler);
+    return record == null ? null : record.getDocId();
+  }
+
+  @Override
+  public Record pushRecords(Iterable<Record> records)
+      throws InterruptedException {
+    return pushRecords(records, null);
+  }
+
+  @Override
+  public Record pushRecords(Iterable<Record> records,
+                            ExceptionHandler handler)
+      throws InterruptedException {
+    for (Record record : records) {
+      this.records.add(record);
+    }
+    return null;
+  }
+
+  @Override
+  public DocId pushNamedResources(Map<DocId, Acl> resources)
+      throws InterruptedException {
+    return pushNamedResources(resources, null);
+  }
+
+  @Override
+  public DocId pushNamedResources(Map<DocId, Acl> resources,
+                                  ExceptionHandler handler)
+      throws InterruptedException {
+    namedResouces.add(Collections.unmodifiableMap(
+        new TreeMap<DocId, Acl>(resources)));
+    return null;
+  }
+
+  public List<Record> getRecords() {
+    return Collections.unmodifiableList(records);
+  }
+
+  public List<Map<DocId, Acl>> getNamedResources() {
+    return Collections.unmodifiableList(namedResouces);
+  }
+
+  public void reset() {
+    records.clear();
+    namedResouces.clear();
+  }
+}
diff --git a/test/com/google/enterprise/adaptor/fs/FsAdaptorTest.java b/test/com/google/enterprise/adaptor/fs/FsAdaptorTest.java
index 9eb2d16..efb317c 100644
--- a/test/com/google/enterprise/adaptor/fs/FsAdaptorTest.java
+++ b/test/com/google/enterprise/adaptor/fs/FsAdaptorTest.java
@@ -1,4 +1,4 @@
-// Copyright 2013 Google Inc. All Rights Reserved.
+// Copyright 2014 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.
@@ -14,38 +14,965 @@
 
 package com.google.enterprise.adaptor.fs;
 
-import com.google.enterprise.adaptor.AccumulatingDocIdPusher;
+import static com.google.enterprise.adaptor.fs.AclView.user;
+import static com.google.enterprise.adaptor.fs.AclView.group;
+import static com.google.enterprise.adaptor.fs.AclView.GenericPermission.*;
 
 import static org.junit.Assert.*;
 
+import static java.nio.file.attribute.AclEntryFlag.*;
+import static java.nio.file.attribute.AclEntryPermission.*;
+import static java.nio.file.attribute.AclEntryType.*;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Sets;
+import com.google.enterprise.adaptor.Acl;
+import com.google.enterprise.adaptor.Acl.InheritanceType;
+import com.google.enterprise.adaptor.AdaptorContext;
+import com.google.enterprise.adaptor.Config;
+import com.google.enterprise.adaptor.DocId;
+import com.google.enterprise.adaptor.DocIdPusher.Record;
+import com.google.enterprise.adaptor.GroupPrincipal;
+import com.google.enterprise.adaptor.UserPrincipal;
+
 import org.junit.*;
 import org.junit.rules.ExpectedException;
 
+import java.io.File;
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Path;
 import java.nio.file.Paths;
+import java.nio.file.attribute.AclFileAttributeView;
+import java.nio.file.attribute.FileTime;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.BlockingQueue;
 
 /** Test cases for {@link FsAdaptor}. */
 public class FsAdaptorTest {
+
+  static final String ROOT = "/";
+  static final Path rootPath = Paths.get(ROOT);
+  static final DocId shareAclDocId = new DocId("shareAcl");
+
+  private final Set<String> windowsAccounts = ImmutableSet.of(
+      "BUILTIN\\Administrators", "Everyone", "BUILTIN\\Users",
+      "BUILTIN\\Guest", "NT AUTHORITY\\INTERACTIVE",
+      "NT AUTHORITY\\Authenticated Users");
+  private final String builtinPrefix = "BUILTIN\\";
+  private final String namespace = "Default";
+
+  private AdaptorContext context = new MockAdaptorContext();
+  private AccumulatingDocIdPusher pusher =
+      (AccumulatingDocIdPusher) context.getDocIdPusher();
+  private Config config = context.getConfig();
+  private MockFile root = new MockFile(ROOT, true);
+  private MockFileDelegate delegate = new MockFileDelegate(root);
+  private FsAdaptor adaptor = new FsAdaptor(delegate);
+  private DocId rootDocId;
+
+  @Before
+  public void setUp() throws Exception {
+    rootDocId = delegate.newDocId(rootPath);
+    adaptor.initConfig(config);
+    config.overrideKey("filesystemadaptor.src", root.getPath());
+    config.overrideKey("adaptor.incrementalPollPeriodSecs", "0");
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    adaptor.destroy();
+  }
+
   @Rule
   public ExpectedException thrown = ExpectedException.none();
 
+  private Path getPath(String path) {
+    return rootPath.resolve(path);
+  }
+
+  private DocId getDocId(String path) throws IOException {
+    return delegate.newDocId(getPath(path));
+  }
+
   @Test
-  public void testGetPathName() throws Exception {
-    TestHelper.assumeOsIsWindows();
-    FsAdaptor adaptor = new FsAdaptor();
-    assertEquals("share", adaptor.getPathName(Paths.get("\\\\host/share/")));
-    assertEquals("folder2", 
-        adaptor.getPathName(Paths.get("C:/folder1/folder2/")));
+  public void testAdaptorStartupShutdown() throws Exception {
+    // Construction of Adaptor happened in setUp(), and
+    // destruction will happen in tearDown(), so the only
+    // thing left is to init the context.
+    adaptor.init(context);
+  }
+
+  @Test
+  public void testAdaptorInitNoSourcePath() throws Exception {
+    config.overrideKey("filesystemadaptor.src", "");
+    thrown.expect(IOException.class);
+    adaptor.init(context);
+  }
+
+  @Test
+  public void testAdaptorInitNonRootSourcePath() throws Exception {
+    root.addChildren(new MockFile("subdir", true));
+    config.overrideKey("filesystemadaptor.src", getPath("subdir").toString());
+    thrown.expect(IllegalStateException.class);
+    adaptor.init(context);
+  }
+
+  @Test
+  public void testAdaptorInitDfsUncActiveStorageUnc() throws Exception {
+    root.setDfsUncActiveStorageUnc(Paths.get("\\\\dfshost\\share"));
+    adaptor.init(context);
+  }
+
+  @Test
+  public void testAdaptorInitNonLinkDfsUncActiveStorageUnc() throws Exception {
+    root.setDfsUncActiveStorageUnc(rootPath);
+    thrown.expect(IOException.class);
+    adaptor.init(context);
+  }
+
+  @Test
+  public void testAdaptorInitSupportedWindowsAccounts() throws Exception {
+    String accounts = "Everyone, BUILTIN\\Users, NT AUTH\\New Users";
+    Set<String> expected =
+        ImmutableSet.of("Everyone", "BUILTIN\\Users", "NT AUTH\\New Users");
+    config.overrideKey("filesystemadaptor.supportedAccounts", accounts);
+    adaptor.init(context);
+    assertEquals(expected, adaptor.getSupportedWindowsAccounts());
+  }
+
+  @Test
+  public void testAdaptorInitBuiltinGroupPrefix() throws Exception {
+    String expected = "TestPrefix";
+    config.overrideKey("filesystemadaptor.builtinGroupPrefix", expected);
+    adaptor.init(context);
+    assertEquals(expected, adaptor.getBuiltinPrefix());
+  }
+
+  @Test
+  public void testAdaptorInitNamespace() throws Exception {
+    String expected = "TestNamespace";
+    config.overrideKey("adaptor.namespace", expected);
+    adaptor.init(context);
+    assertEquals(expected, adaptor.getNamespace());
+  }
+
+  @Test
+  public void testGetFolderName() throws Exception {
+    assertEquals("share", adaptor.getFileName(Paths.get("\\\\host/share/")));
+    assertEquals("folder2",
+        adaptor.getFileName(Paths.get("C:/folder1/folder2/")));
+    assertEquals("folder2",
+        adaptor.getFileName(Paths.get("/folder1/folder2/")));
+    assertEquals("share", adaptor.getFileName(Paths.get("\\\\host/share")));
+    assertEquals("folder1",
+        adaptor.getFileName(Paths.get("/folder1")));
+    assertEquals(File.separator,  // Windows flips the '/' to '\'.
+        adaptor.getFileName(Paths.get("/")));
+    assertEquals("C:\\",
+        adaptor.getFileName(Paths.get("C:\\")));
+  }
+
+  @Test
+  public void testIsSupportedPath() throws Exception {
+    root.addChildren(new MockFile("foo"), new MockFile("bar", true),
+                     new MockFile("link").setIsRegularFile(false));
+    assertTrue(adaptor.isSupportedPath(rootPath));
+    assertTrue(adaptor.isSupportedPath(getPath("foo")));
+    assertTrue(adaptor.isSupportedPath(getPath("bar")));
+    assertFalse(adaptor.isSupportedPath(getPath("link")));
+  }
+
+  @Test
+  public void testIsVisibleDescendantOfRoot() throws Exception {
+    adaptor.init(context);
+    root.addChildren(new MockFile("foo"),
+        new MockFile("hidden.txt").setIsHidden(true),
+        new MockFile("dir1", true).addChildren(new MockFile("bar"),
+            new MockFile("hidden.pdf").setIsHidden(true)),
+        new MockFile("hidden.dir", true).setIsHidden(true).addChildren(
+            new MockFile("baz")));
+    assertTrue(adaptor.isVisibleDescendantOfRoot(rootPath));
+    assertTrue(adaptor.isVisibleDescendantOfRoot(getPath("foo")));
+    assertTrue(adaptor.isVisibleDescendantOfRoot(getPath("dir1")));
+    assertTrue(adaptor.isVisibleDescendantOfRoot(getPath("dir1/bar")));
+    assertFalse(adaptor.isVisibleDescendantOfRoot(getPath("hidden.txt")));
+    assertFalse(adaptor.isVisibleDescendantOfRoot(getPath("dir1/hidden.pdf")));
+    assertFalse(adaptor.isVisibleDescendantOfRoot(getPath("hidden.dir")));
+    assertFalse(adaptor.isVisibleDescendantOfRoot(getPath("hidden.dir/baz")));
+    assertFalse(adaptor.isVisibleDescendantOfRoot(null));
+  }
+
+  @Test
+  public void testGetDocIds() throws Exception {
+    adaptor.init(context);
+    adaptor.getDocIds(pusher);
+
+    // We should just push the root docid.
+    List<Record> records = pusher.getRecords();
+    assertEquals(1, records.size());
+    assertEquals(delegate.newDocId(rootPath), records.get(0).getDocId());
+
+    // We should have pushed an acl for the share.
+    List<Map<DocId, Acl>> namedResources = pusher.getNamedResources();
+    Acl expected = new Acl.Builder().setEverythingCaseInsensitive()
+        .setPermitGroups(Collections.singleton(new GroupPrincipal("Everyone")))
+        .setInheritanceType(InheritanceType.AND_BOTH_PERMIT).build();
+    assertEquals(1, namedResources.size());
+    assertEquals(1, namedResources.get(0).size());
+    assertEquals(expected, namedResources.get(0).get(shareAclDocId));
+  }
+
+  @Test
+  public void testGetDocIdsDfs() throws Exception {
+    Path uncPath = Paths.get("\\\\dfshost\\share");
+    root.setDfsUncActiveStorageUnc(uncPath);
+    root.setDfsShareAclView(MockFile.FULL_ACCESS_ACLVIEW);
+    adaptor.init(context);
+    adaptor.getDocIds(pusher);
+
+    // We should just push the root docid.
+    List<Record> records = pusher.getRecords();
+    assertEquals(1, records.size());
+    assertEquals(delegate.newDocId(rootPath), records.get(0).getDocId());
+
+    // We should have pushed acls for the share and the dfsShare.
+    List<Map<DocId, Acl>> namedResources = pusher.getNamedResources();
+    DocId dfsShareAcl = new DocId("dfsShareAcl");
+    Acl expectedDfsShareAcl = new Acl.Builder().setEverythingCaseInsensitive()
+        .setPermitGroups(Collections.singleton(new GroupPrincipal("Everyone")))
+        .setInheritanceType(InheritanceType.AND_BOTH_PERMIT).build();
+    Acl expectedShareAcl = new Acl.Builder(expectedDfsShareAcl)
+        .setInheritFrom(dfsShareAcl).build();
+    assertEquals(1, namedResources.size());
+    Map<DocId, Acl> acls = namedResources.get(0);
+    assertEquals(2, acls.size());
+    assertEquals(expectedDfsShareAcl, acls.get(dfsShareAcl));
+    assertEquals(expectedShareAcl, acls.get(shareAclDocId));
+  }
+
+  @Test
+  public void testGetDocIdsBrokenDfs() throws Exception {
+    Path uncPath = Paths.get("\\\\dfshost\\share");
+    root.setDfsUncActiveStorageUnc(uncPath);
+    root.setDfsShareAclView(MockFile.FULL_ACCESS_ACLVIEW);
+    adaptor.init(context);
+
+    // Now make the active storage disappear.
+    root.setDfsUncActiveStorageUnc(null);
+    thrown.expect(IOException.class);
+    adaptor.getDocIds(pusher);
+  }
+
+  @Test
+  public void testGetDocContentUnsupportedPath() throws Exception {
+    root.addChildren(new MockFile("unsupported").setIsRegularFile(false));
+    adaptor.init(context);
+    MockResponse response = new MockResponse();
+    adaptor.getDocContent(new MockRequest(getDocId("unsupported")), response);
+    assertTrue(response.notFound);
+  }
+
+  /*
+   * This test was invalidated when the check for isSupportedPath()
+   * was moved above the check for bad DocIds in the beginning of
+   * FsAdaptor.getDocumentContent().  This test still passes, but
+   * the notFound response is coming from the earlier check for
+   * isSupportedPath(), not from the bad DocId.
+   */
+  @Test
+  public void testGetDocContentBadDocId() throws Exception {
+    root.addChildren(new MockFile("badfile"));
+    adaptor.init(context);
+    MockResponse response = new MockResponse();
+    // The requested DocId is missing the root component of the path.
+    adaptor.getDocContent(new MockRequest(new DocId("badfile")), response);
+    assertTrue(response.notFound);
+  }
+
+  @Test
+  public void testGetDocContentHiddenFile() throws Exception {
+    root.addChildren(new MockFile("hidden.txt").setIsHidden(true));
+    adaptor.init(context);
+    MockResponse response = new MockResponse();
+    adaptor.getDocContent(new MockRequest(getDocId("hidden.txt")), response);
+    assertTrue(response.notFound);
+  }
+
+  @Test
+  public void testGetDocContentHiddenDirectory() throws Exception {
+    root.addChildren(new MockFile("hidden.dir", true).setIsHidden(true));
+    adaptor.init(context);
+    MockResponse response = new MockResponse();
+    adaptor.getDocContent(new MockRequest(getDocId("hidden.dir")), response);
+    assertTrue(response.notFound);
+  }
+
+  @Test
+  public void testGetDocContentRegularFile() throws Exception {
+    String fname = "test.html";
+    Date modifyDate = new Date(30000);
+    FileTime modifyTime = FileTime.fromMillis(modifyDate.getTime());
+    String content = "<html><title>Hello World</title></html>";
+    root.addChildren(new MockFile(fname).setLastModifiedTime(modifyTime)
+        .setFileContents(content).setContentType("text/html"));
+    adaptor.init(context);
+
+    MockResponse response = new MockResponse();
+    adaptor.getDocContent(new MockRequest(getDocId(fname)), response);
+    assertFalse(response.notFound);
+    assertEquals(modifyDate, response.lastModified);
+    assertEquals(getPath(fname).toUri(), response.displayUrl);
+    assertEquals("text/html", response.contentType);
+    assertEquals(content, response.content.toString("UTF-8"));
+    // TODO: check metadata.
+    assertNotNull(response.metadata.get("Creation Time"));
+    // ACL checked in other tests.
+  }
+
+  @Test
+  public void testGetDocContentRootAcl() throws Exception {
+    Acl expectedAcl = new Acl.Builder().setEverythingCaseInsensitive()
+        .setPermitGroups(Collections.singleton(new GroupPrincipal("Everyone")))
+        .setInheritFrom(shareAclDocId)
+        .setInheritanceType(InheritanceType.CHILD_OVERRIDES).build();
+    adaptor.init(context);
+    MockRequest request = new MockRequest(delegate.newDocId(rootPath));
+    MockResponse response = new MockResponse();
+    adaptor.getDocContent(request, response);
+    assertEquals(expectedAcl, response.acl);
+  }
+
+  @Test
+  public void testGetDocContentEmptyAcl() throws Exception {
+    Acl expectedAcl = new Acl.Builder().setEverythingCaseInsensitive()
+        .setInheritFrom(rootDocId, "childFilesAcl")
+        .setInheritanceType(InheritanceType.LEAF_NODE).build();
+    testFileAcl(MockFile.EMPTY_ACLVIEW, null, expectedAcl);
+  }
+
+  @Test
+  public void testGetDocContentDirectAcl() throws Exception {
+    AclFileAttributeView aclView = new AclView((user("joe")
+        .type(ALLOW).perms(GENERIC_READ).build()));
+    Acl expectedAcl = new Acl.Builder().setEverythingCaseInsensitive()
+        .setPermitUsers(Collections.singleton(new UserPrincipal("joe")))
+        .setInheritFrom(rootDocId, "childFilesAcl")
+        .setInheritanceType(InheritanceType.LEAF_NODE).build();
+    testFileAcl(aclView, null, expectedAcl);
+  }
+
+  @Test
+  public void testGetDocContentNoInheritAcl() throws Exception {
+    AclFileAttributeView aclView = new AclView((user("joe")
+        .type(ALLOW).perms(GENERIC_READ).build()));
+    // Should inherit from the share, not the parent.
+    Acl expectedAcl = new Acl.Builder().setEverythingCaseInsensitive()
+        .setPermitUsers(Collections.singleton(new UserPrincipal("joe")))
+        .setInheritFrom(shareAclDocId)
+        .setInheritanceType(InheritanceType.LEAF_NODE).build();
+    testFileAcl(aclView, MockFile.EMPTY_ACLVIEW, expectedAcl);
+  }
+
+  private void testFileAcl(AclFileAttributeView aclView,
+      AclFileAttributeView inheritAclView, Acl expectedAcl) throws Exception {
+    String fname = "acltest";
+    root.addChildren(new MockFile(fname).setAclView(aclView)
+                     .setInheritedAclView(inheritAclView));
+    adaptor.init(context);
+    MockResponse response = new MockResponse();
+    adaptor.getDocContent(new MockRequest(getDocId(fname)), response);
+    assertEquals(expectedAcl, response.acl);
+  }
+
+  /** Test that LastAccessTime is restored after reading the file. */
+  @Test
+  public void testPreserveFileLastAccessTime() throws Exception {
+    testPreserveFileLastAccessTime(new MockFile("test") {
+        @Override
+        InputStream newInputStream() throws IOException {
+          setLastAccessTime(FileTime.fromMillis(
+              getLastAccessTime().toMillis() + 1000));
+          return super.newInputStream();
+        }
+      });
+  }
+
+  /** Test LastAccessTime is restored even if exception opening the file. */
+  @Test
+  public void testPreserveFileLastAccessTimeException1() throws Exception {
+    thrown.expect(IOException.class);
+    testPreserveFileLastAccessTime(new MockFile("test") {
+        @Override
+        InputStream newInputStream() throws IOException {
+          setLastAccessTime(FileTime.fromMillis(
+              getLastAccessTime().toMillis() + 1000));
+          throw new IOException("newInputStream");
+        }
+      });
+  }
+
+  /** Test LastAccessTime is restored even if exception reading the file. */
+  @Test
+  public void testPreserveFileLastAccessTimeException2() throws Exception {
+    thrown.expect(IOException.class);
+    testPreserveFileLastAccessTime(new MockFile("test") {
+        @Override
+        InputStream newInputStream() throws IOException {
+          setLastAccessTime(FileTime.fromMillis(
+              getLastAccessTime().toMillis() + 1000));
+          return new FilterInputStream(super.newInputStream()) {
+              @Override
+              public int read(byte[] b, int off, int len) throws IOException {
+                throw new IOException("read");
+              }
+          };
+        }
+      });
+  }
+
+  /** Test LastAccessTime is restored even if exception closing the file. */
+  @Test
+  public void testPreserveFileLastAccessTimeException3() throws Exception {
+    thrown.expect(IOException.class);
+    testPreserveFileLastAccessTime(new MockFile("test") {
+        @Override
+        InputStream newInputStream() throws IOException {
+          setLastAccessTime(FileTime.fromMillis(
+              getLastAccessTime().toMillis() + 1000));
+          return new FilterInputStream(super.newInputStream()) {
+              @Override
+              public void close() throws IOException {
+                throw new IOException("close");
+              }
+          };
+        }
+      });
+  }
+
+  /** Test that failure to restore LastAccessTime is not fatal. */
+  @Test
+  public void testPreserveFileLastAccessTimeException4() throws Exception {
+    testNoPreserveFileLastAccessTime(new MockFile("test") {
+        @Override
+        InputStream newInputStream() throws IOException {
+          setLastAccessTime(FileTime.fromMillis(
+              getLastAccessTime().toMillis() + 1000));
+          return super.newInputStream();
+        }
+        @Override
+        MockFile setLastAccessTime(FileTime accessTime) throws IOException {
+          if (MockFile.DEFAULT_FILETIME.equals(getLastAccessTime())) {
+            // Let the above setting from newInputStream go through.
+            return super.setLastAccessTime(accessTime);
+          } else {
+            // But fail the attempt to restore from FsAdaptor.
+            throw new IOException("Restore LastAccessTime");
+          }
+        }
+      });
+  }
+
+  private void testPreserveFileLastAccessTime(MockFile file) throws Exception {
+    testFileLastAccessTime(file, true);
+  }
+
+  private void testNoPreserveFileLastAccessTime(MockFile file)
+      throws Exception {
+    testFileLastAccessTime(file, false);
+  }
+
+  private void testFileLastAccessTime(MockFile file, boolean isPreserved)
+      throws Exception {
+    String contents = "Test contents";
+    file.setFileContents(contents);
+    root.addChildren(file);
+    adaptor.init(context);
+    MockResponse response = new MockResponse();
+    FileTime lastAccess = file.getLastAccessTime();
+    adaptor.getDocContent(new MockRequest(getDocId(file.getName())), response);
+    // Verify we indeed accessed the file
+    assertEquals(contents, response.content.toString("UTF-8"));
+    if (isPreserved) {
+      assertEquals(lastAccess, file.getLastAccessTime());
+    } else {
+      assertFalse(lastAccess.equals(file.getLastAccessTime()));
+    }
+  }
+
+  @Test
+  public void testGetDocContentRoot() throws Exception {
+    testGetDocContentDirectory(rootPath, rootPath.toString());
+    // ACLs checked in other tests.
+  }
+
+  @Test
+  public void testGetDocContentDirectory() throws Exception {
+    String fname = "test.dir";
+    root.addChildren(new MockFile(fname, true));
+    testGetDocContentDirectory(getPath(fname), fname);
+    // ACLs checked in other tests.
+  }
+
+  private void testGetDocContentDirectory(Path path, String label)
+      throws Exception {
+    MockFile dir = delegate.getFile(path);
+    FileTime modifyTime = dir.getLastModifiedTime();
+    Date modifyDate = new Date(modifyTime.toMillis());
+    dir.addChildren(new MockFile("test.txt"), new MockFile("subdir", true));
+    adaptor.init(context);
+    MockRequest request = new MockRequest(delegate.newDocId(path));
+    MockResponse response = new MockResponse();
+    adaptor.getDocContent(request, response);
+    assertFalse(response.notFound);
+    assertEquals(modifyDate, response.lastModified);
+    assertEquals(path.toUri(), response.displayUrl);
+    assertEquals("text/html; charset=UTF-8", response.contentType);
+    String expectedContent = "<!DOCTYPE html>\n<html><head><title>Folder "
+        + label + "</title></head><body><h1>Folder " + label + "</h1>"
+        + "<li><a href=\"subdir/\">subdir</a></li>"
+        + "<li><a href=\"test.txt\">test.txt</a></li></body></html>";
+    assertEquals(expectedContent, response.content.toString("UTF-8"));
+    assertNotNull(response.metadata.get("Creation Time"));
+  }
+
+  @Test
+  public void testGetDocContentDefaultRootAcls() throws Exception {
+    Acl expectedAcl = new Acl.Builder().setEverythingCaseInsensitive()
+        .setPermitGroups(Collections.singleton(new GroupPrincipal("Everyone")))
+        .setInheritanceType(InheritanceType.CHILD_OVERRIDES)
+        .setInheritFrom(shareAclDocId).build();
+    Map<String, Acl> expectedResources = ImmutableMap.of(
+        "allFoldersAcl", expectedAcl,
+        "allFilesAcl", expectedAcl,
+        "childFoldersAcl", expectedAcl,
+        "childFilesAcl", expectedAcl);
+    testGetDocContentAcls(rootPath, expectedAcl, expectedResources);
+  }
+
+  @Test
+  public void testGetDocContentInheritOnlyRootAcls() throws Exception {
+    AclFileAttributeView inheritOnlyAclView = new AclView(
+        user("Longfellow Deeds").type(ALLOW).perms(GENERIC_READ)
+            .flags(FILE_INHERIT, DIRECTORY_INHERIT, INHERIT_ONLY),
+        group("Administrators").type(ALLOW).perms(GENERIC_ALL)
+            .flags(FILE_INHERIT, DIRECTORY_INHERIT));
+    root.setAclView(inheritOnlyAclView);
+
+    // The root ACL should only include Administrators, not Mr. Deeds.
+    Acl expectedAcl = new Acl.Builder().setEverythingCaseInsensitive()
+        .setPermitGroups(Collections.singleton(
+            new GroupPrincipal("Administrators")))
+        .setInheritanceType(InheritanceType.CHILD_OVERRIDES)
+        .setInheritFrom(shareAclDocId).build();
+    // But the childrens' inherited ACLs should include Mr. Deeds
+    Acl expectedInheritableAcl = new Acl.Builder(expectedAcl)
+        .setPermitUsers(Collections.singleton(
+            new UserPrincipal("Longfellow Deeds")))
+        .build();
+    Map<String, Acl> expectedResources = ImmutableMap.of(
+        "allFoldersAcl", expectedInheritableAcl,
+        "allFilesAcl", expectedInheritableAcl,
+        "childFoldersAcl", expectedInheritableAcl,
+        "childFilesAcl", expectedInheritableAcl);
+    testGetDocContentAcls(rootPath, expectedAcl, expectedResources);
+  }
+
+  @Test
+  public void testGetDocContentNoPropagateRootAcls() throws Exception {
+    AclFileAttributeView noPropagateAclView = new AclView(
+        user("Barren von Dink").type(ALLOW).perms(GENERIC_READ)
+            .flags(FILE_INHERIT, DIRECTORY_INHERIT, NO_PROPAGATE_INHERIT),
+        group("Administrators").type(ALLOW).perms(GENERIC_ALL)
+            .flags(FILE_INHERIT, DIRECTORY_INHERIT));
+    root.setAclView(noPropagateAclView);
+
+    // The root ACL should include both Administrators and the Barren.
+    Acl expectedAcl = new Acl.Builder().setEverythingCaseInsensitive()
+        .setPermitUsers(Collections.singleton(
+            new UserPrincipal("Barren von Dink")))
+        .setPermitGroups(Collections.singleton(
+            new GroupPrincipal("Administrators")))
+        .setInheritanceType(InheritanceType.CHILD_OVERRIDES)
+        .setInheritFrom(shareAclDocId).build();
+    // The direct childrens' inherited ACLs should include both the
+    // Administrators and the Barren, but grandchildren should not
+    // inherit the Barren's NO_PROPAGATE permission.
+    Acl expectedNonChildAcl = new Acl.Builder(expectedAcl)
+        .setPermitUsers(Collections.<UserPrincipal>emptySet()).build();
+    Map<String, Acl> expectedResources = ImmutableMap.of(
+        "allFoldersAcl", expectedNonChildAcl,
+        "allFilesAcl", expectedNonChildAcl,
+        "childFoldersAcl", expectedAcl,
+        "childFilesAcl", expectedAcl);
+    testGetDocContentAcls(rootPath, expectedAcl, expectedResources);
+  }
+
+  @Test
+  public void testGetDocContentFilesOnlyRootAcls() throws Exception {
+    AclFileAttributeView noPropagateAclView = new AclView(
+        user("For Your Files Only").type(ALLOW).perms(GENERIC_READ)
+            .flags(FILE_INHERIT),
+        group("Administrators").type(ALLOW).perms(GENERIC_ALL)
+            .flags(FILE_INHERIT, DIRECTORY_INHERIT));
+    root.setAclView(noPropagateAclView);
+
+    Acl expectedAcl = new Acl.Builder().setEverythingCaseInsensitive()
+        .setPermitUsers(Collections.singleton(
+            new UserPrincipal("For Your Files Only")))
+        .setPermitGroups(Collections.singleton(
+            new GroupPrincipal("Administrators")))
+        .setInheritanceType(InheritanceType.CHILD_OVERRIDES)
+        .setInheritFrom(shareAclDocId).build();
+    // Folders shouldn't include the file-only permissions.
+    Acl expectedFolderAcl = new Acl.Builder(expectedAcl)
+        .setPermitUsers(Collections.<UserPrincipal>emptySet()).build();
+    Map<String, Acl> expectedResources = ImmutableMap.of(
+        "allFoldersAcl", expectedFolderAcl,
+        "allFilesAcl", expectedAcl,
+        "childFoldersAcl", expectedFolderAcl,
+        "childFilesAcl", expectedAcl);
+    testGetDocContentAcls(rootPath, expectedAcl, expectedResources);
+  }
+
+  @Test
+  public void testGetDocContentFoldersOnlyRootAcls() throws Exception {
+    AclFileAttributeView noPropagateAclView = new AclView(
+        user("Fluff 'n Folder").type(ALLOW).perms(GENERIC_READ)
+            .flags(DIRECTORY_INHERIT),
+        group("Administrators").type(ALLOW).perms(GENERIC_ALL)
+            .flags(FILE_INHERIT, DIRECTORY_INHERIT));
+    root.setAclView(noPropagateAclView);
+
+    Acl expectedAcl = new Acl.Builder().setEverythingCaseInsensitive()
+        .setPermitUsers(Collections.singleton(
+            new UserPrincipal("Fluff 'n Folder")))
+        .setPermitGroups(Collections.singleton(
+            new GroupPrincipal("Administrators")))
+        .setInheritanceType(InheritanceType.CHILD_OVERRIDES)
+        .setInheritFrom(shareAclDocId).build();
+    // Files shouldn't include the folder-only permissions.
+    Acl expectedFilesAcl = new Acl.Builder(expectedAcl)
+        .setPermitUsers(Collections.<UserPrincipal>emptySet()).build();
+    Map<String, Acl> expectedResources = ImmutableMap.of(
+        "allFoldersAcl", expectedAcl,
+        "allFilesAcl", expectedFilesAcl,
+        "childFoldersAcl", expectedAcl,
+        "childFilesAcl", expectedFilesAcl);
+    testGetDocContentAcls(rootPath, expectedAcl, expectedResources);
+  }
+
+  @Test
+  public void testGetDocContentDefaultDirectoryAcls() throws Exception {
+    String name = "subdir";
+    root.addChildren(new MockFile(name, true));
+    Acl expectedAcl = new Acl.Builder().setEverythingCaseInsensitive()
+        .setInheritanceType(InheritanceType.CHILD_OVERRIDES)
+        .setInheritFrom(rootDocId, "childFoldersAcl").build();
+    Acl expectedFoldersAcl = new Acl.Builder(expectedAcl)
+        .setInheritFrom(rootDocId, "allFoldersAcl").build();
+    Acl expectedFilesAcl = new Acl.Builder(expectedAcl)
+        .setInheritFrom(rootDocId, "allFilesAcl").build();
+    Map<String, Acl> expectedResources = ImmutableMap.of(
+        "allFoldersAcl", expectedFoldersAcl,
+        "allFilesAcl", expectedFilesAcl,
+        "childFoldersAcl", expectedFoldersAcl,
+        "childFilesAcl", expectedFilesAcl);
+    testGetDocContentAcls(getPath(name), expectedAcl, expectedResources);
+  }
+
+  @Test
+  public void testGetDocContentNoInheritDirectoryAcls() throws Exception {
+    String name = "subdir";
+    AclFileAttributeView orphanAclView = new AclView(user("Annie").type(ALLOW)
+        .perms(GENERIC_READ).flags(FILE_INHERIT, DIRECTORY_INHERIT));
+    root.addChildren(new MockFile(name, true).setAclView(orphanAclView)
+        .setInheritedAclView(MockFile.EMPTY_ACLVIEW));
+    Acl expectedAcl = new Acl.Builder().setEverythingCaseInsensitive()
+        .setPermitUsers(Collections.singleton(new UserPrincipal("Annie")))
+        .setInheritanceType(InheritanceType.CHILD_OVERRIDES)
+        .setInheritFrom(shareAclDocId).build();
+    Map<String, Acl> expectedResources = ImmutableMap.of(
+        "allFoldersAcl", expectedAcl,
+        "allFilesAcl", expectedAcl,
+        "childFoldersAcl", expectedAcl,
+        "childFilesAcl", expectedAcl);
+    testGetDocContentAcls(getPath(name), expectedAcl, expectedResources);
+  }
+
+  @Test
+  public void testGetDocContentInheritOnlyDirectoryAcls() throws Exception {
+    String name = "subdir";
+    AclFileAttributeView inheritOnlyAclView = new AclView(
+        user("Longfellow Deeds").type(ALLOW).perms(GENERIC_READ)
+            .flags(FILE_INHERIT, DIRECTORY_INHERIT, INHERIT_ONLY),
+        group("Administrators").type(ALLOW).perms(GENERIC_ALL)
+            .flags(FILE_INHERIT, DIRECTORY_INHERIT));
+    root.addChildren(new MockFile(name, true).setAclView(inheritOnlyAclView));
+
+    // The root ACL should only include Administrators, not Mr. Deeds.
+    Acl expectedAcl = new Acl.Builder().setEverythingCaseInsensitive()
+        .setPermitGroups(Collections.singleton(
+            new GroupPrincipal("Administrators")))
+        .setInheritanceType(InheritanceType.CHILD_OVERRIDES)
+        .setInheritFrom(rootDocId, "childFoldersAcl").build();
+    // But the childrens' inherited ACLs should include Mr. Deeds
+    Acl expectedFoldersAcl = new Acl.Builder(expectedAcl)
+        .setPermitUsers(Collections.singleton(
+            new UserPrincipal("Longfellow Deeds")))
+        .setInheritFrom(rootDocId, "allFoldersAcl").build();
+    Acl expectedFilesAcl = new Acl.Builder(expectedFoldersAcl)
+        .setInheritFrom(rootDocId, "allFilesAcl").build();
+    Map<String, Acl> expectedResources = ImmutableMap.of(
+        "allFoldersAcl", expectedFoldersAcl,
+        "allFilesAcl", expectedFilesAcl,
+        "childFoldersAcl", expectedFoldersAcl,
+        "childFilesAcl", expectedFilesAcl);
+    testGetDocContentAcls(getPath(name), expectedAcl, expectedResources);
+  }
+
+  @Test
+  public void testGetDocContentNoPropagateDirectoryAcls() throws Exception {
+    String name = "subdir";
+    AclFileAttributeView noPropagateAclView = new AclView(
+        user("Barren von Dink").type(ALLOW).perms(GENERIC_READ)
+            .flags(FILE_INHERIT, DIRECTORY_INHERIT, NO_PROPAGATE_INHERIT),
+        group("Administrators").type(ALLOW).perms(GENERIC_ALL)
+            .flags(FILE_INHERIT, DIRECTORY_INHERIT));
+    root.addChildren(new MockFile(name, true).setAclView(noPropagateAclView));
+
+    // The root ACL should include both Administrators and the Barren.
+    Acl expectedAcl = new Acl.Builder().setEverythingCaseInsensitive()
+        .setPermitUsers(Collections.singleton(
+            new UserPrincipal("Barren von Dink")))
+        .setPermitGroups(Collections.singleton(
+            new GroupPrincipal("Administrators")))
+        .setInheritanceType(InheritanceType.CHILD_OVERRIDES)
+        .setInheritFrom(rootDocId, "childFoldersAcl").build();
+    // The direct childrens' inherited ACLs should include both the
+    // Administrators and the Barren, but grandchildren should not
+    // inherit the Barren's NO_PROPAGATE permission.
+    Acl expectedNonChildAcl = new Acl.Builder(expectedAcl)
+        .setPermitUsers(Collections.<UserPrincipal>emptySet()).build();
+    Map<String, Acl> expectedResources = ImmutableMap.of(
+        "allFoldersAcl", new Acl.Builder(expectedNonChildAcl)
+            .setInheritFrom(rootDocId, "allFoldersAcl").build(),
+        "allFilesAcl", new Acl.Builder(expectedNonChildAcl)
+            .setInheritFrom(rootDocId, "allFilesAcl").build(),
+        "childFoldersAcl", new Acl.Builder(expectedAcl)
+            .setInheritFrom(rootDocId, "allFoldersAcl").build(),
+        "childFilesAcl", new Acl.Builder(expectedAcl)
+            .setInheritFrom(rootDocId, "allFilesAcl").build());
+    testGetDocContentAcls(getPath(name), expectedAcl, expectedResources);
+  }
+
+  @Test
+  public void testGetDocContentFilesOnlyDirectoryAcls() throws Exception {
+    String name = "subdir";
+    AclFileAttributeView filesOnlyAclView = new AclView(
+        user("For Your Files Only").type(ALLOW).perms(GENERIC_READ)
+            .flags(FILE_INHERIT),
+        group("Administrators").type(ALLOW).perms(GENERIC_ALL)
+            .flags(FILE_INHERIT, DIRECTORY_INHERIT));
+    root.addChildren(new MockFile(name, true).setAclView(filesOnlyAclView));
+
+    Acl expectedAcl = new Acl.Builder().setEverythingCaseInsensitive()
+        .setPermitUsers(Collections.singleton(
+            new UserPrincipal("For Your Files Only")))
+        .setPermitGroups(Collections.singleton(
+            new GroupPrincipal("Administrators")))
+        .setInheritanceType(InheritanceType.CHILD_OVERRIDES)
+        .setInheritFrom(rootDocId, "childFoldersAcl").build();
+    // Folders shouldn't include the file-only permissions.
+    Acl expectedFolderAcl = new Acl.Builder(expectedAcl)
+        .setPermitUsers(Collections.<UserPrincipal>emptySet()).build();
+    Map<String, Acl> expectedResources = ImmutableMap.of(
+        "allFoldersAcl", new Acl.Builder(expectedFolderAcl)
+            .setInheritFrom(rootDocId, "allFoldersAcl").build(),
+        "allFilesAcl", new Acl.Builder(expectedAcl)
+            .setInheritFrom(rootDocId, "allFilesAcl").build(),
+        "childFoldersAcl", new Acl.Builder(expectedFolderAcl)
+            .setInheritFrom(rootDocId, "allFoldersAcl").build(),
+        "childFilesAcl", new Acl.Builder(expectedAcl)
+            .setInheritFrom(rootDocId, "allFilesAcl").build());
+    testGetDocContentAcls(getPath(name), expectedAcl, expectedResources);
+  }
+
+  @Test
+  public void testGetDocContentFoldersOnlyDirectoryAcls() throws Exception {
+    String name = "subdir";
+    AclFileAttributeView foldersOnlyAclView = new AclView(
+        user("Fluff 'n Folder").type(ALLOW).perms(GENERIC_READ)
+            .flags(DIRECTORY_INHERIT),
+        group("Administrators").type(ALLOW).perms(GENERIC_ALL)
+            .flags(FILE_INHERIT, DIRECTORY_INHERIT));
+    root.addChildren(new MockFile(name, true).setAclView(foldersOnlyAclView));
+
+    Acl expectedAcl = new Acl.Builder().setEverythingCaseInsensitive()
+        .setPermitUsers(Collections.singleton(
+            new UserPrincipal("Fluff 'n Folder")))
+        .setPermitGroups(Collections.singleton(
+            new GroupPrincipal("Administrators")))
+        .setInheritanceType(InheritanceType.CHILD_OVERRIDES)
+        .setInheritFrom(rootDocId, "childFoldersAcl").build();
+    // Files shouldn't include the folder-only permissions.
+    Acl expectedFilesAcl = new Acl.Builder(expectedAcl)
+        .setPermitUsers(Collections.<UserPrincipal>emptySet()).build();
+    Map<String, Acl> expectedResources = ImmutableMap.of(
+        "allFoldersAcl", new Acl.Builder(expectedAcl)
+            .setInheritFrom(rootDocId, "allFoldersAcl").build(),
+        "allFilesAcl", new Acl.Builder(expectedFilesAcl)
+            .setInheritFrom(rootDocId, "allFilesAcl").build(),
+        "childFoldersAcl", new Acl.Builder(expectedAcl)
+            .setInheritFrom(rootDocId, "allFoldersAcl").build(),
+        "childFilesAcl", new Acl.Builder(expectedFilesAcl)
+            .setInheritFrom(rootDocId, "allFilesAcl").build());
+    testGetDocContentAcls(getPath(name), expectedAcl, expectedResources);
+  }
+
+  private void testGetDocContentAcls(Path path, Acl expectedAcl,
+      Map<String, Acl> expectedAclResources) throws Exception {
+    adaptor.init(context);
+    MockRequest request = new MockRequest(delegate.newDocId(path));
+    MockResponse response = new MockResponse();
+    adaptor.getDocContent(request, response);
+    assertEquals(expectedAcl, response.acl);
+    assertEquals(expectedAclResources, response.namedResources);
+  }
+
+  @Test
+  public void testMonitorZeroFeedSize() throws Exception {
+    config.overrideKey("feed.maxUrls", "0");
+    thrown.expect(IllegalArgumentException.class);
+    adaptor.init(context);
+  }
+
+  @Test
+  public void testMonitorZeroLatency() throws Exception {
+    config.overrideKey("adaptor.incrementalPollPeriodSecs", "0");
+    adaptor.init(context);
+  }
+
+
+  @Test
+  public void testMonitorSubZeroLatency() throws Exception {
+    config.overrideKey("adaptor.incrementalPollPeriodSecs", "-1");
+    thrown.expect(IllegalArgumentException.class);
+    adaptor.init(context);
+  }
+
+  @Test
+  public void testMonitorUnsupportedPath() throws Exception {
+    root.addChildren(new MockFile("unsuppored").setIsRegularFile(false));
+    adaptor.init(context);
+    BlockingQueue<Path> queue = adaptor.getFsMonitorQueue();
+    queue.add(getPath("unsupported"));
+    Thread.sleep(100L);  // Allow FsMonitor to drain the queue.
+    // Verify it has been processed, but not been fed.
+    assertEquals(0, queue.size());
+    assertEquals(0, pusher.getRecords().size());
+    assertEquals(0, pusher.getNamedResources().size());
+  }
+
+  @Test
+  public void testMonitorOneFile() throws Exception {
+    String name = "test";
+    root.addChildren(new MockFile(name));
+    adaptor.init(context);
+    testMonitor(name);
+  }
+
+  @Test
+  public void testMonitorOneDirectory() throws Exception {
+    String name = "test.dir";
+    root.addChildren(new MockFile(name, true));
+    adaptor.init(context);
+    testMonitor(name);
+  }
+
+  @Test
+  public void testMonitorMultipleItems() throws Exception {
+    String dirname = "subdir";
+    String fname = "test.txt";
+    root.addChildren(new MockFile(dirname, true), new MockFile(fname));
+    adaptor.init(context);
+    testMonitor(dirname, fname);
+  }
+
+  @Test
+  public void testMonitorMultipleBatches() throws Exception {
+    String dirname = "subdir";
+    String fname = "test.txt";
+    root.addChildren(new MockFile(dirname, true), new MockFile(fname));
+    adaptor.init(context);
+    testMonitor(dirname);
+    // Make sure the previous batch does not get fed again.
+    pusher.reset();
+    testMonitor(fname);
+  }
+
+  private void testMonitor(String... names) throws Exception {
+    BlockingQueue<Path> queue = adaptor.getFsMonitorQueue();
+    for (String name : names) {
+      queue.add(getPath(name));
+    }
+    Thread.sleep(100L); // Allow FsMonitor to drain the queue.
+    assertEquals(0, queue.size());
+    assertEquals(0, pusher.getNamedResources().size());
+    Set<Record> expected = Sets.newHashSet();
+    for (String name : names) {
+      expected.add(new Record.Builder(getDocId(name))
+                   .setCrawlImmediately(true).build());
+    }
+    assertEquals(expected, Sets.newHashSet(pusher.getRecords()));
   }
 
   @Test
   public void testIncrementalShareAcls() throws Exception {
-    FsAdaptor adaptor = new FsAdaptor();
-    AccumulatingDocIdPusher pusher = new AccumulatingDocIdPusher();
+    adaptor.init(context);
+
+    AclFileAttributeView aclView = new AclView(
+        user("joe").type(ALLOW).perms(GENERIC_READ)
+        .flags(FILE_INHERIT, DIRECTORY_INHERIT));
+    Acl acl =
+        newBuilder(aclView).getAcl().setInheritanceType(
+        InheritanceType.AND_BOTH_PERMIT).build();
+    root.setShareAclView(aclView);
+
     adaptor.getDocIds(pusher);
+    List<Map<DocId, Acl>> namedResources = pusher.getNamedResources();
+    assertEquals(1, namedResources.size());
+    assertEquals(acl, namedResources.get(0).get(shareAclDocId));
+
+    // Clear the pusher and call getModifiedDocIds. Nothing should be
+    // pushed since the share Acl has not changed.
+    pusher.reset();
+    adaptor.getModifiedDocIds(pusher);
+    namedResources = pusher.getNamedResources();
+    assertEquals(0, namedResources.size());
+
+    // Change the share Acl and confirm that that the share Acl is pushed.
+    aclView = new AclView(user("mary").type(ALLOW).perms(GENERIC_READ)
+        .flags(FILE_INHERIT, DIRECTORY_INHERIT));
+    acl = newBuilder(aclView).getAcl().setInheritanceType(
+        InheritanceType.AND_BOTH_PERMIT).build();
+    root.setShareAclView(aclView);
 
     adaptor.getModifiedDocIds(pusher);
-    assertEquals("share", adaptor.getPathName(Paths.get("\\\\host/share/")));
-    assertEquals("folder2", 
-        adaptor.getPathName(Paths.get("C:/folder1/folder2/")));
+    namedResources = pusher.getNamedResources();
+    assertEquals(1, namedResources.size());
+    assertEquals(acl, namedResources.get(0).get(shareAclDocId));
+  }
+
+  /** Returns an AclBuilder for the AclFileAttributeView. */
+  private AclBuilder newBuilder(AclFileAttributeView aclView) {
+    return new AclBuilder(Paths.get("foo", "bar"),
+        aclView, windowsAccounts, builtinPrefix, namespace);
   }
 }
diff --git a/test/com/google/enterprise/adaptor/fs/MockAdaptorContext.java b/test/com/google/enterprise/adaptor/fs/MockAdaptorContext.java
new file mode 100644
index 0000000..5749306
--- /dev/null
+++ b/test/com/google/enterprise/adaptor/fs/MockAdaptorContext.java
@@ -0,0 +1,110 @@
+// Copyright 2014 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 com.google.enterprise.adaptor.fs;
+
+import com.google.enterprise.adaptor.AdaptorContext;
+import com.google.enterprise.adaptor.AuthnAuthority;
+import com.google.enterprise.adaptor.AuthzAuthority;
+import com.google.enterprise.adaptor.Config;
+import com.google.enterprise.adaptor.DocIdEncoder;
+import com.google.enterprise.adaptor.DocIdPusher;
+import com.google.enterprise.adaptor.ExceptionHandler;
+import com.google.enterprise.adaptor.PollingIncrementalLister;
+import com.google.enterprise.adaptor.SensitiveValueDecoder;
+import com.google.enterprise.adaptor.Session;
+import com.google.enterprise.adaptor.StatusSource;
+
+import com.sun.net.httpserver.HttpContext;
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+
+/**
+ * Mock of {@link AdaptorContext}.
+ */
+class MockAdaptorContext implements AdaptorContext {
+  private final Config config = new Config();
+  private final DocIdPusher docIdPusher = new AccumulatingDocIdPusher();
+  private final DocIdEncoder docIdEncoder = new MockDocIdCodec();
+
+  @Override
+  public Config getConfig() {
+    return config;
+  }
+
+  @Override
+  public DocIdPusher getDocIdPusher() {
+    return docIdPusher;
+  }
+
+  @Override
+  public DocIdEncoder getDocIdEncoder() {
+    return docIdEncoder;
+  }
+
+  @Override
+  public void addStatusSource(StatusSource source) {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public void setGetDocIdsFullErrorHandler(ExceptionHandler handler) {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public ExceptionHandler getGetDocIdsFullErrorHandler() {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public void setGetDocIdsIncrementalErrorHandler(
+      ExceptionHandler handler) {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public ExceptionHandler getGetDocIdsIncrementalErrorHandler() {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public SensitiveValueDecoder getSensitiveValueDecoder() {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public HttpContext createHttpContext(String path, HttpHandler handler) {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public Session getUserSession(HttpExchange ex, boolean create) {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public void setPollingIncrementalLister(PollingIncrementalLister lister) {
+  }
+
+  @Override
+  public void setAuthnAuthority(AuthnAuthority authnAuthority) {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public void setAuthzAuthority(AuthzAuthority authzAuthority) {
+    throw new UnsupportedOperationException();
+  }
+}
diff --git a/test/com/google/enterprise/adaptor/fs/MockDocIdCodec.java b/test/com/google/enterprise/adaptor/fs/MockDocIdCodec.java
new file mode 100644
index 0000000..e669083
--- /dev/null
+++ b/test/com/google/enterprise/adaptor/fs/MockDocIdCodec.java
@@ -0,0 +1,37 @@
+// Copyright 2011 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 com.google.enterprise.adaptor.fs;
+
+import com.google.enterprise.adaptor.DocId;
+import com.google.enterprise.adaptor.DocIdEncoder;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+/**
+ * Mock of {@link DocIdCodec}.
+ */
+class MockDocIdCodec implements DocIdEncoder {
+  @Override
+  public URI encodeDocId(DocId docId) {
+    try {
+      String id = docId.getUniqueId();
+      return new URI("http", "localhost",
+          id.startsWith("/") ? id : "/" + id, null);
+    } catch (URISyntaxException ex) {
+      throw new AssertionError();
+    }
+  }
+}
diff --git a/test/com/google/enterprise/adaptor/fs/MockFile.java b/test/com/google/enterprise/adaptor/fs/MockFile.java
new file mode 100644
index 0000000..eb97926
--- /dev/null
+++ b/test/com/google/enterprise/adaptor/fs/MockFile.java
@@ -0,0 +1,399 @@
+// Copyright 2009 Google Inc.
+//
+// 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 com.google.enterprise.adaptor.fs;
+
+import static com.google.enterprise.adaptor.fs.AclView.user;
+import static com.google.enterprise.adaptor.fs.AclView.group;
+
+import static java.nio.file.attribute.AclEntryFlag.*;
+import static java.nio.file.attribute.AclEntryPermission.*;
+import static java.nio.file.attribute.AclEntryType.*;
+
+import com.google.common.base.Charsets;
+import com.google.common.base.Preconditions;
+
+import java.io.ByteArrayInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.attribute.AclFileAttributeView;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.nio.file.attribute.FileTime;
+import java.nio.file.DirectoryStream;
+import java.nio.file.NotDirectoryException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+class MockFile {
+  static final String SEPARATOR = "/";
+  static final FileTime DEFAULT_FILETIME = FileTime.fromMillis(10000);
+  static final AclFileAttributeView FULL_ACCESS_ACLVIEW =
+      new AclView(group("Everyone").type(ALLOW)
+          .perms(READ_DATA, READ_ATTRIBUTES, READ_NAMED_ATTRS, READ_ACL)
+          .flags(FILE_INHERIT, DIRECTORY_INHERIT));
+  static final AclFileAttributeView EMPTY_ACLVIEW = new AclView();
+
+  private MockFile parent;
+  private String name;
+  private boolean isHidden = false;
+  private boolean isRegularFile;
+  private boolean isDirectory;
+  private List<MockFile> directoryContents;
+  private Path dfsUncActiveStorageUnc;
+  private AclFileAttributeView dfsShareAclView;
+  private AclFileAttributeView shareAclView;
+  private AclFileAttributeView aclView;
+  private AclFileAttributeView inheritedAclView;
+  private FileTime creationTime = DEFAULT_FILETIME;
+  private FileTime lastModifiedTime = DEFAULT_FILETIME;
+  private FileTime lastAccessTime = DEFAULT_FILETIME;
+  private String contentType;
+  private byte[] fileContents;
+
+  /**
+   * Create a regular file with the specified {@code name}.
+   *
+   * @param name the name of the file
+   */
+  MockFile(String name) {
+    this(name, false);
+  }
+
+  /**
+   * Create a file or directory with the specified {@code name}.
+   *
+   * @param name the name of the file or directory
+   * @param isDirectory true if this is a directory, false if regular file
+   */
+  MockFile(String name, boolean isDirectory) {
+    Preconditions.checkNotNull(name, "name cannot be null");
+    this.name = name;
+    this.isRegularFile = !isDirectory;
+    this.isDirectory = isDirectory;
+    if (isDirectory) {
+      directoryContents = new ArrayList<MockFile>();
+    } else {
+      setFileContents("Contents of " + name);
+    }
+  }
+
+  /**
+   * Add the supplied files/directories as children of this MockFile.
+   * This automatically sets isDirectory and resets isRegularFile on this
+   * MockFile, and registers this file as the parent of all the children.
+   */
+  MockFile addChildren(MockFile... children) {
+    Preconditions.checkState(isDirectory, "not a directory %s", getPath());
+    for (MockFile child : children) {
+      child.parent = this;
+      directoryContents.add(child);
+    }
+    return this;
+  }
+
+  /**
+   * Returns the child of the given name.
+   */
+  MockFile getChild(String name) throws FileNotFoundException {
+    Preconditions.checkNotNull(name, "name cannot be null");
+    Preconditions.checkState(isDirectory, "not a directory %s", getPath());
+    Iterator<MockFile> it = directoryContents.iterator();
+    while (it.hasNext()) {
+      MockFile f = it.next();
+      if (f.name.equals(name)) {
+        return f;
+      }
+    }
+    throw new FileNotFoundException(
+        "no such file: " + getPath() + SEPARATOR + name);
+  }
+
+  /**
+   * Return the path to this file or directory.
+   */
+  String getPath() {
+    if (parent == null) {
+      return name;
+    } else {
+      String parentPath = parent.getPath();
+      return (parentPath.endsWith(SEPARATOR))
+             ? parentPath + name : parentPath + SEPARATOR + name;
+    }
+  }
+
+  MockFile setName(String name) {
+    Preconditions.checkNotNull(name, "name cannot be null");
+    this.name = name;
+    return this;
+  }
+
+  /**
+   * Return the name to this file or directory.
+   */
+  String getName() {
+    return name;
+  }
+
+  /**
+   * Return the parent directory of this file or directory,
+   * or null if there is no parent.
+   */
+  MockFile getParent() {
+    return parent;
+  }
+
+  boolean isDirectory() throws IOException {
+    return isDirectory;
+  }
+
+  /** If false, maybe a directory, pipe, device, broken link, hidden, etc. */
+  MockFile setIsRegularFile(boolean isRegularFile) {
+    this.isRegularFile = isRegularFile;
+    return this;
+  }
+
+  boolean isRegularFile() throws IOException {
+    return isRegularFile;
+  }
+
+  MockFile setIsHidden(boolean isHidden) {
+    this.isHidden = isHidden;
+    return this;
+  }
+
+  boolean isHidden() throws IOException {
+    return isHidden;
+  }
+
+  MockFile setCreationTime(FileTime creationTime) {
+    Preconditions.checkNotNull(creationTime, "time cannot be null");
+    this.creationTime = creationTime;
+    return this;
+  }
+
+  FileTime getCreationTime() throws IOException {
+    return creationTime;
+  }
+
+  MockFile setLastModifiedTime(FileTime lastModifiedTime) {
+    Preconditions.checkNotNull(lastModifiedTime, "time cannot be null");
+    this.lastModifiedTime = lastModifiedTime;
+    return this;
+  }
+
+  FileTime getLastModifiedTime() throws IOException {
+    return lastModifiedTime;
+  }
+
+  /** Note that the adaptor calls this setter. */
+  MockFile setLastAccessTime(FileTime lastAccessTime) throws IOException {
+    Preconditions.checkNotNull(lastAccessTime, "time cannot be null");
+    this.lastAccessTime = lastAccessTime;
+    return this;
+  }
+
+  FileTime getLastAccessTime() throws IOException {
+    return lastAccessTime;
+  }
+
+  BasicFileAttributes readBasicAttributes() throws IOException {
+    return new MockBasicFileAttributes();
+  }
+
+  MockFile setDfsUncActiveStorageUnc(Path unc) {
+    this.dfsUncActiveStorageUnc = unc;
+    return this;
+  }
+
+  Path getDfsUncActiveStorageUnc() throws IOException {
+    return dfsUncActiveStorageUnc;
+  }
+
+  MockFile setDfsShareAclView(AclFileAttributeView aclView) {
+    this.dfsShareAclView = aclView;
+    return this;
+  }
+
+  AclFileAttributeView getDfsShareAclView() throws IOException {
+    return dfsShareAclView;
+  }
+
+  MockFile setShareAclView(AclFileAttributeView aclView) {
+    this.shareAclView = aclView;
+    return this;
+  }
+
+  AclFileAttributeView getShareAclView() throws IOException {
+    return (shareAclView == null) ? FULL_ACCESS_ACLVIEW : shareAclView;
+  }
+
+  MockFile setAclView(AclFileAttributeView aclView) {
+    this.aclView = aclView;
+    return this;
+  }
+
+  AclFileAttributeView getAclView() throws IOException {
+    if (aclView == null) {
+      return (parent == null) ? FULL_ACCESS_ACLVIEW : EMPTY_ACLVIEW;
+    } else {
+      return aclView;
+    }
+  }
+
+  MockFile setInheritedAclView(AclFileAttributeView aclView) {
+    this.inheritedAclView = aclView;
+    return this;
+  }
+
+  AclFileAttributeView getInheritedAclView() throws IOException {
+    if (inheritedAclView == null) {
+      if (parent == null) {
+        // root has no inherited ACL
+        return EMPTY_ACLVIEW;
+      } else if (parent.parent == null) {
+        // root's children inherit its ACL
+        return parent.getAclView();
+      } else {
+        // all other children inherit from their parent
+        return parent.getInheritedAclView();
+      }
+    } else {
+      return inheritedAclView;
+    }
+  }
+
+  MockFile setContentType(String contentType) {
+    this.contentType = contentType;
+    return this;
+  }
+
+  String getContentType() throws IOException {
+    return isRegularFile ? contentType : null;
+  }
+
+  MockFile setFileContents(String fileContents) {
+    Preconditions.checkNotNull(fileContents, "fileContents cannot be null");
+    setFileContents(fileContents.getBytes(Charsets.UTF_8));
+    if (contentType == null) {
+      contentType = "text/plain";
+    }
+    return this;
+  }
+
+  MockFile setFileContents(byte[] fileContents) {
+    Preconditions.checkState(isRegularFile, "not a regular file %s", getPath());
+    Preconditions.checkNotNull(fileContents, "fileContents cannot be null");
+    this.fileContents = fileContents;
+    return this;
+  }
+
+  InputStream newInputStream() throws IOException {
+    Preconditions.checkState(isRegularFile, "not a regular file %s", getPath());
+    return new ByteArrayInputStream(fileContents);
+  }
+
+  DirectoryStream<Path> newDirectoryStream() throws IOException {
+    if (!isDirectory) {
+      throw new NotDirectoryException("not a directory " + getPath());
+    }
+    return new MockDirectoryStream(directoryContents);
+  }
+
+  @Override
+  public String toString() {
+    return getPath();
+  }
+
+  private class MockBasicFileAttributes implements BasicFileAttributes {
+
+    @Override
+    public Object fileKey() {
+      return MockFile.this;
+    }
+
+    @Override
+    public FileTime creationTime() {
+      return creationTime;
+    }
+
+    @Override
+    public FileTime lastAccessTime() {
+      return lastAccessTime;
+    }
+
+    @Override
+    public FileTime lastModifiedTime() {
+      return lastModifiedTime;
+    }
+
+    @Override
+    public boolean isDirectory() {
+      return isDirectory;
+    }
+
+    @Override
+    public boolean isRegularFile() {
+      return isRegularFile;
+    }
+
+    @Override
+    public boolean isOther() {
+      return !(isDirectory || isRegularFile);
+    }
+
+    @Override
+    public boolean isSymbolicLink() {
+      return false;
+    }
+
+    @Override
+    public long size() {
+      if (isRegularFile && fileContents != null) {
+        return fileContents.length;
+      } else {
+        return 0L;
+      }
+    }
+  }
+
+  private class MockDirectoryStream implements DirectoryStream<Path> {
+    private Iterator<Path> iterator;
+
+    MockDirectoryStream(List<MockFile> files) {
+      ArrayList<Path> paths = new ArrayList<Path>();
+      for (MockFile file : files) {
+        paths.add(Paths.get(file.getPath()));
+      }
+      Collections.sort(paths);
+      iterator = paths.iterator();
+    }
+
+    @Override
+    public Iterator<Path> iterator() {
+      Preconditions.checkState(iterator != null,
+          "multiple attempts to get iterator");
+      Iterator<Path> rtn = iterator;
+      iterator = null;
+      return rtn;
+    }
+
+    @Override
+    public void close() {}
+  }
+}
diff --git a/test/com/google/enterprise/adaptor/fs/MockFileDelegate.java b/test/com/google/enterprise/adaptor/fs/MockFileDelegate.java
new file mode 100644
index 0000000..9a4c6f8
--- /dev/null
+++ b/test/com/google/enterprise/adaptor/fs/MockFileDelegate.java
@@ -0,0 +1,178 @@
+// Copyright 2013 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 com.google.enterprise.adaptor.fs;
+
+import com.google.common.base.Preconditions;
+import com.google.enterprise.adaptor.DocId;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.attribute.AclFileAttributeView;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.nio.file.attribute.FileTime;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.concurrent.BlockingQueue;
+import java.util.Iterator;
+
+class MockFileDelegate implements FileDelegate {
+
+  private final MockFile root;
+
+  MockFileDelegate(MockFile root) {
+    Preconditions.checkNotNull(root, "root cannot be null");
+    this.root = root;
+  }
+
+  /**
+   * Returns the {@link MockFile} identified by the supplied {@link Path}.
+   * @throws FileNotFoundException if the file is not found.
+   */
+  MockFile getFile(Path doc) throws FileNotFoundException {
+    Preconditions.checkNotNull(doc, "doc cannot be null");
+    MockFile file = root;
+    Iterator<Path> iter = doc.iterator();
+    if (doc.getRoot() != null) {
+      // Using startsWith because Path adds a trailing backslash to
+      // UNC roots.  The second check accounts for Windows Path
+      // implementation flipping slashes on Unix paths.
+      if (!(doc.getRoot().toString().startsWith(root.getPath()) ||
+          root.getPath().equals(doc.getRoot().toString().replace('\\', '/')))) {
+        throw new FileNotFoundException("not found: " + doc.toString());
+      }
+    } else if (iter.hasNext()) {
+      if (!(root.getPath().equals(iter.next().toString()))) {
+        throw new FileNotFoundException("not found: " + doc.toString());
+      }
+    }
+    while (iter.hasNext()) {
+      file = file.getChild(iter.next().toString());
+    }
+    return file;
+  }
+
+  @Override
+  public Path getPath(String pathname) throws IOException {
+    Preconditions.checkNotNull(pathname, "pathname cannot be null");
+    return Paths.get(pathname);
+  }
+
+  @Override
+  public boolean isDirectory(Path doc) throws IOException {
+    try {
+      return getFile(doc).isDirectory();
+    } catch (FileNotFoundException e) {
+      return false;
+    }
+  }
+
+  @Override
+  public boolean isRegularFile(Path doc) throws IOException {
+    try {
+      return getFile(doc).isRegularFile();
+    } catch (FileNotFoundException e) {
+      return false;
+    }
+  }
+
+  @Override
+  public boolean isHidden(Path doc) throws IOException {
+    try {
+      return getFile(doc).isHidden();
+    } catch (FileNotFoundException e) {
+      return false;
+    }
+  }
+
+  @Override
+  public BasicFileAttributes readBasicAttributes(Path doc) throws IOException {
+    return getFile(doc).readBasicAttributes();
+  }
+
+  @Override
+  public void setLastAccessTime(Path doc, FileTime time) throws IOException {
+    getFile(doc).setLastAccessTime(time);
+  }
+
+  @Override
+  public String probeContentType(Path doc) throws IOException {
+    return getFile(doc).getContentType();
+  }
+
+  @Override
+  public InputStream newInputStream(Path doc) throws IOException {
+    return getFile(doc).newInputStream();
+  }
+
+  @Override
+  public DirectoryStream<Path> newDirectoryStream(Path doc) throws IOException {
+    return getFile(doc).newDirectoryStream();
+  }
+
+  @Override
+  public DocId newDocId(Path doc) throws IOException {
+    String id = doc.toString().replace('\\', '/');
+    if (isDirectory(doc) && !id.endsWith("/")) {
+      id += "/";
+    }
+    if (id.startsWith("//")) {
+      // String.replaceFirst uses regular expression string and replacement
+      // so they need to be escaped appropriately. The above String.replace
+      // does NOT use expressions so regex escaping is not needed.
+      id = id.replaceFirst("//", "\\\\\\\\");
+    }
+    return new DocId(id);
+  }
+
+  @Override
+  public AclFileAttributeViews getAclViews(Path doc) throws IOException {
+    MockFile file = getFile(doc);
+    return new AclFileAttributeViews(file.getAclView(),
+                                     file.getInheritedAclView());
+  }
+
+  @Override
+  public AclFileAttributeView getShareAclView(Path doc) throws IOException {
+    return root.getShareAclView();
+  }
+
+  @Override
+  public AclFileAttributeView getDfsShareAclView(Path doc) throws IOException {
+    return root.getDfsShareAclView();
+  }
+
+  @Override
+  public Path getDfsUncActiveStorageUnc(Path doc) throws IOException {
+    return root.getDfsUncActiveStorageUnc();
+  }
+
+  @Override
+  public void startMonitorPath(Path watchPath, BlockingQueue<Path> queue)
+    throws IOException {
+    // TODO (bmj): implementation
+  }
+
+  @Override
+  public void stopMonitorPath() {
+    // TODO (bmj): implementation
+  }
+
+  @Override
+  public void destroy() {
+    stopMonitorPath();
+  }
+}
diff --git a/test/com/google/enterprise/adaptor/fs/MockFileDelegateTest.java b/test/com/google/enterprise/adaptor/fs/MockFileDelegateTest.java
new file mode 100644
index 0000000..91f85f8
--- /dev/null
+++ b/test/com/google/enterprise/adaptor/fs/MockFileDelegateTest.java
@@ -0,0 +1,222 @@
+// Copyright 2014 Google Inc.
+//
+// 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 com.google.enterprise.adaptor.fs;
+
+import static org.junit.Assert.*;
+
+import com.google.common.base.Charsets;
+import com.google.common.io.CharStreams;
+import com.google.enterprise.adaptor.DocId;
+
+import org.junit.*;
+import org.junit.rules.ExpectedException;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.nio.file.attribute.FileTime;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Iterator;
+
+/**
+ * Test cases for {@link MockFileDelegate}.
+ */
+public class MockFileDelegateTest {
+
+  @Rule
+  public ExpectedException thrown = ExpectedException.none();
+
+  @Test
+  public void testConstructorNullRoot() throws Exception {
+    thrown.expect(NullPointerException.class);
+    new MockFileDelegate(null);
+  }
+
+  @Test
+  public void testGetPathNullPathname() throws Exception {
+    thrown.expect(NullPointerException.class);
+    new MockFileDelegate(new MockFile("root", true)).getPath(null);
+  }
+
+  @Test
+  public void testGetPath() throws Exception {
+    String delim = File.separator;
+    FileDelegate delegate = new MockFileDelegate(new MockFile("root", true));
+    assertEquals("root", delegate.getPath("root").toString());
+    assertEquals("root" + delim + "foo" + delim + "bar",
+        delegate.getPath("root/foo/bar").toString());
+    assertEquals(delim + "foo" + delim + "bar" + delim + "baz",
+        delegate.getPath("/foo/bar/baz").toString());
+    assertEquals("\\\\server\\share\\dir\\file.txt",
+        delegate.getPath("\\\\server\\share\\dir\\file.txt").toString());
+  }
+
+  @Test
+  public void testGetFileNotFound() throws Exception {
+    MockFile root = new MockFile("root", true).addChildren(new MockFile("foo"));
+    MockFileDelegate delegate = new MockFileDelegate(root);
+    thrown.expect(FileNotFoundException.class);
+    delegate.getFile(delegate.getPath("root/nonExistent"));
+  }
+
+  @Test
+  public void testGetFileRelativeRoot() throws Exception {
+    testGetFile("root");
+  }
+
+  @Test
+  public void testGetFileUncRoot() throws Exception {
+    testGetFile("\\\\host\\share");
+    testGetFile("\\\\host\\share\\");
+  }
+
+  @Test
+  public void testGetFileUnixRoot() throws Exception {
+    testGetFile("/");
+  }
+
+  @Test
+  public void testGetFileDosRoot() throws Exception {
+    testGetFile("C:\\");
+  }
+
+  private void testGetFile(String rootPath) throws Exception {
+    MockFile root = new MockFile(rootPath, true).addChildren(
+        new MockFile("dir1", true).addChildren(new MockFile("foo")),
+        new MockFile("dir2", true).addChildren(new MockFile("bar")),
+        new MockFile("test.txt"));
+    MockFileDelegate delegate = new MockFileDelegate(root);
+
+    assertSame(root, delegate.getFile(delegate.getPath(rootPath)));
+    testGetFile(delegate, getPath(rootPath, "test.txt"));
+    testGetFile(delegate, getPath(rootPath, "dir1"));
+    testGetFile(delegate, getPath(rootPath, "dir2"));
+    testGetFile(delegate, getPath(rootPath, "dir1/foo"));
+    testGetFile(delegate, getPath(rootPath, "dir2/bar"));
+  }
+
+  private String getPath(String parent, String child) {
+    return (parent.endsWith("/")) ? parent + child : parent + "/" + child;
+  }
+
+  private void testGetFile(MockFileDelegate delegate, String pathname)
+      throws Exception {
+    Path path = delegate.getPath(pathname);
+    MockFile file = delegate.getFile(path);
+    assertEquals(pathname, file.getPath());
+    MockFile parent = file.getParent();
+    if (parent != null) {
+      assertSame(parent, delegate.getFile(path.getParent()));
+    }
+  }
+
+  @Test
+  public void testNewDocId() throws Exception {
+    MockFile root = new MockFile("root", true).addChildren(
+        new MockFile("dir1", true).addChildren(new MockFile("foo")));
+    FileDelegate delegate = new MockFileDelegate(root);
+    assertEquals(new DocId("root/"), getDocId(delegate, "root"));
+    assertEquals(new DocId("root/dir1/"), getDocId(delegate, "root/dir1"));
+    assertEquals(new DocId("root/dir1/foo"),
+                 getDocId(delegate, "root/dir1/foo"));
+  }
+
+  private DocId getDocId(FileDelegate delegate, String pathname)
+      throws Exception {
+    return delegate.newDocId(delegate.getPath(pathname));
+  }
+
+  @Test
+  public void testSetLastAccessTime() throws Exception {
+    MockFile root = new MockFile("root", true)
+        .addChildren(new MockFile("test.txt"));
+    FileDelegate delegate = new MockFileDelegate(root);
+    Path path = delegate.getPath("root/test.txt");
+
+    BasicFileAttributes attrs = delegate.readBasicAttributes(path);
+    assertEquals(MockFile.DEFAULT_FILETIME, attrs.lastAccessTime());
+
+    FileTime accessTime = FileTime.fromMillis(40000);
+    delegate.setLastAccessTime(path, accessTime);
+    attrs = delegate.readBasicAttributes(path);
+    assertEquals(accessTime, attrs.lastAccessTime());
+  }
+
+  /**
+   * Most of the MockDelegate methods are simple passthrough calls to the
+   * MockFile methods.  This is a sanity check to make sure I'm calling the
+   * right ones.
+   */
+  @Test
+  public void testPassthroughGetters() throws Exception {
+    FileTime createTime = FileTime.fromMillis(20000);
+    FileTime modifyTime = FileTime.fromMillis(30000);
+    FileTime accessTime = FileTime.fromMillis(40000);
+    String content = "<html><title>Hello World</title></html>";
+    MockFile root = new MockFile("root", true)
+        .addChildren(
+            new MockFile("test.html").setCreationTime(createTime)
+            .setLastModifiedTime(modifyTime).setLastAccessTime(accessTime)
+            .setFileContents(content).setContentType("text/html"));
+
+    FileDelegate delegate = new MockFileDelegate(root);
+    Path path = delegate.getPath("root");
+    assertTrue(delegate.isDirectory(path));
+    assertFalse(delegate.isRegularFile(path));
+    assertNull(delegate.getDfsUncActiveStorageUnc(path));
+    Path uncPath = delegate.getPath("\\\\server\\share");
+    root.setDfsUncActiveStorageUnc(uncPath);
+    assertEquals(uncPath, delegate.getDfsUncActiveStorageUnc(path));
+    assertNull(delegate.getDfsShareAclView(path));
+    root.setDfsShareAclView(MockFile.FULL_ACCESS_ACLVIEW);
+    assertEquals(MockFile.FULL_ACCESS_ACLVIEW,
+                 delegate.getDfsShareAclView(path));
+    AclFileAttributeViews aclViews = delegate.getAclViews(path);
+    assertNotNull(aclViews);
+    assertEquals(MockFile.FULL_ACCESS_ACLVIEW, aclViews.getDirectAclView());
+    assertEquals(MockFile.EMPTY_ACLVIEW, aclViews.getInheritedAclView());
+
+    path = delegate.getPath("root/test.html");
+    assertTrue(delegate.isRegularFile(path));
+    assertFalse(delegate.isDirectory(path));
+    assertFalse(delegate.isHidden(path));
+    assertEquals("text/html", delegate.probeContentType(path));
+    assertEquals(content, readContents(delegate, path));
+    aclViews = delegate.getAclViews(path);
+    assertNotNull(aclViews);
+    assertEquals(MockFile.EMPTY_ACLVIEW, aclViews.getDirectAclView());
+    assertEquals(MockFile.FULL_ACCESS_ACLVIEW, aclViews.getInheritedAclView());
+
+    BasicFileAttributes attrs = delegate.readBasicAttributes(path);
+    assertTrue(attrs.isRegularFile());
+    assertFalse(attrs.isDirectory());
+    assertFalse(attrs.isOther());
+    assertEquals(createTime, attrs.creationTime());
+    assertEquals(modifyTime, attrs.lastModifiedTime());
+    assertEquals(accessTime, attrs.lastAccessTime());
+    assertEquals(content.getBytes(Charsets.UTF_8).length, attrs.size());
+  }
+
+  private String readContents(FileDelegate delegate, Path path)
+      throws IOException {
+    return CharStreams.toString(
+        new InputStreamReader(delegate.newInputStream(path), Charsets.UTF_8));
+  }
+}
diff --git a/test/com/google/enterprise/adaptor/fs/MockFileTest.java b/test/com/google/enterprise/adaptor/fs/MockFileTest.java
new file mode 100644
index 0000000..c65992b
--- /dev/null
+++ b/test/com/google/enterprise/adaptor/fs/MockFileTest.java
@@ -0,0 +1,309 @@
+// Copyright 2014 Google Inc.
+//
+// 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 com.google.enterprise.adaptor.fs;
+
+import static org.junit.Assert.*;
+
+import com.google.common.base.Charsets;
+import com.google.common.io.CharStreams;
+
+import org.junit.*;
+import org.junit.rules.ExpectedException;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.nio.file.attribute.FileTime;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Iterator;
+
+/**
+ * Test cases for {@link MockFile}.
+ */
+public class MockFileTest {
+
+  private static final FileTime createTime = FileTime.fromMillis(20000);
+  private static final FileTime modifyTime = FileTime.fromMillis(30000);
+  private static final FileTime accessTime = FileTime.fromMillis(40000);
+
+  @Rule
+  public ExpectedException thrown = ExpectedException.none();
+
+  @Test
+  public void testConstructorNullName() throws Exception {
+    thrown.expect(NullPointerException.class);
+    new MockFile(null);
+  }
+
+  /** Test constructor for regular files. */
+  @Test
+  public void testFileConstructor() throws Exception {
+    MockFile f = new MockFile("test");
+    checkDefaultConfig(f, "test", false);
+    assertEquals("Contents of test", readContents(f));
+    assertEquals("text/plain", f.getContentType());
+  }
+
+  /** Test constructor for directories . */
+  @Test
+  public void testDirectoryConstructor() throws Exception {
+    MockFile f = new MockFile("test", true);
+    checkDefaultConfig(f, "test", true);
+    DirectoryStream<Path> ds = f.newDirectoryStream();
+    assertNotNull(ds);
+    assertFalse(ds.iterator().hasNext());
+    ds.close();
+  }
+
+  /**
+   * Verifies some of the default file attributes (no explicit setters called).
+   */
+  private void checkDefaultConfig(MockFile file, String name, boolean isDir)
+      throws Exception {
+    assertEquals(name, file.getName());
+    assertEquals(isDir, file.isDirectory());
+    assertEquals(!isDir, file.isRegularFile());
+    assertFalse(file.isHidden());
+    assertNull(file.getParent());
+    assertEquals(MockFile.DEFAULT_FILETIME, file.getCreationTime());
+    assertEquals(MockFile.DEFAULT_FILETIME, file.getLastModifiedTime());
+    assertEquals(MockFile.DEFAULT_FILETIME, file.getLastAccessTime());
+  }
+
+  private String readContents(MockFile file) throws IOException {
+    return CharStreams.toString(
+        new InputStreamReader(file.newInputStream(), Charsets.UTF_8));
+  }
+
+  @Test
+  public void testSetName() throws Exception {
+    assertEquals("foo", new MockFile("test").setName("foo").getName());
+  }
+
+  @Test
+  public void testSetIsRegularFile() throws Exception {
+    MockFile f = new MockFile("test").setIsRegularFile(false);
+    assertFalse(f.isRegularFile());
+    assertFalse(f.isDirectory());
+
+    f.setIsRegularFile(true);
+    assertTrue(f.isRegularFile());
+    assertFalse(f.isDirectory());
+  }
+
+  @Test
+  public void testSetIsHidden() throws Exception {
+    MockFile f = new MockFile("test");
+    assertFalse(f.isHidden());  // default is false.
+    assertTrue(f.setIsHidden(true).isHidden());
+    assertFalse(f.setIsHidden(false).isHidden());
+  }
+
+  @Test
+  public void testSetFileTimes() throws Exception {
+    MockFile f = new MockFile("test").setCreationTime(createTime)
+        .setLastModifiedTime(modifyTime).setLastAccessTime(accessTime);
+    assertEquals(createTime, f.getCreationTime());
+    assertEquals(modifyTime, f.getLastModifiedTime());
+    assertEquals(accessTime, f.getLastAccessTime());
+  }
+
+  @Test
+  public void testReadBasicAttributesRegularFile() throws Exception {
+    MockFile f = new MockFile("test").setCreationTime(createTime)
+        .setLastModifiedTime(modifyTime).setLastAccessTime(accessTime);
+
+    BasicFileAttributes bfa = f.readBasicAttributes();
+    assertNotNull(bfa);
+    assertSame(f, bfa.fileKey());
+    assertEquals(createTime, bfa.creationTime());
+    assertEquals(modifyTime, bfa.lastModifiedTime());
+    assertEquals(accessTime, bfa.lastAccessTime());
+    assertTrue(bfa.isRegularFile());
+    assertFalse(bfa.isDirectory());
+    assertFalse(bfa.isSymbolicLink());
+    assertFalse(bfa.isOther());
+    assertEquals(readContents(f).length(), bfa.size());
+  }
+
+  @Test
+  public void testReadBasicAttributesDirectory() throws Exception {
+    MockFile f = new MockFile("test", true).setCreationTime(createTime)
+        .setLastModifiedTime(modifyTime).setLastAccessTime(accessTime);
+
+    BasicFileAttributes bfa = f.readBasicAttributes();
+    assertNotNull(bfa);
+    assertSame(f, bfa.fileKey());
+    assertEquals(createTime, bfa.creationTime());
+    assertEquals(modifyTime, bfa.lastModifiedTime());
+    assertEquals(accessTime, bfa.lastAccessTime());
+    assertFalse(bfa.isRegularFile());
+    assertTrue(bfa.isDirectory());
+    assertFalse(bfa.isSymbolicLink());
+    assertFalse(bfa.isOther());
+    assertEquals(0L, bfa.size());
+  }
+
+  @Test
+  public void testReadBasicAttributesSpecialFile() throws Exception {
+    // If neither file, nor directory, then it is "special".
+    MockFile f = new MockFile("test", false).setIsRegularFile(false);
+    BasicFileAttributes bfa = f.readBasicAttributes();
+    assertFalse(bfa.isRegularFile());
+    assertFalse(bfa.isDirectory());
+    assertFalse(bfa.isSymbolicLink());
+    assertTrue(bfa.isOther());
+    assertEquals(0L, bfa.size());
+  }
+
+  @Test
+  public void testSetFileContents() throws Exception {
+    String expected = "Hello World";
+    MockFile f = new MockFile("test.txt").setFileContents(expected);
+    assertEquals(expected, readContents(f));
+  }
+
+  @Test
+  public void testSetFileContentsBytes() throws Exception {
+    String expected = "<html><title>Hello World</title></html>";
+    MockFile f = new MockFile("test.html")
+        .setFileContents(expected.getBytes(Charsets.UTF_8))
+        .setContentType("text/html");
+    assertEquals(expected, readContents(f));
+    assertEquals("text/html", f.getContentType());
+  }
+
+  @Test
+  public void testChildren() throws Exception {
+    MockFile root = new MockFile("root", true);
+    MockFile dir1 = new MockFile("dir1", true);
+    MockFile dir2 = new MockFile("dir2", true);
+    MockFile test = new MockFile("test.txt");
+    root.addChildren(test, dir1, dir2);
+    assertNull(root.getParent());
+    assertSame(root, dir1.getParent());
+    assertSame(root, dir2.getParent());
+    assertSame(root, test.getParent());
+    checkDirectoryListing(root, dir1, dir2, test);
+
+    // Test getChild().
+    assertSame(dir1, root.getChild("dir1"));
+    assertSame(dir2, root.getChild("dir2"));
+    assertSame(test, root.getChild("test.txt"));
+
+    // Add another file.
+    MockFile newer = new MockFile("newer.txt");
+    root.addChildren(newer);
+    checkDirectoryListing(root, dir1, dir2, newer, test);
+  }
+
+  private void checkDirectoryListing(MockFile parent, MockFile... children)
+      throws IOException {
+    DirectoryStream<Path> ds = parent.newDirectoryStream();
+    assertNotNull(ds);
+    Iterator<Path> iter = ds.iterator();
+    assertNotNull(iter);
+    for (MockFile child : children) {
+      assertEquals(child.getName(), iter.next().getFileName().toString());
+    }
+    assertFalse(iter.hasNext());
+    ds.close();
+  }
+
+  @Test
+  public void testGetPath() throws Exception {
+    MockFile root = new MockFile("root", true);
+    MockFile dir1 = new MockFile("dir1", true);
+    MockFile test = new MockFile("test.txt");
+    MockFile test1 = new MockFile("test.txt");
+    root.addChildren(test, dir1);
+    dir1.addChildren(test1);
+    assertEquals("root", root.getPath());
+    assertEquals("root/dir1", dir1.getPath());
+    assertEquals("root/test.txt", test.getPath());
+    assertEquals("root/dir1/test.txt", test1.getPath());
+  }
+
+  @Test
+  public void testGetChildNullName() throws Exception {
+    thrown.expect(NullPointerException.class);
+    new MockFile("root", true).getChild(null);
+  }
+
+  @Test
+  public void testGetChildNotFound() throws Exception {
+    thrown.expect(FileNotFoundException.class);
+    new MockFile("root", true).getChild("nonExistent");
+  }
+
+  @Test
+  public void testGetDfsUncActiveStorageUnc() throws Exception {
+    MockFile root = new MockFile("root", true);
+    assertNull(root.getDfsUncActiveStorageUnc());
+    Path uncPath = Paths.get("\\\\server\\share");
+    root.setDfsUncActiveStorageUnc(uncPath);
+    assertEquals(uncPath, root.getDfsUncActiveStorageUnc());
+  }
+
+  @Test
+  public void testGetDfsShareAclView() throws Exception {
+    MockFile root = new MockFile("root", true);
+    assertNull(root.getDfsShareAclView());
+    root.setDfsShareAclView(MockFile.FULL_ACCESS_ACLVIEW);
+    assertEquals(MockFile.FULL_ACCESS_ACLVIEW, root.getDfsShareAclView());
+  }
+
+  @Test
+  public void testDefaultRootAclViews() throws Exception {
+    MockFile root = new MockFile("root", true);
+    assertEquals(MockFile.FULL_ACCESS_ACLVIEW, root.getShareAclView());
+    assertEquals(MockFile.FULL_ACCESS_ACLVIEW, root.getAclView());
+    assertEquals(MockFile.EMPTY_ACLVIEW, root.getInheritedAclView());
+  }
+
+  @Test
+  public void testDefaultNonRootAclViews() throws Exception {
+    MockFile root = new MockFile("root", true);
+    MockFile dir1 = new MockFile("dir1", true);
+    MockFile foo = new MockFile("foo");
+    MockFile bar = new MockFile("bar");
+    root.addChildren(dir1, foo);
+    dir1.addChildren(bar);
+    assertEquals(MockFile.EMPTY_ACLVIEW, dir1.getAclView());
+    assertEquals(MockFile.FULL_ACCESS_ACLVIEW, dir1.getInheritedAclView());
+    assertEquals(MockFile.EMPTY_ACLVIEW, foo.getAclView());
+    assertEquals(MockFile.FULL_ACCESS_ACLVIEW, foo.getInheritedAclView());
+    assertEquals(MockFile.EMPTY_ACLVIEW, bar.getAclView());
+    assertEquals(MockFile.FULL_ACCESS_ACLVIEW, bar.getInheritedAclView());
+  }
+
+  @Test
+  public void testSetAclViews() throws Exception {
+    MockFile root = new MockFile("root", true);
+    MockFile foo = new MockFile("foo");
+    root.addChildren(foo);
+    assertEquals(MockFile.EMPTY_ACLVIEW, foo.getAclView());
+    assertEquals(MockFile.FULL_ACCESS_ACLVIEW, foo.getInheritedAclView());
+
+    foo.setAclView(MockFile.FULL_ACCESS_ACLVIEW);
+    foo.setInheritedAclView(MockFile.EMPTY_ACLVIEW);
+    assertEquals(MockFile.FULL_ACCESS_ACLVIEW, foo.getAclView());
+    assertEquals(MockFile.EMPTY_ACLVIEW, foo.getInheritedAclView());
+  }
+}
diff --git a/test/com/google/enterprise/adaptor/fs/MockRequest.java b/test/com/google/enterprise/adaptor/fs/MockRequest.java
new file mode 100644
index 0000000..850d2fa
--- /dev/null
+++ b/test/com/google/enterprise/adaptor/fs/MockRequest.java
@@ -0,0 +1,50 @@
+// Copyright 2014 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 com.google.enterprise.adaptor.fs;
+
+import com.google.enterprise.adaptor.DocId;
+import com.google.enterprise.adaptor.Request;
+
+import java.util.Date;
+
+/** A trivial implemenation of {@link Request} */
+class MockRequest implements Request {
+  private final DocId docid;
+  private final Date lastAccess;
+
+  MockRequest(DocId docid) {
+    this(docid, null);
+  }
+
+  MockRequest(DocId docid, Date lastAccess) {
+    this.docid = docid;
+    this.lastAccess = lastAccess;
+  }
+
+  @Override
+  public boolean hasChangedSinceLastAccess(Date lastModified) {
+    return lastModified.after(lastAccess);
+  }
+
+  @Override
+  public Date getLastAccessTime() {
+    return lastAccess;
+  }
+
+  @Override
+  public DocId getDocId() {
+    return docid;
+  }
+}
diff --git a/test/com/google/enterprise/adaptor/fs/MockResponse.java b/test/com/google/enterprise/adaptor/fs/MockResponse.java
new file mode 100644
index 0000000..edbbaaa
--- /dev/null
+++ b/test/com/google/enterprise/adaptor/fs/MockResponse.java
@@ -0,0 +1,124 @@
+// Copyright 2014 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 com.google.enterprise.adaptor.fs;
+
+import com.google.enterprise.adaptor.Acl;
+import com.google.enterprise.adaptor.Response;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.URI;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * An implementation of {@link Response} that implements only those items that
+ * the adaptor uses.
+ */
+class MockResponse implements Response {
+
+  boolean notModified = false;
+  boolean notFound = false;
+  String contentType;
+  Date lastModified;
+  URI displayUrl;
+  Acl acl;
+  Map<String, String> metadata = new HashMap<String, String>();
+  Map<String, Acl> namedResources = new HashMap<String, Acl>();
+  ByteArrayOutputStream content;
+
+  @Override
+  public void respondNotModified() throws IOException {
+    notModified = true;
+  }
+
+  @Override
+  public void respondNotFound() throws IOException {
+    notFound = true;
+  }
+
+  @Override
+  public OutputStream getOutputStream() throws IOException {
+    content = new ByteArrayOutputStream();
+    return content;
+  }
+
+  @Override
+  public void setContentType(String contentType) {
+    this.contentType = contentType;
+  }
+
+  @Override
+  public void setLastModified(Date lastModified) {
+    this.lastModified = lastModified;
+  }
+
+  @Override
+  public void addMetadata(String key, String value) {
+    metadata.put(key, value);
+  }
+
+  @Override
+  public void setAcl(Acl acl) {
+    this.acl = acl;
+  }
+
+  @Override
+  public void putNamedResource(String fragment, Acl acl) {
+    namedResources.put(fragment, acl);
+  }
+
+  @Override
+  public void setDisplayUrl(URI displayUrl) {
+    this.displayUrl = displayUrl;
+  }
+
+  @Override
+  public void setSecure(boolean secure) {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public void addAnchor(URI uri, String text) {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public void setNoIndex(boolean noIndex) {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public void setNoFollow(boolean noFollow) {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public void setNoArchive(boolean noArchive) {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public void setCrawlOnce(boolean crawlOnce) {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public void setLock(boolean lock) {
+    throw new UnsupportedOperationException();
+  }
+}
diff --git a/test/com/google/enterprise/adaptor/fs/NioFileDelegateTest.java b/test/com/google/enterprise/adaptor/fs/NioFileDelegateTest.java
index ae5eaa7..4db3dce 100644
--- a/test/com/google/enterprise/adaptor/fs/NioFileDelegateTest.java
+++ b/test/com/google/enterprise/adaptor/fs/NioFileDelegateTest.java
@@ -45,15 +45,16 @@
   public TemporaryFolder temp = new TemporaryFolder();
 
   private Path newTempDir(String name) throws IOException {
-    return temp.newFolder(name).toPath();
+    return temp.newFolder(name).toPath().toRealPath();
   }
 
   private Path newTempFile(String name) throws IOException {
-    return temp.newFile(name).toPath();
+    return temp.newFile(name).toPath().toRealPath();
   }
 
   private Path newTempFile(Path parent, String name) throws IOException {
-    Preconditions.checkArgument(parent.startsWith(temp.getRoot().toPath()));
+    Preconditions.checkArgument(parent.startsWith(temp.getRoot().toPath()
+        .toRealPath()));
     return Files.createFile(parent.resolve(name));
   }
 
@@ -162,7 +163,7 @@
 
   @Test
   public void testNewDocId() throws Exception {
-    Path root = temp.getRoot().toPath();
+    Path root = temp.getRoot().toPath().toRealPath();
     Path dir = newTempDir("testDir");
     Path file = newTempFile(dir, "test");
 
diff --git a/test/com/google/enterprise/adaptor/fs/UnsupportedDocIdPusher.java b/test/com/google/enterprise/adaptor/fs/UnsupportedDocIdPusher.java
new file mode 100644
index 0000000..e9b3439
--- /dev/null
+++ b/test/com/google/enterprise/adaptor/fs/UnsupportedDocIdPusher.java
@@ -0,0 +1,83 @@
+// Copyright 2013 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 com.google.enterprise.adaptor.fs;
+
+import com.google.enterprise.adaptor.Acl;
+import com.google.enterprise.adaptor.DocId;
+import com.google.enterprise.adaptor.DocIdPusher;
+import com.google.enterprise.adaptor.ExceptionHandler;
+import com.google.enterprise.adaptor.GroupPrincipal;
+import com.google.enterprise.adaptor.Principal;
+
+import java.util.Collection;
+import java.util.Map;
+
+/** Throws UnsupportedOperationException for all calls. */
+class UnsupportedDocIdPusher implements DocIdPusher {
+
+  @Override
+  public DocId pushDocIds(Iterable<DocId> docIds)
+      throws InterruptedException {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public DocId pushDocIds(Iterable<DocId> docIds,
+      ExceptionHandler handler)
+      throws InterruptedException {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public Record pushRecords(Iterable<Record> records)
+      throws InterruptedException {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public Record pushRecords(Iterable<Record> records,
+      ExceptionHandler handler)
+      throws InterruptedException {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public DocId pushNamedResources(Map<DocId, Acl> resources)
+      throws InterruptedException {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public DocId pushNamedResources(Map<DocId, Acl> resources,
+      ExceptionHandler handler)
+      throws InterruptedException {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public GroupPrincipal pushGroupDefinitions(
+      Map<GroupPrincipal, ? extends Collection<Principal>> defs,
+      boolean caseSensitive) throws InterruptedException {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public GroupPrincipal pushGroupDefinitions(
+      Map<GroupPrincipal, ? extends Collection<Principal>> defs,
+      boolean caseSensitive, ExceptionHandler handler)
+      throws InterruptedException {
+    throw new UnsupportedOperationException();
+  }
+}
diff --git a/test/com/google/enterprise/adaptor/fs/WindowsAclFileAttributeViewsTest.java b/test/com/google/enterprise/adaptor/fs/WindowsAclFileAttributeViewsTest.java
new file mode 100644
index 0000000..2b87cbe
--- /dev/null
+++ b/test/com/google/enterprise/adaptor/fs/WindowsAclFileAttributeViewsTest.java
@@ -0,0 +1,340 @@
+// Copyright 2014 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 com.google.enterprise.adaptor.fs;
+
+import static org.junit.Assert.*;
+import static org.junit.Assume.*;
+
+import org.junit.*;
+import org.junit.rules.ExpectedException;
+
+import com.sun.jna.platform.win32.Advapi32Util.Account;
+import com.sun.jna.platform.win32.Win32Exception;
+import com.sun.jna.platform.win32.WinError;
+import com.sun.jna.platform.win32.WinNT;
+import com.sun.jna.platform.win32.WinNT.SID_NAME_USE;
+
+import java.nio.file.attribute.AclEntry;
+import java.nio.file.attribute.AclEntryFlag;
+import java.nio.file.attribute.AclEntryPermission;
+import java.nio.file.attribute.AclEntryType;
+import java.nio.file.attribute.GroupPrincipal;
+import java.nio.file.attribute.UserPrincipal;
+import java.util.EnumSet;
+import java.util.Set;
+
+/** Tests for {@link WindowsAclFileAttributeViews} */
+public class WindowsAclFileAttributeViewsTest {
+
+  private final WindowsAclFileAttributeViews wafav =
+      new TestAclFileAttributeViews();
+
+  @Rule
+  public ExpectedException thrown = ExpectedException.none();
+
+  @Test
+  public void testNewAclEntryUnsupportedAccessType() throws Exception {
+    WinNT.ACCESS_ACEStructure ace = new AceBuilder()
+        .setType(WinNT.SYSTEM_AUDIT_ACE_TYPE).build();
+    assertNull(wafav.newAclEntry(ace));
+  }
+
+  @Test
+  public void testNewAclEntryUnresolvableSid() throws Exception {
+    TestHelper.assumeOsIsWindows(); // For new Win32Exception().
+    WinNT.ACCESS_ACEStructure ace = new AceBuilder()
+        .setSid(new AccountSid(null)).build();
+    assertNull(wafav.newAclEntry(ace));
+  }
+
+  @Test
+  public void testNewAclEntryUnsupportedAccountType() throws Exception {
+    WinNT.ACCESS_ACEStructure ace = new AceBuilder()
+        .setSid(new AccountSid(SID_NAME_USE.SidTypeUnknown, "", "")).build();
+    assertNull(wafav.newAclEntry(ace));
+  }
+
+  @Test
+  public void testNewAclEntryUserPrincipal() throws Exception {
+    testNewAclEntryUserPrincipal(AccountSid.user("userName", null), "userName");
+  }
+
+  @Test
+  public void testNewAclEntryUserWithDomainPrincipal() throws Exception {
+    testNewAclEntryUserPrincipal(AccountSid.user("userName", "domain"),
+                                 "domain\\userName");
+  }
+
+  private void testNewAclEntryUserPrincipal(AccountSid account,
+      String expectedName) throws Exception {
+    WinNT.ACCESS_ACEStructure ace = new AceBuilder().setSid(account).build();
+    AclEntry aclEntry = wafav.newAclEntry(ace);
+    assertNotNull(aclEntry);
+    UserPrincipal principal = aclEntry.principal();
+    assertNotNull(principal);
+    assertFalse(principal instanceof GroupPrincipal);
+    assertEquals(expectedName, principal.getName());
+  }
+
+  @Test
+  public void testNewAclEntryGroupPrincipal() throws Exception {
+    testNewAclEntryGroupPrincipal(AccountSid.group("groupName", null),
+                                  "groupName");
+  }
+
+  @Test
+  public void testNewAclEntryGroupWithDomainPrincipal() throws Exception {
+    testNewAclEntryGroupPrincipal(AccountSid.group("groupName", "domain"),
+                                 "domain\\groupName");
+  }
+
+  @Test
+  public void testNewAclEntryAliasPrincipal() throws Exception {
+    AccountSid account =
+        new AccountSid(SID_NAME_USE.SidTypeAlias, "alias", "domain");
+    testNewAclEntryGroupPrincipal(account, "domain\\alias");
+  }
+
+  @Test
+  public void testNewAclEntryWellKnownGroupPrincipal() throws Exception {
+    AccountSid account =
+        new AccountSid(SID_NAME_USE.SidTypeWellKnownGroup, "wellKnown", null);
+    testNewAclEntryGroupPrincipal(account, "wellKnown");
+  }
+
+  private void testNewAclEntryGroupPrincipal(AccountSid account,
+      String expectedName) throws Exception {
+    WinNT.ACCESS_ACEStructure ace = new AceBuilder().setSid(account).build();
+    AclEntry aclEntry = wafav.newAclEntry(ace);
+    assertNotNull(aclEntry);
+    UserPrincipal principal = aclEntry.principal();
+    assertNotNull(principal);
+    assertTrue(principal instanceof GroupPrincipal);
+    assertEquals(expectedName, principal.getName());
+  }
+
+  @Test
+  public void testNewAclEntryIndividualPermissions() throws Exception {
+    testNewAclEntryPermissions(WinNT.FILE_READ_DATA,
+                               AclEntryPermission.READ_DATA);
+    testNewAclEntryPermissions(WinNT.FILE_READ_ATTRIBUTES,
+                               AclEntryPermission.READ_ATTRIBUTES);
+    testNewAclEntryPermissions(WinNT.FILE_READ_EA,
+                               AclEntryPermission.READ_NAMED_ATTRS);
+    testNewAclEntryPermissions(WinNT.READ_CONTROL,
+                               AclEntryPermission.READ_ACL);
+    testNewAclEntryPermissions(WinNT.FILE_WRITE_DATA,
+                               AclEntryPermission.WRITE_DATA);
+    testNewAclEntryPermissions(WinNT.FILE_APPEND_DATA,
+                               AclEntryPermission.APPEND_DATA);
+    testNewAclEntryPermissions(WinNT.FILE_WRITE_ATTRIBUTES,
+                               AclEntryPermission.WRITE_ATTRIBUTES);
+    testNewAclEntryPermissions(WinNT.FILE_WRITE_EA,
+                               AclEntryPermission.WRITE_NAMED_ATTRS);
+    testNewAclEntryPermissions(WinNT.WRITE_DAC,
+                               AclEntryPermission.WRITE_ACL);
+    testNewAclEntryPermissions(WinNT.WRITE_OWNER,
+                               AclEntryPermission.WRITE_OWNER);
+    testNewAclEntryPermissions(WinNT.DELETE,
+                               AclEntryPermission.DELETE);
+    testNewAclEntryPermissions(WinNT.FILE_DELETE_CHILD,
+                               AclEntryPermission.DELETE_CHILD);
+    testNewAclEntryPermissions(WinNT.SYNCHRONIZE,
+                               AclEntryPermission.SYNCHRONIZE);
+    testNewAclEntryPermissions(WinNT.FILE_EXECUTE,
+                               AclEntryPermission.EXECUTE);
+  }
+
+  @Test
+  public void testNewAclEntryFullPermissions() throws Exception {
+    testNewAclEntryPermissions(WinNT.FILE_ALL_ACCESS,
+                               AclEntryPermission.values());
+
+  }
+
+  @Test
+  public void testNewAclEntryGenericPermissions() throws Exception {
+    testNewAclEntryPermissions(WinNT.GENERIC_READ, AclEntryPermission.READ_DATA,
+        AclEntryPermission.READ_ATTRIBUTES, AclEntryPermission.READ_NAMED_ATTRS,
+        AclEntryPermission.READ_ACL, AclEntryPermission.SYNCHRONIZE);
+    testNewAclEntryPermissions(WinNT.GENERIC_WRITE,
+        AclEntryPermission.WRITE_DATA, AclEntryPermission.APPEND_DATA,
+        AclEntryPermission.READ_ACL, AclEntryPermission.WRITE_ATTRIBUTES,
+        AclEntryPermission.WRITE_NAMED_ATTRS, AclEntryPermission.SYNCHRONIZE);
+    testNewAclEntryPermissions(WinNT.GENERIC_EXECUTE,
+        AclEntryPermission.EXECUTE, AclEntryPermission.READ_ATTRIBUTES,
+        AclEntryPermission.READ_ACL, AclEntryPermission.SYNCHRONIZE);
+    testNewAclEntryPermissions(WinNT.GENERIC_ALL, AclEntryPermission.values());
+  }
+
+  private void testNewAclEntryPermissions(int acePermissions,
+      AclEntryPermission... expectedPermissions) throws Exception {
+    Set<AclEntryPermission> expected =
+        EnumSet.noneOf(AclEntryPermission.class);
+    for (AclEntryPermission perm : expectedPermissions) {
+      expected.add(perm);
+    }
+    WinNT.ACCESS_ACEStructure ace = new AceBuilder()
+        .setSid(AccountSid.user("userName", null))
+        .setPerms(acePermissions)
+        .build();
+    AclEntry aclEntry = wafav.newAclEntry(ace);
+    assertNotNull(aclEntry);
+    assertEquals(expected, aclEntry.permissions());
+  }
+
+  @Test
+  public void testNewAclEntryIndividualFlags() throws Exception {
+    testNewAclEntryFlags(WinNT.OBJECT_INHERIT_ACE, AclEntryFlag.FILE_INHERIT);
+    testNewAclEntryFlags(WinNT.INHERIT_ONLY_ACE, AclEntryFlag.INHERIT_ONLY);
+    testNewAclEntryFlags(WinNT.CONTAINER_INHERIT_ACE,
+                         AclEntryFlag.DIRECTORY_INHERIT);
+    testNewAclEntryFlags(WinNT.NO_PROPAGATE_INHERIT_ACE,
+                         AclEntryFlag.NO_PROPAGATE_INHERIT);
+  }
+
+  @Test
+  public void testNewAclEntryMultipleFlags() throws Exception {
+    testNewAclEntryFlags((byte) (WinNT.OBJECT_INHERIT_ACE |
+        WinNT.CONTAINER_INHERIT_ACE | WinNT.INHERIT_ONLY_ACE |
+        WinNT.NO_PROPAGATE_INHERIT_ACE), AclEntryFlag.values());
+  }
+
+  private void testNewAclEntryFlags(byte aceFlags,
+      AclEntryFlag... expectedFlags) throws Exception {
+    Set<AclEntryFlag> expected = EnumSet.noneOf(AclEntryFlag.class);
+    for (AclEntryFlag flag : expectedFlags) {
+      expected.add(flag);
+    }
+    WinNT.ACCESS_ACEStructure ace = new AceBuilder()
+        .setSid(AccountSid.user("userName", null))
+        .setFlags(aceFlags)
+        .build();
+    AclEntry aclEntry = wafav.newAclEntry(ace);
+    assertNotNull(aclEntry);
+    assertEquals(expected, aclEntry.flags());
+  }
+
+  static class AceBuilder {
+    private Ace ace = new Ace();
+
+    public AceBuilder setType(byte type) {
+      ace.AceType = type;
+      return this;
+    }
+
+    public AceBuilder setFlags(byte... flags) {
+      for (byte flag : flags) {
+        ace.AceFlags |= flag;
+      }
+      return this;
+    }
+
+    public AceBuilder setPerms(int... perms) {
+      for (int perm : perms) {
+        ace.Mask |= perm;
+      }
+      return this;
+    }
+
+    public AceBuilder setSid(WinNT.PSID sid) {
+      ace.setSID(sid);
+      return this;
+    }
+
+    public WinNT.ACCESS_ACEStructure build() {
+      return ace;
+    }
+  }
+
+  static class Ace extends WinNT.ACCESS_ACEStructure {
+    // psid is not publicly settable in ACCESS_ACEStructure.
+    private WinNT.PSID sid;
+
+    public void setSID(WinNT.PSID sid) {
+      this.sid = sid;
+    }
+
+    @Override
+    public WinNT.PSID getSID() {
+      return (sid != null) ? sid : super.getSID();
+    }
+
+    @Override
+    public String getSidString() {
+      return (sid != null) ? sid.toString() : super.getSidString();
+    }
+  }
+
+  /** A SID implemention that wraps an Account, avoiding AD lookup. */
+  static class AccountSid extends WinNT.PSID {
+    private final Account account;
+
+    public static AccountSid user(String name, String domain) {
+      return new AccountSid(SID_NAME_USE.SidTypeUser, name, domain);
+    }
+
+    public static AccountSid group(String name, String domain) {
+      return new AccountSid(SID_NAME_USE.SidTypeGroup, name, domain);
+    }
+
+    public AccountSid(Account account) {
+      this.account = account;
+    }
+
+    public AccountSid(int type, String name, String domain) {
+      account = new Account();
+      account.accountType = type;
+      account.name = name;
+      account.domain = domain;
+    }
+
+    public Account getAccount() throws Win32Exception {
+      if (account == null) {
+        throw new Win32Exception(WinError.ERROR_NONE_MAPPED);
+      }
+      return account;
+    }
+
+    @Override
+    public String toString() {
+      if (account == null) {
+        return "null";
+      } else {
+        return (account.domain == null) ? account.name
+            : account.domain + "\\" + account.name;
+      }
+    }
+  }
+
+  /**
+   * An subclass of WindowsAclFileAttributeViews that avoids making
+   * actual Windows API calls.
+   */
+  static class TestAclFileAttributeViews extends WindowsAclFileAttributeViews {
+    public TestAclFileAttributeViews() {
+      super(null, null, null, null, null);
+    }
+
+    @Override
+    Account getAccountBySid(WinNT.PSID sid) throws Win32Exception {
+      if (sid instanceof AccountSid) {
+        return ((AccountSid) sid).getAccount();
+      } else {
+        return super.getAccountBySid(sid);
+      }
+    }
+  }
+}
diff --git a/test/com/google/enterprise/adaptor/fs/WindowsFileDelegateTest.java b/test/com/google/enterprise/adaptor/fs/WindowsFileDelegateTest.java
index f345598..0a536eb 100644
--- a/test/com/google/enterprise/adaptor/fs/WindowsFileDelegateTest.java
+++ b/test/com/google/enterprise/adaptor/fs/WindowsFileDelegateTest.java
@@ -72,11 +72,11 @@
   }
 
   private Path newTempDir(String name) throws IOException {
-    return temp.newFolder(name).toPath();
+    return temp.newFolder(name).toPath().toRealPath();
   }
 
   private Path newTempFile(String name) throws IOException {
-    return temp.newFile(name).toPath();
+    return temp.newFile(name).toPath().toRealPath();
   }
 
   private Path newTempFile(Path parent, String name) throws IOException {
