Verify at config adaptor has permission to crawl root

Verify in init() that the adaptor has the required permission to list
the contents of the root path.
diff --git a/src/com/google/enterprise/adaptor/fs/FsAdaptor.java b/src/com/google/enterprise/adaptor/fs/FsAdaptor.java
index fc3fd4d..c89a506 100644
--- a/src/com/google/enterprise/adaptor/fs/FsAdaptor.java
+++ b/src/com/google/enterprise/adaptor/fs/FsAdaptor.java
@@ -37,6 +37,7 @@
 import java.io.OutputStreamWriter;
 import java.io.Writer;
 import java.nio.charset.Charset;
+import java.nio.file.AccessDeniedException;
 import java.nio.file.Path;
 import java.nio.file.attribute.AclFileAttributeView;
 import java.nio.file.attribute.BasicFileAttributes;
@@ -236,6 +237,15 @@
           + "shared.");
     }
 
+    // Verify that the adaptor has permission to read the contents of the root.
+    try {
+      delegate.newDirectoryStream(rootPath);
+    } catch (AccessDeniedException e) {
+      throw new IOException("Unable to list the contents of " + rootPath +
+          ". This can happen if the Windows account used to crawl " +
+          "the path does not have sufficient permissions.", e);
+    }
+
     builtinPrefix = context.getConfig().getValue(CONFIG_BUILTIN_PREFIX);
     log.log(Level.CONFIG, "builtinPrefix: {0}", builtinPrefix);
 
diff --git a/test/com/google/enterprise/adaptor/fs/FsAdaptorTest.java b/test/com/google/enterprise/adaptor/fs/FsAdaptorTest.java
index 635b65e..793d0f0 100644
--- a/test/com/google/enterprise/adaptor/fs/FsAdaptorTest.java
+++ b/test/com/google/enterprise/adaptor/fs/FsAdaptorTest.java
@@ -43,6 +43,8 @@
 import java.io.FilterInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.nio.file.AccessDeniedException;
+import java.nio.file.DirectoryStream;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.nio.file.attribute.AclFileAttributeView;
@@ -940,6 +942,20 @@
   }
 
   @Test
+  public void testInitListRootContentsAccessDenied() throws Exception {
+    delegate = new MockFileDelegate(root) {
+      @Override
+      public DirectoryStream<Path> newDirectoryStream(Path doc)
+          throws IOException {
+        throw new AccessDeniedException(doc.toString());
+      }
+    };
+    adaptor = new FsAdaptor(delegate);
+    thrown.expect(IOException.class);
+    adaptor.init(context);
+  }
+
+  @Test
   public void testAdaptorInitUncDenyShareAclAccess() throws Exception {
     root = new DenyShareAclAccessMockFile(ROOT, true);
     delegate = new MockFileDelegate(root);