Make empty path lookups work correctly (equivalent to ".").
diff --git a/src/main/java/com/google/jimfs/internal/JimfsFileSystemProvider.java b/src/main/java/com/google/jimfs/internal/JimfsFileSystemProvider.java
index e391c62..42d06ac 100644
--- a/src/main/java/com/google/jimfs/internal/JimfsFileSystemProvider.java
+++ b/src/main/java/com/google/jimfs/internal/JimfsFileSystemProvider.java
@@ -114,6 +114,7 @@
     URI jarUri = URI.create("jar:" + pathUri);
 
     try {
+      // pass the new jar:jimfs://... URI to be handled by ZipFileSystemProvider
       return FileSystems.newFileSystem(jarUri, env);
     } catch (Exception e) {
       // if any exception occurred, assume the file wasn't a zip file and that we don't support
diff --git a/src/main/java/com/google/jimfs/internal/JimfsSecureDirectoryStream.java b/src/main/java/com/google/jimfs/internal/JimfsSecureDirectoryStream.java
index 85ceb7a..3af7756 100644
--- a/src/main/java/com/google/jimfs/internal/JimfsSecureDirectoryStream.java
+++ b/src/main/java/com/google/jimfs/internal/JimfsSecureDirectoryStream.java
@@ -60,12 +60,7 @@
 
   @Override
   protected Iterable<String> snapshotEntryNames() throws IOException {
-    tree.readLock().lock();
-    try {
-      return tree.snapshotBaseEntries();
-    } finally {
-      tree.readLock().unlock();
-    }
+    return tree.snapshotBaseEntries();
   }
 
   @Override
@@ -117,8 +112,7 @@
 
   @Override
   public <V extends FileAttributeView> V getFileAttributeView(Class<V> type) {
-    return getFileAttributeView(
-        JimfsPath.empty(tree.getBasePath().getFileSystem()), type);
+    return getFileAttributeView(tree.getBasePath().getFileSystem().getPath("."), type);
   }
 
   @Override
diff --git a/src/main/java/com/google/jimfs/internal/LookupService.java b/src/main/java/com/google/jimfs/internal/LookupService.java
index 9462d1c..eb68201 100644
--- a/src/main/java/com/google/jimfs/internal/LookupService.java
+++ b/src/main/java/com/google/jimfs/internal/LookupService.java
@@ -54,9 +54,16 @@
     checkNotNull(path);
     checkNotNull(linkHandling);
 
-    File base = path.isAbsolute()
-        ? tree.getSuperRoot().base()
-        : tree.base();
+    File base;
+    if (path.isAbsolute()) {
+      base = tree.getSuperRoot().base();
+    } else {
+      base = tree.base();
+      if (isEmpty(path)) {
+        // empty path is equivalent to "." in a lookup
+        path = path.getFileSystem().getPath(".");
+      }
+    }
 
     tree.readLock().lock();
     try {
@@ -74,6 +81,9 @@
       throws IOException {
     if (path.isAbsolute()) {
       base = tree.getSuperRoot().base();
+    } else if (isEmpty(path)) {
+      // empty path is equivalent to "." in a lookup
+      path = path.getFileSystem().getPath(".");
     }
 
     checkNotNull(linkHandling);
@@ -138,7 +148,7 @@
     }
 
     TargetPath targetPath = link.content();
-    return lookup(table.get(Name.SELF), targetPath.path(), FOLLOW_LINKS, linkDepth + 1);
+    return lookup(table.self(), targetPath.path(), FOLLOW_LINKS, linkDepth + 1);
   }
 
   @Nullable
@@ -155,4 +165,13 @@
     Iterables.addAll(names, path.allNames());
     return names;
   }
+
+  /**
+   * Returns true if path has no root component (is not absolute) and either has no name
+   * components or only has a single name component, the empty string.
+   */
+  private static boolean isEmpty(JimfsPath path) {
+    return !path.isAbsolute() && (path.getNameCount() == 0
+        || path.getNameCount() == 1 && path.getName(0).toString().equals(""));
+  }
 }
diff --git a/src/test/java/com/google/jimfs/JimfsIntegrationTest.java b/src/test/java/com/google/jimfs/JimfsIntegrationTest.java
index 1bed31d..298b588 100644
--- a/src/test/java/com/google/jimfs/JimfsIntegrationTest.java
+++ b/src/test/java/com/google/jimfs/JimfsIntegrationTest.java
@@ -1536,8 +1536,7 @@
     assertThat("/..").isSameFileAs("/");
     assertThat("/../../..").isSameFileAs("/");
     assertThat("../../../..").isSameFileAs("/");
-
-    //assertThat("/work").isSameFileAs("");
+    assertThat("").isSameFileAs("/work");
 
     Files.createDirectories(path("/foo/bar/baz"));
     Files.createSymbolicLink(path("/foo/bar/link1"), path("../link2"));
@@ -1582,10 +1581,9 @@
       assertThat("/baz/stuff/b").doesNotExist();
       assertThat("/baz/stuff").hasChildren("a", "bar", "barLink");
 
-      // TODO(cgdecker): make empty path work right
-      /*ASSERT.that(secureStream.getFileAttributeView(BasicFileAttributeView.class)
+      ASSERT.that(secureStream.getFileAttributeView(BasicFileAttributeView.class)
           .readAttributes()
-          .isDirectory()).isTrue();*/
+          .isDirectory()).isTrue();
 
       ASSERT.that(secureStream.getFileAttributeView(path("a"), BasicFileAttributeView.class)
           .readAttributes()