7006126: (fs) Updates to file system API (1/2011)
authoralanb
Fri, 28 Jan 2011 09:28:43 +0000
changeset 8158 77d9c0f1c19f
parent 7988 d31b7cc371ef
child 8159 f710beb7e29a
7006126: (fs) Updates to file system API (1/2011) Reviewed-by: chegar, sherman
jdk/make/java/java/FILES_java.gmk
jdk/make/java/nio/FILES_java.gmk
jdk/make/mkdemo/Makefile
jdk/src/share/classes/java/io/BufferedReader.java
jdk/src/share/classes/java/io/BufferedWriter.java
jdk/src/share/classes/java/io/File.java
jdk/src/share/classes/java/io/FileInputStream.java
jdk/src/share/classes/java/io/FileOutputStream.java
jdk/src/share/classes/java/io/FilePermission.java
jdk/src/share/classes/java/io/SerialCallbackContext.java
jdk/src/share/classes/java/io/TempFileHelper.java
jdk/src/share/classes/java/nio/channels/FileChannel.java
jdk/src/share/classes/java/nio/channels/SeekableByteChannel.java
jdk/src/share/classes/java/nio/file/AccessMode.java
jdk/src/share/classes/java/nio/file/CopyMoveHelper.java
jdk/src/share/classes/java/nio/file/CopyOption.java
jdk/src/share/classes/java/nio/file/DirectoryStream.java
jdk/src/share/classes/java/nio/file/FileRef.java
jdk/src/share/classes/java/nio/file/FileStore.java
jdk/src/share/classes/java/nio/file/FileSystem.java
jdk/src/share/classes/java/nio/file/FileSystems.java
jdk/src/share/classes/java/nio/file/FileTreeWalker.java
jdk/src/share/classes/java/nio/file/FileVisitor.java
jdk/src/share/classes/java/nio/file/Files.java
jdk/src/share/classes/java/nio/file/LinkOption.java
jdk/src/share/classes/java/nio/file/LinkPermission.java
jdk/src/share/classes/java/nio/file/OpenOption.java
jdk/src/share/classes/java/nio/file/Path.java
jdk/src/share/classes/java/nio/file/PathMatcher.java
jdk/src/share/classes/java/nio/file/Paths.java
jdk/src/share/classes/java/nio/file/SecureDirectoryStream.java
jdk/src/share/classes/java/nio/file/TempFileHelper.java
jdk/src/share/classes/java/nio/file/WatchEvent.java
jdk/src/share/classes/java/nio/file/WatchKey.java
jdk/src/share/classes/java/nio/file/WatchService.java
jdk/src/share/classes/java/nio/file/attribute/AclEntry.java
jdk/src/share/classes/java/nio/file/attribute/AclFileAttributeView.java
jdk/src/share/classes/java/nio/file/attribute/Attributes.java
jdk/src/share/classes/java/nio/file/attribute/BasicFileAttributeView.java
jdk/src/share/classes/java/nio/file/attribute/BasicFileAttributes.java
jdk/src/share/classes/java/nio/file/attribute/DosFileAttributeView.java
jdk/src/share/classes/java/nio/file/attribute/DosFileAttributes.java
jdk/src/share/classes/java/nio/file/attribute/FileAttribute.java
jdk/src/share/classes/java/nio/file/attribute/FileAttributeView.java
jdk/src/share/classes/java/nio/file/attribute/FileOwnerAttributeView.java
jdk/src/share/classes/java/nio/file/attribute/FileStoreSpaceAttributeView.java
jdk/src/share/classes/java/nio/file/attribute/FileStoreSpaceAttributes.java
jdk/src/share/classes/java/nio/file/attribute/FileTime.java
jdk/src/share/classes/java/nio/file/attribute/PosixFileAttributeView.java
jdk/src/share/classes/java/nio/file/attribute/PosixFileAttributes.java
jdk/src/share/classes/java/nio/file/attribute/PosixFilePermission.java
jdk/src/share/classes/java/nio/file/attribute/PosixFilePermissions.java
jdk/src/share/classes/java/nio/file/attribute/UserDefinedFileAttributeView.java
jdk/src/share/classes/java/nio/file/attribute/package-info.java
jdk/src/share/classes/java/nio/file/package-info.java
jdk/src/share/classes/java/nio/file/spi/FileSystemProvider.java
jdk/src/share/classes/java/nio/file/spi/FileTypeDetector.java
jdk/src/share/classes/java/util/Scanner.java
jdk/src/share/classes/sun/nio/fs/AbstractAclFileAttributeView.java
jdk/src/share/classes/sun/nio/fs/AbstractBasicFileAttributeView.java
jdk/src/share/classes/sun/nio/fs/AbstractFileSystemProvider.java
jdk/src/share/classes/sun/nio/fs/AbstractFileTypeDetector.java
jdk/src/share/classes/sun/nio/fs/AbstractPath.java
jdk/src/share/classes/sun/nio/fs/AbstractPoller.java
jdk/src/share/classes/sun/nio/fs/AbstractUserDefinedFileAttributeView.java
jdk/src/share/classes/sun/nio/fs/AbstractWatchKey.java
jdk/src/share/classes/sun/nio/fs/AbstractWatchService.java
jdk/src/share/classes/sun/nio/fs/DynamicFileAttributeView.java
jdk/src/share/classes/sun/nio/fs/FileOwnerAttributeViewImpl.java
jdk/src/share/classes/sun/nio/fs/PollingWatchService.java
jdk/src/share/classes/sun/security/provider/SeedGenerator.java
jdk/src/share/classes/sun/tools/jar/Main.java
jdk/src/share/sample/nio/file/AclEdit.java
jdk/src/share/sample/nio/file/Chmod.java
jdk/src/share/sample/nio/file/Copy.java
jdk/src/share/sample/nio/file/DiskUsage.java
jdk/src/share/sample/nio/file/FileType.java
jdk/src/share/sample/nio/file/WatchDir.java
jdk/src/share/sample/nio/file/Xdd.java
jdk/src/solaris/classes/sun/nio/fs/GnomeFileTypeDetector.java
jdk/src/solaris/classes/sun/nio/fs/LinuxDosFileAttributeView.java
jdk/src/solaris/classes/sun/nio/fs/LinuxFileSystem.java
jdk/src/solaris/classes/sun/nio/fs/LinuxFileSystemProvider.java
jdk/src/solaris/classes/sun/nio/fs/LinuxUserDefinedFileAttributeView.java
jdk/src/solaris/classes/sun/nio/fs/LinuxWatchService.java
jdk/src/solaris/classes/sun/nio/fs/SolarisAclFileAttributeView.java
jdk/src/solaris/classes/sun/nio/fs/SolarisFileSystem.java
jdk/src/solaris/classes/sun/nio/fs/SolarisFileSystemProvider.java
jdk/src/solaris/classes/sun/nio/fs/SolarisUserDefinedFileAttributeView.java
jdk/src/solaris/classes/sun/nio/fs/SolarisWatchService.java
jdk/src/solaris/classes/sun/nio/fs/UnixCopyFile.java
jdk/src/solaris/classes/sun/nio/fs/UnixFileAttributeViews.java
jdk/src/solaris/classes/sun/nio/fs/UnixFileAttributes.java
jdk/src/solaris/classes/sun/nio/fs/UnixFileStore.java
jdk/src/solaris/classes/sun/nio/fs/UnixFileSystem.java
jdk/src/solaris/classes/sun/nio/fs/UnixFileSystemProvider.java
jdk/src/solaris/classes/sun/nio/fs/UnixPath.java
jdk/src/solaris/classes/sun/nio/fs/UnixSecureDirectoryStream.java
jdk/src/windows/classes/sun/nio/fs/RegistryFileTypeDetector.java
jdk/src/windows/classes/sun/nio/fs/WindowsFileAttributeViews.java
jdk/src/windows/classes/sun/nio/fs/WindowsFileCopy.java
jdk/src/windows/classes/sun/nio/fs/WindowsFileStore.java
jdk/src/windows/classes/sun/nio/fs/WindowsFileSystem.java
jdk/src/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java
jdk/src/windows/classes/sun/nio/fs/WindowsPath.java
jdk/src/windows/classes/sun/nio/fs/WindowsPathParser.java
jdk/src/windows/classes/sun/nio/fs/WindowsSecurityDescriptor.java
jdk/src/windows/classes/sun/nio/fs/WindowsUserDefinedFileAttributeView.java
jdk/src/windows/classes/sun/nio/fs/WindowsWatchService.java
jdk/test/demo/zipfs/basic.sh
jdk/test/java/io/File/IsHidden.java
jdk/test/java/io/File/SetAccess.java
jdk/test/java/io/File/SymLinks.java
jdk/test/java/io/FileInputStream/LargeFileAvailable.java
jdk/test/java/nio/channels/FileChannel/AtomicAppend.java
jdk/test/java/nio/channels/FileChannel/Transfer.java
jdk/test/java/nio/file/DirectoryStream/Basic.java
jdk/test/java/nio/file/DirectoryStream/DriveLetter.java
jdk/test/java/nio/file/DirectoryStream/SecureDS.java
jdk/test/java/nio/file/FileStore/Basic.java
jdk/test/java/nio/file/Files/BytesAndLines.java
jdk/test/java/nio/file/Files/CheckPermissions.java
jdk/test/java/nio/file/Files/ContentType.java
jdk/test/java/nio/file/Files/CopyAndMove.java
jdk/test/java/nio/file/Files/CreateFileTree.java
jdk/test/java/nio/file/Files/DeleteOnClose.java
jdk/test/java/nio/file/Files/FileAttributes.java
jdk/test/java/nio/file/Files/ForceLoad.java
jdk/test/java/nio/file/Files/InterruptCopy.java
jdk/test/java/nio/file/Files/Links.java
jdk/test/java/nio/file/Files/META-INF/services/java.nio.file.spi.FileTypeDetector
jdk/test/java/nio/file/Files/MaxDepth.java
jdk/test/java/nio/file/Files/Misc.java
jdk/test/java/nio/file/Files/PassThroughFileSystem.java
jdk/test/java/nio/file/Files/PrintFileTree.java
jdk/test/java/nio/file/Files/SBC.java
jdk/test/java/nio/file/Files/SimpleFileTypeDetector.java
jdk/test/java/nio/file/Files/SkipSiblings.java
jdk/test/java/nio/file/Files/TemporaryFiles.java
jdk/test/java/nio/file/Files/TerminateWalk.java
jdk/test/java/nio/file/Files/WalkWithSecurity.java
jdk/test/java/nio/file/Files/delete_on_close.sh
jdk/test/java/nio/file/Files/denyAll.policy
jdk/test/java/nio/file/Files/grantAll.policy
jdk/test/java/nio/file/Files/grantTopOnly.policy
jdk/test/java/nio/file/Files/probeContentType/Basic.java
jdk/test/java/nio/file/Files/probeContentType/ForceLoad.java
jdk/test/java/nio/file/Files/probeContentType/META-INF/services/java.nio.file.spi.FileTypeDetector
jdk/test/java/nio/file/Files/probeContentType/SimpleFileTypeDetector.java
jdk/test/java/nio/file/Files/walkFileTree/CreateFileTree.java
jdk/test/java/nio/file/Files/walkFileTree/MaxDepth.java
jdk/test/java/nio/file/Files/walkFileTree/Nulls.java
jdk/test/java/nio/file/Files/walkFileTree/PrintFileTree.java
jdk/test/java/nio/file/Files/walkFileTree/SkipSiblings.java
jdk/test/java/nio/file/Files/walkFileTree/TerminateWalk.java
jdk/test/java/nio/file/Files/walkFileTree/WalkWithSecurity.java
jdk/test/java/nio/file/Files/walkFileTree/denyAll.policy
jdk/test/java/nio/file/Files/walkFileTree/grantAll.policy
jdk/test/java/nio/file/Files/walkFileTree/grantTopOnly.policy
jdk/test/java/nio/file/Files/walkFileTree/walk_file_tree.sh
jdk/test/java/nio/file/Files/walk_file_tree.sh
jdk/test/java/nio/file/Path/CheckPermissions.java
jdk/test/java/nio/file/Path/CopyAndMove.java
jdk/test/java/nio/file/Path/DeleteOnClose.java
jdk/test/java/nio/file/Path/FileAttributes.java
jdk/test/java/nio/file/Path/InterruptCopy.java
jdk/test/java/nio/file/Path/Links.java
jdk/test/java/nio/file/Path/Misc.java
jdk/test/java/nio/file/Path/PassThroughFileSystem.java
jdk/test/java/nio/file/Path/PathOps.java
jdk/test/java/nio/file/Path/SBC.java
jdk/test/java/nio/file/Path/TemporaryFiles.java
jdk/test/java/nio/file/Path/delete_on_close.sh
jdk/test/java/nio/file/TestUtil.java
jdk/test/java/nio/file/WatchService/Basic.java
jdk/test/java/nio/file/WatchService/FileTreeModifier.java
jdk/test/java/nio/file/WatchService/LotsOfEvents.java
jdk/test/java/nio/file/WatchService/SensitivityModifier.java
jdk/test/java/nio/file/attribute/AclFileAttributeView/Basic.java
jdk/test/java/nio/file/attribute/BasicFileAttributeView/Basic.java
jdk/test/java/nio/file/attribute/DosFileAttributeView/Basic.java
jdk/test/java/nio/file/attribute/FileStoreAttributeView/Basic.java
jdk/test/java/nio/file/attribute/FileTime/Basic.java
jdk/test/java/nio/file/attribute/PosixFileAttributeView/Basic.java
jdk/test/java/nio/file/attribute/UserDefinedFileAttributeView/Basic.java
jdk/test/java/nio/file/spi/SetDefaultProvider.java
jdk/test/java/nio/file/spi/TestProvider.java
--- a/jdk/make/java/java/FILES_java.gmk	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/make/java/java/FILES_java.gmk	Fri Jan 28 09:28:43 2011 +0000
@@ -443,7 +443,6 @@
             java/io/FileReader.java \
         java/io/PipedReader.java \
         java/io/StringReader.java \
-    java/io/TempFileHelper.java \
     java/io/Writer.java \
 	java/io/BufferedWriter.java \
 	    java/io/PrintWriter.java \
--- a/jdk/make/java/nio/FILES_java.gmk	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/make/java/nio/FILES_java.gmk	Fri Jan 28 09:28:43 2011 +0000
@@ -81,12 +81,12 @@
 	java/nio/file/ClosedDirectoryStreamException.java \
 	java/nio/file/ClosedFileSystemException.java \
 	java/nio/file/ClosedWatchServiceException.java \
+	java/nio/file/CopyMoveHelper.java \
 	java/nio/file/CopyOption.java \
 	java/nio/file/DirectoryIteratorException.java \
 	java/nio/file/DirectoryNotEmptyException.java \
 	java/nio/file/DirectoryStream.java \
 	java/nio/file/FileAlreadyExistsException.java \
-	java/nio/file/FileRef.java \
 	java/nio/file/FileStore.java \
 	java/nio/file/FileSystem.java \
 	java/nio/file/FileSystemAlreadyExistsException.java \
@@ -116,6 +116,7 @@
 	java/nio/file/StandardCopyOption.java \
 	java/nio/file/StandardOpenOption.java \
 	java/nio/file/StandardWatchEventKind.java \
+	java/nio/file/TempFileHelper.java \
 	java/nio/file/WatchEvent.java \
 	java/nio/file/WatchKey.java \
 	java/nio/file/WatchService.java \
@@ -127,7 +128,6 @@
 	java/nio/file/attribute/AclEntryType.java \
 	java/nio/file/attribute/AclFileAttributeView.java \
 	java/nio/file/attribute/AttributeView.java \
-	java/nio/file/attribute/Attributes.java \
 	java/nio/file/attribute/BasicFileAttributeView.java \
 	java/nio/file/attribute/BasicFileAttributes.java \
 	java/nio/file/attribute/DosFileAttributeView.java \
@@ -136,8 +136,6 @@
 	java/nio/file/attribute/FileAttributeView.java \
 	java/nio/file/attribute/FileOwnerAttributeView.java \
 	java/nio/file/attribute/FileStoreAttributeView.java \
-	java/nio/file/attribute/FileStoreSpaceAttributeView.java \
-	java/nio/file/attribute/FileStoreSpaceAttributes.java \
 	java/nio/file/attribute/FileTime.java \
 	java/nio/file/attribute/GroupPrincipal.java \
 	java/nio/file/attribute/UserDefinedFileAttributeView.java \
@@ -246,6 +244,7 @@
 	sun/nio/fs/AbstractAclFileAttributeView.java \
 	sun/nio/fs/AbstractBasicFileAttributeView.java \
 	sun/nio/fs/AbstractFileTypeDetector.java \
+        sun/nio/fs/AbstractFileSystemProvider.java \
 	sun/nio/fs/AbstractPath.java \
 	sun/nio/fs/AbstractPoller.java \
 	sun/nio/fs/AbstractUserDefinedFileAttributeView.java \
--- a/jdk/make/mkdemo/Makefile	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/make/mkdemo/Makefile	Fri Jan 28 09:28:43 2011 +0000
@@ -31,7 +31,7 @@
 PRODUCT = demos
 include $(BUILDDIR)/common/Defs.gmk
 
-SUBDIRS            = jni nio
+SUBDIRS            = jni
 SUBDIRS_desktop    = applets jfc
 SUBDIRS_management = management
 SUBDIRS_misc       = scripting
--- a/jdk/src/share/classes/java/io/BufferedReader.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/io/BufferedReader.java	Fri Jan 28 09:28:43 2011 +0000
@@ -54,6 +54,7 @@
  *
  * @see FileReader
  * @see InputStreamReader
+ * @see java.nio.file.Files#newBufferedReader
  *
  * @author      Mark Reinhold
  * @since       JDK1.1
@@ -374,6 +375,8 @@
      *             stream has been reached
      *
      * @exception  IOException  If an I/O error occurs
+     *
+     * @see java.nio.file.Files#readAllLines
      */
     public String readLine() throws IOException {
         return readLine(false);
--- a/jdk/src/share/classes/java/io/BufferedWriter.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/io/BufferedWriter.java	Fri Jan 28 09:28:43 2011 +0000
@@ -57,6 +57,7 @@
  * @see PrintWriter
  * @see FileWriter
  * @see OutputStreamWriter
+ * @see java.nio.file.Files#newBufferedWriter
  *
  * @author      Mark Reinhold
  * @since       JDK1.1
--- a/jdk/src/share/classes/java/io/File.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/io/File.java	Fri Jan 28 09:28:43 2011 +0000
@@ -35,8 +35,7 @@
 import java.security.AccessController;
 import java.security.SecureRandom;
 import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.attribute.FileAttribute;
+import java.nio.file.FileSystems;
 import sun.security.action.GetPropertyAction;
 
 /**
@@ -139,9 +138,10 @@
  * many of the limitations of the {@code java.io.File} class.
  * The {@link #toPath toPath} method may be used to obtain a {@link
  * Path} that uses the abstract path represented by a {@code File} object to
- * locate a file. The resulting {@code Path} provides more efficient and
- * extensive access to file attributes, additional file operations, and I/O
- * exceptions to help diagnose errors when an operation on a file fails.
+ * locate a file. The resulting {@code Path} may be used with the {@link
+ * java.nio.file.Files} class to provide more efficient and extensive access to
+ * additional file operations, file attributes, and I/O exceptions to help
+ * diagnose errors when an operation on a file fails.
  *
  * @author  unascribed
  * @since   JDK1.0
@@ -778,6 +778,12 @@
      * Tests whether the file denoted by this abstract pathname is a
      * directory.
      *
+     * <p> Where it is required to distinguish an I/O exception from the case
+     * that the file is not a directory, or where several attributes of the
+     * same file are required at the same time, then the {@link
+     * java.nio.file.Files#readAttributes(Path,Class,LinkOption[])
+     * Files.readAttributes} method may be used.
+     *
      * @return <code>true</code> if and only if the file denoted by this
      *          abstract pathname exists <em>and</em> is a directory;
      *          <code>false</code> otherwise
@@ -786,8 +792,6 @@
      *          If a security manager exists and its <code>{@link
      *          java.lang.SecurityManager#checkRead(java.lang.String)}</code>
      *          method denies read access to the file
-     *
-     * @see java.nio.file.attribute.Attributes#readBasicFileAttributes
      */
     public boolean isDirectory() {
         SecurityManager security = System.getSecurityManager();
@@ -804,6 +808,12 @@
      * addition, satisfies other system-dependent criteria.  Any non-directory
      * file created by a Java application is guaranteed to be a normal file.
      *
+     * <p> Where it is required to distinguish an I/O exception from the case
+     * that the file is not a normal file, or where several attributes of the
+     * same file are required at the same time, then the {@link
+     * java.nio.file.Files#readAttributes(Path,Class,LinkOption[])
+     * Files.readAttributes} method may be used.
+     *
      * @return  <code>true</code> if and only if the file denoted by this
      *          abstract pathname exists <em>and</em> is a normal file;
      *          <code>false</code> otherwise
@@ -812,8 +822,6 @@
      *          If a security manager exists and its <code>{@link
      *          java.lang.SecurityManager#checkRead(java.lang.String)}</code>
      *          method denies read access to the file
-     *
-     * @see java.nio.file.attribute.Attributes#readBasicFileAttributes
      */
     public boolean isFile() {
         SecurityManager security = System.getSecurityManager();
@@ -853,6 +861,13 @@
      * Returns the time that the file denoted by this abstract pathname was
      * last modified.
      *
+     * <p> Where it is required to distinguish an I/O exception from the case
+     * where {@code 0L} is returned, or where several attributes of the
+     * same file are required at the same time, or where the time of last
+     * access or the creation time are required, then the {@link
+     * java.nio.file.Files#readAttributes(Path,Class,LinkOption[])
+     * Files.readAttributes} method may be used.
+     *
      * @return  A <code>long</code> value representing the time the file was
      *          last modified, measured in milliseconds since the epoch
      *          (00:00:00 GMT, January 1, 1970), or <code>0L</code> if the
@@ -862,8 +877,6 @@
      *          If a security manager exists and its <code>{@link
      *          java.lang.SecurityManager#checkRead(java.lang.String)}</code>
      *          method denies read access to the file
-     *
-     * @see java.nio.file.attribute.Attributes#readBasicFileAttributes
      */
     public long lastModified() {
         SecurityManager security = System.getSecurityManager();
@@ -877,6 +890,12 @@
      * Returns the length of the file denoted by this abstract pathname.
      * The return value is unspecified if this pathname denotes a directory.
      *
+     * <p> Where it is required to distinguish an I/O exception from the case
+     * that {@code 0L} is returned, or where several attributes of the same file
+     * are required at the same time, then the {@link
+     * java.nio.file.Files#readAttributes(Path,Class,LinkOption[])
+     * Files.readAttributes} method may be used.
+     *
      * @return  The length, in bytes, of the file denoted by this abstract
      *          pathname, or <code>0L</code> if the file does not exist.  Some
      *          operating systems may return <code>0L</code> for pathnames
@@ -886,8 +905,6 @@
      *          If a security manager exists and its <code>{@link
      *          java.lang.SecurityManager#checkRead(java.lang.String)}</code>
      *          method denies read access to the file
-     *
-     * @see java.nio.file.attribute.Attributes#readBasicFileAttributes
      */
     public long length() {
         SecurityManager security = System.getSecurityManager();
@@ -937,11 +954,10 @@
      * this pathname denotes a directory, then the directory must be empty in
      * order to be deleted.
      *
-     * <p> Note that the {@link Path} class defines the {@link Path#delete
-     * delete} method to throw an {@link IOException} when a file cannot be
-     * deleted. This is useful for error reporting and to diagnose why a file
-     * cannot be deleted. The {@link #toPath toPath} method may be used to
-     * obtain a {@code Path} representing this abstract pathname.
+     * <p> Note that the {@link java.nio.file.Files} class defines the {@link
+     * java.nio.file.Files#delete(Path) delete} method to throw an {@link IOException}
+     * when a file cannot be deleted. This is useful for error reporting and to
+     * diagnose why a file cannot be deleted.
      *
      * @return  <code>true</code> if and only if the file or directory is
      *          successfully deleted; <code>false</code> otherwise
@@ -1009,12 +1025,11 @@
      * will appear in any specific order; they are not, in particular,
      * guaranteed to appear in alphabetical order.
      *
-     * <p> Note that the {@link Path} class defines the {@link
-     * Path#newDirectoryStream newDirectoryStream} method to open a directory
-     * and iterate over the names of the files in the directory. This may use
-     * less resources when working with very large directories. The {@link
-     * #toPath toPath} method may be used to obtain a {@code Path} representing
-     * this abstract pathname.
+     * <p> Note that the {@link java.nio.file.Files} class defines the {@link
+     * java.nio.file.Files#newDirectoryStream(Path) newDirectoryStream} method to
+     * open a directory and iterate over the names of the files in the directory.
+     * This may use less resources when working with very large directories, and
+     * may be more responsive when working with remote directories.
      *
      * @return  An array of strings naming the files and directories in the
      *          directory denoted by this abstract pathname.  The array will be
@@ -1061,6 +1076,8 @@
      *          If a security manager exists and its {@link
      *          SecurityManager#checkRead(String)} method denies read access to
      *          the directory
+     *
+     * @see java.nio.file.Files#newDirectoryStream(Path,String)
      */
     public String[] list(FilenameFilter filter) {
         String names[] = list();
@@ -1095,12 +1112,11 @@
      * will appear in any specific order; they are not, in particular,
      * guaranteed to appear in alphabetical order.
      *
-     * <p> Note that the {@link Path} class defines the {@link
-     * Path#newDirectoryStream newDirectoryStream} method to open a directory
-     * and iterate over the names of the files in the directory. This may use
-     * less resources when working with very large directories. The {@link
-     * #toPath toPath} method may be used to obtain a {@code Path} representing
-     * this abstract pathname.
+     * <p> Note that the {@link java.nio.file.Files} class defines the {@link
+     * java.nio.file.Files#newDirectoryStream(Path) newDirectoryStream} method
+     * to open a directory and iterate over the names of the files in the
+     * directory. This may use less resources when working with very large
+     * directories.
      *
      * @return  An array of abstract pathnames denoting the files and
      *          directories in the directory denoted by this abstract pathname.
@@ -1154,6 +1170,7 @@
      *          the directory
      *
      * @since  1.2
+     * @see java.nio.file.Files#newDirectoryStream(Path,String)
      */
     public File[] listFiles(FilenameFilter filter) {
         String ss[] = list();
@@ -1191,6 +1208,7 @@
      *          the directory
      *
      * @since  1.2
+     * @see java.nio.file.Files#newDirectoryStream(Path,java.nio.file.DirectoryStream.Filter)
      */
     public File[] listFiles(FileFilter filter) {
         String ss[] = list();
@@ -1207,12 +1225,6 @@
     /**
      * Creates the directory named by this abstract pathname.
      *
-     * <p> Note that the {@link Path} class defines the {@link Path#createDirectory
-     * createDirectory} method to throw an {@link IOException} when a directory
-     * cannot be created. This is useful for error reporting and to diagnose why
-     * a directory cannot be created. The {@link #toPath toPath} method may be
-     * used to obtain a {@code Path} representing this abstract pathname.
-     *
      * @return  <code>true</code> if and only if the directory was
      *          created; <code>false</code> otherwise
      *
@@ -1278,10 +1290,9 @@
      * already exists.  The return value should always be checked to make sure
      * that the rename operation was successful.
      *
-     * <p> Note that the {@link Path} class defines the {@link Path#moveTo
-     * moveTo} method to move or rename a file in a platform independent manner.
-     * The {@link #toPath toPath} method may be used to obtain a {@code Path}
-     * representing this abstract pathname.
+     * <p> Note that the {@link java.nio.file.Files} class defines the {@link
+     * java.nio.file.Files#move move} method to move or rename a file in a
+     * platform independent manner.
      *
      * @param  dest  The new abstract pathname for the named file
      *
@@ -1369,10 +1380,9 @@
      * Sets the owner's or everybody's write permission for this abstract
      * pathname.
      *
-     * <p> The {@link java.nio.file.attribute.Attributes Attributes} class
-     * defines methods that operate on file attributes including file
-     * permissions. This may be used when finer manipulation of file permissions
-     * is required.
+     * <p> The {@link java.nio.file.Files} class defines methods that operate on
+     * file attributes including file permissions. This may be used when finer
+     * manipulation of file permissions is required.
      *
      * @param   writable
      *          If <code>true</code>, sets the access permission to allow write
@@ -1437,10 +1447,9 @@
      * Sets the owner's or everybody's read permission for this abstract
      * pathname.
      *
-     * <p> The {@link java.nio.file.attribute.Attributes  Attributes} class
-     * defines methods that operate on file attributes including file
-     * permissions. This may be used when finer manipulation of file permissions
-     * is required.
+     * <p> The {@link java.nio.file.Files} class defines methods that operate on
+     * file attributes including file permissions. This may be used when finer
+     * manipulation of file permissions is required.
      *
      * @param   readable
      *          If <code>true</code>, sets the access permission to allow read
@@ -1511,10 +1520,9 @@
      * Sets the owner's or everybody's execute permission for this abstract
      * pathname.
      *
-     * <p> The {@link java.nio.file.attribute.Attributes  Attributes} class
-     * defines methods that operate on file attributes including file
-     * permissions. This may be used when finer manipulation of file permissions
-     * is required.
+     * <p> The {@link java.nio.file.Files} class defines methods that operate on
+     * file attributes including file permissions. This may be used when finer
+     * manipulation of file permissions is required.
      *
      * @param   executable
      *          If <code>true</code>, sets the access permission to allow execute
@@ -1646,6 +1654,7 @@
      *          filesystem roots.
      *
      * @since  1.2
+     * @see java.nio.file.FileStore
      */
     public static File[] listRoots() {
         return fs.listRoots();
@@ -1753,7 +1762,7 @@
 
     /* -- Temporary files -- */
 
-    static class TempDirectory {
+    private static class TempDirectory {
         private TempDirectory() { }
 
         // temporary directory location
@@ -1880,11 +1889,12 @@
      * java.lang.String, java.io.File)
      * createTempFile(prefix,&nbsp;suffix,&nbsp;null)}</code>.
      *
-     * <p> The {@link #createTemporaryFile(String,String,FileAttribute[])} method
-     * provides an alternative method to create an empty file in the
-     * temporary-file directory. Files created by that method may have more
-     * restrictive access permissions to files created by this method and so
-     * may be more suited to security-sensitive applications.
+     * <p> The {@link
+     * java.nio.file.Files#createTempFile(String,String,java.nio.file.attribute.FileAttribute[])
+     * Files.createTempFile} method provides an alternative method to create an
+     * empty file in the temporary-file directory. Files created by that method
+     * may have more restrictive access permissions to files created by this
+     * method and so may be more suited to security-sensitive applications.
      *
      * @param  prefix     The prefix string to be used in generating the file's
      *                    name; must be at least three characters long
@@ -1907,6 +1917,7 @@
      *          method does not allow a file to be created
      *
      * @since 1.2
+     * @see java.nio.file.Files#createTempDirectory(String,FileAttribute[])
      */
     public static File createTempFile(String prefix, String suffix)
         throws IOException
@@ -1914,61 +1925,6 @@
         return createTempFile(prefix, suffix, null);
     }
 
-    /**
-     * Creates an empty file in the default temporary-file directory, using
-     * the given prefix and suffix to generate its name.
-     *
-     * <p> The {@code attrs} parameter is an optional array of {@link FileAttribute
-     * attributes} to set atomically when creating the file. Each attribute is
-     * identified by its {@link FileAttribute#name name}. If more than one attribute
-     * of the same name is included in the array then all but the last occurrence
-     * is ignored.
-     *
-     * <p> Where the {@code attrs} parameter does not specify <i>access
-     * permissions</i> to set atomically when creating the file, then the
-     * resulting file may have more restrictive access permissions than files
-     * created by the {@link #createTempFile(java.lang.String, java.lang.String)}
-     * method.
-     *
-     * @param   prefix
-     *          The prefix string to be used in generating the file's
-     *          name; must be at least three characters long
-     * @param   suffix
-     *          The suffix string to be used in generating the file's
-     *          name; may be {@code null}, in which case the suffix
-     *          {@code ".tmp"} will be used
-     * @param   attrs
-     *          An optional list of file attributes to set atomically when creating
-     *          the file
-     *
-     * @return  An abstract pathname denoting a newly-created empty file
-     *
-     * @throws  IllegalArgumentException
-     *          If the {@code prefix} argument contains fewer than three
-     *          characters
-     * @throws  UnsupportedOperationException
-     *          If the array contains an attribute that cannot be set atomically
-     *          when creating the file
-     * @throws  IOException
-     *          If a file could not be created
-     * @throws  SecurityException
-     *          If a security manager exists and its <code>{@link
-     *          java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
-     *          method does not allow a file to be created.
-     *
-     * @since 1.7
-     */
-    public static File createTemporaryFile(String prefix,
-                                           String suffix,
-                                           FileAttribute<?>... attrs)
-        throws IOException
-    {
-        if (prefix.length() < 3)
-            throw new IllegalArgumentException("Prefix string too short");
-        suffix = (suffix == null) ? ".tmp" : suffix;
-        return TempFileHelper.createFile(prefix, suffix, attrs);
-    }
-
     /* -- Basic infrastructure -- */
 
     /**
@@ -2104,6 +2060,7 @@
      *          path (see {@link java.nio.file.FileSystem#getPath FileSystem.getPath})
      *
      * @since   1.7
+     * @see Path#toFile
      */
     public Path toPath() {
         Path result = filePath;
@@ -2111,12 +2068,7 @@
             synchronized (this) {
                 result = filePath;
                 if (result == null) {
-                    if (path.length() == 0) {
-                        // assume default file system treats "." as current directory
-                        result = Paths.get(".");
-                    } else {
-                        result = Paths.get(path);
-                    }
+                    result = FileSystems.getDefault().getPath(path);
                     filePath = result;
                 }
             }
--- a/jdk/src/share/classes/java/io/FileInputStream.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/io/FileInputStream.java	Fri Jan 28 09:28:43 2011 +0000
@@ -42,6 +42,7 @@
  * @see     java.io.File
  * @see     java.io.FileDescriptor
  * @see     java.io.FileOutputStream
+ * @see     java.nio.file.Files#newInputStream
  * @since   JDK1.0
  */
 public
--- a/jdk/src/share/classes/java/io/FileOutputStream.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/io/FileOutputStream.java	Fri Jan 28 09:28:43 2011 +0000
@@ -46,6 +46,7 @@
  * @see     java.io.File
  * @see     java.io.FileDescriptor
  * @see     java.io.FileInputStream
+ * @see     java.nio.file.Files#newOutputStream
  * @since   JDK1.0
  */
 public
--- a/jdk/src/share/classes/java/io/FilePermission.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/io/FilePermission.java	Fri Jan 28 09:28:43 2011 +0000
@@ -72,7 +72,7 @@
  *    <DT> readlink
  *    <DD> read link permission. Allows the target of a
  *         <a href="../nio/file/package-summary.html#links">symbolic link</a>
- *         to be read by invoking the {@link java.nio.file.Path#readSymbolicLink
+ *         to be read by invoking the {@link java.nio.file.Files#readSymbolicLink
  *         readSymbolicLink } method.
  * </DL>
  * <P>
--- a/jdk/src/share/classes/java/io/SerialCallbackContext.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/io/SerialCallbackContext.java	Fri Jan 28 09:28:43 2011 +0000
@@ -54,5 +54,3 @@
           thread = null;
       }
   }
-
-
--- a/jdk/src/share/classes/java/io/TempFileHelper.java	Thu Jan 13 22:21:58 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,139 +0,0 @@
-/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.io;
-
-import java.nio.file.FileSystems;
-import java.nio.file.InvalidPathException;
-import java.nio.file.FileAlreadyExistsException;
-import java.nio.file.attribute.FileAttribute;
-import java.nio.file.attribute.PosixFilePermission;
-import java.nio.file.attribute.PosixFilePermissions;
-import static java.nio.file.attribute.PosixFilePermission.*;
-import java.util.Set;
-import java.util.EnumSet;
-
-/**
- * Helper class to support creation of temporary files and directory with
- * initial attributes.
- */
-
-class TempFileHelper {
-    private TempFileHelper() { }
-
-    // default file and directory permissions (lazily initialized)
-    private static class PermissionsHolder {
-        static final boolean hasPosixPermissions = FileSystems.getDefault()
-            .supportedFileAttributeViews().contains("posix");
-        static final FileAttribute<Set<PosixFilePermission>> filePermissions =
-            PosixFilePermissions.asFileAttribute(EnumSet.of(OWNER_READ, OWNER_WRITE));
-        static final FileAttribute<Set<PosixFilePermission>> directoryPermissions =
-            PosixFilePermissions.asFileAttribute(EnumSet
-                .of(OWNER_READ, OWNER_WRITE, OWNER_EXECUTE));
-    }
-
-    /**
-     * Creates a file or directory in the temporary directory.
-     */
-    private static File create(String prefix,
-                               String suffix,
-                               FileAttribute[] attrs,
-                               boolean isDirectory)
-        throws IOException
-    {
-        // in POSIX environments use default file and directory permissions
-        // if initial permissions not given by caller.
-        if (PermissionsHolder.hasPosixPermissions) {
-            if (attrs.length == 0) {
-                // no attributes so use default permissions
-                attrs = new FileAttribute<?>[1];
-                attrs[0] = (isDirectory) ? PermissionsHolder.directoryPermissions :
-                    PermissionsHolder.filePermissions;
-            } else {
-                // check if posix permissions given; if not use default
-                boolean hasPermissions = false;
-                for (int i=0; i<attrs.length; i++) {
-                    if (attrs[i].name().equals("posix:permissions")) {
-                        hasPermissions = true;
-                        break;
-                    }
-                }
-                if (!hasPermissions) {
-                    FileAttribute<?>[] copy = new FileAttribute<?>[attrs.length+1];
-                    System.arraycopy(attrs, 0, copy, 0, attrs.length);
-                    attrs = copy;
-                    attrs[attrs.length-1] = (isDirectory) ?
-                        PermissionsHolder.directoryPermissions :
-                        PermissionsHolder.filePermissions;
-                }
-            }
-        }
-
-        // loop generating random names until file or directory can be created
-        SecurityManager sm = System.getSecurityManager();
-        for (;;) {
-            File tmpdir = File.TempDirectory.location();
-            File f = File.TempDirectory.generateFile(prefix, suffix, tmpdir);
-            try {
-                if (isDirectory) {
-                    f.toPath().createDirectory(attrs);
-                } else {
-                    f.toPath().createFile(attrs);
-                }
-                return f;
-            } catch (InvalidPathException e) {
-                // don't reveal temporary directory location
-                if (sm != null)
-                    throw new IllegalArgumentException("Invalid prefix or suffix");
-                throw e;
-            } catch (SecurityException e) {
-                // don't reveal temporary directory location
-                if (sm != null)
-                    throw new SecurityException("Unable to create temporary file");
-                throw e;
-            } catch (FileAlreadyExistsException e) {
-                // ignore
-            }
-        }
-    }
-
-    /**
-     * Creates a file in the temporary directory.
-     */
-    static File createFile(String prefix,  String suffix, FileAttribute[] attrs)
-        throws IOException
-    {
-        return create(prefix, suffix, attrs, false);
-    }
-
-    /**
-     * Creates a directory in the temporary directory.
-     */
-    static File createDirectory(String prefix, FileAttribute[] attrs)
-        throws IOException
-    {
-        return create(prefix, "", attrs, true);
-    }
-}
--- a/jdk/src/share/classes/java/nio/channels/FileChannel.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/nio/channels/FileChannel.java	Fri Jan 28 09:28:43 2011 +0000
@@ -248,7 +248,7 @@
      * FileSystemProvider#newFileChannel newFileChannel} method on the
      * provider that created the {@code Path}.
      *
-     * @param   file
+     * @param   path
      *          The path of the file to open or create
      * @param   options
      *          Options specifying how the file is opened
@@ -261,7 +261,7 @@
      * @throws  IllegalArgumentException
      *          If the set contains an invalid combination of options
      * @throws  UnsupportedOperationException
-     *          If the {@code file} is associated with a provider that does not
+     *          If the {@code path} is associated with a provider that does not
      *          support creating file channels, or an unsupported open option is
      *          specified, or the array contains an attribute that cannot be set
      *          atomically when creating the file
@@ -278,13 +278,13 @@
      *
      * @since   1.7
      */
-    public static FileChannel open(Path file,
+    public static FileChannel open(Path path,
                                    Set<? extends OpenOption> options,
                                    FileAttribute<?>... attrs)
         throws IOException
     {
-        FileSystemProvider provider = file.getFileSystem().provider();
-        return provider.newFileChannel(file, options, attrs);
+        FileSystemProvider provider = path.getFileSystem().provider();
+        return provider.newFileChannel(path, options, attrs);
     }
 
     private static final FileAttribute<?>[] NO_ATTRIBUTES = new FileAttribute[0];
@@ -295,10 +295,12 @@
      * <p> An invocation of this method behaves in exactly the same way as the
      * invocation
      * <pre>
-     *     fc.{@link #open(Path,Set,FileAttribute[]) open}(file, options, new FileAttribute&lt;?&gt;[0]);
+     *     fc.{@link #open(Path,Set,FileAttribute[]) open}(file, opts, new FileAttribute&lt;?&gt;[0]);
      * </pre>
+     * where {@code opts} is a set of the options specified in the {@code
+     * options} array.
      *
-     * @param   file
+     * @param   path
      *          The path of the file to open or create
      * @param   options
      *          Options specifying how the file is opened
@@ -308,7 +310,7 @@
      * @throws  IllegalArgumentException
      *          If the set contains an invalid combination of options
      * @throws  UnsupportedOperationException
-     *          If the {@code file} is associated with a provider that does not
+     *          If the {@code path} is associated with a provider that does not
      *          support creating file channels, or an unsupported open option is
      *          specified
      * @throws  IOException
@@ -324,12 +326,12 @@
      *
      * @since   1.7
      */
-    public static FileChannel open(Path file, OpenOption... options)
+    public static FileChannel open(Path path, OpenOption... options)
         throws IOException
     {
         Set<OpenOption> set = new HashSet<OpenOption>(options.length);
         Collections.addAll(set, options);
-        return open(file, set, NO_ATTRIBUTES);
+        return open(path, set, NO_ATTRIBUTES);
     }
 
     // -- Channel operations --
--- a/jdk/src/share/classes/java/nio/channels/SeekableByteChannel.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/nio/channels/SeekableByteChannel.java	Fri Jan 28 09:28:43 2011 +0000
@@ -47,7 +47,7 @@
  * so that method invocations on the implementation class can be chained.
  *
  * @since 1.7
- * @see java.nio.file.Path#newByteChannel
+ * @see java.nio.file.Files#newByteChannel
  */
 
 public interface SeekableByteChannel
--- a/jdk/src/share/classes/java/nio/file/AccessMode.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/AccessMode.java	Fri Jan 28 09:28:43 2011 +0000
@@ -29,8 +29,6 @@
  * Defines access modes used to test the accessibility of a file.
  *
  * @since 1.7
- *
- * @see Path#checkAccess
  */
 
 public enum AccessMode {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/nio/file/CopyMoveHelper.java	Fri Jan 28 09:28:43 2011 +0000
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+import java.nio.file.attribute.*;
+import java.io.InputStream;
+import java.io.IOException;
+
+/**
+ * Helper class to support copying or moving files when the source and target
+ * are associated with different providers.
+ */
+
+class CopyMoveHelper {
+    private CopyMoveHelper() { }
+
+    /**
+     * Parses the arguments for a file copy operation.
+     */
+    private static class CopyOptions {
+        boolean replaceExisting = false;
+        boolean copyAttributes = false;
+        boolean followLinks = true;
+
+        private CopyOptions() { }
+
+        static CopyOptions parse(CopyOption... options) {
+            CopyOptions result = new CopyOptions();
+            for (CopyOption option: options) {
+                if (option == StandardCopyOption.REPLACE_EXISTING) {
+                    result.replaceExisting = true;
+                    continue;
+                }
+                if (option == LinkOption.NOFOLLOW_LINKS) {
+                    result.followLinks = false;
+                    continue;
+                }
+                if (option == StandardCopyOption.COPY_ATTRIBUTES) {
+                    result.copyAttributes = true;
+                    continue;
+                }
+                if (option == null)
+                    throw new NullPointerException();
+                throw new UnsupportedOperationException("'" + option +
+                    "' is not a recognized copy option");
+            }
+            return result;
+        }
+    }
+
+    /**
+     * Converts the given array of options for moving a file to options suitable
+     * for copying the file when a move is implemented as copy + delete.
+     */
+    private static CopyOption[] convertMoveToCopyOptions(CopyOption... options)
+        throws AtomicMoveNotSupportedException
+    {
+        int len = options.length;
+        CopyOption[] newOptions = new CopyOption[len+2];
+        for (int i=0; i<len; i++) {
+            CopyOption option = options[i];
+            if (option == StandardCopyOption.ATOMIC_MOVE) {
+                throw new AtomicMoveNotSupportedException(null, null,
+                    "Atomic move between providers is not supported");
+            }
+            newOptions[i] = option;
+        }
+        newOptions[len] = LinkOption.NOFOLLOW_LINKS;
+        newOptions[len+1] = StandardCopyOption.COPY_ATTRIBUTES;
+        return newOptions;
+    }
+
+    /**
+     * Simple copy for use when source and target are associated with different
+     * providers
+     */
+    static void copyToForeignTarget(Path source, Path target,
+                                    CopyOption... options)
+        throws IOException
+    {
+        CopyOptions opts = CopyOptions.parse(options);
+        LinkOption[] linkOptions = (opts.followLinks) ? new LinkOption[0] :
+            new LinkOption[] { LinkOption.NOFOLLOW_LINKS };
+
+        // attributes of source file
+        BasicFileAttributes attrs = Files.readAttributes(source,
+                                                         BasicFileAttributes.class,
+                                                         linkOptions);
+        if (attrs.isSymbolicLink())
+            throw new IOException("Copying of symbolic links not supported");
+
+        // delete target if it exists and REPLACE_EXISTING is specified
+        if (opts.replaceExisting) {
+            Files.deleteIfExists(target);
+        } else if (Files.exists(target))
+            throw new FileAlreadyExistsException(target.toString());
+
+        // create directory or copy file
+        if (attrs.isDirectory()) {
+            Files.createDirectory(target);
+        } else {
+            try (InputStream in = Files.newInputStream(source)) {
+                Files.copy(in, target);
+            }
+        }
+
+        // copy basic attributes to target
+        if (opts.copyAttributes) {
+            BasicFileAttributeView view =
+                Files.getFileAttributeView(target, BasicFileAttributeView.class, linkOptions);
+            try {
+                view.setTimes(attrs.lastModifiedTime(),
+                              attrs.lastAccessTime(),
+                              attrs.creationTime());
+            } catch (IOException x) {
+                // rollback
+                try {
+                    Files.delete(target);
+                } catch (IOException ignore) { }
+                throw x;
+            }
+        }
+    }
+
+    /**
+     * Simple move implements as copy+delete for use when source and target are
+     * associated with different providers
+     */
+    static void moveToForeignTarget(Path source, Path target,
+                                    CopyOption... options) throws IOException
+    {
+        copyToForeignTarget(source, target, convertMoveToCopyOptions(options));
+        Files.delete(source);
+    }
+}
--- a/jdk/src/share/classes/java/nio/file/CopyOption.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/CopyOption.java	Fri Jan 28 09:28:43 2011 +0000
@@ -28,8 +28,12 @@
 /**
  * An object that configures how to copy or move a file.
  *
- * <p> Objects of this type may be used with the {@link Path#copyTo copyTo} and
- * {@link Path#moveTo moveTo} methods to configure how a file is copied or moved.
+ * <p> Objects of this type may be used with the {@link
+ * Files#copy(Path,Path,CopyOption[]) Files.copy(Path,Path,CopyOption...)},
+ * {@link Files#copy(java.io.InputStream,Path,CopyOption[])
+ * Files.copy(InputStream,Path,CopyOption...)} and {@link Files#move
+ * Files.move(Path,Path,CopyOption...)} methods to configure how a file is
+ * copied or moved.
  *
  * <p> The {@link StandardCopyOption} enumeration type defines the
  * <i>standard</i> options.
--- a/jdk/src/share/classes/java/nio/file/DirectoryStream.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/DirectoryStream.java	Fri Jan 28 09:28:43 2011 +0000
@@ -54,7 +54,7 @@
  * construct to ensure that the stream is closed:
  * <pre>
  *   Path dir = ...
- *   try (DirectoryStream&lt;Path&gt; stream = dir.newDirectoryStream()) {
+ *   try (DirectoryStream&lt;Path&gt; stream = Files.newDirectoryStream(dir)) {
  *       for (Path entry: stream) {
  *           ...
  *       }
@@ -97,8 +97,8 @@
  * both the for-each and try-with-resources constructs.
  * <pre>
  *   List&lt;Path&gt; listSourceFiles(Path dir) throws IOException {
- *       List&lt;Path&gt; result = new ArrayList&lt;Path&gt;();
- *       try (DirectoryStream&lt;Path&gt; stream = dir.newDirectoryStream("*.{c,h,cpp,hpp,java}")) {
+ *       List&lt;Path&gt; result = new ArrayList&lt;&gt;();
+ *       try (DirectoryStream&lt;Path&gt; stream = Files.newDirectoryStream(dir, "*.{c,h,cpp,hpp,java}")) {
  *           for (Path entry: stream) {
  *               result.add(entry);
  *           }
@@ -113,7 +113,7 @@
  *
  * @since 1.7
  *
- * @see Path#newDirectoryStream
+ * @see Files#newDirectoryStream(Path)
  */
 
 public interface DirectoryStream<T>
@@ -122,9 +122,9 @@
     /**
      * An interface that is implemented by objects that decide if a directory
      * entry should be accepted or filtered. A {@code Filter} is passed as the
-     * parameter to the {@link Path#newDirectoryStream(DirectoryStream.Filter)
-     * newDirectoryStream} method when opening a directory to iterate over the
-     * entries in the directory.
+     * parameter to the {@link Files#newDirectoryStream(Path,DirectoryStream.Filter)}
+     * method when opening a directory to iterate over the entries in the
+     * directory.
      *
      * @param   <T>     the type of the directory entry
      *
--- a/jdk/src/share/classes/java/nio/file/FileRef.java	Thu Jan 13 22:21:58 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,322 +0,0 @@
-/*
- * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.nio.file;
-
-import java.nio.file.attribute.*;
-import java.util.Map;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.IOException;
-
-/**
- * A reference to a file.
- *
- * <p> A {@code FileRef} is an object that locates a file and defines methods to
- * open the file for reading or writing. It also provides access to associated
- * metadata or file attributes.
- *
- * @since 1.7
- * @see java.nio.file.attribute.Attributes
- * @see java.io.File#toPath
- */
-
-public interface FileRef {
-
-    /**
-     * Opens the file referenced by this object, returning an input stream to
-     * read from the file. The stream will not be buffered, and is not required
-     * to support the {@link InputStream#mark mark} or {@link InputStream#reset
-     * reset} methods. The stream will be safe for access by multiple concurrent
-     * threads. Reading commences at the beginning of the file.
-     *
-     * <p> The {@code options} parameter determines how the file is opened.
-     * If no options are present then it is equivalent to opening the file with
-     * the {@link StandardOpenOption#READ READ} option. In addition to the {@code
-     * READ} option, an implementation may also support additional implementation
-     * specific options.
-     *
-     * @return  an input stream to read bytes from the file
-     *
-     * @throws  IllegalArgumentException
-     *          if an invalid combination of options is specified
-     * @throws  UnsupportedOperationException
-     *          if an unsupported option is specified
-     * @throws  IOException
-     *          if an I/O error occurs
-     * @throws  SecurityException
-     *          In the case of the default provider, and a security manager is
-     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
-     *          method is invoked to check read access to the file.
-     */
-    InputStream newInputStream(OpenOption... options) throws IOException;
-
-    /**
-     * Opens or creates the file located by this object for writing, returning
-     * an output stream to write bytes to the file.
-     *
-     * <p> The {@code options} parameter determines how the file is opened.
-     * If no options are present then this method creates a new file for writing
-     * or truncates an existing file. In addition to the {@link StandardOpenOption
-     * standard} options, an implementation may also support additional
-     * implementation specific options.
-     *
-     * <p> The resulting stream will not be buffered. The stream will be safe
-     * for access by multiple concurrent threads.
-     *
-     * @param   options
-     *          options specifying how the file is opened
-     *
-     * @return  a new output stream
-     *
-     * @throws  IllegalArgumentException
-     *          if {@code options} contains an invalid combination of options
-     * @throws  UnsupportedOperationException
-     *          if an unsupported option is specified
-     * @throws  IOException
-     *          if an I/O error occurs
-     * @throws  SecurityException
-     *          In the case of the default provider, and a security manager is
-     *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
-     *          method is invoked to check write access to the file.
-     */
-    OutputStream newOutputStream(OpenOption... options) throws IOException;
-
-    /**
-     * Returns a file attribute view of a given type.
-     *
-     * <p> A file attribute view provides a read-only or updatable view of a
-     * set of file attributes. This method is intended to be used where the file
-     * attribute view defines type-safe methods to read or update the file
-     * attributes. The {@code type} parameter is the type of the attribute view
-     * required and the method returns an instance of that type if supported.
-     * The {@link BasicFileAttributeView} type supports access to the basic
-     * attributes of a file. Invoking this method to select a file attribute
-     * view of that type will always return an instance of that class.
-     *
-     * <p> The {@code options} array may be used to indicate how symbolic links
-     * are handled by the resulting file attribute view for the case that the
-     * file is a symbolic link. By default, symbolic links are followed. If the
-     * option {@link LinkOption#NOFOLLOW_LINKS NOFOLLOW_LINKS} is present then
-     * symbolic links are not followed. This option is ignored by implementations
-     * that do not support symbolic links.
-     *
-     * @param   type
-     *          the {@code Class} object corresponding to the file attribute view
-     * @param   options
-     *          options indicating how symbolic links are handled
-     *
-     * @return  a file attribute view of the specified type, or {@code null} if
-     *          the attribute view type is not available
-     *
-     * @throws  UnsupportedOperationException
-     *          If options contains an unsupported option. This exception is
-     *          specified to allow the {@code LinkOption} enum be extended
-     *          in future releases.
-     *
-     * @see Attributes#readBasicFileAttributes
-     */
-    <V extends FileAttributeView> V getFileAttributeView(Class<V> type,
-                                                         LinkOption... options);
-
-    /**
-     * Sets the value of a file attribute.
-     *
-     * <p> The {@code attribute} parameter identifies the attribute to be set
-     * and takes the form:
-     * <blockquote>
-     * [<i>view-name</i><b>:</b>]<i>attribute-name</i>
-     * </blockquote>
-     * where square brackets [...] delineate an optional component and the
-     * character {@code ':'} stands for itself.
-     *
-     * <p> <i>view-name</i> is the {@link FileAttributeView#name name} of a {@link
-     * FileAttributeView} that identifies a set of file attributes. If not
-     * specified then it defaults to {@code "basic"}, the name of the file
-     * attribute view that identifies the basic set of file attributes common to
-     * many file systems. <i>attribute-name</i> is the name of the attribute
-     * within the set.
-     *
-     * <p> <b>Usage Example:</b>
-     * Suppose we want to set the DOS "hidden" attribute:
-     * <pre>
-     *    file.setAttribute("dos:hidden", true);
-     * </pre>
-     *
-     * @param   attribute
-     *          the attribute to set
-     * @param   value
-     *          the attribute value
-     * @param   options
-     *          options indicating how symbolic links are handled
-     *
-     * @throws  UnsupportedOperationException
-     *          if the attribute view is not available or it does not support
-     *          updating the attribute
-     * @throws  IllegalArgumentException
-     *          if the attribute value is of the correct type but has an
-     *          inappropriate value
-     * @throws  ClassCastException
-     *          If the attribute value is not of the expected type or is a
-     *          collection containing elements that are not of the expected
-     *          type
-     * @throws  IOException
-     *          If an I/O error occurs
-     * @throws  SecurityException
-     *          In the case of the default provider, and a security manager is
-     *          installed, its {@link SecurityManager#checkWrite(String) checkWrite}
-     *          method denies write access to the file. If this method is invoked
-     *          to set security sensitive attributes then the security manager
-     *          may be invoked to check for additional permissions.
-     */
-    void setAttribute(String attribute, Object value, LinkOption... options)
-        throws IOException;
-
-    /**
-     * Reads the value of a file attribute.
-     *
-     * <p> The {@code attribute} parameter identifies the attribute to be read
-     * and takes the form:
-     * <blockquote>
-     * [<i>view-name</i><b>:</b>]<i>attribute-name</i>
-     * </blockquote>
-     * where square brackets [...] delineate an optional component and the
-     * character {@code ':'} stands for itself.
-     *
-     * <p> <i>view-name</i> is the {@link FileAttributeView#name name} of a {@link
-     * FileAttributeView} that identifies a set of file attributes. If not
-     * specified then it defaults to {@code "basic"}, the name of the file
-     * attribute view that identifies the basic set of file attributes common to
-     * many file systems. <i>attribute-name</i> is the name of the attribute.
-     *
-     * <p> The {@code options} array may be used to indicate how symbolic links
-     * are handled for the case that the file is a symbolic link. By default,
-     * symbolic links are followed and the file attribute of the final target
-     * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS
-     * NOFOLLOW_LINKS} is present then symbolic links are not followed and so
-     * the method returns the file attribute of the symbolic link.
-     *
-     * <p> <b>Usage Example:</b>
-     * Suppose we require the user ID of the file owner on a system that
-     * supports a "{@code unix}" view:
-     * <pre>
-     *    int uid = (Integer)file.getAttribute("unix:uid");
-     * </pre>
-     *
-     * @param   attribute
-     *          the attribute to read
-     * @param   options
-     *          options indicating how symbolic links are handled
-     * @return  the attribute value or {@code null} if the attribute view
-     *          is not available or it does not support reading the attribute
-     *
-     *          reading the attribute
-     * @throws  IOException
-     *          if an I/O error occurs
-     * @throws  SecurityException
-     *          In the case of the default provider, and a security manager is
-     *          installed, its {@link SecurityManager#checkRead(String) checkRead}
-     *          method denies read access to the file. If this method is invoked
-     *          to read security sensitive attributes then the security manager
-     *          may be invoked to check for additional permissions.
-     */
-    Object getAttribute(String attribute, LinkOption... options) throws IOException;
-
-    /**
-     * Reads a set of file attributes as a bulk operation.
-     *
-     * <p> The {@code attributes} parameter identifies the attributes to be read
-     * and takes the form:
-     * <blockquote>
-     * [<i>view-name</i><b>:</b>]<i>attribute-list</i>
-     * </blockquote>
-     * where square brackets [...] delineate an optional component and the
-     * character {@code ':'} stands for itself.
-     *
-     * <p> <i>view-name</i> is the {@link FileAttributeView#name name} of a {@link
-     * FileAttributeView} that identifies a set of file attributes. If not
-     * specified then it defaults to {@code "basic"}, the name of the file
-     * attribute view that identifies the basic set of file attributes common to
-     * many file systems.
-     *
-     * <p> The <i>attribute-list</i> component is a comma separated list of
-     * zero or more names of attributes to read. If the list contains the value
-     * {@code "*"} then all attributes are read. Attributes that are not supported
-     * are ignored and will not be present in the returned map. It is
-     * implementation specific if all attributes are read as an atomic operation
-     * with respect to other file system operations.
-     *
-     * <p> The following examples demonstrate possible values for the {@code
-     * attributes} parameter:
-     *
-     * <blockquote>
-     * <table border="0">
-     * <tr>
-     *   <td> {@code "*"} </td>
-     *   <td> Read all {@link BasicFileAttributes basic-file-attributes}. </td>
-     * </tr>
-     * <tr>
-     *   <td> {@code "size,lastModifiedTime,lastAccessTime"} </td>
-     *   <td> Reads the file size, last modified time, and last access time
-     *     attributes. </td>
-     * </tr>
-     * <tr>
-     *   <td> {@code "posix:*"} </td>
-     *   <td> Read all {@link PosixFileAttributes POSIX-file-attributes}.. </td>
-     * </tr>
-     * <tr>
-     *   <td> {@code "posix:permissions,owner,size"} </td>
-     *   <td> Reads the POSX file permissions, owner, and file size. </td>
-     * </tr>
-     * </table>
-     * </blockquote>
-     *
-     * <p> The {@code options} array may be used to indicate how symbolic links
-     * are handled for the case that the file is a symbolic link. By default,
-     * symbolic links are followed and the file attribute of the final target
-     * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS
-     * NOFOLLOW_LINKS} is present then symbolic links are not followed and so
-     * the method returns the file attribute of the symbolic link.
-     *
-     * @param   attributes
-     *          The attributes to read
-     * @param   options
-     *          Options indicating how symbolic links are handled
-     *
-     * @return  A map of the attributes returned; may be empty. The map's keys
-     *          are the attribute names, its values are the attribute values
-     *
-     * @throws  IOException
-     *          If an I/O error occurs
-     * @throws  SecurityException
-     *          In the case of the default provider, and a security manager is
-     *          installed, its {@link SecurityManager#checkRead(String) checkRead}
-     *          method denies read access to the file. If this method is invoked
-     *          to read security sensitive attributes then the security manager
-     *          may be invoke to check for additional permissions.
-     */
-    Map<String,?> readAttributes(String attributes, LinkOption... options)
-        throws IOException;
-}
--- a/jdk/src/share/classes/java/nio/file/FileStore.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/FileStore.java	Fri Jan 28 09:28:43 2011 +0000
@@ -32,16 +32,13 @@
  * Storage for files. A {@code FileStore} represents a storage pool, device,
  * partition, volume, concrete file system or other implementation specific means
  * of file storage. The {@code FileStore} for where a file is stored is obtained
- * by invoking the {@link Path#getFileStore getFileStore} method, or all file
+ * by invoking the {@link Files#getFileStore getFileStore} method, or all file
  * stores can be enumerated by invoking the {@link FileSystem#getFileStores
  * getFileStores} method.
  *
  * <p> In addition to the methods defined by this class, a file store may support
  * one or more {@link FileStoreAttributeView FileStoreAttributeView} classes
  * that provide a read-only or updatable view of a set of file store attributes.
- * File stores associated with the default provider support the {@link
- * FileStoreSpaceAttributeView} to read the space related attributes of the
- * file store.
  *
  * @since 1.7
  */
@@ -87,6 +84,51 @@
     public abstract boolean isReadOnly();
 
     /**
+     * Returns the size, in bytes, of the file store.
+     *
+     * @return  the size of the file store, in bytes
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     */
+    public abstract long getTotalSpace() throws IOException;
+
+    /**
+     * Returns the number of bytes available to this Java virtual machine on the
+     * file store.
+     *
+     * <p> The returned number of available bytes is a hint, but not a
+     * guarantee, that it is possible to use most or any of these bytes.  The
+     * number of usable bytes is most likely to be accurate immediately
+     * after the space attributes are obtained. It is likely to be made inaccurate
+     * by any external I/O operations including those made on the system outside
+     * of this Java virtual machine.
+     *
+     * @return  the number of bytes available
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     */
+    public abstract long getUsableSpace() throws IOException;
+
+    /**
+     * Returns the number of unallocated bytes in the file store.
+     *
+     * <p> The returned number of unallocated bytes is a hint, but not a
+     * guarantee, that it is possible to use most or any of these bytes.  The
+     * number of unallocated bytes is most likely to be accurate immediately
+     * after the space attributes are obtained. It is likely to be
+     * made inaccurate by any external I/O operations including those made on
+     * the system outside of this virtual machine.
+     *
+     * @return  the number of unallocated bytes
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     */
+    public abstract long getUnallocatedSpace() throws IOException;
+
+    /**
      * Tells whether or not this file store supports the file attributes
      * identified by the given file attribute view.
      *
@@ -131,12 +173,6 @@
      * The {@code type} parameter is the type of the attribute view required and
      * the method returns an instance of that type if supported.
      *
-     * <p> For {@code FileStore} objects created by the default provider, then
-     * the file stores support the {@link FileStoreSpaceAttributeView} that
-     * provides access to space attributes. In that case invoking this method
-     * with a parameter value of {@code FileStoreSpaceAttributeView.class} will
-     * always return an instance of that class.
-     *
      * @param   type
      *          the {@code Class} object corresponding to the attribute view
      *
@@ -160,10 +196,6 @@
      * a {@link FileStore AttributeView} that identifies a set of file attributes.
      * <i>attribute-name</i> is the name of the attribute.
      *
-     * <p> For {@code FileStore} objects created by the default provider, then
-     * the file stores support the {@link FileStoreSpaceAttributeView} that
-     * provides access to space attributes.
-     *
      * <p> <b>Usage Example:</b>
      * Suppose we want to know if ZFS compression is enabled (assuming the "zfs"
      * view is supported):
--- a/jdk/src/share/classes/java/nio/file/FileSystem.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/FileSystem.java	Fri Jan 28 09:28:43 2011 +0000
@@ -38,8 +38,8 @@
  * <p> The default file system, obtained by invoking the {@link FileSystems#getDefault
  * FileSystems.getDefault} method, provides access to the file system that is
  * accessible to the Java virtual machine. The {@link FileSystems} class defines
- * methods to create file systems that provide access to other types of file
- * systems.
+ * methods to create file systems that provide access to other types of (custom)
+ * file systems.
  *
  * <p> A file system is the factory for several types of objects:
  *
@@ -214,10 +214,9 @@
      * Suppose we want to print the space usage for all file stores:
      * <pre>
      *     for (FileStore store: FileSystems.getDefault().getFileStores()) {
-     *         FileStoreSpaceAttributes attrs = Attributes.readFileStoreSpaceAttributes(store);
-     *         long total = attrs.totalSpace() / 1024;
-     *         long used = (attrs.totalSpace() - attrs.unallocatedSpace()) / 1024;
-     *         long avail = attrs.usableSpace() / 1024;
+     *         long total = store.getTotalSpace() / 1024;
+     *         long used = (store.getTotalSpace() - store.getUnallocatedSpace()) / 1024;
+     *         long avail = store.getUsableSpace() / 1024;
      *         System.out.format("%-20s %12d %12d %12d%n", store, total, used, avail);
      *     }
      * </pre>
@@ -244,7 +243,20 @@
     public abstract Set<String> supportedFileAttributeViews();
 
     /**
-     * Converts a path string to a {@code Path}.
+     * Converts a path string, or a sequence of strings that when joined form
+     * a path string, to a {@code Path}. If {@code more} does not specify any
+     * elements then the value of the {@code first} parameter is the path string
+     * to convert. If {@code more} specifies one or more elements then each
+     * non-empty string, including {@code first}, is considered to be a sequence
+     * of name elements (see {@link Path}) and is joined to form a path string.
+     * The details as to how the Strings are joined is provider specific but
+     * typically they will be joined using the {@link #getSeparator
+     * name-separator} as the separator. For example, if the name separator is
+     * "{@code /}" and {@code getPath("/foo","bar","gus")} is invoked, then the
+     * path string {@code "/foo/bar/gus"} is converted to a {@code Path}.
+     * A {@code Path} representing an empty path is returned if {@code first}
+     * is the empty string and {@code more} does not contain any non-empty
+     * strings.
      *
      * <p> The parsing and conversion to a path object is inherently
      * implementation dependent. In the simplest case, the path string is rejected,
@@ -270,18 +282,17 @@
      * index} value indicating the first position in the {@code path} parameter
      * that caused the path string to be rejected.
      *
-     * <p> Invoking this method with an empty path string throws
-     * {@code InvalidPathException}.
+     * @param   first
+     *          the path string or initial part of the path string
+     * @param   more
+     *          additional strings to be joined to form the path string
      *
-     * @param   path
-     *          The path string
-     *
-     * @return  A {@code Path} object
+     * @return  the resulting {@code Path}
      *
      * @throws  InvalidPathException
      *          If the path string cannot be converted
      */
-    public abstract Path getPath(String path);
+    public abstract Path getPath(String first, String... more);
 
     /**
      * Returns a {@code PathMatcher} that performs match operations on the
@@ -290,9 +301,9 @@
      *
      * The {@code syntaxAndPattern} parameter identifies the syntax and the
      * pattern and takes the form:
-     * <blockquote>
+     * <blockquote><pre>
      * <i>syntax</i><b>:</b><i>pattern</i>
-     * </blockquote>
+     * </pre></blockquote>
      * where {@code ':'} stands for itself.
      *
      * <p> A {@code FileSystem} implementation supports the "{@code glob}" and
@@ -409,7 +420,7 @@
      * @throws  UnsupportedOperationException
      *          If the pattern syntax is not known to the implementation
      *
-     * @see Path#newDirectoryStream(String)
+     * @see Files#newDirectoryStream(Path,String)
      */
     public abstract PathMatcher getPathMatcher(String syntaxAndPattern);
 
@@ -421,10 +432,8 @@
      * <p> <b>Usage Example:</b>
      * Suppose we want to make "joe" the owner of a file:
      * <pre>
-     *     Path file = ...
-     *     UserPrincipal joe = file.getFileSystem().getUserPrincipalLookupService()
-     *         .lookupPrincipalByName("joe");
-     *     Attributes.setOwner(file, joe);
+     *     UserPrincipalLookupService lookupService = FileSystems.getDefault().getUserPrincipalLookupService();
+     *     Files.setOwner(path, lookupService.lookupPrincipalByName("joe"));
      * </pre>
      *
      * @throws  UnsupportedOperationException
--- a/jdk/src/share/classes/java/nio/file/FileSystems.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/FileSystems.java	Fri Jan 28 09:28:43 2011 +0000
@@ -164,8 +164,8 @@
      * to the first provider instance. The third provider class is instantiated
      * by invoking it with a reference to the second instance, and so on. The
      * last provider to be instantiated becomes the default provider; its {@code
-     * getFileSystem} method is invoked with the URI {@code "file:///"} to create
-     * the default file system.
+     * getFileSystem} method is invoked with the URI {@code "file:///"} to
+     * get a reference to the default file system.
      *
      * <p> Subsequent invocations of this method return the file system that was
      * returned by the first invocation.
@@ -238,7 +238,7 @@
      * Suppose there is a provider identified by the scheme {@code "memory"}
      * installed:
      * <pre>
-     *   Map&lt;String,String&gt; env = new HashMap&lt;String,String&gt;();
+     *   Map&lt;String,String&gt; env = new HashMap&lt;&gt;();
      *   env.put("capacity", "16G");
      *   env.put("blockSize", "4k");
      *   FileSystem fs = FileSystems.newFileSystem(URI.create("memory:///?name=logfs"), env);
@@ -343,33 +343,25 @@
      *
      * <p> This method makes use of specialized providers that create pseudo file
      * systems where the contents of one or more files is treated as a file
-     * system. The {@code file} parameter is a reference to an existing file
-     * and the {@code env} parameter is a map of provider specific properties to
-     * configure the file system.
+     * system.
      *
      * <p> This method iterates over the {@link FileSystemProvider#installedProviders()
      * installed} providers. It invokes, in turn, each provider's {@link
-     * FileSystemProvider#newFileSystem(FileRef,Map) newFileSystem(FileRef,Map)} method.
-     * If a provider returns a file system then the iteration terminates
-     * and the file system is returned. If none of the installed providers return
-     * a {@code FileSystem} then an attempt is made to locate the provider using
-     * the given class loader. If a provider returns a file system then the lookup
-     * terminates and the file system is returned.
+     * FileSystemProvider#newFileSystem(Path,Map) newFileSystem(Path,Map)} method
+     * with an empty map. If a provider returns a file system then the iteration
+     * terminates and the file system is returned. If none of the installed
+     * providers return a {@code FileSystem} then an attempt is made to locate
+     * the provider using the given class loader. If a provider returns a file
+     * system then the lookup terminates and the file system is returned.
      *
-     * @param   file
-     *          a reference to a file
-     * @param   env
-     *          a map of provider specific properties to configure the file system;
-     *          may be empty
+     * @param   path
+     *          the path to the file
      * @param   loader
      *          the class loader to locate the provider or {@code null} to only
      *          attempt to locate an installed provider
      *
      * @return  a new file system
      *
-     * @throws  IllegalArgumentException
-     *          if the {@code env} parameter does not contain properties required
-     *          by the provider, or a property value is invalid
      * @throws  ProviderNotFoundException
      *          if a provider supporting this file type cannot be located
      * @throws  ServiceConfigurationError
@@ -380,18 +372,18 @@
      *          if a security manager is installed and it denies an unspecified
      *          permission
      */
-    public static FileSystem newFileSystem(FileRef file,
-                                           Map<String,?> env,
+    public static FileSystem newFileSystem(Path path,
                                            ClassLoader loader)
         throws IOException
     {
-        if (file == null)
+        if (path == null)
             throw new NullPointerException();
+        Map<String,?> env = Collections.emptyMap();
 
         // check installed providers
         for (FileSystemProvider provider: FileSystemProvider.installedProviders()) {
             try {
-                return provider.newFileSystem(file, env);
+                return provider.newFileSystem(path, env);
             } catch (UnsupportedOperationException uoe) {
             }
         }
@@ -402,7 +394,7 @@
                 .load(FileSystemProvider.class, loader);
             for (FileSystemProvider provider: sl) {
                 try {
-                    return provider.newFileSystem(file, env);
+                    return provider.newFileSystem(path, env);
                 } catch (UnsupportedOperationException uoe) {
                 }
             }
--- a/jdk/src/share/classes/java/nio/file/FileTreeWalker.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/FileTreeWalker.java	Fri Jan 28 09:28:43 2011 +0000
@@ -69,7 +69,8 @@
         FileVisitResult result = walk(start,
                                       0,
                                       new ArrayList<AncestorDirectory>());
-        Objects.nonNull(result, "FileVisitor returned null");
+        if (result == null)
+            throw new NullPointerException("FileVisitor returned null");
     }
 
     /**
@@ -102,12 +103,13 @@
         if (attrs == null) {
             try {
                 try {
-                    attrs = Attributes.readBasicFileAttributes(file, linkOptions);
+                    attrs = Files.readAttributes(file, BasicFileAttributes.class, linkOptions);
                 } catch (IOException x1) {
                     if (followLinks) {
                         try {
-                            attrs = Attributes
-                                .readBasicFileAttributes(file, LinkOption.NOFOLLOW_LINKS);
+                            attrs = Files.readAttributes(file,
+                                                         BasicFileAttributes.class,
+                                                         LinkOption.NOFOLLOW_LINKS);
                         } catch (IOException x2) {
                             exc = x2;
                         }
@@ -151,7 +153,7 @@
                 } else {
                     boolean isSameFile = false;
                     try {
-                        isSameFile = file.isSameFile(ancestor.file());
+                        isSameFile = Files.isSameFile(file, ancestor.file());
                     } catch (IOException x) {
                         // ignore
                     } catch (SecurityException x) {
@@ -175,7 +177,7 @@
 
             // open the directory
             try {
-                stream = file.newDirectoryStream();
+                stream = Files.newDirectoryStream(file);
             } catch (IOException x) {
                 return visitor.visitFileFailed(file, x);
             } catch (SecurityException x) {
@@ -212,7 +214,11 @@
             } finally {
                 try {
                     stream.close();
-                } catch (IOException x) { }
+                } catch (IOException e) {
+                    // IOException will be notified to postVisitDirectory
+                    if (ioe == null)
+                        ioe = e;
+                }
             }
 
             // invoke postVisitDirectory last
--- a/jdk/src/share/classes/java/nio/file/FileVisitor.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/FileVisitor.java	Fri Jan 28 09:28:43 2011 +0000
@@ -30,8 +30,8 @@
 
 /**
  * A visitor of files. An implementation of this interface is provided to the
- * {@link Files#walkFileTree walkFileTree} utility method to visit each file
- * in a tree.
+ * {@link Files#walkFileTree Files.walkFileTree} methods to visit each file in
+ * a file tree.
  *
  * <p> <b>Usage Examples:</b>
  * Suppose we want to delete a file tree. In that case, each directory should
@@ -43,19 +43,20 @@
  *         public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
  *             throws IOException
  *         {
- *             file.delete();
+ *             Files.delete(file);
  *             return FileVisitResult.CONTINUE;
  *         }
  *         &#64;Override
  *         public FileVisitResult postVisitDirectory(Path dir, IOException e)
  *             throws IOException
  *         {
- *             if (e != null) {
+ *             if (e == null) {
+ *                 Files.delete(dir);
+ *                 return FileVisitResult.CONTINUE;
+ *             } else {
  *                 // directory iteration failed
  *                 throw e;
  *             }
- *             dir.delete();
- *             return FileVisitResult.CONTINUE;
  *         }
  *     });
  * </pre>
@@ -72,10 +73,12 @@
  *             public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
  *                 throws IOException
  *             {
+ *                 Path targetdir = target.resolve(source.relativize(dir));
  *                 try {
- *                     dir.copyTo(target.resolve(source.relativize(dir)));
+ *                     Files.copy(dir, targetdir);
  *                 } catch (FileAlreadyExistsException e) {
- *                      // ignore
+ *                      if (!Files.isDirectory(targetdir))
+ *                          throw e;
  *                 }
  *                 return CONTINUE;
  *             }
@@ -83,7 +86,7 @@
  *             public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
  *                 throws IOException
  *             {
- *                 file.copyTo(target.resolve(source.relativize(file)));
+ *                 Files.copy(file, target.resolve(source.relativize(file)));
  *                 return CONTINUE;
  *             }
  *         });
--- a/jdk/src/share/classes/java/nio/file/Files.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/Files.java	Fri Jan 28 09:28:43 2011 +0000
@@ -25,16 +25,32 @@
 
 package java.nio.file;
 
+import java.nio.file.attribute.*;
+import java.nio.file.spi.FileSystemProvider;
 import java.nio.file.spi.FileTypeDetector;
-import java.nio.file.attribute.*;
+import java.nio.channels.SeekableByteChannel;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
 import java.io.IOException;
 import java.util.*;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
 
 /**
- * This class consists exclusively of static methods that operate on files or
- * directories.
+ * This class consists exclusively of static methods that operate on files,
+ * directories, or other types of files.
+ *
+ * <p> In most cases, the methods defined here will delegate to the associated
+ * file system provider to perform the file operations.
  *
  * @since 1.7
  */
@@ -42,8 +58,1422 @@
 public final class Files {
     private Files() { }
 
+    /**
+     * Returns the {@code FileSystemProvider} to delegate to.
+     */
+    private static FileSystemProvider provider(Path path) {
+        return path.getFileSystem().provider();
+    }
+
+    // -- File contents --
+
+    /**
+     * Opens a file, returning an input stream to read from the file. The stream
+     * will not be buffered, and is not required to support the {@link
+     * InputStream#mark mark} or {@link InputStream#reset reset} methods. The
+     * stream will be safe for access by multiple concurrent threads. Reading
+     * commences at the beginning of the file. Whether the returned stream is
+     * <i>asynchronously closeable</i> and/or <i>interruptible</i> is highly
+     * file system provider specific and therefore not specified.
+     *
+     * <p> The {@code options} parameter determines how the file is opened.
+     * If no options are present then it is equivalent to opening the file with
+     * the {@link StandardOpenOption#READ READ} option. In addition to the {@code
+     * READ} option, an implementation may also support additional implementation
+     * specific options.
+     *
+     * @param   path
+     *          the path to the file to open
+     * @param   options
+     *          options specifying how the file is opened
+     *
+     * @return  a new input stream
+     *
+     * @throws  IllegalArgumentException
+     *          if an invalid combination of options is specified
+     * @throws  UnsupportedOperationException
+     *          if an unsupported option is specified
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the file.
+     */
+    public static InputStream newInputStream(Path path, OpenOption... options)
+        throws IOException
+    {
+        return provider(path).newInputStream(path, options);
+    }
+
+    /**
+     * Opens or creates a file, returning an output stream that may be used to
+     * write bytes to the file. The resulting stream will not be buffered. The
+     * stream will be safe for access by multiple concurrent threads. Whether
+     * the returned stream is <i>asynchronously closeable</i> and/or
+     * <i>interruptible</i> is highly file system provider specific and
+     * therefore not specified.
+     *
+     * <p> This method opens or creates a file in exactly the manner specified
+     * by the {@link #newByteChannel(Path,Set,FileAttribute[]) newByteChannel}
+     * method with the exception that the {@link StandardOpenOption#READ READ}
+     * option may not be present in the array of options. If no options are
+     * present then this method works as if the {@link StandardOpenOption#CREATE
+     * CREATE}, {@link StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING},
+     * and {@link StandardOpenOption#WRITE WRITE} options are present. In other
+     * words, it opens the file for writing, creating the file if it doesn't
+     * exist, or initially truncating an existing {@link #isRegularFile
+     * regular-file} to a size of {@code 0} if it exists.
+     *
+     * <p> <b>Usage Examples:</b>
+     * <pre>
+     *     Path path = ...
+     *
+     *     // replace an existing file or create the file if it doesn't initially exist
+     *     OutputStream out = Files.newOutputStream(path);
+     *
+     *     // append to an existing file, fail if the file does not exist
+     *     out = Files.newOutputStream(path, APPEND);
+     *
+     *     // append to an existing file, create file if it doesn't initially exist
+     *     out = Files.newOutputStream(CREATE, APPEND);
+     *
+     *     // always create new file, failing if it already exists
+     *     out = Files.newOutputStream(CREATE_NEW);
+     * </pre>
+     *
+     * @param   path
+     *          the path to the file to open or create
+     * @param   options
+     *          options specifying how the file is opened
+     *
+     * @return  a new output stream
+     *
+     * @throws  IllegalArgumentException
+     *          if {@code options} contains an invalid combination of options
+     * @throws  UnsupportedOperationException
+     *          if an unsupported option is specified
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method is invoked to check write access to the file. The {@link
+     *          SecurityManager#checkDelete(String) checkDelete} method is
+     *          invoked to check delete access if the file is opened with the
+     *          {@code DELETE_ON_CLOSE} option.
+     */
+    public static OutputStream newOutputStream(Path path, OpenOption... options)
+        throws IOException
+    {
+        return provider(path).newOutputStream(path, options);
+    }
+
+    /**
+     * Opens or creates a file, returning a seekable byte channel to access the
+     * file.
+     *
+     * <p> The {@code options} parameter determines how the file is opened.
+     * The {@link StandardOpenOption#READ READ} and {@link
+     * StandardOpenOption#WRITE WRITE} options determine if the file should be
+     * opened for reading and/or writing. If neither option (or the {@link
+     * StandardOpenOption#APPEND APPEND} option) is present then the file is
+     * opened for reading. By default reading or writing commence at the
+     * beginning of the file.
+     *
+     * <p> In the addition to {@code READ} and {@code WRITE}, the following
+     * options may be present:
+     *
+     * <table border=1 cellpadding=5 summary="">
+     * <tr> <th>Option</th> <th>Description</th> </tr>
+     * <tr>
+     *   <td> {@link StandardOpenOption#APPEND APPEND} </td>
+     *   <td> If this option is present then the file is opened for writing and
+     *     each invocation of the channel's {@code write} method first advances
+     *     the position to the end of the file and then writes the requested
+     *     data. Whether the advancement of the position and the writing of the
+     *     data are done in a single atomic operation is system-dependent and
+     *     therefore unspecified. This option may not be used in conjunction
+     *     with the {@code READ} or {@code TRUNCATE_EXISTING} options. </td>
+     * </tr>
+     * <tr>
+     *   <td> {@link StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING} </td>
+     *   <td> If this option is present then the existing file is truncated to
+     *   a size of 0 bytes. This option is ignored when the file is opened only
+     *   for reading. </td>
+     * </tr>
+     * <tr>
+     *   <td> {@link StandardOpenOption#CREATE_NEW CREATE_NEW} </td>
+     *   <td> If this option is present then a new file is created, failing if
+     *   the file already exists or is a symbolic link. When creating a file the
+     *   check for the existence of the file and the creation of the file if it
+     *   does not exist is atomic with respect to other file system operations.
+     *   This option is ignored when the file is opened only for reading. </td>
+     * </tr>
+     * <tr>
+     *   <td > {@link StandardOpenOption#CREATE CREATE} </td>
+     *   <td> If this option is present then an existing file is opened if it
+     *   exists, otherwise a new file is created. This option is ignored if the
+     *   {@code CREATE_NEW} option is also present or the file is opened only
+     *   for reading. </td>
+     * </tr>
+     * <tr>
+     *   <td > {@link StandardOpenOption#DELETE_ON_CLOSE DELETE_ON_CLOSE} </td>
+     *   <td> When this option is present then the implementation makes a
+     *   <em>best effort</em> attempt to delete the file when closed by the
+     *   {@link SeekableByteChannel#close close} method. If the {@code close}
+     *   method is not invoked then a <em>best effort</em> attempt is made to
+     *   delete the file when the Java virtual machine terminates. </td>
+     * </tr>
+     * <tr>
+     *   <td>{@link StandardOpenOption#SPARSE SPARSE} </td>
+     *   <td> When creating a new file this option is a <em>hint</em> that the
+     *   new file will be sparse. This option is ignored when not creating
+     *   a new file. </td>
+     * </tr>
+     * <tr>
+     *   <td> {@link StandardOpenOption#SYNC SYNC} </td>
+     *   <td> Requires that every update to the file's content or metadata be
+     *   written synchronously to the underlying storage device. (see <a
+     *   href="package-summary.html#integrity"> Synchronized I/O file
+     *   integrity</a>). </td>
+     * <tr>
+     * <tr>
+     *   <td> {@link StandardOpenOption#DSYNC DSYNC} </td>
+     *   <td> Requires that every update to the file's content be written
+     *   synchronously to the underlying storage device. (see <a
+     *   href="package-summary.html#integrity"> Synchronized I/O file
+     *   integrity</a>). </td>
+     * </tr>
+     * </table>
+     *
+     * <p> An implementation may also support additional implementation specific
+     * options.
+     *
+     * <p> The {@code attrs} parameter is optional {@link FileAttribute
+     * file-attributes} to set atomically when a new file is created.
+     *
+     * <p> In the case of the default provider, the returned seekable byte channel
+     * is a {@link java.nio.channels.FileChannel}.
+     *
+     * <p> <b>Usage Examples:</b>
+     * <pre>
+     *     Path path = ...
+     *
+     *     // open file for reading
+     *     ReadableByteChannel rbc = Files.newByteChannel(path, EnumSet.of(READ)));
+     *
+     *     // open file for writing to the end of an existing file, creating
+     *     // the file if it doesn't already exist
+     *     WritableByteChannel wbc = Files.newByteChannel(path, EnumSet.of(CREATE,APPEND));
+     *
+     *     // create file with initial permissions, opening it for both reading and writing
+     *     {@code FileAttribute<<SetPosixFilePermission>> perms = ...}
+     *     SeekableByteChannel sbc = Files.newByteChannel(path, EnumSet.of(CREATE_NEW,READ,WRITE), perms);
+     * </pre>
+     *
+     * @param   path
+     *          the path to the file to open or create
+     * @param   options
+     *          options specifying how the file is opened
+     * @param   attrs
+     *          an optional list of file attributes to set atomically when
+     *          creating the file
+     *
+     * @return  a new seekable byte channel
+     *
+     * @throws  IllegalArgumentException
+     *          if the set contains an invalid combination of options
+     * @throws  UnsupportedOperationException
+     *          if an unsupported open option is specified or the array contains
+     *          attributes that cannot be set atomically when creating the file
+     * @throws  FileAlreadyExistsException
+     *          if a file of that name already exists and the {@link
+     *          StandardOpenOption#CREATE_NEW CREATE_NEW} option is specified
+     *          <i>(optional specific exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the path if the file is
+     *          opened for reading. The {@link SecurityManager#checkWrite(String)
+     *          checkWrite} method is invoked to check write access to the path
+     *          if the file is opened for writing. The {@link
+     *          SecurityManager#checkDelete(String) checkDelete} method is
+     *          invoked to check delete access if the file is opened with the
+     *          {@code DELETE_ON_CLOSE} option.
+     *
+     * @see java.nio.channels.FileChannel#open(Path,Set,FileAttribute[])
+     */
+    public static SeekableByteChannel newByteChannel(Path path,
+                                                     Set<? extends OpenOption> options,
+                                                     FileAttribute<?>... attrs)
+        throws IOException
+    {
+        return provider(path).newByteChannel(path, options, attrs);
+    }
+
+    /**
+     * Opens or creates a file, returning a seekable byte channel to access the
+     * file.
+     *
+     * <p> This method opens or creates a file in exactly the manner specified
+     * by the {@link #newByteChannel(Path,Set,FileAttribute[]) newByteChannel}
+     * method.
+     *
+     * @param   path
+     *          the path to the file to open or create
+     * @param   options
+     *          options specifying how the file is opened
+     *
+     * @return  a new seekable byte channel
+     *
+     * @throws  IllegalArgumentException
+     *          if the set contains an invalid combination of options
+     * @throws  UnsupportedOperationException
+     *          if an unsupported open option is specified
+     * @throws  FileAlreadyExistsException
+     *          if a file of that name already exists and the {@link
+     *          StandardOpenOption#CREATE_NEW CREATE_NEW} option is specified
+     *          <i>(optional specific exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the path if the file is
+     *          opened for reading. The {@link SecurityManager#checkWrite(String)
+     *          checkWrite} method is invoked to check write access to the path
+     *          if the file is opened for writing. The {@link
+     *          SecurityManager#checkDelete(String) checkDelete} method is
+     *          invoked to check delete access if the file is opened with the
+     *          {@code DELETE_ON_CLOSE} option.
+     *
+     * @see java.nio.channels.FileChannel#open(Path,OpenOption[])
+     */
+    public static SeekableByteChannel newByteChannel(Path path, OpenOption... options)
+        throws IOException
+    {
+        Set<OpenOption> set = new HashSet<OpenOption>(options.length);
+        Collections.addAll(set, options);
+        return newByteChannel(path, set);
+    }
+
+    // -- Directories --
+
+    /**
+     * Opens a directory, returning a {@link DirectoryStream} to iterate over
+     * all entries in the directory. The elements returned by the directory
+     * stream's {@link DirectoryStream#iterator iterator} are of type {@code
+     * Path}, each one representing an entry in the directory. The {@code Path}
+     * objects are obtained as if by {@link Path#resolve(Path) resolving} the
+     * name of the directory entry against {@code dir}.
+     *
+     * <p> When not using the try-with-resources construct, then directory
+     * stream's {@code close} method should be invoked after iteration is
+     * completed so as to free any resources held for the open directory.
+     *
+     * <p> When an implementation supports operations on entries in the
+     * directory that execute in a race-free manner then the returned directory
+     * stream is a {@link SecureDirectoryStream}.
+     *
+     * @param   dir
+     *          the path to the directory
+     *
+     * @return  a new and open {@code DirectoryStream} object
+     *
+     * @throws  NotDirectoryException
+     *          if the file could not otherwise be opened because it is not
+     *          a directory <i>(optional specific exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the directory.
+     */
+    public static DirectoryStream<Path> newDirectoryStream(Path dir)
+        throws IOException
+    {
+        return provider(dir).newDirectoryStream(dir, new DirectoryStream.Filter<Path>() {
+            @Override
+            public boolean accept(Path entry) {
+                return true;
+            }
+        });
+    }
+
+    /**
+     * Opens a directory, returning a {@link DirectoryStream} to iterate over
+     * the entries in the directory. The elements returned by the directory
+     * stream's {@link DirectoryStream#iterator iterator} are of type {@code
+     * Path}, each one representing an entry in the directory. The {@code Path}
+     * objects are obtained as if by {@link Path#resolve(Path) resolving} the
+     * name of the directory entry against {@code dir}. The entries returned by
+     * the iterator are filtered by matching the {@code String} representation
+     * of their file names against the given <em>globbing</em> pattern.
+     *
+     * <p> For example, suppose we want to iterate over the files ending with
+     * ".java" in a directory:
+     * <pre>
+     *     Path dir = ...
+     *     try (DirectoryStream&lt;Path&gt; stream = Files.newDirectoryStream(dir, "*.java")) {
+     *         :
+     *     }
+     * </pre>
+     *
+     * <p> The globbing pattern is specified by the {@link
+     * FileSystem#getPathMatcher getPathMatcher} method.
+     *
+     * <p> When not using the try-with-resources construct, then directory
+     * stream's {@code close} method should be invoked after iteration is
+     * completed so as to free any resources held for the open directory.
+     *
+     * <p> When an implementation supports operations on entries in the
+     * directory that execute in a race-free manner then the returned directory
+     * stream is a {@link SecureDirectoryStream}.
+     *
+     * @param   dir
+     *          the path to the directory
+     * @param   glob
+     *          the glob pattern
+     *
+     * @return  a new and open {@code DirectoryStream} object
+     *
+     * @throws  java.util.regex.PatternSyntaxException
+     *          if the pattern is invalid
+     * @throws  NotDirectoryException
+     *          if the file could not otherwise be opened because it is not
+     *          a directory <i>(optional specific exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the directory.
+     */
+    public static DirectoryStream<Path> newDirectoryStream(Path dir, String glob)
+        throws IOException
+    {
+        // avoid creating a matcher if all entries are required.
+        if (glob.equals("*"))
+            return newDirectoryStream(dir);
+
+        // create a matcher and return a filter that uses it.
+        FileSystem fs = dir.getFileSystem();
+        final PathMatcher matcher = fs.getPathMatcher("glob:" + glob);
+        DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
+            @Override
+            public boolean accept(Path entry)  {
+                return matcher.matches(entry.getFileName());
+            }
+        };
+        return fs.provider().newDirectoryStream(dir, filter);
+    }
+
+    /**
+     * Opens a directory, returning a {@link DirectoryStream} to iterate over
+     * the entries in the directory. The elements returned by the directory
+     * stream's {@link DirectoryStream#iterator iterator} are of type {@code
+     * Path}, each one representing an entry in the directory. The {@code Path}
+     * objects are obtained as if by {@link Path#resolve(Path) resolving} the
+     * name of the directory entry against {@code dir}. The entries returned by
+     * the iterator are filtered by the given {@link DirectoryStream.Filter
+     * filter}.
+     *
+     * <p> When not using the try-with-resources construct, then directory
+     * stream's {@code close} method should be invoked after iteration is
+     * completed so as to free any resources held for the open directory.
+     *
+     * <p> Where the filter terminates due to an uncaught error or runtime
+     * exception then it is propagated to the {@link Iterator#hasNext()
+     * hasNext} or {@link Iterator#next() next} method. Where an {@code
+     * IOException} is thrown, it results in the {@code hasNext} or {@code
+     * next} method throwing a {@link DirectoryIteratorException} with the
+     * {@code IOException} as the cause.
+     *
+     * <p> When an implementation supports operations on entries in the
+     * directory that execute in a race-free manner then the returned directory
+     * stream is a {@link SecureDirectoryStream}.
+     *
+     * <p> <b>Usage Example:</b>
+     * Suppose we want to iterate over the files in a directory that are
+     * larger than 8K.
+     * <pre>
+     *     DirectoryStream.Filter&lt;Path&gt; filter = new DirectoryStream.Filter&lt;Path&gt;() {
+     *         public boolean accept(Path file) throws IOException {
+     *             return (Files.size(file) > 8192L);
+     *         }
+     *     };
+     *     Path dir = ...
+     *     try (DirectoryStream&lt;Path&gt; stream = Files.newDirectoryStream(dir, filter)) {
+     *         :
+     *     }
+     * </pre>
+     *
+     * @param   dir
+     *          the path to the directory
+     * @param   filter
+     *          the directory stream filter
+     *
+     * @return  a new and open {@code DirectoryStream} object
+     *
+     * @throws  NotDirectoryException
+     *          if the file could not otherwise be opened because it is not
+     *          a directory <i>(optional specific exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the directory.
+     */
+    public static DirectoryStream<Path> newDirectoryStream(Path dir,
+                                                           DirectoryStream.Filter<? super Path> filter)
+        throws IOException
+    {
+        return provider(dir).newDirectoryStream(dir, filter);
+    }
+
+    // -- Creation and deletion --
+
+    /**
+     * Creates a new and empty file, failing if the file already exists. The
+     * check for the existence of the file and the creation of the new file if
+     * it does not exist are a single operation that is atomic with respect to
+     * all other filesystem activities that might affect the directory.
+     *
+     * <p> The {@code attrs} parameter is optional {@link FileAttribute
+     * file-attributes} to set atomically when creating the file. Each attribute
+     * is identified by its {@link FileAttribute#name name}. If more than one
+     * attribute of the same name is included in the array then all but the last
+     * occurrence is ignored.
+     *
+     * @param   path
+     *          the path to the file to create
+     * @param   attrs
+     *          an optional list of file attributes to set atomically when
+     *          creating the file
+     *
+     * @return  the file
+     *
+     * @throws  UnsupportedOperationException
+     *          if the array contains an attribute that cannot be set atomically
+     *          when creating the file
+     * @throws  FileAlreadyExistsException
+     *          if a file of that name already exists
+     *          <i>(optional specific exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs or the parent directory does not exist
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method is invoked to check write access to the new file.
+     */
+    public static Path createFile(Path path, FileAttribute<?>... attrs)
+        throws IOException
+    {
+        EnumSet<StandardOpenOption> options =
+            EnumSet.<StandardOpenOption>of(StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE);
+        newByteChannel(path, options, attrs).close();
+        return path;
+    }
+
+    /**
+     * Creates a new directory. The check for the existence of the file and the
+     * creation of the directory if it does not exist are a single operation
+     * that is atomic with respect to all other filesystem activities that might
+     * affect the directory. The {@link #createDirectories createDirectories}
+     * method should be used where it is required to create all nonexistent
+     * parent directories first.
+     *
+     * <p> The {@code attrs} parameter is optional {@link FileAttribute
+     * file-attributes} to set atomically when creating the directory. Each
+     * attribute is identified by its {@link FileAttribute#name name}. If more
+     * than one attribute of the same name is included in the array then all but
+     * the last occurrence is ignored.
+     *
+     * @param   dir
+     *          the directory to create
+     * @param   attrs
+     *          an optional list of file attributes to set atomically when
+     *          creating the directory
+     *
+     * @return  the directory
+     *
+     * @throws  UnsupportedOperationException
+     *          if the array contains an attribute that cannot be set atomically
+     *          when creating the directory
+     * @throws  FileAlreadyExistsException
+     *          if a directory could not otherwise be created because a file of
+     *          that name already exists <i>(optional specific exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs or the parent directory does not exist
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method is invoked to check write access to the new directory.
+     */
+    public static Path createDirectory(Path dir, FileAttribute<?>... attrs)
+        throws IOException
+    {
+        provider(dir).createDirectory(dir, attrs);
+        return dir;
+    }
+
+    /**
+     * Creates a directory by creating all nonexistent parent directories first.
+     * Unlike the {@link #createDirectory createDirectory} method, an exception
+     * is not thrown if the directory could not be created because it already
+     * exists.
+     *
+     * <p> The {@code attrs} parameter is optional {@link FileAttribute
+     * file-attributes} to set atomically when creating the nonexistent
+     * directories. Each file attribute is identified by its {@link
+     * FileAttribute#name name}. If more than one attribute of the same name is
+     * included in the array then all but the last occurrence is ignored.
+     *
+     * <p> If this method fails, then it may do so after creating some, but not
+     * all, of the parent directories.
+     *
+     * @param   dir
+     *          the directory to create
+     *
+     * @param   attrs
+     *          an optional list of file attributes to set atomically when
+     *          creating the directory
+     *
+     * @return  the directory
+     *
+     * @throws  UnsupportedOperationException
+     *          if the array contains an attribute that cannot be set atomically
+     *          when creating the directory
+     * @throws  FileAlreadyExistsException
+     *          if {@code dir} exists but is not a directory <i>(optional specific
+     *          exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          in the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method is invoked prior to attempting to create a directory and
+     *          its {@link SecurityManager#checkRead(String) checkRead} is
+     *          invoked for each parent directory that is checked. If {@code
+     *          dir} is not an absolute path then its {@link Path#toAbsolutePath
+     *          toAbsolutePath} may need to be invoked to get its absolute path.
+     *          This may invoke the security manager's {@link
+     *          SecurityManager#checkPropertyAccess(String) checkPropertyAccess}
+     *          method to check access to the system property {@code user.dir}
+     */
+    public static Path createDirectories(Path dir, FileAttribute<?>... attrs)
+        throws IOException
+    {
+        // attempt to create the directory
+        try {
+            createAndCheckIsDirectory(dir, attrs);
+            return dir;
+        } catch (FileAlreadyExistsException x) {
+            // file exists and is not a directory
+            throw x;
+        } catch (IOException x) {
+            // parent may not exist or other reason
+        }
+        SecurityException se = null;
+        try {
+            dir = dir.toAbsolutePath();
+        } catch (SecurityException x) {
+            // don't have permission to get absolute path
+            se = x;
+        }
+        // find a decendent that exists
+        Path parent = dir.getParent();
+        while (parent != null) {
+            try {
+                provider(parent).checkAccess(parent);
+                break;
+            } catch (NoSuchFileException x) {
+                // does not exist
+            }
+            parent = parent.getParent();
+        }
+        if (parent == null) {
+            // unable to find existing parent
+            if (se != null)
+                throw se;
+            throw new IOException("Root directory does not exist");
+        }
+
+        // create directories
+        Path child = parent;
+        for (Path name: parent.relativize(dir)) {
+            child = child.resolve(name);
+            createAndCheckIsDirectory(child, attrs);
+        }
+        return dir;
+    }
+
+    /**
+     * Used by createDirectories to attempt to create a directory. A no-op
+     * if the directory already exists.
+     */
+    private static void createAndCheckIsDirectory(Path dir,
+                                                  FileAttribute<?>... attrs)
+        throws IOException
+    {
+        try {
+            createDirectory(dir, attrs);
+        } catch (FileAlreadyExistsException x) {
+            if (!isDirectory(dir, LinkOption.NOFOLLOW_LINKS))
+                throw x;
+        }
+    }
+
+    /**
+     * Creates a new empty file in the specified directory, using the given
+     * prefix and suffix strings to generate its name. The resulting
+     * {@code Path} is associated with the same {@code FileSystem} as the given
+     * directory.
+     *
+     * <p> The details as to how the name of the file is constructed is
+     * implementation dependent and therefore not specified. Where possible
+     * the {@code prefix} and {@code suffix} are used to construct candidate
+     * names in the same manner as the {@link
+     * java.io.File#createTempFile(String,String,File)} method.
+     *
+     * <p> As with the {@code File.createTempFile} methods, this method is only
+     * part of a temporary-file facility. Where used as a <em>work files</em>,
+     * the resulting file may be opened using the {@link
+     * StandardOpenOption#DELETE_ON_CLOSE DELETE_ON_CLOSE} option so that the
+     * file is deleted when the appropriate {@code close} method is invoked.
+     * Alternatively, a {@link Runtime#addShutdownHook shutdown-hook}, or the
+     * {@link java.io.File#deleteOnExit} mechanism may be used to delete the
+     * file automatically.
+     *
+     * <p> The {@code attrs} parameter is optional {@link FileAttribute
+     * file-attributes} to set atomically when creating the file. Each attribute
+     * is identified by its {@link FileAttribute#name name}. If more than one
+     * attribute of the same name is included in the array then all but the last
+     * occurrence is ignored. When no file attributes are specified, then the
+     * resulting file may have more restrictive access permissions to files
+     * created by the {@link java.io.File#createTempFile(String,String,File)}
+     * method.
+     *
+     * @param   dir
+     *          the path to directory in which to create the file
+     * @param   prefix
+     *          the prefix string to be used in generating the file's name;
+     *          may be {@code null}
+     * @param   suffix
+     *          the suffix string to be used in generating the file's name;
+     *          may be {@code null}, in which case "{@code .tmp}" is used
+     * @param   attrs
+     *          an optional list of file attributes to set atomically when
+     *          creating the file
+     *
+     * @return  the path to the newly created file that did not exist before
+     *          this method was invoked
+     *
+     * @throws  IllegalArgumentException
+     *          if the prefix or suffix parameters cannot be used to generate
+     *          a candidate file name
+     * @throws  UnsupportedOperationException
+     *          if the array contains an attribute that cannot be set atomically
+     *          when creating the directory
+     * @throws  IOException
+     *          if an I/O error occurs or {@code dir} does not exist
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method is invoked to check write access to the file.
+     */
+    public static Path createTempFile(Path dir,
+                                      String prefix,
+                                      String suffix,
+                                      FileAttribute<?>... attrs)
+        throws IOException
+    {
+        return TempFileHelper.createTempFile(dir, prefix, suffix, attrs);
+    }
+
+    /**
+     * Creates an empty file in the default temporary-file directory, using
+     * the given prefix and suffix to generate its name. The resulting {@code
+     * Path} is associated with the default {@code FileSystem}.
+     *
+     * <p> This method works in exactly the manner specified by the
+     * {@link #createTempFile(Path,String,String,FileAttribute[])} method for
+     * the case that the {@code dir} parameter is the temporary-file directory.
+     *
+     * @param   prefix
+     *          the prefix string to be used in generating the file's name;
+     *          may be {@code null}
+     * @param   suffix
+     *          the suffix string to be used in generating the file's name;
+     *          may be {@code null}, in which case "{@code .tmp}" is used
+     * @param   attrs
+     *          an optional list of file attributes to set atomically when
+     *          creating the file
+     *
+     * @return  the path to the newly created file that did not exist before
+     *          this method was invoked
+     *
+     * @throws  IllegalArgumentException
+     *          if the prefix or suffix parameters cannot be used to generate
+     *          a candidate file name
+     * @throws  UnsupportedOperationException
+     *          if the array contains an attribute that cannot be set atomically
+     *          when creating the directory
+     * @throws  IOException
+     *          if an I/O error occurs or the temporary-file directory does not
+     *          exist
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method is invoked to check write access to the file.
+     */
+    public static Path createTempFile(String prefix,
+                                      String suffix,
+                                      FileAttribute<?>... attrs)
+        throws IOException
+    {
+        return TempFileHelper.createTempFile(null, prefix, suffix, attrs);
+    }
+
+    /**
+     * Creates a new directory in the specified directory, using the given
+     * prefix to generate its name.  The resulting {@code Path} is associated
+     * with the same {@code FileSystem} as the given directory.
+     *
+     * <p> The details as to how the name of the directory is constructed is
+     * implementation dependent and therefore not specified. Where possible
+     * the {@code prefix} is used to construct candidate names.
+     *
+     * <p> As with the {@code createTempFile} methods, this method is only
+     * part of a temporary-file facility. A {@link Runtime#addShutdownHook
+     * shutdown-hook}, or the {@link java.io.File#deleteOnExit} mechanism may be
+     * used to delete the directory automatically.
+     *
+     * <p> The {@code attrs} parameter is optional {@link FileAttribute
+     * file-attributes} to set atomically when creating the directory. Each
+     * attribute is identified by its {@link FileAttribute#name name}. If more
+     * than one attribute of the same name is included in the array then all but
+     * the last occurrence is ignored.
+     *
+     * @param   dir
+     *          the path to directory in which to create the directory
+     * @param   prefix
+     *          the prefix string to be used in generating the directory's name;
+     *          may be {@code null}
+     * @param   attrs
+     *          an optional list of file attributes to set atomically when
+     *          creating the directory
+     *
+     * @return  the path to the newly created directory that did not exist before
+     *          this method was invoked
+     *
+     * @throws  IllegalArgumentException
+     *          if the prefix cannot be used to generate a candidate directory name
+     * @throws  UnsupportedOperationException
+     *          if the array contains an attribute that cannot be set atomically
+     *          when creating the directory
+     * @throws  IOException
+     *          if an I/O error occurs or {@code dir} does not exist
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method is invoked to check write access when creating the
+     *          directory.
+     */
+    public static Path createTempDirectory(Path dir,
+                                           String prefix,
+                                           FileAttribute<?>... attrs)
+        throws IOException
+    {
+        return TempFileHelper.createTempDirectory(dir, prefix, attrs);
+    }
+
+    /**
+     * Creates a new directory in the default temporary-file directory, using
+     * the given prefix and suffix to generate its name. The resulting {@code
+     * Path} is associated with the default {@code FileSystem}.
+     *
+     * <p> This method works in exactly the manner specified by {@link
+     * #createTempDirectory(Path,String,FileAttribute[])} method for the case
+     * that the {@code dir} parameter is the temporary-file directory.
+     *
+     * @param   prefix
+     *          the prefix string to be used in generating the directory's name;
+     *          may be {@code null}
+     * @param   attrs
+     *          an optional list of file attributes to set atomically when
+     *          creating the directory
+     *
+     * @return  the path to the newly created directory that did not exist before
+     *          this method was invoked
+     *
+     * @throws  IllegalArgumentException
+     *          if the prefix cannot be used to generate a candidate directory name
+     * @throws  UnsupportedOperationException
+     *          if the array contains an attribute that cannot be set atomically
+     *          when creating the directory
+     * @throws  IOException
+     *          if an I/O error occurs or the temporary-file directory does not
+     *          exist
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method is invoked to check write access when creating the
+     *          directory.
+     */
+    public static Path createTempDirectory(String prefix,
+                                           FileAttribute<?>... attrs)
+        throws IOException
+    {
+        return TempFileHelper.createTempDirectory(null, prefix, attrs);
+    }
+
+    /**
+     * Creates a symbolic link to a target <i>(optional operation)</i>.
+     *
+     * <p> The {@code target} parameter is the target of the link. It may be an
+     * {@link Path#isAbsolute absolute} or relative path and may not exist. When
+     * the target is a relative path then file system operations on the resulting
+     * link are relative to the path of the link.
+     *
+     * <p> The {@code attrs} parameter is optional {@link FileAttribute
+     * attributes} to set atomically when creating the link. Each attribute is
+     * identified by its {@link FileAttribute#name name}. If more than one attribute
+     * of the same name is included in the array then all but the last occurrence
+     * is ignored.
+     *
+     * <p> Where symbolic links are supported, but the underlying {@link FileStore}
+     * does not support symbolic links, then this may fail with an {@link
+     * IOException}. Additionally, some operating systems may require that the
+     * Java virtual machine be started with implementation specific privileges to
+     * create symbolic links, in which case this method may throw {@code IOException}.
+     *
+     * @param   link
+     *          the path of the symbolic link to create
+     * @param   target
+     *          the target of the symbolic link
+     * @param   attrs
+     *          the array of attributes to set atomically when creating the
+     *          symbolic link
+     *
+     * @return  the path to the symbolic link
+     *
+     * @throws  UnsupportedOperationException
+     *          if the implementation does not support symbolic links or the
+     *          array contains an attribute that cannot be set atomically when
+     *          creating the symbolic link
+     * @throws  FileAlreadyExistsException
+     *          if a file with the name already exists <i>(optional specific
+     *          exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager
+     *          is installed, it denies {@link LinkPermission}<tt>("symbolic")</tt>
+     *          or its {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method denies write access to the path of the symbolic link.
+     */
+    public static Path createSymbolicLink(Path link, Path target,
+                                          FileAttribute<?>... attrs)
+        throws IOException
+    {
+        provider(link).createSymbolicLink(link, target, attrs);
+        return link;
+    }
+
+    /**
+     * Creates a new link (directory entry) for an existing file <i>(optional
+     * operation)</i>.
+     *
+     * <p> The {@code link} parameter locates the directory entry to create.
+     * The {@code existing} parameter is the path to an existing file. This
+     * method creates a new directory entry for the file so that it can be
+     * accessed using {@code link} as the path. On some file systems this is
+     * known as creating a "hard link". Whether the file attributes are
+     * maintained for the file or for each directory entry is file system
+     * specific and therefore not specified. Typically, a file system requires
+     * that all links (directory entries) for a file be on the same file system.
+     * Furthermore, on some platforms, the Java virtual machine may require to
+     * be started with implementation specific privileges to create hard links
+     * or to create links to directories.
+     *
+     * @param   link
+     *          the link (directory entry) to create
+     * @param   existing
+     *          a path to an existing file
+     *
+     * @return  the path to the link (directory entry)
+     *
+     * @throws  UnsupportedOperationException
+     *          if the implementation does not support adding an existing file
+     *          to a directory
+     * @throws  FileAlreadyExistsException
+     *          if the entry could not otherwise be created because a file of
+     *          that name already exists <i>(optional specific exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager
+     *          is installed, it denies {@link LinkPermission}<tt>("hard")</tt>
+     *          or its {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method denies write access to either the link or the
+     *          existing file.
+     */
+    public static Path createLink(Path link, Path existing) throws IOException {
+        provider(link).createLink(link, existing);
+        return link;
+    }
+
+    /**
+     * Deletes a file.
+     *
+     * <p> An implementation may require to examine the file to determine if the
+     * file is a directory. Consequently this method may not be atomic with respect
+     * to other file system operations.  If the file is a symbolic link then the
+     * symbolic link itself, not the final target of the link, is deleted.
+     *
+     * <p> If the file is a directory then the directory must be empty. In some
+     * implementations a directory has entries for special files or links that
+     * are created when the directory is created. In such implementations a
+     * directory is considered empty when only the special entries exist.
+     * This method can be used with the {@link #walkFileTree walkFileTree}
+     * method to delete a directory and all entries in the directory, or an
+     * entire <i>file-tree</i> where required.
+     *
+     * <p> On some operating systems it may not be possible to remove a file when
+     * it is open and in use by this Java virtual machine or other programs.
+     *
+     * @param   path
+     *          the path to the file to delete
+     *
+     * @throws  NoSuchFileException
+     *          if the file does not exist <i>(optional specific exception)</i>
+     * @throws  DirectoryNotEmptyException
+     *          if the file is a directory and could not otherwise be deleted
+     *          because the directory is not empty <i>(optional specific
+     *          exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkDelete(String)} method
+     *          is invoked to check delete access to the file
+     */
+    public static void delete(Path path) throws IOException {
+        provider(path).delete(path);
+    }
+
+    /**
+     * Deletes a file if it exists.
+     *
+     * <p> As with the {@link #delete(Path) delete(Path)} method, an
+     * implementation may need to examine the file to determine if the file is a
+     * directory. Consequently this method may not be atomic with respect to
+     * other file system operations.  If the file is a symbolic link, then the
+     * symbolic link itself, not the final target of the link, is deleted.
+     *
+     * <p> If the file is a directory then the directory must be empty. In some
+     * implementations a directory has entries for special files or links that
+     * are created when the directory is created. In such implementations a
+     * directory is considered empty when only the special entries exist.
+     *
+     * <p> On some operating systems it may not be possible to remove a file when
+     * it is open and in use by this Java virtual machine or other programs.
+     *
+     * @param   path
+     *          the path to the file to delete
+     *
+     * @return  {@code true} if the file was deleted by this method; {@code
+     *          false} if the file could not be deleted because it did not
+     *          exist
+     *
+     * @throws  DirectoryNotEmptyException
+     *          if the file is a directory and could not otherwise be deleted
+     *          because the directory is not empty <i>(optional specific
+     *          exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkDelete(String)} method
+     *          is invoked to check delete access to the file.
+     */
+    public static boolean deleteIfExists(Path path) throws IOException {
+        return provider(path).deleteIfExists(path);
+    }
+
+    // -- Copying and moving files --
+
+    /**
+     * Copy a file to a target file.
+     *
+     * <p> This method copies a file to the target file with the {@code
+     * options} parameter specifying how the copy is performed. By default, the
+     * copy fails if the target file already exists or is a symbolic link,
+     * except if the source and target are the {@link #isSameFile same} file, in
+     * which case the method completes without copying the file. File attributes
+     * are not required to be copied to the target file. If symbolic links are
+     * supported, and the file is a symbolic link, then the final target of the
+     * link is copied. If the file is a directory then it creates an empty
+     * directory in the target location (entries in the directory are not
+     * copied). This method can be used with the {@link #walkFileTree
+     * walkFileTree} method to copy a directory and all entries in the directory,
+     * or an entire <i>file-tree</i> where required.
+     *
+     * <p> The {@code options} parameter may include any of the following:
+     *
+     * <table border=1 cellpadding=5 summary="">
+     * <tr> <th>Option</th> <th>Description</th> </tr>
+     * <tr>
+     *   <td> {@link StandardCopyOption#REPLACE_EXISTING REPLACE_EXISTING} </td>
+     *   <td> If the target file exists, then the target file is replaced if it
+     *     is not a non-empty directory. If the target file exists and is a
+     *     symbolic link, then the symbolic link itself, not the target of
+     *     the link, is replaced. </td>
+     * </tr>
+     * <tr>
+     *   <td> {@link StandardCopyOption#COPY_ATTRIBUTES COPY_ATTRIBUTES} </td>
+     *   <td> Attempts to copy the file attributes associated with this file to
+     *     the target file. The exact file attributes that are copied is platform
+     *     and file system dependent and therefore unspecified. Minimally, the
+     *     {@link BasicFileAttributes#lastModifiedTime last-modified-time} is
+     *     copied to the target file if supported by both the source and target
+     *     file store. Copying of file timestamps may result in precision
+     *     loss. </td>
+     * </tr>
+     * <tr>
+     *   <td> {@link LinkOption#NOFOLLOW_LINKS NOFOLLOW_LINKS} </td>
+     *   <td> Symbolic links are not followed. If the file is a symbolic link,
+     *     then the symbolic link itself, not the target of the link, is copied.
+     *     It is implementation specific if file attributes can be copied to the
+     *     new link. In other words, the {@code COPY_ATTRIBUTES} option may be
+     *     ignored when copying a symbolic link. </td>
+     * </tr>
+     * </table>
+     *
+     * <p> An implementation of this interface may support additional
+     * implementation specific options.
+     *
+     * <p> Copying a file is not an atomic operation. If an {@link IOException}
+     * is thrown then it possible that the target file is incomplete or some of
+     * its file attributes have not been copied from the source file. When the
+     * {@code REPLACE_EXISTING} option is specified and the target file exists,
+     * then the target file is replaced. The check for the existence of the file
+     * and the creation of the new file may not be atomic with respect to other
+     * file system activities.
+     *
+     * <p> <b>Usage Example:</b>
+     * Suppose we want to copy a file into a directory, giving it the same file
+     * name as the source file:
+     * <pre>
+     *     Path source = ...
+     *     Path newdir = ...
+     *     Files.copy(source, newdir.resolve(source.getFileName());
+     * </pre>
+     *
+     * @param   source
+     *          the path to the file to copy
+     * @param   target
+     *          the path to the target file (may be associated with a different
+     *          provider to the source path)
+     * @param   options
+     *          options specifying how the copy should be done
+     *
+     * @return  the path to the target file
+     *
+     * @throws  UnsupportedOperationException
+     *          if the array contains a copy option that is not supported
+     * @throws  FileAlreadyExistsException
+     *          if the target file exists but cannot be replaced because the
+     *          {@code REPLACE_EXISTING} option is not specified <i>(optional
+     *          specific exception)</i>
+     * @throws  DirectoryNotEmptyException
+     *          the {@code REPLACE_EXISTING} option is specified but the file
+     *          cannot be replaced because it is a non-empty directory
+     *          <i>(optional specific exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the source file, the
+     *          {@link SecurityManager#checkWrite(String) checkWrite} is invoked
+     *          to check write access to the target file. If a symbolic link is
+     *          copied the security manager is invoked to check {@link
+     *          LinkPermission}{@code ("symbolic")}.
+     */
+    public static Path copy(Path source, Path target, CopyOption... options)
+        throws IOException
+    {
+        FileSystemProvider provider = provider(source);
+        if (provider(target) == provider) {
+            // same provider
+            provider.copy(source, target, options);
+        } else {
+            // different providers
+            CopyMoveHelper.copyToForeignTarget(source, target, options);
+        }
+        return target;
+    }
+
+    /**
+     * Move or rename a file to a target file.
+     *
+     * <p> By default, this method attempts to move the file to the target
+     * file, failing if the target file exists except if the source and
+     * target are the {@link #isSameFile same} file, in which case this method
+     * has no effect. If the file is a symbolic link then the symbolic link
+     * itself, not the target of the link, is moved. This method may be
+     * invoked to move an empty directory. In some implementations a directory
+     * has entries for special files or links that are created when the
+     * directory is created. In such implementations a directory is considered
+     * empty when only the special entries exist. When invoked to move a
+     * directory that is not empty then the directory is moved if it does not
+     * require moving the entries in the directory.  For example, renaming a
+     * directory on the same {@link FileStore} will usually not require moving
+     * the entries in the directory. When moving a directory requires that its
+     * entries be moved then this method fails (by throwing an {@code
+     * IOException}). To move a <i>file tree</i> may involve copying rather
+     * than moving directories and this can be done using the {@link
+     * #copy copy} method in conjunction with the {@link
+     * #walkFileTree Files.walkFileTree} utility method.
+     *
+     * <p> The {@code options} parameter may include any of the following:
+     *
+     * <table border=1 cellpadding=5 summary="">
+     * <tr> <th>Option</th> <th>Description</th> </tr>
+     * <tr>
+     *   <td> {@link StandardCopyOption#REPLACE_EXISTING REPLACE_EXISTING} </td>
+     *   <td> If the target file exists, then the target file is replaced if it
+     *     is not a non-empty directory. If the target file exists and is a
+     *     symbolic link, then the symbolic link itself, not the target of
+     *     the link, is replaced. </td>
+     * </tr>
+     * <tr>
+     *   <td> {@link StandardCopyOption#ATOMIC_MOVE ATOMIC_MOVE} </td>
+     *   <td> The move is performed as an atomic file system operation and all
+     *     other options are ignored. If the target file exists then it is
+     *     implementation specific if the existing file is replaced or this method
+     *     fails by throwing an {@link IOException}. If the move cannot be
+     *     performed as an atomic file system operation then {@link
+     *     AtomicMoveNotSupportedException} is thrown. This can arise, for
+     *     example, when the target location is on a different {@code FileStore}
+     *     and would require that the file be copied, or target location is
+     *     associated with a different provider to this object. </td>
+     * </table>
+     *
+     * <p> An implementation of this interface may support additional
+     * implementation specific options.
+     *
+     * <p> Where the move requires that the file be copied then the {@link
+     * BasicFileAttributes#lastModifiedTime last-modified-time} is copied to the
+     * new file. An implementation may also attempt to copy other file
+     * attributes but is not required to fail if the file attributes cannot be
+     * copied. When the move is performed as a non-atomic operation, and a {@code
+     * IOException} is thrown, then the state of the files is not defined. The
+     * original file and the target file may both exist, the target file may be
+     * incomplete or some of its file attributes may not been copied from the
+     * original file.
+     *
+     * <p> <b>Usage Examples:</b>
+     * Suppose we want to rename a file to "newname", keeping the file in the
+     * same directory:
+     * <pre>
+     *     Path source = ...
+     *     Files.move(source, source.resolveSibling("newname"));
+     * </pre>
+     * Alternatively, suppose we want to move a file to new directory, keeping
+     * the same file name, and replacing any existing file of that name in the
+     * directory:
+     * <pre>
+     *     Path source = ...
+     *     Path newdir = ...
+     *     Files.move(source, newdir.resolve(source.getFileName()), REPLACE_EXISTING);
+     * </pre>
+     *
+     * @param   source
+     *          the path to the file to move
+     * @param   target
+     *          the path to the target file (may be associated with a different
+     *          provider to the source path)
+     * @param   options
+     *          options specifying how the move should be done
+     *
+     * @return  the path to the target file
+     *
+     * @throws  UnsupportedOperationException
+     *          if the array contains a copy option that is not supported
+     * @throws  FileAlreadyExistsException
+     *          if the target file exists but cannot be replaced because the
+     *          {@code REPLACE_EXISTING} option is not specified <i>(optional
+     *          specific exception)</i>
+     * @throws  DirectoryNotEmptyException
+     *          the {@code REPLACE_EXISTING} option is specified but the file
+     *          cannot be replaced because it is a non-empty directory
+     *          <i>(optional specific exception)</i>
+     * @throws  AtomicMoveNotSupportedException
+     *          if the options array contains the {@code ATOMIC_MOVE} option but
+     *          the file cannot be moved as an atomic file system operation.
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method is invoked to check write access to both the source and
+     *          target file.
+     */
+    public static Path move(Path source, Path target, CopyOption... options)
+        throws IOException
+    {
+        FileSystemProvider provider = provider(source);
+        if (provider(target) == provider) {
+            // same provider
+            provider.move(source, target, options);
+        } else {
+            // different providers
+            CopyMoveHelper.moveToForeignTarget(source, target, options);
+        }
+        return target;
+    }
+
+    // -- Miscellenous --
+
+    /**
+     * Reads the target of a symbolic link <i>(optional operation)</i>.
+     *
+     * <p> If the file system supports <a href="package-summary.html#links">symbolic
+     * links</a> then this method is used to read the target of the link, failing
+     * if the file is not a symbolic link. The target of the link need not exist.
+     * The returned {@code Path} object will be associated with the same file
+     * system as {@code link}.
+     *
+     * @param   link
+     *          the path to the symbolic link
+     *
+     * @return  a {@code Path} object representing the target of the link
+     *
+     * @throws  UnsupportedOperationException
+     *          if the implementation does not support symbolic links
+     * @throws  NotLinkException
+     *          if the target could otherwise not be read because the file
+     *          is not a symbolic link <i>(optional specific exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager
+     *          is installed, it checks that {@code FilePermission} has been
+     *          granted with the "{@code readlink}" action to read the link.
+     */
+    public static Path readSymbolicLink(Path link) throws IOException {
+        return provider(link).readSymbolicLink(link);
+    }
+
+    /**
+     * Returns the {@link FileStore} representing the file store where a file
+     * is located.
+     *
+     * <p> Once a reference to the {@code FileStore} is obtained it is
+     * implementation specific if operations on the returned {@code FileStore},
+     * or {@link FileStoreAttributeView} objects obtained from it, continue
+     * to depend on the existence of the file. In particular the behavior is not
+     * defined for the case that the file is deleted or moved to a different
+     * file store.
+     *
+     * @param   path
+     *          the path to the file
+     *
+     * @return  the file store where the file is stored
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the file, and in
+     *          addition it checks {@link RuntimePermission}<tt>
+     *          ("getFileStoreAttributes")</tt>
+     */
+    public static FileStore getFileStore(Path path) throws IOException {
+        return provider(path).getFileStore(path);
+    }
+
+    /**
+     * Tests if two paths locate the same file.
+     *
+     * <p> If both {@code Path} objects are {@link Path#equals(Object) equal}
+     * then this method returns {@code true} without checking if the file exists.
+     * If the two {@code Path} objects are associated with different providers
+     * then this method returns {@code false}. Otherwise, this method checks if
+     * both {@code Path} objects locate the same file, and depending on the
+     * implementation, may require to open or access both files.
+     *
+     * <p> If the file system and files remain static, then this method implements
+     * an equivalence relation for non-null {@code Paths}.
+     * <ul>
+     * <li>It is <i>reflexive</i>: for {@code Path} {@code f},
+     *     {@code isSameFile(f,f)} should return {@code true}.
+     * <li>It is <i>symmetric</i>: for two {@code Paths} {@code f} and {@code g},
+     *     {@code isSameFile(f,g)} will equal {@code isSameFile(g,f)}.
+     * <li>It is <i>transitive</i>: for three {@code Paths}
+     *     {@code f}, {@code g}, and {@code h}, if {@code isSameFile(f,g)} returns
+     *     {@code true} and {@code isSameFile(g,h)} returns {@code true}, then
+     *     {@code isSameFile(g,h)} will return return {@code true}.
+     * </ul>
+     *
+     * @param   path
+     *          one path to the file
+     * @param   path2
+     *          the other path
+     *
+     * @return  {@code true} if, and only if, the two paths locate the same file
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to both files.
+     *
+     * @see java.nio.file.attribute.BasicFileAttributes#fileKey
+     */
+    public static boolean isSameFile(Path path, Path path2) throws IOException {
+        return provider(path).isSameFile(path, path2);
+    }
+
+    /**
+     * Tells whether or not a file is considered <em>hidden</em>. The exact
+     * definition of hidden is platform or provider dependent. On UNIX for
+     * example a file is considered to be hidden if its name begins with a
+     * period character ('.'). On Windows a file is considered hidden if it
+     * isn't a directory and the DOS {@link DosFileAttributes#isHidden hidden}
+     * attribute is set.
+     *
+     * <p> Depending on the implementation this method may require to access
+     * the file system to determine if the file is considered hidden.
+     *
+     * @param   path
+     *          the path to the file to test
+     *
+     * @return  {@code true} if the file is considered hidden
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the file.
+     */
+    public static boolean isHidden(Path path) throws IOException {
+        return provider(path).isHidden(path);
+    }
+
     // lazy loading of default and installed file type detectors
-    private static class DefaultFileTypeDetectorHolder {
+    private static class FileTypeDetectors{
         static final FileTypeDetector defaultFileTypeDetector =
             sun.nio.fs.DefaultFileTypeDetector.create();
         static final List<FileTypeDetector> installeDetectors =
@@ -54,7 +1484,7 @@
             return AccessController
                 .doPrivileged(new PrivilegedAction<List<FileTypeDetector>>() {
                     @Override public List<FileTypeDetector> run() {
-                        List<FileTypeDetector> list = new ArrayList<FileTypeDetector>();
+                        List<FileTypeDetector> list = new ArrayList<>();
                         ServiceLoader<FileTypeDetector> loader = ServiceLoader
                             .load(FileTypeDetector.class, ClassLoader.getSystemClassLoader());
                         for (FileTypeDetector detector: loader) {
@@ -100,34 +1530,949 @@
      * Message Bodies</i></a>. The string is guaranteed to be parsable according
      * to the grammar in the RFC.
      *
-     * @param   file
-     *          The file reference
+     * @param   path
+     *          the path to the file to probe
      *
      * @return  The content type of the file, or {@code null} if the content
      *          type cannot be determined
      *
      * @throws  IOException
-     *          If an I/O error occurs
+     *          if an I/O error occurs
      * @throws  SecurityException
      *          If a security manager is installed and it denies an unspecified
      *          permission required by a file type detector implementation.
      */
-    public static String probeContentType(FileRef file)
+    public static String probeContentType(Path path)
         throws IOException
     {
         // try installed file type detectors
-        for (FileTypeDetector detector: DefaultFileTypeDetectorHolder.installeDetectors) {
-            String result = detector.probeContentType(file);
+        for (FileTypeDetector detector: FileTypeDetectors.installeDetectors) {
+            String result = detector.probeContentType(path);
             if (result != null)
                 return result;
         }
 
         // fallback to default
-        return DefaultFileTypeDetectorHolder.defaultFileTypeDetector
-            .probeContentType(file);
+        return FileTypeDetectors.defaultFileTypeDetector.probeContentType(path);
+    }
+
+    // -- File Attributes --
+
+    /**
+     * Returns a file attribute view of a given type.
+     *
+     * <p> A file attribute view provides a read-only or updatable view of a
+     * set of file attributes. This method is intended to be used where the file
+     * attribute view defines type-safe methods to read or update the file
+     * attributes. The {@code type} parameter is the type of the attribute view
+     * required and the method returns an instance of that type if supported.
+     * The {@link BasicFileAttributeView} type supports access to the basic
+     * attributes of a file. Invoking this method to select a file attribute
+     * view of that type will always return an instance of that class.
+     *
+     * <p> The {@code options} array may be used to indicate how symbolic links
+     * are handled by the resulting file attribute view for the case that the
+     * file is a symbolic link. By default, symbolic links are followed. If the
+     * option {@link LinkOption#NOFOLLOW_LINKS NOFOLLOW_LINKS} is present then
+     * symbolic links are not followed. This option is ignored by implementations
+     * that do not support symbolic links.
+     *
+     * <p> <b>Usage Example:</b>
+     * Suppose we want read or set a file's ACL, if supported:
+     * <pre>
+     *     Path path = ...
+     *     AclFileAttributeView view = Files.getFileAttributeView(path, AclFileAttributeView.class);
+     *     if (view != null) {
+     *         List&lt;AclEntry&gt acl = view.getAcl();
+     *         :
+     *     }
+     * </pre>
+     *
+     *
+     * @param   path
+     *          the path to the file
+     * @param   type
+     *          the {@code Class} object corresponding to the file attribute view
+     * @param   options
+     *          options indicating how symbolic links are handled
+     *
+     * @return  a file attribute view of the specified type, or {@code null} if
+     *          the attribute view type is not available
+     */
+    public static <V extends FileAttributeView> V getFileAttributeView(Path path,
+                                                                       Class<V> type,
+                                                                       LinkOption... options)
+    {
+        return provider(path).getFileAttributeView(path, type, options);
+    }
+
+    /**
+     * Reads a file's attributes as a bulk operation.
+     *
+     * <p> The {@code type} parameter is the type of the attributes required
+     * and this method returns an instance of that type if supported. All
+     * implementations support a basic set of file attributes and so invoking
+     * this method with a  {@code type} parameter of {@code
+     * BasicFileAttributes.class} will not throw {@code
+     * UnsupportedOperationException}.
+     *
+     * <p> The {@code options} array may be used to indicate how symbolic links
+     * are handled for the case that the file is a symbolic link. By default,
+     * symbolic links are followed and the file attribute of the final target
+     * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS
+     * NOFOLLOW_LINKS} is present then symbolic links are not followed.
+     *
+     * <p> It is implementation specific if all file attributes are read as an
+     * atomic operation with respect to other file system operations.
+     *
+     * <p> <b>Usage Example:</b>
+     * Suppose we want to read a file's attributes in bulk:
+     * <pre>
+     *    Path path = ...
+     *    BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class);
+     * </pre>
+     * Alternatively, suppose we want to read file's POSIX attributes without
+     * following symbolic links:
+     * <pre>
+     *    PosixFileAttributes attrs = Files.readAttributes(path, PosixFileAttributes.class, NOFOLLOW_LINKS);
+     * </pre>
+     *
+     * @param   path
+     *          the path to the file
+     * @param   type
+     *          the {@code Class} of the file attributes required
+     *          to read
+     * @param   options
+     *          options indicating how symbolic links are handled
+     *
+     * @return  the file attributes
+     *
+     * @throws  UnsupportedOperationException
+     *          if an attributes of the given type are not supported
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, a security manager is
+     *          installed, its {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the file. If this
+     *          method is invoked to read security sensitive attributes then the
+     *          security manager may be invoke to check for additional permissions.
+     */
+    public static <A extends BasicFileAttributes> A readAttributes(Path path,
+                                                                   Class<A> type,
+                                                                   LinkOption... options)
+        throws IOException
+    {
+        return provider(path).readAttributes(path, type, options);
+    }
+
+    /**
+     * Sets the value of a file attribute.
+     *
+     * <p> The {@code attribute} parameter identifies the attribute to be set
+     * and takes the form:
+     * <blockquote>
+     * [<i>view-name</i><b>:</b>]<i>attribute-name</i>
+     * </blockquote>
+     * where square brackets [...] delineate an optional component and the
+     * character {@code ':'} stands for itself.
+     *
+     * <p> <i>view-name</i> is the {@link FileAttributeView#name name} of a {@link
+     * FileAttributeView} that identifies a set of file attributes. If not
+     * specified then it defaults to {@code "basic"}, the name of the file
+     * attribute view that identifies the basic set of file attributes common to
+     * many file systems. <i>attribute-name</i> is the name of the attribute
+     * within the set.
+     *
+     * <p> The {@code options} array may be used to indicate how symbolic links
+     * are handled for the case that the file is a symbolic link. By default,
+     * symbolic links are followed and the file attribute of the final target
+     * of the link is set. If the option {@link LinkOption#NOFOLLOW_LINKS
+     * NOFOLLOW_LINKS} is present then symbolic links are not followed.
+     *
+     * <p> <b>Usage Example:</b>
+     * Suppose we want to set the DOS "hidden" attribute:
+     * <pre>
+     *    Path path = ...
+     *    Files.setAttribute(path, "dos:hidden", true);
+     * </pre>
+     *
+     * @param   path
+     *          the path to the file
+     * @param   attribute
+     *          the attribute to set
+     * @param   value
+     *          the attribute value
+     * @param   options
+     *          options indicating how symbolic links are handled
+     *
+     * @return  the {@code path} parameter
+     *
+     * @throws  UnsupportedOperationException
+     *          if the attribute view is not available or it does not support
+     *          updating the attribute
+     * @throws  IllegalArgumentException
+     *          if the attribute value is of the correct type but has an
+     *          inappropriate value
+     * @throws  ClassCastException
+     *          if the attribute value is not of the expected type or is a
+     *          collection containing elements that are not of the expected
+     *          type
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, its {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method denies write access to the file. If this method is invoked
+     *          to set security sensitive attributes then the security manager
+     *          may be invoked to check for additional permissions.
+     */
+    public static Path setAttribute(Path path, String attribute, Object value,
+                                    LinkOption... options)
+        throws IOException
+    {
+        provider(path).setAttribute(path, attribute, value, options);
+        return path;
+    }
+
+    /**
+     * Reads the value of a file attribute.
+     *
+     * <p> The {@code attribute} parameter identifies the attribute to be read
+     * and takes the form:
+     * <blockquote>
+     * [<i>view-name</i><b>:</b>]<i>attribute-name</i>
+     * </blockquote>
+     * where square brackets [...] delineate an optional component and the
+     * character {@code ':'} stands for itself.
+     *
+     * <p> <i>view-name</i> is the {@link FileAttributeView#name name} of a {@link
+     * FileAttributeView} that identifies a set of file attributes. If not
+     * specified then it defaults to {@code "basic"}, the name of the file
+     * attribute view that identifies the basic set of file attributes common to
+     * many file systems. <i>attribute-name</i> is the name of the attribute.
+     *
+     * <p> The {@code options} array may be used to indicate how symbolic links
+     * are handled for the case that the file is a symbolic link. By default,
+     * symbolic links are followed and the file attribute of the final target
+     * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS
+     * NOFOLLOW_LINKS} is present then symbolic links are not followed.
+     *
+     * <p> <b>Usage Example:</b>
+     * Suppose we require the user ID of the file owner on a system that
+     * supports a "{@code unix}" view:
+     * <pre>
+     *    Path path = ...
+     *    int uid = (Integer)Files.getAttribute(path, "unix:uid");
+     * </pre>
+     *
+     * @param   path
+     *          the path to the file
+     * @param   attribute
+     *          the attribute to read
+     * @param   options
+     *          options indicating how symbolic links are handled
+     *
+     * @return  the attribute value or {@code null} if the attribute view
+     *          is not available or it does not support reading the attribute
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, its {@link SecurityManager#checkRead(String) checkRead}
+     *          method denies read access to the file. If this method is invoked
+     *          to read security sensitive attributes then the security manager
+     *          may be invoked to check for additional permissions.
+     */
+    public static Object getAttribute(Path path, String attribute,
+                                      LinkOption... options)
+        throws IOException
+    {
+        // only one attribute should be read
+        if (attribute.indexOf('*') >= 0 || attribute.indexOf(',') >= 0)
+            return null;
+        Map<String,Object> map = readAttributes(path, attribute, options);
+        String name;
+        int pos = attribute.indexOf(':');
+        if (pos == -1) {
+            name = attribute;
+        } else {
+            name = (pos == attribute.length()) ? "" : attribute.substring(pos+1);
+        }
+        return map.get(name);
+    }
+
+    /**
+     * Reads a set of file attributes as a bulk operation.
+     *
+     * <p> The {@code attributes} parameter identifies the attributes to be read
+     * and takes the form:
+     * <blockquote>
+     * [<i>view-name</i><b>:</b>]<i>attribute-list</i>
+     * </blockquote>
+     * where square brackets [...] delineate an optional component and the
+     * character {@code ':'} stands for itself.
+     *
+     * <p> <i>view-name</i> is the {@link FileAttributeView#name name} of a {@link
+     * FileAttributeView} that identifies a set of file attributes. If not
+     * specified then it defaults to {@code "basic"}, the name of the file
+     * attribute view that identifies the basic set of file attributes common to
+     * many file systems.
+     *
+     * <p> The <i>attribute-list</i> component is a comma separated list of
+     * zero or more names of attributes to read. If the list contains the value
+     * {@code "*"} then all attributes are read. Attributes that are not supported
+     * are ignored and will not be present in the returned map. It is
+     * implementation specific if all attributes are read as an atomic operation
+     * with respect to other file system operations.
+     *
+     * <p> The following examples demonstrate possible values for the {@code
+     * attributes} parameter:
+     *
+     * <blockquote>
+     * <table border="0">
+     * <tr>
+     *   <td> {@code "*"} </td>
+     *   <td> Read all {@link BasicFileAttributes basic-file-attributes}. </td>
+     * </tr>
+     * <tr>
+     *   <td> {@code "size,lastModifiedTime,lastAccessTime"} </td>
+     *   <td> Reads the file size, last modified time, and last access time
+     *     attributes. </td>
+     * </tr>
+     * <tr>
+     *   <td> {@code "posix:*"} </td>
+     *   <td> Read all {@link PosixFileAttributes POSIX-file-attributes}. </td>
+     * </tr>
+     * <tr>
+     *   <td> {@code "posix:permissions,owner,size"} </td>
+     *   <td> Reads the POSX file permissions, owner, and file size. </td>
+     * </tr>
+     * </table>
+     * </blockquote>
+     *
+     * <p> The {@code options} array may be used to indicate how symbolic links
+     * are handled for the case that the file is a symbolic link. By default,
+     * symbolic links are followed and the file attribute of the final target
+     * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS
+     * NOFOLLOW_LINKS} is present then symbolic links are not followed.
+     *
+     * @param   path
+     *          the path to the file
+     * @param   attributes
+     *          the attributes to read
+     * @param   options
+     *          options indicating how symbolic links are handled
+     *
+     * @return  a map of the attributes returned; may be empty. The map's keys
+     *          are the attribute names, its values are the attribute values
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, its {@link SecurityManager#checkRead(String) checkRead}
+     *          method denies read access to the file. If this method is invoked
+     *          to read security sensitive attributes then the security manager
+     *          may be invoke to check for additional permissions.
+     */
+    public static Map<String,Object> readAttributes(Path path, String attributes,
+                                                    LinkOption... options)
+        throws IOException
+    {
+        return provider(path).readAttributes(path, attributes, options);
+    }
+
+    /**
+     * Returns a file's POSIX file permissions.
+     *
+     * <p> The {@code path} parameter is associated with a {@code FileSystem}
+     * that supports the {@link PosixFileAttributeView}. This attribute view
+     * provides access to file attributes commonly associated with files on file
+     * systems used by operating systems that implement the Portable Operating
+     * System Interface (POSIX) family of standards.
+     *
+     * <p> The {@code options} array may be used to indicate how symbolic links
+     * are handled for the case that the file is a symbolic link. By default,
+     * symbolic links are followed and the file attribute of the final target
+     * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS
+     * NOFOLLOW_LINKS} is present then symbolic links are not followed.
+     *
+     * @param   path
+     *          the path to the file
+     * @param   options
+     *          options indicating how symbolic links are handled
+     *
+     * @return  the file permissions
+     *
+     * @throws  UnsupportedOperationException
+     *          if the associated file system does not support the {@code
+     *          PosixFileAttributeView}
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, a security manager is
+     *          installed, and it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
+     *          or its {@link SecurityManager#checkRead(String) checkRead} method
+     *          denies read access to the file.
+     */
+    public static Set<PosixFilePermission> getPosixFilePermissions(Path path,
+                                                                   LinkOption... options)
+        throws IOException
+    {
+        return readAttributes(path, PosixFileAttributes.class, options).permissions();
+    }
+
+    /**
+     * Sets a file's POSIX permissions.
+     *
+     * <p> The {@code path} parameter is associated with a {@code FileSystem}
+     * that supports the {@link PosixFileAttributeView}. This attribute view
+     * provides access to file attributes commonly associated with files on file
+     * systems used by operating systems that implement the Portable Operating
+     * System Interface (POSIX) family of standards.
+     *
+     * @param   path
+     *          A file reference that locates the file
+     * @param   perms
+     *          The new set of permissions
+     *
+     * @throws  UnsupportedOperationException
+     *          if the associated file system does not support the {@code
+     *          PosixFileAttributeView}
+     * @throws  ClassCastException
+     *          if the sets contains elements that are not of type {@code
+     *          PosixFilePermission}
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
+     *          or its {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method denies write access to the file.
+     */
+    public static Path setPosixFilePermissions(Path path,
+                                               Set<PosixFilePermission> perms)
+        throws IOException
+    {
+        PosixFileAttributeView view =
+            getFileAttributeView(path, PosixFileAttributeView.class);
+        if (view == null)
+            throw new UnsupportedOperationException();
+        view.setPermissions(perms);
+        return path;
+    }
+
+    /**
+     * Returns the owner of a file.
+     *
+     * <p> The {@code path} parameter is associated with a file system that
+     * supports {@link FileOwnerAttributeView}. This file attribute view provides
+     * access to a file attribute that is the owner of the file.
+     *
+     * @param   path
+     *          A file reference that locates the file
+     * @param   options
+     *          options indicating how symbolic links are handled
+     *
+     * @return  A user principal representing the owner of the file
+     *
+     * @throws  UnsupportedOperationException
+     *          if the associated file system does not support the {@code
+     *          FileOwnerAttributeView}
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
+     *          or its {@link SecurityManager#checkRead(String) checkRead} method
+     *          denies read access to the file.
+     */
+    public static UserPrincipal getOwner(Path path, LinkOption... options) throws IOException {
+        FileOwnerAttributeView view =
+            getFileAttributeView(path, FileOwnerAttributeView.class, options);
+        if (view == null)
+            throw new UnsupportedOperationException();
+        return view.getOwner();
     }
 
     /**
+     * Updates the file owner.
+     *
+     * <p> The {@code path} parameter is associated with a file system that
+     * supports {@link FileOwnerAttributeView}. This file attribute view provides
+     * access to a file attribute that is the owner of the file.
+     *
+     * <p> <b>Usage Example:</b>
+     * Suppose we want to make "joe" the owner of a file:
+     * <pre>
+     *     Path path = ...
+     *     UserPrincipalLookupService lookupService =
+     *         provider(path).getUserPrincipalLookupService();
+     *     UserPrincipal joe = lookupService.lookupPrincipalByName("joe");
+     *     Files.setOwner(path, joe);
+     * </pre>
+     *
+     * @param   path
+     *          A file reference that locates the file
+     * @param   owner
+     *          The new file owner
+     *
+     * @throws  UnsupportedOperationException
+     *          if the associated file system does not support the {@code
+     *          FileOwnerAttributeView}
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
+     *          or its {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method denies write access to the file.
+     *
+     * @see FileSystem#getUserPrincipalLookupService
+     * @see java.nio.file.attribute.UserPrincipalLookupService
+     */
+    public static Path setOwner(Path path, UserPrincipal owner)
+        throws IOException
+    {
+        FileOwnerAttributeView view =
+            getFileAttributeView(path, FileOwnerAttributeView.class);
+        if (view == null)
+            throw new UnsupportedOperationException();
+        view.setOwner(owner);
+        return path;
+    }
+
+    /**
+     * Tests whether a file is a symbolic link.
+     *
+     * <p> Where is it required to distinguish an I/O exception from the case
+     * that the file is not a symbolic link then the file attributes can be
+     * read with the {@link #readAttributes(Path,Class,LinkOption[])
+     * readAttributes} method and the file type tested with the {@link
+     * BasicFileAttributes#isSymbolicLink} method.
+     *
+     * @return  {@code true} if the file is a symbolic link; {@code false} if
+     *          the file does not exist, is not a symbolic link, or it cannot
+     *          be determined if the file is symbolic link or not.
+     *
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, its {@link SecurityManager#checkRead(String) checkRead}
+     *          method denies read access to the file.
+     */
+    public static boolean isSymbolicLink(Path path) {
+        try {
+            return readAttributes(path,
+                                  BasicFileAttributes.class,
+                                  LinkOption.NOFOLLOW_LINKS).isSymbolicLink();
+        } catch (IOException ioe) {
+            return false;
+        }
+    }
+
+    /**
+     * Tests whether a file is a directory.
+     *
+     * <p> The {@code options} array may be used to indicate how symbolic links
+     * are handled for the case that the file is a symbolic link. By default,
+     * symbolic links are followed and the file attribute of the final target
+     * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS
+     * NOFOLLOW_LINKS} is present then symbolic links are not followed.
+     *
+     * <p> Where is it required to distinguish an I/O exception from the case
+     * that the file is not a directory then the file attributes can be
+     * read with the {@link #readAttributes(Path,Class,LinkOption[])
+     * readAttributes} method and the file type tested with the {@link
+     * BasicFileAttributes#isDirectory} method.
+     *
+     * @param   path
+     *          the path to the file to test
+     * @param   options
+     *          options indicating how symbolic links are handled
+     *
+     * @return  {@code true} if the file is a directory; {@code false} if
+     *          the file does not exist, is not a directory, or it cannot
+     *          be determined if the file is directory or not.
+     *
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, its {@link SecurityManager#checkRead(String) checkRead}
+     *          method denies read access to the file.
+     */
+    public static boolean isDirectory(Path path, LinkOption... options) {
+        try {
+            return readAttributes(path, BasicFileAttributes.class, options).isDirectory();
+        } catch (IOException ioe) {
+            return false;
+        }
+    }
+
+    /**
+     * Tests whether a file is a regular file with opaque content.
+     *
+     * <p> The {@code options} array may be used to indicate how symbolic links
+     * are handled for the case that the file is a symbolic link. By default,
+     * symbolic links are followed and the file attribute of the final target
+     * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS
+     * NOFOLLOW_LINKS} is present then symbolic links are not followed.
+     *
+     * <p> Where is it required to distinguish an I/O exception from the case
+     * that the file is not a regular file then the file attributes can be
+     * read with the {@link #readAttributes(Path,Class,LinkOption[])
+     * readAttributes} method and the file type tested with the {@link
+     * BasicFileAttributes#isRegularFile} method.
+     *
+     * @param   path
+     *          the path to the file
+     * @param   options
+     *          options indicating how symbolic links are handled
+     *
+     * @return  {@code true} if the file is a regular file; {@code false} if
+     *          the file does not exist, is not a direcregular filetory, or it
+     *          cannot be determined if the file is regular file or not.
+     *
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, its {@link SecurityManager#checkRead(String) checkRead}
+     *          method denies read access to the file.
+     */
+    public static boolean isRegularFile(Path path, LinkOption... options) {
+        try {
+            return readAttributes(path, BasicFileAttributes.class, options).isRegularFile();
+        } catch (IOException ioe) {
+            return false;
+        }
+    }
+
+    /**
+     * Returns a file's last modified time.
+     *
+     * <p> The {@code options} array may be used to indicate how symbolic links
+     * are handled for the case that the file is a symbolic link. By default,
+     * symbolic links are followed and the file attribute of the final target
+     * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS
+     * NOFOLLOW_LINKS} is present then symbolic links are not followed.
+     *
+     * @param   path
+     *          the path to the file
+     * @param   options
+     *          options indicating how symbolic links are handled
+     *
+     * @return  a {@code FileTime} representing the time the file was last
+     *          modified, or an implementation specific default when a time
+     *          stamp to indicate the time of last modification is not supported
+     *          by the file system
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, its {@link SecurityManager#checkRead(String) checkRead}
+     *          method denies read access to the file.
+     *
+     * @see BasicFileAttributes#lastModifiedTime
+     */
+    public static FileTime getLastModifiedTime(Path path, LinkOption... options)
+        throws IOException
+    {
+        return readAttributes(path, BasicFileAttributes.class, options).lastModifiedTime();
+    }
+
+    /**
+     * Updates a file's last modified time attribute. The file time is converted
+     * to the epoch and precision supported by the file system. Converting from
+     * finer to coarser granularities result in precision loss. The behavior of
+     * this method when attempting to set the last modified time when it is not
+     * supported by the file system or is outside the range supported by the
+     * underlying file store is not defined. It may or not fail by throwing an
+     * {@code IOException}.
+     *
+     * <p> <b>Usage Example:</b>
+     * Suppose we want to set the last modified time to the current time:
+     * <pre>
+     *    Path path = ...
+     *    FileTime now = FileTime.fromMillis(System.currentTimeMillis());
+     *    Files.setLastModifiedTime(path, now);
+     * </pre>
+     *
+     * @param   path
+     *          the path to the file
+     * @param   time
+     *          the new last modified time
+     *
+     * @return  the file
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, the security manager's {@link
+     *          SecurityManager#checkWrite(String) checkWrite} method is invoked
+     *          to check write access to file
+     *
+     * @see BasicFileAttributeView#setTimes
+     */
+    public static Path setLastModifiedTime(Path path, FileTime time)
+        throws IOException
+    {
+        getFileAttributeView(path, BasicFileAttributeView.class)
+            .setTimes(time, null, null);
+        return path;
+    }
+
+    /**
+     * Returns the size of a file (in bytes). The size may differ from the
+     * actual size on the file system due to compression, support for sparse
+     * files, or other reasons. The size of files that are not {@link
+     * #isRegularFile regular} files is implementation specific and
+     * therefore unspecified.
+     *
+     * @param   path
+     *          the path to the file
+     *
+     * @return  the file size, in bytes
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, its {@link SecurityManager#checkRead(String) checkRead}
+     *          method denies read access to the file.
+     *
+     * @see BasicFileAttributes#size
+     */
+    public static long size(Path path) throws IOException {
+        return readAttributes(path, BasicFileAttributes.class).size();
+    }
+
+    // -- Accessibility --
+
+    /**
+     * Returns {@code false} if NOFOLLOW_LINKS is present.
+     */
+    private static boolean followLinks(LinkOption... options) {
+        boolean followLinks = true;
+        for (LinkOption opt: options) {
+            if (opt == LinkOption.NOFOLLOW_LINKS) {
+                followLinks = false;
+                continue;
+            }
+            if (opt == null)
+                throw new NullPointerException();
+            throw new AssertionError("Should not get here");
+        }
+        return followLinks;
+    }
+
+    /**
+     * Tests whether a file exists.
+     *
+     * <p> The {@code options} parameter may be used to indicate how symbolic links
+     * are handled for the case that the file is a symbolic link. By default,
+     * symbolic links are followed. If the option {@link LinkOption#NOFOLLOW_LINKS
+     * NOFOLLOW_LINKS} is present then symbolic links are not followed.
+     *
+     * <p> Note that the result of this method is immediately outdated. If this
+     * method indicates the file exists then there is no guarantee that a
+     * subsequence access will succeed. Care should be taken when using this
+     * method in security sensitive applications.
+     *
+     * @param   path
+     *          the path to the file to test
+     * @param   options
+     *          options indicating how symbolic links are handled
+     * .
+     * @return  {@code true} if the file exists; {@code false} if the file does
+     *          not exist or its existence cannot be determined.
+     *
+     * @throws  SecurityException
+     *          In the case of the default provider, the {@link
+     *          SecurityManager#checkRead(String)} is invoked to check
+     *          read access to the file.
+     *
+     * @see #notExists
+     */
+    public static boolean exists(Path path, LinkOption... options) {
+        try {
+            if (followLinks(options)) {
+                provider(path).checkAccess(path);
+            } else {
+                // attempt to read attributes without following links
+                readAttributes(path, BasicFileAttributes.class,
+                               LinkOption.NOFOLLOW_LINKS);
+            }
+            // file exists
+            return true;
+        } catch (IOException x) {
+            // does not exist or unable to determine if file exists
+            return false;
+        }
+
+    }
+
+    /**
+     * Tests whether the file located by this path does not exist. This method
+     * is intended for cases where it is required to take action when it can be
+     * confirmed that a file does not exist.
+     *
+     * <p> The {@code options} parameter may be used to indicate how symbolic links
+     * are handled for the case that the file is a symbolic link. By default,
+     * symbolic links are followed. If the option {@link LinkOption#NOFOLLOW_LINKS
+     * NOFOLLOW_LINKS} is present then symbolic links are not followed.
+     *
+     * <p> Note that this method is not the complement of the {@link #exists
+     * exists} method. Where it is not possible to determine if a file exists
+     * or not then both methods return {@code false}. As with the {@code exists}
+     * method, the result of this method is immediately outdated. If this
+     * method indicates the file does exist then there is no guarantee that a
+     * subsequence attempt to create the file will succeed. Care should be taken
+     * when using this method in security sensitive applications.
+     *
+     * @param   path
+     *          the path to the file to test
+     * @param   options
+     *          options indicating how symbolic links are handled
+     *
+     * @return  {@code true} if the file does not exist; {@code false} if the
+     *          file exists or its existence cannot be determined
+     *
+     * @throws  SecurityException
+     *          In the case of the default provider, the {@link
+     *          SecurityManager#checkRead(String)} is invoked to check
+     *          read access to the file.
+     */
+    public static boolean notExists(Path path, LinkOption... options) {
+        try {
+            if (followLinks(options)) {
+                provider(path).checkAccess(path);
+            } else {
+                // attempt to read attributes without following links
+                readAttributes(path, BasicFileAttributes.class,
+                               LinkOption.NOFOLLOW_LINKS);
+            }
+            // file exists
+            return false;
+        } catch (NoSuchFileException x) {
+            // file confirmed not to exist
+            return true;
+        } catch (IOException x) {
+            return false;
+        }
+    }
+
+    /**
+     * Used by isReadbale, isWritable, isExecutable to test access to a file.
+     */
+    private static boolean isAccessible(Path path, AccessMode... modes) {
+        try {
+            provider(path).checkAccess(path, modes);
+            return true;
+        } catch (IOException x) {
+            return false;
+        }
+    }
+
+    /**
+     * Tests whether a file is readable. This method checks that a file exists
+     * and that this Java virtual machine has appropriate privileges that would
+     * allow it open the file for reading. Depending on the implementation, this
+     * method may require to read file permissions, access control lists, or
+     * other file attributes in order to check the effective access to the file.
+     * Consequently, this method may not be atomic with respect to other file
+     * system operations.
+     *
+     * <p> Note that the result of this method is immediately outdated, there is
+     * no guarantee that a subsequent attempt to open the file for reading will
+     * succeed (or even that it will access the same file). Care should be taken
+     * when using this method in security sensitive applications.
+     *
+     * @param   path
+     *          the path to the file to check
+     *
+     * @return  {@code true} if the file exists and is readable; {@code false}
+     *          if the file does not exist, read access would be denied because
+     *          the Java virtual machine has insufficient privileges, or access
+     *          cannot be determined
+     *
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          is invoked to check read access to the file.
+     */
+    public static boolean isReadable(Path path) {
+        return isAccessible(path, AccessMode.READ);
+    }
+
+    /**
+     * Tests whether a file is writable. This method checks that a file exists
+     * and that this Java virtual machine has appropriate privileges that would
+     * allow it open the file for writing. Depending on the implementation, this
+     * method may require to read file permissions, access control lists, or
+     * other file attributes in order to check the effective access to the file.
+     * Consequently, this method may not be atomic with respect to other file
+     * system operations.
+     *
+     * <p> Note that result of this method is immediately outdated, there is no
+     * guarantee that a subsequent attempt to open the file for writing will
+     * succeed (or even that it will access the same file). Care should be taken
+     * when using this method in security sensitive applications.
+     *
+     * @param   path
+     *          the path to the file to check
+     *
+     * @return  {@code true} if the file exists and is writable; {@code false}
+     *          if the file does not exist, write access would be denied because
+     *          the Java virtual machine has insufficient privileges, or access
+     *          cannot be determined
+     *
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+     *          is invoked to check write access to the file.
+     */
+    public static boolean isWritable(Path path) {
+        return isAccessible(path, AccessMode.WRITE);
+    }
+
+    /**
+     * Tests whether a file is executable. This method checks that a file exists
+     * and that this Java virtual machine has appropriate privileges to {@link
+     * Runtime#exec execute} the file. The semantics may differ when checking
+     * access to a directory. For example, on UNIX systems, checking for
+     * execute access checks that the Java virtual machine has permission to
+     * search the directory in order to access file or subdirectories.
+     *
+     * <p> Depending on the implementation, this method may require to read file
+     * permissions, access control lists, or other file attributes in order to
+     * check the effective access to the file. Consequently, this method may not
+     * be atomic with respect to other file system operations.
+     *
+     * <p> Note that the result of this method is immediately outdated, there is
+     * no guarantee that a subsequent attempt to execute the file will succeed
+     * (or even that it will access the same file). Care should be taken when
+     * using this method in security sensitive applications.
+     *
+     * @param   path
+     *          the path to the file to check
+     *
+     * @return  {@code true} if the file exists and is executable; {@code false}
+     *          if the file does not exist, execute access would be denied because
+     *          the Java virtual machine has insufficient privileges, or access
+     *          cannot be determined
+     *
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkExec(String)
+     *          checkExec} is invoked to check execute access to the file.
+     */
+    public static boolean isExecutable(Path path) {
+       return isAccessible(path, AccessMode.EXECUTE);
+    }
+
+    // -- Recursive operations --
+
+    /**
      * Walks a file tree.
      *
      * <p> This method walks a file tree rooted at a given starting file. The
@@ -139,7 +2484,7 @@
      * an uncaught error, or runtime exception, then the traversal is terminated
      * and the error or exception is propagated to the caller of this method.
      *
-     * <p> For each file encountered this method attempts to gets its {@link
+     * <p> For each file encountered this method attempts to read its {@link
      * java.nio.file.attribute.BasicFileAttributes}. If the file is not a
      * directory then the {@link FileVisitor#visitFile visitFile} method is
      * invoked with the file attributes. If the file attributes cannot be read,
@@ -174,7 +2519,7 @@
      * arises when there is an entry in a directory that is an ancestor of the
      * directory. Cycle detection is done by recording the {@link
      * java.nio.file.attribute.BasicFileAttributes#fileKey file-key} of directories,
-     * or if file keys are not available, by invoking the {@link Path#isSameFile
+     * or if file keys are not available, by invoking the {@link #isSameFile
      * isSameFile} method to test if a directory is the same file as an
      * ancestor. When a cycle is detected it is treated as an I/O error, and the
      * {@link FileVisitor#visitFileFailed visitFileFailed} method is invoked with
@@ -197,25 +2542,27 @@
      * that file (or directory).
      *
      * @param   start
-     *          The starting file
+     *          the starting file
      * @param   options
-     *          Options to configure the traversal
+     *          options to configure the traversal
      * @param   maxDepth
-     *          The maximum number of directory levels to visit
+     *          the maximum number of directory levels to visit
      * @param   visitor
-     *          The file visitor to invoke for each file
+     *          the file visitor to invoke for each file
+     *
+     * @return  the starting file
      *
      * @throws  IllegalArgumentException
-     *          If the {@code maxDepth} parameter is negative
+     *          if the {@code maxDepth} parameter is negative
      * @throws  SecurityException
      *          If the security manager denies access to the starting file.
      *          In the case of the default provider, the {@link
      *          SecurityManager#checkRead(String) checkRead} method is invoked
      *          to check read access to the directory.
      * @throws  IOException
-     *          If an I/O error is thrown by a visitor method
+     *          if an I/O error is thrown by a visitor method
      */
-    public static void walkFileTree(Path start,
+    public static Path walkFileTree(Path start,
                                     Set<FileVisitOption> options,
                                     int maxDepth,
                                     FileVisitor<? super Path> visitor)
@@ -224,6 +2571,7 @@
         if (maxDepth < 0)
             throw new IllegalArgumentException("'maxDepth' is negative");
         new FileTreeWalker(options, visitor, maxDepth).walk(start);
+        return start;
     }
 
     /**
@@ -234,11 +2582,15 @@
      * <blockquote><pre>
      * walkFileTree(start, EnumSet.noneOf(FileVisitOption.class), Integer.MAX_VALUE, visitor)
      * </pre></blockquote>
+     * In other words, it does not follow symbolic links, and visits all levels
+     * of the file level.
      *
      * @param   start
-     *          The starting file
+     *          the starting file
      * @param   visitor
-     *          The file visitor to invoke for each file
+     *          the file visitor to invoke for each file
+     *
+     * @return  the starting file
      *
      * @throws  SecurityException
      *          If the security manager denies access to the starting file.
@@ -246,118 +2598,511 @@
      *          SecurityManager#checkRead(String) checkRead} method is invoked
      *          to check read access to the directory.
      * @throws  IOException
-     *          If an I/O error is thrown by a visitor method
+     *          if an I/O error is thrown by a visitor method
      */
-    public static void walkFileTree(Path start, FileVisitor<? super Path> visitor)
+    public static Path walkFileTree(Path start, FileVisitor<? super Path> visitor)
+        throws IOException
+    {
+        return walkFileTree(start,
+                            EnumSet.noneOf(FileVisitOption.class),
+                            Integer.MAX_VALUE,
+                            visitor);
+    }
+
+
+    // -- Utility methods for simple usages --
+
+    // buffer size used for reading and writing
+    private static final int BUFFER_SIZE = 8192;
+
+    /**
+     * Opens a file for reading, returning a {@code BufferedReader} that may be
+     * used to read text from the file in an efficient manner. Bytes from the
+     * file are decoded into characters using the specified charset. Reading
+     * commences at the beginning of the file.
+     *
+     * <p> The {@code Reader} methods that read from the file throw {@code
+     * IOException} if a malformed or unmappable byte sequence is read.
+     *
+     * @param   path
+     *          the path to the file
+     * @param   cs
+     *          the charset to use for decoding
+     *
+     * @return  a new buffered reader, with default buffer size, to read text
+     *          from the file
+     *
+     * @throws  IOException
+     *          if an I/O error occurs opening the file
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the file.
+     *
+     * @see #readAllLines
+     */
+    public static BufferedReader newBufferedReader(Path path, Charset cs)
         throws IOException
     {
-        walkFileTree(start,
-                     EnumSet.noneOf(FileVisitOption.class),
-                     Integer.MAX_VALUE,
-                     visitor);
+        CharsetDecoder decoder = cs.newDecoder();
+        Reader reader = new InputStreamReader(newInputStream(path), decoder);
+        return new BufferedReader(reader);
+    }
+
+    /**
+     * Opens or creates a file for writing, returning a {@code BufferedWriter}
+     * that may be used to write text to the file in an efficient manner.
+     * The {@code options} parameter specifies how the the file is created or
+     * opened. If no options are present then this method works as if the {@link
+     * StandardOpenOption#CREATE CREATE}, {@link
+     * StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING}, and {@link
+     * StandardOpenOption#WRITE WRITE} options are present. In other words, it
+     * opens the file for writing, creating the file if it doesn't exist, or
+     * initially truncating an existing {@link #isRegularFile regular-file} to
+     * a size of {@code 0} if it exists.
+     *
+     * <p> The {@code Writer} methods to write text throw {@code IOException}
+     * if the text cannot be encoded using the specified charset.
+     *
+     * @param   path
+     *          the path to the file
+     * @param   cs
+     *          the charset to use for encoding
+     * @param   options
+     *          options specifying how the file is opened
+     *
+     * @return  a new buffered writer, with default buffer size, to write text
+     *          to the file
+     *
+     * @throws  IOException
+     *          if an I/O error occurs opening or creating the file
+     * @throws  UnsupportedOperationException
+     *          if an unsupported option is specified
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method is invoked to check write access to the file.
+     *
+     * @see #write(Path,Iterable,Charset,OpenOption[])
+     */
+    public static BufferedWriter newBufferedWriter(Path path, Charset cs,
+                                                   OpenOption... options)
+        throws IOException
+    {
+        CharsetEncoder encoder = cs.newEncoder();
+        Writer writer = new OutputStreamWriter(newOutputStream(path, options), encoder);
+        return new BufferedWriter(writer);
+    }
+
+    /**
+     * Reads all bytes from an input stream and writes them to an output stream.
+     */
+    private static long copy(InputStream source, OutputStream sink)
+        throws IOException
+    {
+        long nread = 0L;
+        byte[] buf = new byte[BUFFER_SIZE];
+        int n;
+        while ((n = source.read(buf)) > 0) {
+            sink.write(buf, 0, n);
+            nread += n;
+        }
+        return nread;
     }
 
     /**
-     * Creates a directory by creating all nonexistent parent directories first.
+     * Copies all bytes from an input stream to a file. On return, the input
+     * stream will be at end of stream.
+     *
+     * <p> By default, the copy fails if the target file already exists or is a
+     * symbolic link. If the {@link StandardCopyOption#REPLACE_EXISTING
+     * REPLACE_EXISTING} option is specified, and the target file already exists,
+     * then it is replaced if it is not a non-empty directory. If the target
+     * file exists and is a symbolic link, then the symbolic link is replaced.
+     * In this release, the {@code REPLACE_EXISTING} option is the only option
+     * required to be supported by this method. Additional options may be
+     * supported in future releases.
      *
-     * <p> The {@code attrs} parameter is an optional array of {@link FileAttribute
-     * file-attributes} to set atomically when creating the nonexistent
-     * directories. Each file attribute is identified by its {@link
-     * FileAttribute#name name}. If more than one attribute of the same name is
-     * included in the array then all but the last occurrence is ignored.
+     * <p>  If an I/O error occurs reading from the input stream or writing to
+     * the file, then it may do so after the target file has been created and
+     * after some bytes have been read or written. Consequently the input
+     * stream may not be at end of stream and may be in an inconsistent state.
+     * It is strongly recommended that the input stream be promptly closed if an
+     * I/O error occurs.
+     *
+     * <p> This method may block indefinitely reading from the input stream (or
+     * writing to the file). The behavior for the case that the input stream is
+     * <i>asynchronously closed</i> or the thread interrupted during the copy is
+     * highly input stream and file system provider specific and therefore not
+     * specified.
      *
-     * <p> If this method fails, then it may do so after creating some, but not
-     * all, of the parent directories.
+     * <p> <b>Usage example</b>: Suppose we want to capture a web page and save
+     * it to a file:
+     * <pre>
+     *     Path path = ...
+     *     URI u = URI.create("http://java.sun.com/");
+     *     try (InputStream in = u.toURL().openStream()) {
+     *         Files.copy(in, path);
+     *     }
+     * </pre>
      *
-     * @param   dir
-     *          the directory to create
+     * @param   in
+     *          the input stream to read from
+     * @param   target
+     *          the path to the file
+     * @param   options
+     *          options specifying how the copy should be done
+     *
+     * @return  the number of bytes read or written
      *
-     * @param   attrs
-     *          an optional list of file attributes to set atomically when
-     *          creating the directory
-     *
+     * @throws  IOException
+     *          if an I/O error occurs when reading or writing
+     * @throws  FileAlreadyExistsException
+     *          if the target file exists but cannot be replaced because the
+     *          {@code REPLACE_EXISTING} option is not specified <i>(optional
+     *          specific exception)</i>
+     * @throws  DirectoryNotEmptyException
+     *          the {@code REPLACE_EXISTING} option is specified but the file
+     *          cannot be replaced because it is a non-empty directory
+     *          <i>(optional specific exception)</i>     *
      * @throws  UnsupportedOperationException
-     *          if the array contains an attribute that cannot be set atomically
-     *          when creating the directory
-     * @throws  FileAlreadyExistsException
-     *          if {@code dir} exists but is not a directory <i>(optional specific
-     *          exception)</i>
-     * @throws  IOException
-     *          if an I/O error occurs
+     *          if {@code options} contains a copy option that is not supported
      * @throws  SecurityException
-     *          in the case of the default provider, and a security manager is
+     *          In the case of the default provider, and a security manager is
      *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
-     *          method is invoked prior to attempting to create a directory and
-     *          its {@link SecurityManager#checkRead(String) checkRead} is
-     *          invoked for each parent directory that is checked. If {@code
-     *          dir} is not an absolute path then its {@link Path#toAbsolutePath
-     *          toAbsolutePath} may need to be invoked to get its absolute path.
-     *          This may invoke the security manager's {@link
-     *          SecurityManager#checkPropertyAccess(String) checkPropertyAccess}
-     *          method to check access to the system property {@code user.dir}
-     *
+     *          method is invoked to check write access to the file. Where the
+     *          {@code REPLACE_EXISTING} option is specified, the security
+     *          manager's {@link SecurityManager#checkDelete(String) checkDelete}
+     *          method is invoked to check that an existing file can be deleted.
      */
-    public static void createDirectories(Path dir, FileAttribute<?>... attrs)
+    public static long copy(InputStream in, Path target, CopyOption... options)
         throws IOException
     {
-        // attempt to create the directory
-        try {
-            createAndCheckIsDirectory(dir, attrs);
-            return;
-        } catch (FileAlreadyExistsException x) {
-            // file exists and is not a directory
-            throw x;
-        } catch (IOException x) {
-            // parent may not exist or other reason
+        // ensure not null before opening file
+        Objects.nonNull(in);
+
+        // check for REPLACE_EXISTING
+        boolean replaceExisting = false;
+        for (CopyOption opt: options) {
+            if (opt == StandardCopyOption.REPLACE_EXISTING) {
+                replaceExisting = true;
+            } else {
+                if (opt == null) {
+                    throw new NullPointerException("options contains 'null'");
+                }  else {
+                    throw new UnsupportedOperationException(opt + " not supported");
+                }
+            }
         }
 
-        // find existing parent (may require absolute path)
+        // attempt to delete an existing file
         SecurityException se = null;
-        try {
-            dir = dir.toAbsolutePath();
-        } catch (SecurityException x) {
-            // don't have permission to get absolute path
-            se = x;
+        if (replaceExisting) {
+            try {
+                deleteIfExists(target);
+            } catch (SecurityException x) {
+                se = x;
+            }
         }
-        Path parent = dir.getParent();
-        while (parent != null) {
-            try {
-                parent.checkAccess();
-                break;
-            } catch (NoSuchFileException x) {
-                // does not exist
-            }
-            parent = parent.getParent();
-        }
-        if (parent == null) {
-            // unable to find existing parent
+
+        // attempt to create target file. If it fails with
+        // FileAlreadyExistsException then it may be because the security
+        // manager prevented us from deleting the file, in which case we just
+        // throw the SecurityException.
+        OutputStream ostream;
+        try {
+            ostream = newOutputStream(target, StandardOpenOption.CREATE_NEW,
+                                              StandardOpenOption.WRITE);
+        } catch (FileAlreadyExistsException x) {
             if (se != null)
                 throw se;
-            throw new IOException("Root directory does not exist");
+            // someone else won the race and created the file
+            throw x;
         }
 
-        // create directories
-        Path child = parent;
-        for (Path name: parent.relativize(dir)) {
-            child = child.resolve(name);
-            createAndCheckIsDirectory(child, attrs);
+        // do the copy
+        try (OutputStream out = ostream) {
+            return copy(in, out);
         }
     }
 
     /**
-     * Attempts to create a directory. Does nothing if the directory already
-     * exists.
+     * Copies all bytes from a file to an output stream.
+     *
+     * <p> If an I/O error occurs reading from the file or writing to the output
+     * stream, then it may do so after some bytes have been read or written.
+     * Consequently the output stream may be in an inconsistent state. It is
+     * strongly recommended that the output stream be promptly closed if an I/O
+     * error occurs.
+     *
+     * <p> This method may block indefinitely writing to the output stream (or
+     * reading from the file). The behavior for the case that the output stream
+     * is <i>asynchronously closed</i> or the thread interrupted during the copy
+     * is highly output stream and file system provider specific and therefore
+     * not specified.
+     *
+     * <p> Note that if the given output stream is {@link java.io.Flushable}
+     * then its {@link java.io.Flushable#flush flush} method may need to invoked
+     * after this method completes so as to flush any buffered output.
+     *
+     * @param   source
+     *          the  path to the file
+     * @param   out
+     *          the output stream to write to
+     *
+     * @return  the number of bytes read or written
+     *
+     * @throws  IOException
+     *          if an I/O error occurs when reading or writing
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the file.
      */
-    private static void createAndCheckIsDirectory(Path dir, FileAttribute<?>... attrs)
+    public static long copy(Path source, OutputStream out) throws IOException {
+        // ensure not null before opening file
+        Objects.nonNull(out);
+
+        try (InputStream in = newInputStream(source)) {
+            return copy(in, out);
+        }
+    }
+
+    /**
+     * Read all the bytes from an input stream. The {@code initialSize}
+     * parameter indicates the initial size of the byte[] to allocate.
+     */
+    private static byte[] read(InputStream source, int initialSize)
         throws IOException
     {
-        try {
-            dir.createDirectory(attrs);
-        } catch (FileAlreadyExistsException x) {
-            boolean isDirectory = Attributes
-                .readBasicFileAttributes(dir, LinkOption.NOFOLLOW_LINKS).isDirectory();
-            if (!isDirectory)
-                throw x;
+        int capacity = initialSize;
+        byte[] buf = new byte[capacity];
+        int nread = 0;
+        int rem = buf.length;
+        int n;
+        // read to EOF which may read more or less than initialSize (eg: file
+        // is truncated while we are reading)
+        while ((n = source.read(buf, nread, rem)) > 0) {
+            nread += n;
+            rem -= n;
+            assert rem >= 0;
+            if (rem == 0) {
+                // need larger buffer
+                int newCapacity = capacity << 1;
+                if (newCapacity < 0) {
+                    if (capacity == Integer.MAX_VALUE)
+                        throw new OutOfMemoryError("Required array size too large");
+                    newCapacity = Integer.MAX_VALUE;
+                }
+                rem = newCapacity - capacity;
+                buf = Arrays.copyOf(buf, newCapacity);
+                capacity = newCapacity;
+            }
+        }
+        return (capacity == nread) ? buf : Arrays.copyOf(buf, nread);
+    }
+
+    /**
+     * Read all the bytes from a file. The method ensures that the file is
+     * closed when all bytes have been read or an I/O error, or other runtime
+     * exception, is thrown.
+     *
+     * <p> Note that this method is intended for simple cases where it is
+     * convenient to read all bytes into a byte array. It is not intended for
+     * reading in large files.
+     *
+     * @param   path
+     *          the path to the file
+     *
+     * @return  a byte array containing the bytes read from the file
+     *
+     * @throws  IOException
+     *          if an I/O error occurs reading from the stream
+     * @throws  OutOfMemoryError
+     *          if an array of the required size cannot be allocated, for
+     *          example the file is larger that {@code 2GB}
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the file.
+     */
+    public static byte[] readAllBytes(Path path) throws IOException {
+        long size = size(path);
+        if (size > (long)Integer.MAX_VALUE)
+            throw new OutOfMemoryError("Required array size too large");
+
+        try (InputStream in = newInputStream(path)) {
+             return read(in, (int)size);
+        }
+    }
+
+    /**
+     * Read all lines from a file. This method ensures that the file is
+     * closed when all bytes have been read or an I/O error, or other runtime
+     * exception, is thrown. Bytes from the file are decoded into characters
+     * using the specified charset.
+     *
+     * <p> This method recognizes the following as line terminators:
+     * <ul>
+     *   <li> <code>&#92;u000D</code> followed by <code>&#92;u000A</code>,
+     *     CARRIAGE RETURN followed by LINE FEED </li>
+     *   <li> <code>&#92;u000A</code>, LINE FEED </li>
+     *   <li> <code>&#92;u000D</code>, CARRIAGE RETURN </li>
+     * </ul>
+     * <p> Additional Unicode line terminators may be recognized in future
+     * releases.
+     *
+     * <p> Note that this method is intended for simple cases where it is
+     * convenient to read all lines in a single operation. It is not intended
+     * for reading in large files.
+     *
+     * @param   path
+     *          the path to the file
+     * @param   cs
+     *          the charset to use for decoding
+     *
+     * @return  the lines from the file as a {@code List}; whether the {@code
+     *          List} is modifiable or not is implementation dependent and
+     *          therefore not specified
+     *
+     * @throws  IOException
+     *          if an I/O error occurs reading from the file or a malformed or
+     *          unmappable byte sequence is read
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the file.
+     *
+     * @see #newBufferedReader
+     */
+    public static List<String> readAllLines(Path path, Charset cs)
+        throws IOException
+    {
+        try (BufferedReader reader = newBufferedReader(path, cs)) {
+            List<String> result = new ArrayList<>();
+            for (;;) {
+                String line = reader.readLine();
+                if (line == null)
+                    break;
+                result.add(line);
+            }
+            return result;
         }
     }
+
+    /**
+     * Writes bytes to a file. The {@code options} parameter specifies how the
+     * the file is created or opened. If no options are present then this method
+     * works as if the {@link StandardOpenOption#CREATE CREATE}, {@link
+     * StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING}, and {@link
+     * StandardOpenOption#WRITE WRITE} options are present. In other words, it
+     * opens the file for writing, creating the file if it doesn't exist, or
+     * initially truncating an existing {@link #isRegularFile regular-file} to
+     * a size of {@code 0}. All bytes in the byte array are written to the file.
+     * The method ensures that the file is closed when all bytes have been
+     * written (or an I/O error or other runtime exception is thrown). If an I/O
+     * error occurs then it may do so after the file has created or truncated,
+     * or after some bytes have been written to the file.
+     *
+     * <p> <b>Usage example</b>: By default the method creates a new file or
+     * overrides an existing file. Suppose you instead want to append bytes
+     * to an existing file:
+     * <pre>
+     *     Path path = ...
+     *     byte[] bytes = ...
+     *     Files.write(path, bytes, StandardOpenOption.APPEND);
+     * </pre>
+     *
+     * @param   path
+     *          the path to the file
+     * @param   bytes
+     *          the byte array with the bytes to write
+     * @param   options
+     *          options specifying how the file is opened
+     *
+     * @return  the path
+     *
+     * @throws  IOException
+     *          if an I/O error occurs writing to or creating the file
+     * @throws  UnsupportedOperationException
+     *          if an unsupported option is specified
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method is invoked to check write access to the file.
+     */
+    public static Path write(Path path, byte[] bytes, OpenOption... options)
+        throws IOException
+    {
+        // ensure bytes is not null before opening file
+        Objects.nonNull(bytes);
+
+        try (OutputStream out = Files.newOutputStream(path, options)) {
+            int len = bytes.length;
+            int rem = len;
+            while (rem > 0) {
+                int n = Math.min(rem, BUFFER_SIZE);
+                out.write(bytes, (len-rem), n);
+                rem -= n;
+            }
+        }
+        return path;
+    }
+
+    /**
+     * Write lines of text to a file. Each line is a char sequence and is
+     * written to the file in sequence with each line terminated by the
+     * platform's line separator, as defined by the system property {@code
+     * line.separator}. Characters are encoded into bytes using the specified
+     * charset.
+     *
+     * <p> The {@code options} parameter specifies how the the file is created
+     * or opened. If no options are present then this method works as if the
+     * {@link StandardOpenOption#CREATE CREATE}, {@link
+     * StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING}, and {@link
+     * StandardOpenOption#WRITE WRITE} options are present. In other words, it
+     * opens the file for writing, creating the file if it doesn't exist, or
+     * initially truncating an existing {@link #isRegularFile regular-file} to
+     * a size of {@code 0}. The method ensures that the file is closed when all
+     * lines have been written (or an I/O error or other runtime exception is
+     * thrown). If an I/O error occurs then it may do so after the file has
+     * created or truncated, or after some bytes have been written to the file.
+     *
+     * @param   path
+     *          the path to the file
+     * @param   lines
+     *          an object to iterate over the char sequences
+     * @param   cs
+     *          the charset to use for encoding
+     * @param   options
+     *          options specifying how the file is opened
+     *
+     * @return  the path
+     *
+     * @throws  IOException
+     *          if an I/O error occurs writing to or creating the file, or the
+     *          text cannot be encoded using the specified charset
+     * @throws  UnsupportedOperationException
+     *          if an unsupported option is specified
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method is invoked to check write access to the file.
+     */
+    public static Path write(Path path, Iterable<? extends CharSequence> lines,
+                             Charset cs, OpenOption... options)
+        throws IOException
+    {
+        // ensure lines is not null before opening file
+        Objects.nonNull(lines);
+        CharsetEncoder encoder = cs.newEncoder();
+        OutputStream out = newOutputStream(path, options);
+        try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, encoder))) {
+            for (CharSequence line: lines) {
+                writer.append(line);
+                writer.newLine();
+            }
+        }
+        return path;
+    }
 }
--- a/jdk/src/share/classes/java/nio/file/LinkOption.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/LinkOption.java	Fri Jan 28 09:28:43 2011 +0000
@@ -35,8 +35,8 @@
     /**
      * Do not follow symbolic links.
      *
-     * @see FileRef#getFileAttributeView(Class,LinkOption[])
-     * @see Path#copyTo
+     * @see Files#getFileAttributeView(Path,Class,LinkOption[])
+     * @see Files#copy
      * @see SecureDirectoryStream#newByteChannel
      */
     NOFOLLOW_LINKS;
--- a/jdk/src/share/classes/java/nio/file/LinkPermission.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/LinkPermission.java	Fri Jan 28 09:28:43 2011 +0000
@@ -59,8 +59,8 @@
  *
  * @since 1.7
  *
- * @see Path#createLink
- * @see Path#createSymbolicLink
+ * @see Files#createLink
+ * @see Files#createSymbolicLink
  */
 public final class LinkPermission extends BasicPermission {
     static final long serialVersionUID = -1441492453772213220L;
--- a/jdk/src/share/classes/java/nio/file/OpenOption.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/OpenOption.java	Fri Jan 28 09:28:43 2011 +0000
@@ -29,8 +29,8 @@
  * An object that configures how to open or create a file.
  *
  * <p> Objects of this type are used by methods such as {@link
- * Path#newOutputStream(OpenOption[]) newOutputStream}, {@link
- * Path#newByteChannel newByteChannel}, {@link
+ * Files#newOutputStream(Path,OpenOption[]) newOutputStream}, {@link
+ * Files#newByteChannel newByteChannel}, {@link
  * java.nio.channels.FileChannel#open FileChannel.open}, and {@link
  * java.nio.channels.AsynchronousFileChannel#open AsynchronousFileChannel.open}
  * when opening or creating a file.
--- a/jdk/src/share/classes/java/nio/file/Path.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/Path.java	Fri Jan 28 09:28:43 2011 +0000
@@ -25,147 +25,95 @@
 
 package java.nio.file;
 
-import java.nio.file.attribute.*;
-import java.nio.channels.SeekableByteChannel;
+import java.io.File;
 import java.io.IOException;
-import java.io.OutputStream;
 import java.net.URI;
 import java.util.Iterator;
-import java.util.Set;
 
 /**
- * A file reference that locates a file using a system dependent path. The file
- * is not required to exist.
- *
- * <p> On many platforms a <em>path</em> is the means to locate and access files
- * in a file system. A path is hierarchical and composed of a sequence of
- * directory and file name elements separated by a special separator or
- * delimiter.
- *
- * <h4>Path operations</h4>
+ * An object that may be used to locate a file in a file system. It will
+ * typically represent a system dependent file path.
  *
- * <p> A system dependent path represented by this class is conceptually a
- * sequence of name elements and optionally a <em>root component</em>. The name
- * that is <em>farthest</em> from the root of the directory hierarchy is the
- * name of a file or directory. The other elements are directory names. The root
- * component typically identifies a file system hierarchy. A {@code Path} can
- * represent a root, a root and a sequence of names, or simply one or more name
- * elements. It defines the {@link #getName() getName}, {@link #getParent
- * getParent}, {@link #getRoot getRoot}, and {@link #subpath subpath} methods
- * to access the components or a subsequence of its name elements.
+ * <p> A {@code Path} represents a path that is hierarchical and composed of a
+ * sequence of directory and file name elements separated by a special separator
+ * or delimiter. A <em>root component</em>, that identifies a file system
+ * hierarchy, may also be present. The name element that is <em>farthest</em>
+ * from the root of the directory hierarchy is the name of a file or directory.
+ * The other name elements are directory names. A {@code Path} can represent a
+ * root, a root and a sequence of names, or simply one or more name elements.
+ * A {@code Path} is considered to be an <i>empty path</i> if it consists
+ * solely of one name element that is empty. Accessing a file using an
+ * <i>empty path</i> is equivalent to accessing the default directory of the
+ * file system. {@code Path} defines the {@link #getFileName() getFileName},
+ * {@link #getParent getParent}, {@link #getRoot getRoot}, and {@link #subpath
+ * subpath} methods to access the path components or a subsequence of its name
+ * elements.
  *
  * <p> In addition to accessing the components of a path, a {@code Path} also
- * defines {@link #resolve(Path) resolve} and {@link #relativize relativize}
- * operations. Paths can also be {@link #compareTo compared}, and tested
- * against each other using using the {@link #startsWith startsWith} and {@link
- * #endsWith endWith} methods.
- *
- * <h4>File operations</h4>
+ * defines the {@link #resolve(Path) resolve} and {@link #resolveSibling(Path)
+ * resolveSibling} methods to combine paths. The {@link #relativize relativize}
+ * method that can be used to construct a relative path between two paths.
+ * Paths can be {@link #compareTo compared}, and tested against each other using
+ * the {@link #startsWith startsWith} and {@link #endsWith endWith} methods.
  *
- * <p> A {@code Path} is either <em>absolute</em> or <em>relative</em>. An
- * absolute path is complete in that does not need to be combined with another
- * path in order to locate a file. All operations on relative paths are first
- * resolved against a file system's default directory as if by invoking the
- * {@link #toAbsolutePath toAbsolutePath} method.
- *
- * <p> In addition to the operations defined by the {@link FileRef} interface,
- * this class defines the following operations:
+ * <p> This interface extends {@link Watchable} interface so that a directory
+ * located by a path can be {@link #register registered} with a {@link
+ * WatchService} and entries in the directory watched. </p>
  *
- * <ul>
- *   <li><p> The {@link #newByteChannel newByteChannel} method
- *     may be used to open a file and obtain a byte channel for reading or
- *     writing. </p></li>
- *   <li><p> Files may be {@link #createFile(FileAttribute[]) created}, or
- *     directories may be {@link #createDirectory(FileAttribute[]) created}.
- *     </p></li>
- *   <li><p> The {@link #delete delete} method may be used to delete a file.
- *     </p></li>
- *   <li><p> The {@link #checkAccess checkAccess} method may be used to check
- *     the existence or accessibility of a file. </p></li>
- *   <li><p> The {@link #isSameFile isSameFile} method may be used to test if
- *     two file references locate the same file. </p></li>
- *   <li><p> The {@link #getFileStore getFileStore} method may be used to
- *     obtain the {@link FileStore} representing the storage where a file is
- *     located. </p></li>
- *   <li><p> Directories can be {@link #newDirectoryStream opened} so as to
- *      iterate over the entries in the directory. </p></li>
- *   <li><p> Files can be {@link #copyTo(Path,CopyOption[]) copied} or
- *     {@link #moveTo(Path,CopyOption[]) moved}. </p></li>
- *   <li><p> Symbolic links may be {@link #createSymbolicLink created}, or the
- *     target of a symbolic link may be {@link #readSymbolicLink read}. </p></li>
- *   <li><p> The {@link #toRealPath real} path of an existing file may be
- *     obtained. </li></p>
- * </ul>
+ * <p> <b>WARNING:</b> This interface is only intended to be implemented by
+ * those developing custom file system implementations. Methods may be added to
+ * this interface in future releases. </p>
  *
- * <p> This class implements {@link Watchable} interface so that a directory
- * located by a path can be {@link #register registered} with a {@link WatchService}.
- * and entries in the directory watched.
- *
- * <h4>File attributes</h4>
- *
- * In addition to the {@link #setAttribute setAttribute} and {@link #getAttribute
- * getAttribute} methods, the <a href="attribute/package-summary.html">{@code
- * java.nio.file.attribute}</a> package provides type-safe and efficient access
- * to file attributes or <em>meta-data</em> associated with files. The {@link
- * Attributes Attributes} class defines methods that operate on or return file
- * attributes. For example, the file type, size, timestamps, and other
- * <em>basic</em> meta-data are obtained, in bulk, by invoking the {@link
- * Attributes#readBasicFileAttributes Attributes.readBasicFileAttributes} method:
+ * <a name="interop"><h4>Accessing Files</h4></a>
+ * <p> Paths may be used with the {@link Files} class to operate on files,
+ * directories, and other types of files. For example, suppose we want a {@link
+ * java.io.BufferedReader} to read text from a file "{@code access.log}". The
+ * file is located in a directory "{@code logs}" relative to the current working
+ * directory and is UTF-8 encoded.
  * <pre>
- *     Path file = ...
- *     BasicFileAttributes attrs = Attributes.readBasicFileAttributes(file);
+ *     Path path = FileSystems.getDefault().getPath("logs", "access.log");
+ *     BufferReader reader = Files.newBufferedReader(path, Charset.forName("UTF-8"));
  * </pre>
  *
  * <a name="interop"><h4>Interoperability</h4></a>
- *
- * <p> Paths created by file systems associated with the default {@link
+ * <p> Paths associated with the default {@link
  * java.nio.file.spi.FileSystemProvider provider} are generally interoperable
  * with the {@link java.io.File java.io.File} class. Paths created by other
  * providers are unlikely to be interoperable with the abstract path names
- * represented by {@code java.io.File}. The {@link java.io.File#toPath
- * File.toPath} method may be used to obtain a {@code Path} from the abstract
- * path name represented by a {@code java.io.File java.io.File} object. The
- * resulting {@code Path} can be used to operate on the same file as the {@code
- * java.io.File} object.
- *
- * <p> Path objects created by file systems associated with the default
- * provider are interoperable with objects created by other file systems created
- * by the same provider. Path objects created by file systems associated with
- * other providers may not be interoperable with other file systems created by
- * the same provider. The reasons for this are provider specific.
+ * represented by {@code java.io.File}. The {@link java.io.File#toPath toPath}
+ * method may be used to obtain a {@code Path} from the abstract path name
+ * represented by a {@code java.io.File} object. The resulting {@code Path} can
+ * be used to operate on the same file as the {@code java.io.File} object. In
+ * addition, the {@link #toFile toFile} method is useful to construct a {@code
+ * File} from the {@code String} representation of a {@code Path}.
  *
  * <h4>Concurrency</h4></a>
- *
- * <p> Instances of this class are immutable and safe for use by multiple concurrent
- * threads.
+ * <p> Implementations of this interface are immutable and safe for use by
+ * multiple concurrent threads.
  *
  * @since 1.7
+ * @see Paths
  */
 
-public abstract class Path
-    implements FileRef, Comparable<Path>, Iterable<Path>, Watchable
+public interface Path
+    extends Comparable<Path>, Iterable<Path>, Watchable
 {
     /**
-     * Initializes a new instance of this class.
-     */
-    protected Path() { }
-
-    /**
      * Returns the file system that created this object.
      *
      * @return  the file system that created this object
      */
-    public abstract FileSystem getFileSystem();
+    FileSystem getFileSystem();
 
     /**
      * Tells whether or not this path is absolute.
      *
-     * <p> An absolute path is complete in that it doesn't need to be
-     * combined with other path information in order to locate a file.
+     * <p> An absolute path is complete in that it doesn't need to be combined
+     * with other path information in order to locate a file.
      *
      * @return  {@code true} if, and only if, this path is absolute
      */
-    public abstract boolean isAbsolute();
+    boolean isAbsolute();
 
     /**
      * Returns the root component of this path as a {@code Path} object,
@@ -174,17 +122,17 @@
      * @return  a path representing the root component of this path,
      *          or {@code null}
      */
-    public abstract Path getRoot();
+    Path getRoot();
 
     /**
-     * Returns the name of the file or directory denoted by this path. The
-     * file name is the <em>farthest</em> element from the root in the directory
-     * hierarchy.
+     * Returns the name of the file or directory denoted by this path as a
+     * {@code Path} object. The file name is the <em>farthest</em> element from
+     * the root in the directory hierarchy.
      *
      * @return  a path representing the name of the file or directory, or
      *          {@code null} if this path has zero elements
      */
-    public abstract Path getName();
+    Path getFileName();
 
     /**
      * Returns the <em>parent path</em>, or {@code null} if this path does not
@@ -209,7 +157,7 @@
      *
      * @return  a path representing the path's parent
      */
-    public abstract Path getParent();
+    Path getParent();
 
     /**
      * Returns the number of name elements in the path.
@@ -217,10 +165,10 @@
      * @return  the number of elements in the path, or {@code 0} if this path
      *          only represents a root component
      */
-    public abstract int getNameCount();
+    int getNameCount();
 
-   /**
-     * Returns a name element of this path.
+    /**
+     * Returns a name element of this path as a {@code Path} object.
      *
      * <p> The {@code index} parameter is the index of the name element to return.
      * The element that is <em>closest</em> to the root in the directory hierarchy
@@ -237,7 +185,7 @@
      *          equal to the number of elements, or this path has zero name
      *          elements
      */
-    public abstract Path getName(int index);
+    Path getName(int index);
 
     /**
      * Returns a relative {@code Path} that is a subsequence of the name
@@ -264,7 +212,7 @@
      *          the number of elements. If {@code endIndex} is less than or
      *          equal to {@code beginIndex}, or larger than the number of elements.
      */
-    public abstract Path subpath(int beginIndex, int endIndex);
+    Path subpath(int beginIndex, int endIndex);
 
     /**
      * Tests if this path starts with the given path.
@@ -286,7 +234,25 @@
      * @return  {@code true} if this path starts with the given path; otherwise
      *          {@code false}
      */
-    public abstract boolean startsWith(Path other);
+    boolean startsWith(Path other);
+
+    /**
+     * Tests if this path starts with a {@code Path}, constructed by converting
+     * the given path string, in exactly the manner specified by the {@link
+     * #startsWith(Path) startsWith(Path)} method. On UNIX for example, the path
+     * "{@code foo/bar}" starts with "{@code foo}" and "{@code foo/bar}". It
+     * does not start with "{@code f}" or "{@code fo}".
+     *
+     * @param   other
+     *          the given path string
+     *
+     * @return  {@code true} if this path starts with the given path; otherwise
+     *          {@code false}
+     *
+     * @throws  InvalidPathException
+     *          If the path string cannot be converted to a Path.
+     */
+    boolean startsWith(String other);
 
     /**
      * Tests if this path ends with the given path.
@@ -310,7 +276,25 @@
      * @return  {@code true} if this path ends with the given path; otherwise
      *          {@code false}
      */
-    public abstract boolean endsWith(Path other);
+    boolean endsWith(Path other);
+
+    /**
+     * Tests if this path ends with a {@code Path}, constructed by converting
+     * the given path string, in exactly the manner specified by the {@link
+     * #endsWith(Path) endsWith(Path)} method. On UNIX for example, the path
+     * "{@code foo/bar}" ends with "{@code foo/bar}" and "{@code bar}". It does
+     * not end with "{@code r}" or "{@code /bar}".
+     *
+     * @param   other
+     *          the given path string
+     *
+     * @return  {@code true} if this path starts with the given path; otherwise
+     *          {@code false}
+     *
+     * @throws  InvalidPathException
+     *          If the path string cannot be converted to a Path.
+     */
+    boolean endsWith(String other);
 
     /**
      * Returns a path that is this path with redundant name elements eliminated.
@@ -330,14 +314,14 @@
      * path may result in the path that locates a different file than the original
      * path. This can arise when the preceding name is a symbolic link.
      *
-     * @return  the resulting path, or this path if it does not contain
-     *          redundant name elements, or {@code null} if this path does not
-     *          have a root component and all name elements are redundant
+     * @return  the resulting path or this path if it does not contain
+     *          redundant name elements; an empty path is returned if this path
+     *          does have a root component and all name elements are redundant
      *
      * @see #getParent
      * @see #toRealPath
      */
-    public abstract Path normalize();
+    Path normalize();
 
     // -- resolution and relativization --
 
@@ -346,28 +330,31 @@
      *
      * <p> If the {@code other} parameter is an {@link #isAbsolute() absolute}
      * path then this method trivially returns {@code other}. If {@code other}
-     * is {@code null} then this path is returned. Otherwise this method
-     * considers this path to be a directory and resolves the given path
-     * against this path. In the simplest case, the given path does not have
-     * a {@link #getRoot root} component, in which case this method <em>joins</em>
-     * the given path to this path and returns a resulting path that {@link
-     * #endsWith ends} with the given path. Where the given path has a root
-     * component then resolution is highly implementation dependent and therefore
-     * unspecified.
+     * is an <i>empty path</i> then this method trivially returns this path.
+     * Otherwise this method considers this path to be a directory and resolves
+     * the given path against this path. In the simplest case, the given path
+     * does not have a {@link #getRoot root} component, in which case this method
+     * <em>joins</em> the given path to this path and returns a resulting path
+     * that {@link #endsWith ends} with the given path. Where the given path has
+     * a root component then resolution is highly implementation dependent and
+     * therefore unspecified.
      *
      * @param   other
-     *          the path to resolve against this path; can be {@code null}
+     *          the path to resolve against this path
      *
      * @return  the resulting path
      *
      * @see #relativize
      */
-    public abstract Path resolve(Path other);
+    Path resolve(Path other);
 
     /**
      * Converts a given path string to a {@code Path} and resolves it against
      * this {@code Path} in exactly the manner specified by the {@link
-     * #resolve(Path) resolve} method.
+     * #resolve(Path) resolve} method. For example, suppose that the name
+     * separator is "{@code /}" and a path represents "{@code foo/bar}", then
+     * invoking this method with the path string "{@code gus}" will result in
+     * the {@code Path} "{@code foo/bar/gus}".
      *
      * @param   other
      *          the path string to resolve against this path
@@ -375,11 +362,49 @@
      * @return  the resulting path
      *
      * @throws  InvalidPathException
-     *          If the path string cannot be converted to a Path.
+     *          if the path string cannot be converted to a Path.
      *
      * @see FileSystem#getPath
      */
-    public abstract Path resolve(String other);
+    Path resolve(String other);
+
+    /**
+     * Resolves the given path against this path's {@link #getParent parent}
+     * path. This is useful where a file name needs to be <i>replaced</i> with
+     * another file name. For example, suppose that the name separator is
+     * "{@code /}" and a path represents "{@code dir1/dir2/foo}", then invoking
+     * this method with the {@code Path} "{@code bar}" will result in the {@code
+     * Path} "{@code dir1/dir2/bar}". If this path does not have a parent path,
+     * or {@code other} is {@link #isAbsolute() absolute}, then this method
+     * returns {@code other}. If {@code other} is an empty path then this method
+     * returns this path's parent, or where this path doesn't have a parent, the
+     * empty path.
+     *
+     * @param   other
+     *          the path to resolve against this path's parent
+     *
+     * @return  the resulting path
+     *
+     * @see #resolve(Path)
+     */
+    Path resolveSibling(Path other);
+
+    /**
+     * Converts a given path string to a {@code Path} and resolves it against
+     * this path's {@link #getParent parent} path in exactly the manner
+     * specified by the {@link #resolveSibling(Path) resolveSibling} method.
+     *
+     * @param   other
+     *          the path string to resolve against this path's parent
+     *
+     * @return  the resulting path
+     *
+     * @throws  InvalidPathException
+     *          if the path string cannot be converted to a Path.
+     *
+     * @see FileSystem#getPath
+     */
+    Path resolveSibling(String other);
 
     /**
      * Constructs a relative path between this path and a given path.
@@ -395,17 +420,17 @@
      * constructed if only one of the paths have a root component. Where both
      * paths have a root component then it is implementation dependent if a
      * relative path can be constructed. If this path and the given path are
-     * {@link #equals equal} then {@code null} is returned.
+     * {@link #equals equal} then an <i>empty path</i> is returned.
      *
-     * <p> For any two paths <i>p</i> and <i>q</i>, where <i>q</i> does not have
-     * a root component,
+     * <p> For any two {@link #normalize normalized} paths <i>p</i> and
+     * <i>q</i>, where <i>q</i> does not have a root component,
      * <blockquote>
      *   <i>p</i><tt>.relativize(</tt><i>p</i><tt>.resolve(</tt><i>q</i><tt>)).equals(</tt><i>q</i><tt>)</tt>
      * </blockquote>
      *
      * <p> When symbolic links are supported, then whether the resulting path,
      * when resolved against this path, yields a path that can be used to locate
-     * the {@link #isSameFile same} file as {@code other} is implementation
+     * the {@link Files#isSameFile same} file as {@code other} is implementation
      * dependent. For example, if this path is  {@code "/a/b"} and the given
      * path is {@code "/a/x"} then the resulting relative path may be {@code
      * "../x"}. If {@code "b"} is a symbolic link then is implementation
@@ -414,185 +439,14 @@
      * @param   other
      *          the path to relativize against this path
      *
-     * @return  the resulting relative path, or {@code null} if both paths are
+     * @return  the resulting relative path, or an empty path if both paths are
      *          equal
      *
      * @throws  IllegalArgumentException
      *          if {@code other} is not a {@code Path} that can be relativized
      *          against this path
      */
-    public abstract Path relativize(Path other);
-
-    // -- file operations --
-
-    /**
-     * Deletes the file located by this path.
-     *
-     * <p> An implementation may require to examine the file to determine if the
-     * file is a directory. Consequently this method may not be atomic with respect
-     * to other file system operations.  If the file is a symbolic link then the
-     * symbolic link itself, not the final target of the link, is deleted.
-     *
-     * <p> If the file is a directory then the directory must be empty. In some
-     * implementations a directory has entries for special files or links that
-     * are created when the directory is created. In such implementations a
-     * directory is considered empty when only the special entries exist.
-     *
-     * <p> On some operating systems it may not be possible to remove a file when
-     * it is open and in use by this Java virtual machine or other programs.
-     *
-     * @throws  NoSuchFileException
-     *          if the file does not exist <i>(optional specific exception)</i>
-     * @throws  DirectoryNotEmptyException
-     *          if the file is a directory and could not otherwise be deleted
-     *          because the directory is not empty <i>(optional specific
-     *          exception)</i>
-     * @throws  IOException
-     *          if an I/O error occurs
-     * @throws  SecurityException
-     *          In the case of the default provider, and a security manager is
-     *          installed, the {@link SecurityManager#checkDelete(String)} method
-     *          is invoked to check delete access to the file
-     */
-    public abstract void delete() throws IOException;
-
-    /**
-     * Deletes the file located by this path, if it exists.
-     *
-     * <p> As with the {@link #delete delete()} method, an implementation may
-     * need to examine the file to determine if the file is a directory.
-     * Consequently this method may not be atomic with respect to other file
-     * system operations.  If the file is a symbolic link, then the symbolic
-     * link itself, not the final target of the link, is deleted.
-     *
-     * <p> If the file is a directory then the directory must be empty. In some
-     * implementations a directory has entries for special files or links that
-     * are created when the directory is created. In such implementations a
-     * directory is considered empty when only the special entries exist.
-     *
-     * <p> On some operating systems it may not be possible to remove a file when
-     * it is open and in use by this Java virtual machine or other programs.
-     *
-     * @throws  DirectoryNotEmptyException
-     *          if the file is a directory and could not otherwise be deleted
-     *          because the directory is not empty <i>(optional specific
-     *          exception)</i>
-     * @throws  IOException
-     *          if an I/O error occurs
-     * @throws  SecurityException
-     *          In the case of the default provider, and a security manager is
-     *          installed, the {@link SecurityManager#checkDelete(String)} method
-     *          is invoked to check delete access to the file.
-     */
-    public abstract void deleteIfExists() throws IOException;
-
-    /**
-     * Creates a symbolic link to a target <i>(optional operation)</i>.
-     *
-     * <p> The {@code target} parameter is the target of the link. It may be an
-     * {@link Path#isAbsolute absolute} or relative path and may not exist. When
-     * the target is a relative path then file system operations on the resulting
-     * link are relative to the path of the link.
-     *
-     * <p> The {@code attrs} parameter is an optional array of {@link FileAttribute
-     * attributes} to set atomically when creating the link. Each attribute is
-     * identified by its {@link FileAttribute#name name}. If more than one attribute
-     * of the same name is included in the array then all but the last occurrence
-     * is ignored.
-     *
-     * <p> Where symbolic links are supported, but the underlying {@link FileStore}
-     * does not support symbolic links, then this may fail with an {@link
-     * IOException}. Additionally, some operating systems may require that the
-     * Java virtual machine be started with implementation specific privileges to
-     * create symbolic links, in which case this method may throw {@code IOException}.
-     *
-     * @param   target
-     *          the target of the symbolic link
-     * @param   attrs
-     *          the array of attributes to set atomically when creating the
-     *          symbolic link
-     *
-     * @return  this path
-     *
-     * @throws  UnsupportedOperationException
-     *          if the implementation does not support symbolic links or the
-     *          array contains an attribute that cannot be set atomically when
-     *          creating the symbolic link
-     * @throws  FileAlreadyExistsException
-     *          if a file with the name already exists <i>(optional specific
-     *          exception)</i>
-     * @throws  IOException
-     *          if an I/O error occurs
-     * @throws  SecurityException
-     *          In the case of the default provider, and a security manager
-     *          is installed, it denies {@link LinkPermission}<tt>("symbolic")</tt>
-     *          or its {@link SecurityManager#checkWrite(String) checkWrite}
-     *          method denies write access to the path of the symbolic link.
-     */
-    public abstract Path createSymbolicLink(Path target, FileAttribute<?>... attrs)
-        throws IOException;
-
-    /**
-     * Creates a new link (directory entry) for an existing file <i>(optional
-     * operation)</i>.
-     *
-     * <p> This path locates the directory entry to create. The {@code existing}
-     * parameter is the path to an existing file. This method creates a new
-     * directory entry for the file so that it can be accessed using this path.
-     * On some file systems this is known as creating a "hard link". Whether the
-     * file attributes are maintained for the file or for each directory entry
-     * is file system specific and therefore not specified. Typically, a file
-     * system requires that all links (directory entries) for a file be on the
-     * same file system. Furthermore, on some platforms, the Java virtual machine
-     * may require to be started with implementation specific privileges to
-     * create hard links or to create links to directories.
-     *
-     * @param   existing
-     *          a reference to an existing file
-     *
-     * @return  this path
-     *
-     * @throws  UnsupportedOperationException
-     *          if the implementation does not support adding an existing file
-     *          to a directory
-     * @throws  FileAlreadyExistsException
-     *          if the entry could not otherwise be created because a file of
-     *          that name already exists <i>(optional specific exception)</i>
-     * @throws  IOException
-     *          if an I/O error occurs
-     * @throws  SecurityException
-     *          In the case of the default provider, and a security manager
-     *          is installed, it denies {@link LinkPermission}<tt>("hard")</tt>
-     *          or its {@link SecurityManager#checkWrite(String) checkWrite}
-     *          method denies write access to both this path and the path of the
-     *          existing file.
-     */
-    public abstract Path createLink(Path existing) throws IOException;
-
-    /**
-     * Reads the target of a symbolic link <i>(optional operation)</i>.
-     *
-     * <p> If the file system supports <a href="package-summary.html#links">symbolic
-     * links</a> then this method is used to read the target of the link, failing
-     * if the file is not a symbolic link. The target of the link need not exist.
-     * The returned {@code Path} object will be associated with the same file
-     * system as this {@code Path}.
-     *
-     * @return  a {@code Path} object representing the target of the link
-     *
-     * @throws  UnsupportedOperationException
-     *          if the implementation does not support symbolic links
-     * @throws  NotLinkException
-     *          if the target could otherwise not be read because the file
-     *          is not a symbolic link <i>(optional specific exception)</i>
-     * @throws  IOException
-     *          if an I/O error occurs
-     * @throws  SecurityException
-     *          In the case of the default provider, and a security manager
-     *          is installed, it checks that {@code FilePermission} has been
-     *          granted with the "{@code readlink}" action to read the link.
-     */
-    public abstract Path readSymbolicLink() throws IOException;
+    Path relativize(Path other);
 
     /**
      * Returns a URI to represent this path.
@@ -647,7 +501,7 @@
      *          is installed, the {@link #toAbsolutePath toAbsolutePath} method
      *          throws a security exception.
      */
-    public abstract URI toUri();
+    URI toUri();
 
     /**
      * Returns a {@code Path} object representing the absolute path of this
@@ -670,14 +524,14 @@
      *          checkPropertyAccess} method is invoked to check access to the
      *          system property {@code user.dir}
      */
-    public abstract Path toAbsolutePath();
+    Path toAbsolutePath();
 
     /**
      * Returns the <em>real</em> path of an existing file.
      *
      * <p> The precise definition of this method is implementation dependent but
      * in general it derives from this path, an {@link #isAbsolute absolute}
-     * path that locates the {@link #isSameFile same} file as this path, but
+     * path that locates the {@link Files#isSameFile same} file as this path, but
      * with name elements that represent the actual name of the directories
      * and the file. For example, where filename comparisons on a file system
      * are case insensitive then the name elements represent the names in their
@@ -713,756 +567,25 @@
      *          checkPropertyAccess} method is invoked to check access to the
      *          system property {@code user.dir}
      */
-    public abstract Path toRealPath(boolean resolveLinks) throws IOException;
-
-    /**
-     * Copy the file located by this path to a target location.
-     *
-     * <p> This method copies the file located by this {@code Path} to the
-     * target location with the {@code options} parameter specifying how the
-     * copy is performed. By default, the copy fails if the target file already
-     * exists, except if the source and target are the {@link #isSameFile same}
-     * file, in which case this method has no effect. File attributes are not
-     * required to be copied to the target file. If symbolic links are supported,
-     * and the file is a symbolic link, then the final target of the link is copied.
-     * If the file is a directory then it creates an empty directory in the target
-     * location (entries in the directory are not copied). This method can be
-     * used with the {@link Files#walkFileTree Files.walkFileTree} utility
-     * method to copy a directory and all entries in the directory, or an entire
-     * <i>file-tree</i> where required.
-     *
-     * <p> The {@code options} parameter is an array of options and may contain
-     * any of the following:
-     *
-     * <table border=1 cellpadding=5 summary="">
-     * <tr> <th>Option</th> <th>Description</th> </tr>
-     * <tr>
-     *   <td> {@link StandardCopyOption#REPLACE_EXISTING REPLACE_EXISTING} </td>
-     *   <td> If the target file exists, then the target file is replaced if it
-     *     is not a non-empty directory. If the target file exists and is a
-     *     symbolic link, then the symbolic link itself, not the target of
-     *     the link, is replaced. </td>
-     * </tr>
-     * <tr>
-     *   <td> {@link StandardCopyOption#COPY_ATTRIBUTES COPY_ATTRIBUTES} </td>
-     *   <td> Attempts to copy the file attributes associated with this file to
-     *     the target file. The exact file attributes that are copied is platform
-     *     and file system dependent and therefore unspecified. Minimally, the
-     *     {@link BasicFileAttributes#lastModifiedTime last-modified-time} is
-     *     copied to the target file if supported by both the source and target
-     *     file store. Copying of file timestamps may result in precision
-     *     loss. </td>
-     * </tr>
-     * <tr>
-     *   <td> {@link LinkOption#NOFOLLOW_LINKS NOFOLLOW_LINKS} </td>
-     *   <td> Symbolic links are not followed. If the file, located by this path,
-     *     is a symbolic link, then the symbolic link itself, not the target of
-     *     the link, is copied. It is implementation specific if file attributes
-     *     can be copied to the new link. In other words, the {@code
-     *     COPY_ATTRIBUTES} option may be ignored when copying a symbolic link. </td>
-     * </tr>
-     * </table>
-     *
-     * <p> An implementation of this interface may support additional
-     * implementation specific options.
-     *
-     * <p> Copying a file is not an atomic operation. If an {@link IOException}
-     * is thrown then it possible that the target file is incomplete or some of
-     * its file attributes have not been copied from the source file. When the
-     * {@code REPLACE_EXISTING} option is specified and the target file exists,
-     * then the target file is replaced. The check for the existence of the file
-     * and the creation of the new file may not be atomic with respect to other
-     * file system activities.
-     *
-     * @param   target
-     *          the target location
-     * @param   options
-     *          options specifying how the copy should be done
-     *
-     * @return  the target
-     *
-     * @throws  UnsupportedOperationException
-     *          if the array contains a copy option that is not supported
-     * @throws  FileAlreadyExistsException
-     *          if the target file exists and cannot be replaced because the
-     *          {@code REPLACE_EXISTING} option is not specified, or the target
-     *          file is a non-empty directory <i>(optional specific exception)</i>
-     * @throws  IOException
-     *          if an I/O error occurs
-     * @throws  SecurityException
-     *          In the case of the default provider, and a security manager is
-     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
-     *          method is invoked to check read access to the source file, the
-     *          {@link SecurityManager#checkWrite(String) checkWrite} is invoked
-     *          to check write access to the target file. If a symbolic link is
-     *          copied the security manager is invoked to check {@link
-     *          LinkPermission}{@code ("symbolic")}.
-     */
-    public abstract Path copyTo(Path target, CopyOption... options)
-        throws IOException;
-
-    /**
-     * Move or rename the file located by this path to a target location.
-     *
-     * <p> By default, this method attempts to move the file to the target
-     * location, failing if the target file exists except if the source and
-     * target are the {@link #isSameFile same} file, in which case this method
-     * has no effect. If the file is a symbolic link then the symbolic link
-     * itself, not the target of the link, is moved. This method may be
-     * invoked to move an empty directory. In some implementations a directory
-     * has entries for special files or links that are created when the
-     * directory is created. In such implementations a directory is considered
-     * empty when only the special entries exist. When invoked to move a
-     * directory that is not empty then the directory is moved if it does not
-     * require moving the entries in the directory.  For example, renaming a
-     * directory on the same {@link FileStore} will usually not require moving
-     * the entries in the directory. When moving a directory requires that its
-     * entries be moved then this method fails (by throwing an {@code
-     * IOException}). To move a <i>file tree</i> may involve copying rather
-     * than moving directories and this can be done using the {@link
-     * #copyTo copyTo} method in conjunction with the {@link
-     * Files#walkFileTree Files.walkFileTree} utility method.
-     *
-     * <p> The {@code options} parameter is an array of options and may contain
-     * any of the following:
-     *
-     * <table border=1 cellpadding=5 summary="">
-     * <tr> <th>Option</th> <th>Description</th> </tr>
-     * <tr>
-     *   <td> {@link StandardCopyOption#REPLACE_EXISTING REPLACE_EXISTING} </td>
-     *   <td> If the target file exists, then the target file is replaced if it
-     *     is not a non-empty directory. If the target file exists and is a
-     *     symbolic link, then the symbolic link itself, not the target of
-     *     the link, is replaced. </td>
-     * </tr>
-     * <tr>
-     *   <td> {@link StandardCopyOption#ATOMIC_MOVE ATOMIC_MOVE} </td>
-     *   <td> The move is performed as an atomic file system operation and all
-     *     other options are ignored. If the target file exists then it is
-     *     implementation specific if the existing file is replaced or this method
-     *     fails by throwing an {@link IOException}. If the move cannot be
-     *     performed as an atomic file system operation then {@link
-     *     AtomicMoveNotSupportedException} is thrown. This can arise, for
-     *     example, when the target location is on a different {@code FileStore}
-     *     and would require that the file be copied, or target location is
-     *     associated with a different provider to this object. </td>
-     * </table>
-     *
-     * <p> An implementation of this interface may support additional
-     * implementation specific options.
-     *
-     * <p> Where the move requires that the file be copied then the {@link
-     * BasicFileAttributes#lastModifiedTime last-modified-time} is copied to the
-     * new file. An implementation may also attempt to copy other file
-     * attributes but is not required to fail if the file attributes cannot be
-     * copied. When the move is performed as a non-atomic operation, and a {@code
-     * IOException} is thrown, then the state of the files is not defined. The
-     * original file and the target file may both exist, the target file may be
-     * incomplete or some of its file attributes may not been copied from the
-     * original file.
-     *
-     * @param   target
-     *          the target location
-     * @param   options
-     *          options specifying how the move should be done
-     *
-     * @return  the target
-     *
-     * @throws  UnsupportedOperationException
-     *          if the array contains a copy option that is not supported
-     * @throws  FileAlreadyExistsException
-     *          if the target file exists and cannot be replaced because the
-     *          {@code REPLACE_EXISTING} option is not specified, or the target
-     *          file is a non-empty directory
-     * @throws  AtomicMoveNotSupportedException
-     *          if the options array contains the {@code ATOMIC_MOVE} option but
-     *          the file cannot be moved as an atomic file system operation.
-     * @throws  IOException
-     *          if an I/O error occurs
-     * @throws  SecurityException
-     *          In the case of the default provider, and a security manager is
-     *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
-     *          method is invoked to check write access to both the source and
-     *          target file.
-     */
-    public abstract Path moveTo(Path target, CopyOption... options)
-        throws IOException;
+    Path toRealPath(boolean resolveLinks) throws IOException;
 
     /**
-     * Opens the directory referenced by this object, returning a {@code
-     * DirectoryStream} to iterate over all entries in the directory. The
-     * elements returned by the directory stream's {@link DirectoryStream#iterator
-     * iterator} are of type {@code Path}, each one representing an entry in the
-     * directory. The {@code Path} objects are obtained as if by {@link
-     * #resolve(Path) resolving} the name of the directory entry against this
-     * path.
-     *
-     * <p> The directory stream's {@code close} method should be invoked after
-     * iteration is completed so as to free any resources held for the open
-     * directory.
-     *
-     * <p> When an implementation supports operations on entries in the
-     * directory that execute in a race-free manner then the returned directory
-     * stream is a {@link SecureDirectoryStream}.
-     *
-     * @return  a new and open {@code DirectoryStream} object
-     *
-     * @throws  NotDirectoryException
-     *          if the file could not otherwise be opened because it is not
-     *          a directory <i>(optional specific exception)</i>
-     * @throws  IOException
-     *          if an I/O error occurs
-     * @throws  SecurityException
-     *          In the case of the default provider, and a security manager is
-     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
-     *          method is invoked to check read access to the directory.
-     */
-    public abstract DirectoryStream<Path> newDirectoryStream()
-        throws IOException;
-
-    /**
-     * Opens the directory referenced by this object, returning a {@code
-     * DirectoryStream} to iterate over the entries in the directory. The
-     * elements returned by the directory stream's {@link DirectoryStream#iterator
-     * iterator} are of type {@code Path}, each one representing an entry in the
-     * directory. The {@code Path} objects are obtained as if by {@link
-     * #resolve(Path) resolving} the name of the directory entry against this
-     * path. The entries returned by the iterator are filtered by matching the
-     * {@code String} representation of their file names against the given
-     * <em>globbing</em> pattern.
-     *
-     * <p> For example, suppose we want to iterate over the files ending with
-     * ".java" in a directory:
-     * <pre>
-     *     Path dir = ...
-     *     DirectoryStream&lt;Path&gt; stream = dir.newDirectoryStream("*.java");
-     * </pre>
-     *
-     * <p> The globbing pattern is specified by the {@link
-     * FileSystem#getPathMatcher getPathMatcher} method.
-     *
-     * <p> The directory stream's {@code close} method should be invoked after
-     * iteration is completed so as to free any resources held for the open
-     * directory.
-     *
-     * <p> When an implementation supports operations on entries in the
-     * directory that execute in a race-free manner then the returned directory
-     * stream is a {@link SecureDirectoryStream}.
-     *
-     * @param   glob
-     *          the glob pattern
-     *
-     * @return  a new and open {@code DirectoryStream} object
-     *
-     * @throws  java.util.regex.PatternSyntaxException
-     *          if the pattern is invalid
-     * @throws  NotDirectoryException
-     *          if the file could not otherwise be opened because it is not
-     *          a directory <i>(optional specific exception)</i>
-     * @throws  IOException
-     *          if an I/O error occurs
-     * @throws  SecurityException
-     *          In the case of the default provider, and a security manager is
-     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
-     *          method is invoked to check read access to the directory.
-     */
-    public abstract DirectoryStream<Path> newDirectoryStream(String glob)
-        throws IOException;
-
-    /**
-     * Opens the directory referenced by this object, returning a {@code
-     * DirectoryStream} to iterate over the entries in the directory. The
-     * elements returned by the directory stream's {@link DirectoryStream#iterator
-     * iterator} are of type {@code Path}, each one representing an entry in the
-     * directory. The {@code Path} objects are obtained as if by {@link
-     * #resolve(Path) resolving} the name of the directory entry against this
-     * path. The entries returned by the iterator are filtered by the given
-     * {@link DirectoryStream.Filter filter}.
-     *
-     * <p> The directory stream's {@code close} method should be invoked after
-     * iteration is completed so as to free any resources held for the open
-     * directory.
+     * Returns a {@link File} object representing this path. Where this {@code
+     * Path} is associated with the default provider, then this method is
+     * equivalent to returning a {@code File} object constructed with the
+     * {@code String} representation of this path.
      *
-     * <p> Where the filter terminates due to an uncaught error or runtime
-     * exception then it is propagated to the {@link Iterator#hasNext()
-     * hasNext} or {@link Iterator#next() next} method. Where an {@code
-     * IOException} is thrown, it results in the {@code hasNext} or {@code
-     * next} method throwing a {@link DirectoryIteratorException} with the
-     * {@code IOException} as the cause.
-     *
-     * <p> When an implementation supports operations on entries in the
-     * directory that execute in a race-free manner then the returned directory
-     * stream is a {@link SecureDirectoryStream}.
-     *
-     * <p> <b>Usage Example:</b>
-     * Suppose we want to iterate over the files in a directory that are
-     * larger than 8K.
-     * <pre>
-     *     DirectoryStream.Filter&lt;Path&gt; filter = new DirectoryStream.Filter&lt;Path&gt;() {
-     *         public boolean accept(Path file) throws IOException {
-     *             long size = Attributes.readBasicFileAttributes(file).size();
-     *             return (size > 8192L);
-     *         }
-     *     };
-     *     Path dir = ...
-     *     DirectoryStream&lt;Path&gt; stream = dir.newDirectoryStream(filter);
-     * </pre>
-     * @param   filter
-     *          the directory stream filter
-     *
-     * @return  a new and open {@code DirectoryStream} object
-     *
-     * @throws  NotDirectoryException
-     *          if the file could not otherwise be opened because it is not
-     *          a directory <i>(optional specific exception)</i>
-     * @throws  IOException
-     *          if an I/O error occurs
-     * @throws  SecurityException
-     *          In the case of the default provider, and a security manager is
-     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
-     *          method is invoked to check read access to the directory.
-     */
-    public abstract DirectoryStream<Path> newDirectoryStream(DirectoryStream.Filter<? super Path> filter)
-        throws IOException;
-
-    /**
-     * Creates a new and empty file, failing if the file already exists.
+     * <p> If this path was created by invoking the {@code File} {@link
+     * File#toPath toPath} method then there is no guarantee that the {@code
+     * File} object returned by this method is {@link #equals equal} to the
+     * original {@code File}.
      *
-     * <p> This {@code Path} locates the file to create. The check for the
-     * existence of the file and the creation of the new file if it does not
-     * exist are a single operation that is atomic with respect to all other
-     * filesystem activities that might affect the directory.
-     *
-     * <p> The {@code attrs} parameter is an optional array of {@link FileAttribute
-     * file-attributes} to set atomically when creating the file. Each attribute
-     * is identified by its {@link FileAttribute#name name}. If more than one
-     * attribute of the same name is included in the array then all but the last
-     * occurrence is ignored.
-     *
-     * @param   attrs
-     *          an optional list of file attributes to set atomically when
-     *          creating the file
-     *
-     * @return  this path
-     *
-     * @throws  UnsupportedOperationException
-     *          if the array contains an attribute that cannot be set atomically
-     *          when creating the file
-     * @throws  FileAlreadyExistsException
-     *          if a file of that name already exists
-     *          <i>(optional specific exception)</i>
-     * @throws  IOException
-     *          if an I/O error occurs
-     * @throws  SecurityException
-     *          In the case of the default provider, and a security manager is
-     *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
-     *          method is invoked to check write access to the new file.
-     */
-    public abstract Path createFile(FileAttribute<?>... attrs) throws IOException;
-
-    /**
-     * Creates a new directory.
-     *
-     * <p> This {@code Path} locates the directory to create. The check for the
-     * existence of the file and the creation of the directory if it does not
-     * exist are a single operation that is atomic with respect to all other
-     * filesystem activities that might affect the directory.
-     *
-     * <p> The {@code attrs} parameter is an optional array of {@link FileAttribute
-     * file-attributes} to set atomically when creating the directory. Each
-     * file attribute is identified by its {@link FileAttribute#name name}. If
-     * more than one attribute of the same name is included in the array then all
-     * but the last occurrence is ignored.
-     *
-     * @param   attrs
-     *          an optional list of file attributes to set atomically when
-     *          creating the directory
-     *
-     * @return  this path
+     * @return  a {@code File} object representing this path
      *
      * @throws  UnsupportedOperationException
-     *          if the array contains an attribute that cannot be set atomically
-     *          when creating the directory
-     * @throws  FileAlreadyExistsException
-     *          if a directory could not otherwise be created because a file of
-     *          that name already exists <i>(optional specific exception)</i>
-     * @throws  IOException
-     *          if an I/O error occurs
-     * @throws  SecurityException
-     *          In the case of the default provider, and a security manager is
-     *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
-     *          method is invoked to check write access to the new directory.
-     *
-     * @see Files#createDirectories
-     */
-    public abstract Path createDirectory(FileAttribute<?>... attrs)
-        throws IOException;
-
-    /**
-     * Opens or creates a file, returning a seekable byte channel to access the
-     * file.
-     *
-     * <p> The {@code options} parameter determines how the file is opened.
-     * The {@link StandardOpenOption#READ READ} and {@link StandardOpenOption#WRITE WRITE}
-     * options determine if the file should be opened for reading and/or writing.
-     * If neither option (or the {@link StandardOpenOption#APPEND APPEND}
-     * option) is contained in the array then the file is opened for reading.
-     * By default reading or writing commences at the beginning of the file.
-     *
-     * <p> In the addition to {@code READ} and {@code WRITE}, the following
-     * options may be present:
-     *
-     * <table border=1 cellpadding=5 summary="">
-     * <tr> <th>Option</th> <th>Description</th> </tr>
-     * <tr>
-     *   <td> {@link StandardOpenOption#APPEND APPEND} </td>
-     *   <td> If this option is present then the file is opened for writing and
-     *     each invocation of the channel's {@code write} method first advances
-     *     the position to the end of the file and then writes the requested
-     *     data. Whether the advancement of the position and the writing of the
-     *     data are done in a single atomic operation is system-dependent and
-     *     therefore unspecified. This option may not be used in conjunction
-     *     with the {@code READ} or {@code TRUNCATE_EXISTING} options. </td>
-     * </tr>
-     * <tr>
-     *   <td> {@link StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING} </td>
-     *   <td> If this option is present then the existing file is truncated to
-     *   a size of 0 bytes. This option is ignored when the file is opened only
-     *   for reading. </td>
-     * </tr>
-     * <tr>
-     *   <td> {@link StandardOpenOption#CREATE_NEW CREATE_NEW} </td>
-     *   <td> If this option is present then a new file is created, failing if
-     *   the file already exists or is a symbolic link. When creating a file the
-     *   check for the existence of the file and the creation of the file if it
-     *   does not exist is atomic with respect to other file system operations.
-     *   This option is ignored when the file is opened only for reading. </td>
-     * </tr>
-     * <tr>
-     *   <td > {@link StandardOpenOption#CREATE CREATE} </td>
-     *   <td> If this option is present then an existing file is opened if it
-     *   exists, otherwise a new file is created. This option is ignored if the
-     *   {@code CREATE_NEW} option is also present or the file is opened only
-     *   for reading. </td>
-     * </tr>
-     * <tr>
-     *   <td > {@link StandardOpenOption#DELETE_ON_CLOSE DELETE_ON_CLOSE} </td>
-     *   <td> When this option is present then the implementation makes a
-     *   <em>best effort</em> attempt to delete the file when closed by the
-     *   {@link SeekableByteChannel#close close} method. If the {@code close}
-     *   method is not invoked then a <em>best effort</em> attempt is made to
-     *   delete the file when the Java virtual machine terminates. </td>
-     * </tr>
-     * <tr>
-     *   <td>{@link StandardOpenOption#SPARSE SPARSE} </td>
-     *   <td> When creating a new file this option is a <em>hint</em> that the
-     *   new file will be sparse. This option is ignored when not creating
-     *   a new file. </td>
-     * </tr>
-     * <tr>
-     *   <td> {@link StandardOpenOption#SYNC SYNC} </td>
-     *   <td> Requires that every update to the file's content or metadata be
-     *   written synchronously to the underlying storage device. (see <a
-     *   href="package-summary.html#integrity"> Synchronized I/O file
-     *   integrity</a>). </td>
-     * <tr>
-     * <tr>
-     *   <td> {@link StandardOpenOption#DSYNC DSYNC} </td>
-     *   <td> Requires that every update to the file's content be written
-     *   synchronously to the underlying storage device. (see <a
-     *   href="package-summary.html#integrity"> Synchronized I/O file
-     *   integrity</a>). </td>
-     * </tr>
-     * </table>
-     *
-     * <p> An implementation may also support additional implementation specific
-     * options.
-     *
-     * <p> The {@code attrs} parameter is an optional array of file {@link
-     * FileAttribute file-attributes} to set atomically when a new file is created.
-     *
-     * <p> In the case of the default provider, the returned seekable byte channel
-     * is a {@link java.nio.channels.FileChannel}.
-     *
-     * <p> <b>Usage Examples:</b>
-     * <pre>
-     *     Path file = ...
-     *
-     *     // open file for reading
-     *     ReadableByteChannel rbc = file.newByteChannel(EnumSet.of(READ)));
-     *
-     *     // open file for writing to the end of an existing file, creating
-     *     // the file if it doesn't already exist
-     *     WritableByteChannel wbc = file.newByteChannel(EnumSet.of(CREATE,APPEND));
-     *
-     *     // create file with initial permissions, opening it for both reading and writing
-     *     FileAttribute&lt;Set&lt;PosixFilePermission&gt;&gt; perms = ...
-     *     SeekableByteChannel sbc = file.newByteChannel(EnumSet.of(CREATE_NEW,READ,WRITE), perms);
-     * </pre>
-     *
-     * @param   options
-     *          Options specifying how the file is opened
-     * @param   attrs
-     *          An optional list of file attributes to set atomically when
-     *          creating the file
-     *
-     * @return  a new seekable byte channel
-     *
-     * @throws  IllegalArgumentException
-     *          if the set contains an invalid combination of options
-     * @throws  UnsupportedOperationException
-     *          if an unsupported open option is specified or the array contains
-     *          attributes that cannot be set atomically when creating the file
-     * @throws  FileAlreadyExistsException
-     *          if a file of that name already exists and the {@link
-     *          StandardOpenOption#CREATE_NEW CREATE_NEW} option is specified
-     *          <i>(optional specific exception)</i>
-     * @throws  IOException
-     *          if an I/O error occurs
-     * @throws  SecurityException
-     *          In the case of the default provider, and a security manager is
-     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
-     *          method is invoked to check read access to the path if the file is
-     *          opened for reading. The {@link SecurityManager#checkWrite(String)
-     *          checkWrite} method is invoked to check write access to the path
-     *          if the file is opened for writing.
-     */
-    public abstract SeekableByteChannel newByteChannel(Set<? extends OpenOption> options,
-                                                       FileAttribute<?>... attrs)
-        throws IOException;
-
-    /**
-     * Opens or creates a file, returning a seekable byte channel to access the
-     * file.
-     *
-     * <p> This method opens or creates a file in exactly the manner specified
-     * by the {@link Path#newByteChannel(Set,FileAttribute[]) newByteChannel}
-     * method.
-     *
-     * @param   options
-     *          options specifying how the file is opened
-     *
-     * @return  a new seekable byte channel
-     *
-     * @throws  IllegalArgumentException
-     *          if the set contains an invalid combination of options
-     * @throws  UnsupportedOperationException
-     *          if an unsupported open option is specified
-     * @throws  FileAlreadyExistsException
-     *          if a file of that name already exists and the {@link
-     *          StandardOpenOption#CREATE_NEW CREATE_NEW} option is specified
-     *          <i>(optional specific exception)</i>
-     * @throws  IOException
-     *          if an I/O error occurs
-     * @throws  SecurityException
-     *          In the case of the default provider, and a security manager is
-     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
-     *          method is invoked to check read access to the path if the file is
-     *          opened for reading. The {@link SecurityManager#checkWrite(String)
-     *          checkWrite} method is invoked to check write access to the path
-     *          if the file is opened for writing.
+     *          if this {@code Path} is not associated with the default provider
      */
-    public abstract SeekableByteChannel newByteChannel(OpenOption... options)
-        throws IOException;
-
-    /**
-     * Opens or creates the file located by this object for writing, returning
-     * an output stream to write bytes to the file.
-     *
-     * <p> This method opens or creates a file in exactly the manner specified
-     * by the {@link Path#newByteChannel(Set,FileAttribute[]) newByteChannel}
-     * method except that the {@link StandardOpenOption#READ READ} option may not
-     * be present in the array of open options.
-     *
-     * @param   options
-     *          options specifying how the file is opened
-     *
-     * @return  a new output stream
-     *
-     * @throws  IllegalArgumentException            {@inheritDoc}
-     * @throws  UnsupportedOperationException       {@inheritDoc}
-     * @throws  IOException                         {@inheritDoc}
-     * @throws  SecurityException                   {@inheritDoc}
-     */
-    @Override
-    public abstract OutputStream newOutputStream(OpenOption... options)
-        throws IOException;
-
-    /**
-     * Tells whether or not the file located by this object is considered
-     * <em>hidden</em>. The exact definition of hidden is platform or provider
-     * dependent. On UNIX for example a file is considered to be hidden if its
-     * name begins with a period character ('.'). On Windows a file is
-     * considered hidden if it isn't a directory and the DOS {@link
-     * DosFileAttributes#isHidden hidden} attribute is set.
-     *
-     * <p> Depending on the implementation this method may require to access
-     * the file system to determine if the file is considered hidden.
-     *
-     * @return  {@code true} if the file is considered hidden
-     *
-     * @throws  IOException
-     *          if an I/O error occurs
-     * @throws  SecurityException
-     *          In the case of the default provider, and a security manager is
-     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
-     *          method is invoked to check read access to the file.
-     */
-    public abstract boolean isHidden() throws IOException;
-
-    /**
-     * Checks the existence and optionally the accessibility of the file
-     * located by this path.
-     *
-     * <p> This method checks the existence of a file and that this Java virtual
-     * machine has appropriate privileges that would allow it access the file
-     * according to all of access modes specified in the {@code modes} parameter
-     * as follows:
-     *
-     * <table border=1 cellpadding=5 summary="">
-     * <tr> <th>Value</th> <th>Description</th> </tr>
-     * <tr>
-     *   <td> {@link AccessMode#READ READ} </td>
-     *   <td> Checks that the file exists and that the Java virtual machine has
-     *     permission to read the file. </td>
-     * </tr>
-     * <tr>
-     *   <td> {@link AccessMode#WRITE WRITE} </td>
-     *   <td> Checks that the file exists and that the Java virtual machine has
-     *     permission to write to the file, </td>
-     * </tr>
-     * <tr>
-     *   <td> {@link AccessMode#EXECUTE EXECUTE} </td>
-     *   <td> Checks that the file exists and that the Java virtual machine has
-     *     permission to {@link Runtime#exec execute} the file. The semantics
-     *     may differ when checking access to a directory. For example, on UNIX
-     *     systems, checking for {@code EXECUTE} access checks that the Java
-     *     virtual machine has permission to search the directory in order to
-     *     access file or subdirectories. </td>
-     * </tr>
-     * </table>
-     *
-     * <p> If the {@code modes} parameter is of length zero, then the existence
-     * of the file is checked.
-     *
-     * <p> This method follows symbolic links if the file referenced by this
-     * object is a symbolic link. Depending on the implementation, this method
-     * may require to read file permissions, access control lists, or other
-     * file attributes in order to check the effective access to the file. To
-     * determine the effective access to a file may require access to several
-     * attributes and so in some implementations this method may not be atomic
-     * with respect to other file system operations. Furthermore, as the result
-     * of this method is immediately outdated, there is no guarantee that a
-     * subsequence access will succeed (or even that it will access the same
-     * file). Care should be taken when using this method in security sensitive
-     * applications.
-     *
-     * @param   modes
-     *          The access modes to check; may have zero elements
-     *
-     * @throws  UnsupportedOperationException
-     *          an implementation is required to support checking for
-     *          {@code READ}, {@code WRITE}, and {@code EXECUTE} access. This
-     *          exception is specified to allow for the {@code Access} enum to
-     *          be extended in future releases.
-     * @throws  NoSuchFileException
-     *          if a file does not exist <i>(optional specific exception)</i>
-     * @throws  AccessDeniedException
-     *          the requested access would be denied or the access cannot be
-     *          determined because the Java virtual machine has insufficient
-     *          privileges or other reasons. <i>(optional specific exception)</i>
-     * @throws  IOException
-     *          if an I/O error occurs
-     * @throws  SecurityException
-     *          In the case of the default provider, and a security manager is
-     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
-     *          is invoked when checking read access to the file or only the
-     *          existence of the file, the {@link SecurityManager#checkWrite(String)
-     *          checkWrite} is invoked when checking write access to the file,
-     *          and {@link SecurityManager#checkExec(String) checkExec} is invoked
-     *          when checking execute access.
-     */
-    public abstract void checkAccess(AccessMode... modes) throws IOException;
-
-    /**
-     * Tests whether the file located by this path exists.
-     *
-     * <p> This convenience method is intended for cases where it is required to
-     * take action when it can be confirmed that a file exists. This method simply
-     * invokes the {@link #checkAccess checkAccess} method to check if the file
-     * exists. If the {@code checkAccess} method succeeds then this method returns
-     * {@code true}, otherwise if an {@code IOException} is thrown (because the
-     * file doesn't exist or cannot be accessed by this Java virtual machine)
-     * then {@code false} is returned.
-     *
-     * <p> Note that the result of this method is immediately outdated. If this
-     * method indicates the file exists then there is no guarantee that a
-     * subsequence access will succeed. Care should be taken when using this
-     * method in security sensitive applications.
-     *
-     * @return  {@code true} if the file exists; {@code false} if the file does
-     *          not exist or its existence cannot be determined.
-     *
-     * @throws  SecurityException
-     *          In the case of the default provider, the {@link
-     *          SecurityManager#checkRead(String)} is invoked to check
-     *          read access to the file.
-     *
-     * @see #notExists
-     */
-    public abstract boolean exists();
-
-    /**
-     * Tests whether the file located by this path does not exist.
-     *
-     * <p> This convenience method is intended for cases where it is required to
-     * take action when it can be confirmed that a file does not exist. This
-     * method invokes the {@link #checkAccess checkAccess} method to check if the
-     * file exists. If the file does not exist then {@code true} is returned,
-     * otherwise the file exists or cannot be accessed by this Java virtual
-     * machine and {@code false} is returned.
-     *
-     * <p> Note that this method is not the complement of the {@link #exists
-     * exists} method. Where it is not possible to determine if a file exists
-     * or not then both methods return {@code false}. As with the {@code exists}
-     * method, the result of this method is immediately outdated. If this
-     * method indicates the file does exist then there is no guarantee that a
-     * subsequence attempt to create the file will succeed. Care should be taken
-     * when using this method in security sensitive applications.
-     *
-     * @return  {@code true} if the file does not exist; {@code false} if the
-     *          file exists or its existence cannot be determined.
-     *
-     * @throws  SecurityException
-     *          In the case of the default provider, the {@link
-     *          SecurityManager#checkRead(String)} is invoked to check
-     *          read access to the file.
-     */
-    public abstract boolean notExists();
-
-    /**
-     * Returns the {@link FileStore} representing the file store where an
-     * existing file, located by this path, is stored.
-     *
-     * <p> Once a reference to the {@code FileStore} is obtained it is
-     * implementation specific if operations on the returned {@code FileStore},
-     * or {@link FileStoreAttributeView} objects obtained from it, continue
-     * to depend on the existence of the file. In particular the behavior is not
-     * defined for the case that the file is deleted or moved to a different
-     * file store.
-     *
-     * @return  the file store where the file is stored
-     *
-     * @throws  IOException
-     *          if an I/O error occurs
-     * @throws  SecurityException
-     *          In the case of the default provider, and a security manager is
-     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
-     *          method is invoked to check read access to the file, and in
-     *          addition it checks {@link RuntimePermission}<tt>
-     *          ("getFileStoreAttributes")</tt>
-     */
-    public abstract FileStore getFileStore() throws IOException;
+    File toFile();
 
     // -- watchable --
 
@@ -1471,8 +594,8 @@
      *
      * <p> In this release, this path locates a directory that exists. The
      * directory is registered with the watch service so that entries in the
-     * directory can be watched. The {@code events} parameter is an array of
-     * events to register and may contain the following events:
+     * directory can be watched. The {@code events} parameter is the events to
+     * register and may contain the following events:
      * <ul>
      *   <li>{@link StandardWatchEventKind#ENTRY_CREATE ENTRY_CREATE} -
      *       entry created or moved into the directory</li>
@@ -1489,10 +612,10 @@
      * <p> The set of events may include additional implementation specific
      * event that are not defined by the enum {@link StandardWatchEventKind}
      *
-     * <p> The {@code modifiers} parameter is an array of <em>modifiers</em>
-     * that qualify how the directory is registered. This release does not
-     * define any <em>standard</em> modifiers. The array may contain
-     * implementation specific modifiers.
+     * <p> The {@code modifiers} parameter specifies <em>modifiers</em> that
+     * qualify how the directory is registered. This release does not define any
+     * <em>standard</em> modifiers. It may contain implementation specific
+     * modifiers.
      *
      * <p> Where a file is registered with a watch service by means of a symbolic
      * link then it is implementation specific if the watch continues to depend
@@ -1525,9 +648,9 @@
      *          method is invoked to check read access to the file.
      */
     @Override
-    public abstract WatchKey register(WatchService watcher,
-                                      WatchEvent.Kind<?>[] events,
-                                      WatchEvent.Modifier... modifiers)
+    WatchKey register(WatchService watcher,
+                      WatchEvent.Kind<?>[] events,
+                      WatchEvent.Modifier... modifiers)
         throws IOException;
 
     /**
@@ -1573,8 +696,8 @@
      *          method is invoked to check read access to the file.
      */
     @Override
-    public abstract WatchKey register(WatchService watcher,
-                                      WatchEvent.Kind<?>... events)
+    WatchKey register(WatchService watcher,
+                      WatchEvent.Kind<?>... events)
         throws IOException;
 
     // -- Iterable --
@@ -1591,7 +714,7 @@
      * @return  an iterator over the name elements of this path.
      */
     @Override
-    public abstract Iterator<Path> iterator();
+    Iterator<Path> iterator();
 
     // -- compareTo/equals/hashCode --
 
@@ -1609,50 +732,7 @@
      *          lexicographically greater than the argument
      */
     @Override
-    public abstract int compareTo(Path other);
-
-    /**
-     * Tests if the file referenced by this object is the same file referenced
-     * by another object.
-     *
-     * <p> If this {@code Path} and the given {@code Path} are {@link
-     * #equals(Object) equal} then this method returns {@code true} without checking
-     * if the file exists. If the {@code Path} and the given {@code Path}
-     * are associated with different providers, or the given {@code Path} is
-     * {@code null} then this method returns {@code false}. Otherwise, this method
-     * checks if both {@code Paths} locate the same file, and depending on the
-     * implementation, may require to open or access both files.
-     *
-     * <p> If the file system and files remain static, then this method implements
-     * an equivalence relation for non-null {@code Paths}.
-     * <ul>
-     * <li>It is <i>reflexive</i>: for a non-null {@code Path} {@code f},
-     *     {@code f.isSameFile(f)} should return {@code true}.
-     * <li>It is <i>symmetric</i>: for two non-null {@code Path}
-     *     {@code f} and {@code g}, {@code f.isSameFile(g)} will equal
-     *     {@code g.isSameFile(f)}.
-     * <li>It is <i>transitive</i>: for three {@code Paths}
-     *     {@code f}, {@code g}, and {@code h}, if {@code f.isSameFile(g)} returns
-     *     {@code true} and {@code g.isSameFile(h)} returns {@code true}, then
-     *     {@code f.isSameFile(h)} will return return {@code true}.
-     * </ul>
-     *
-     * @param   other
-     *          the other file reference
-     *
-     * @return  {@code true} if, and only if, this object and the given object
-     *          locate the same file
-     *
-     * @throws  IOException
-     *          if an I/O error occurs
-     * @throws  SecurityException
-     *          In the case of the default provider, and a security manager is
-     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
-     *          method is invoked to check read access to both files.
-     *
-     * @see java.nio.file.attribute.BasicFileAttributes#fileKey
-     */
-    public abstract boolean isSameFile(Path other) throws IOException;
+    int compareTo(Path other);
 
     /**
      * Tests this path for equality with the given object.
@@ -1663,7 +743,9 @@
      * <p> Whether or not two path are equal depends on the file system
      * implementation. In some cases the paths are compared without regard
      * to case, and others are case sensitive. This method does not access the
-     * file system and the file is not required to exist.
+     * file system and the file is not required to exist. Where required, the
+     * {@link Files#isSameFile isSameFile} method may be used to check if two
+     * paths locate the same file.
      *
      * <p> This method satisfies the general contract of the {@link
      * java.lang.Object#equals(Object) Object.equals} method. </p>
@@ -1674,8 +756,7 @@
      * @return  {@code true} if, and only if, the given object is a {@code Path}
      *          that is identical to this {@code Path}
      */
-    @Override
-    public abstract boolean equals(Object other);
+    boolean equals(Object other);
 
     /**
      * Computes a hash code for this path.
@@ -1686,8 +767,7 @@
      *
      * @return  the hash-code value for this path
      */
-    @Override
-    public abstract int hashCode();
+    int hashCode();
 
     /**
      * Returns the string representation of this path.
@@ -1701,6 +781,5 @@
      *
      * @return  the string representation of this path
      */
-    @Override
-    public abstract String toString();
+    String toString();
 }
--- a/jdk/src/share/classes/java/nio/file/PathMatcher.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/PathMatcher.java	Fri Jan 28 09:28:43 2011 +0000
@@ -32,7 +32,7 @@
  * @since 1.7
  *
  * @see FileSystem#getPathMatcher
- * @see Path#newDirectoryStream(String)
+ * @see Files#newDirectoryStream(Path,String)
  */
 
 public interface PathMatcher {
--- a/jdk/src/share/classes/java/nio/file/Paths.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/Paths.java	Fri Jan 28 09:28:43 2011 +0000
@@ -39,14 +39,27 @@
     private Paths() { }
 
     /**
-     * Constructs a {@code Path} by converting the given path string.
+     * Converts a path string, or a sequence of strings that when joined form
+     * a path string, to a {@code Path}. If {@code more} does not specify any
+     * elements then the value of the {@code first} parameter is the path string
+     * to convert. If {@code more} specifies one or more elements then each
+     * non-empty string, including {@code first}, is considered to be a sequence
+     * of name elements (see {@link Path}) and is joined to form a path string.
+     * The details as to how the Strings are joined is provider specific but
+     * typically they will be joined using the {@link FileSystem#getSeparator
+     * name-separator} as the separator. For example, if the name separator is
+     * "{@code /}" and {@code getPath("/foo","bar","gus")} is invoked, then the
+     * path string {@code "/foo/bar/gus"} is converted to a {@code Path}.
+     * A {@code Path} representing an empty path is returned if {@code first}
+     * is the empty string and {@code more} does not contain any non-empty
+     * strings.
      *
      * <p> The {@code Path} is obtained by invoking the {@link FileSystem#getPath
      * getPath} method of the {@link FileSystems#getDefault default} {@link
      * FileSystem}.
      *
-     * <p> Note that while this method is very convenient, using it will
-     * imply an assumed reference to the default FileSystem and limit the
+     * <p> Note that while this method is very convenient, using it will imply
+     * an assumed reference to the default {@code FileSystem} and limit the
      * utility of the calling code. Hence it should not be used in library code
      * intended for flexible reuse. A more flexible alternative is to use an
      * existing {@code Path} instance as an anchor, such as:
@@ -55,8 +68,10 @@
      *     Path path = dir.resolve("file");
      * </pre>
      *
-     * @param   path
-     *          the path string to convert
+     * @param   first
+     *          the path string or initial part of the path string
+     * @param   more
+     *          additional strings to be joined to form the path string
      *
      * @return  the resulting {@code Path}
      *
@@ -65,8 +80,8 @@
      *
      * @see FileSystem#getPath
      */
-    public static Path get(String path) {
-        return FileSystems.getDefault().getPath(path);
+    public static Path get(String first, String... more) {
+        return FileSystems.getDefault().getPath(first, more);
     }
 
     /**
--- a/jdk/src/share/classes/java/nio/file/SecureDirectoryStream.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/SecureDirectoryStream.java	Fri Jan 28 09:28:43 2011 +0000
@@ -43,7 +43,7 @@
  *
  * <p> A {@code SecureDirectoryStream} requires corresponding support from the
  * underlying operating system. Where an implementation supports this features
- * then the {@code DirectoryStream} returned by the {@link Path#newDirectoryStream
+ * then the {@code DirectoryStream} returned by the {@link Files#newDirectoryStream
  * newDirectoryStream} method will be a {@code SecureDirectoryStream} and must
  * be cast to that type in order to invoke the methods defined by this interface.
  *
@@ -56,20 +56,15 @@
  * @since   1.7
  */
 
-public abstract class SecureDirectoryStream<T>
-    implements DirectoryStream<T>
+public interface SecureDirectoryStream<T>
+    extends DirectoryStream<T>
 {
     /**
-     * Initialize a new instance of this class.
-     */
-    protected SecureDirectoryStream() { }
-
-    /**
      * Opens the directory identified by the given path, returning a {@code
      * SecureDirectoryStream} to iterate over the entries in the directory.
      *
      * <p> This method works in exactly the manner specified by the {@link
-     * Path#newDirectoryStream() newDirectoryStream} method for the case that
+     * Files#newDirectoryStream(Path) newDirectoryStream} method for the case that
      * the {@code path} parameter is an {@link Path#isAbsolute absolute} path.
      * When the parameter is a relative path then the directory to open is
      * relative to this open directory. The {@link
@@ -99,8 +94,7 @@
      *          installed, the {@link SecurityManager#checkRead(String) checkRead}
      *          method is invoked to check read access to the directory.
      */
-    public abstract SecureDirectoryStream<T> newDirectoryStream(T path,
-                                                                LinkOption... options)
+    SecureDirectoryStream<T> newDirectoryStream(T path, LinkOption... options)
         throws IOException;
 
     /**
@@ -108,11 +102,11 @@
      * channel to access the file.
      *
      * <p> This method works in exactly the manner specified by the {@link
-     * Path#newByteChannel Path.newByteChannel} method for the
+     * Files#newByteChannel Files.newByteChannel} method for the
      * case that the {@code path} parameter is an {@link Path#isAbsolute absolute}
      * path. When the parameter is a relative path then the file to open or
      * create is relative to this open directory. In addition to the options
-     * defined by the {@code Path.newByteChannel} method, the {@link
+     * defined by the {@code Files.newByteChannel} method, the {@link
      * LinkOption#NOFOLLOW_LINKS NOFOLLOW_LINKS} option may be used to
      * ensure that this method fails if the file is a symbolic link.
      *
@@ -149,15 +143,15 @@
      *          checkWrite} method is invoked to check write access to the path
      *          if the file is opened for writing.
      */
-    public abstract SeekableByteChannel newByteChannel(T path,
-                                                       Set<? extends OpenOption> options,
-                                                       FileAttribute<?>... attrs)
+    SeekableByteChannel newByteChannel(T path,
+                                       Set<? extends OpenOption> options,
+                                       FileAttribute<?>... attrs)
         throws IOException;
 
     /**
      * Deletes a file.
      *
-     * <p> Unlike the {@link Path#delete delete()} method, this method does
+     * <p> Unlike the {@link Files#delete delete()} method, this method does
      * not first examine the file to determine if the file is a directory.
      * Whether a directory is deleted by this method is system dependent and
      * therefore not specified. If the file is a symbolic link, then the link
@@ -179,12 +173,12 @@
      *          installed, the {@link SecurityManager#checkDelete(String) checkDelete}
      *          method is invoked to check delete access to the file
      */
-    public abstract void deleteFile(T path) throws IOException;
+    void deleteFile(T path) throws IOException;
 
     /**
      * Deletes a directory.
      *
-     * <p> Unlike the {@link Path#delete delete()} method, this method
+     * <p> Unlike the {@link Files#delete delete()} method, this method
      * does not first examine the file to determine if the file is a directory.
      * Whether non-directories are deleted by this method is system dependent and
      * therefore not specified. When the parameter is a relative path then the
@@ -207,12 +201,12 @@
      *          installed, the {@link SecurityManager#checkDelete(String) checkDelete}
      *          method is invoked to check delete access to the directory
      */
-    public abstract void deleteDirectory(T path) throws IOException;
+    void deleteDirectory(T path) throws IOException;
 
     /**
      * Move a file from this directory to another directory.
      *
-     * <p> This method works in a similar manner to {@link Path#moveTo moveTo}
+     * <p> This method works in a similar manner to {@link Files#move move}
      * method when the {@link StandardCopyOption#ATOMIC_MOVE ATOMIC_MOVE} option
      * is specified. That is, this method moves a file as an atomic file system
      * operation. If the {@code srcpath} parameter is an {@link Path#isAbsolute
@@ -247,7 +241,7 @@
      *          method is invoked to check write access to both the source and
      *          target file.
      */
-    public abstract void move(T srcpath, SecureDirectoryStream<T> targetdir, T targetpath)
+    void move(T srcpath, SecureDirectoryStream<T> targetdir, T targetpath)
         throws IOException;
 
     /**
@@ -273,7 +267,7 @@
      *          this directory stream, or {@code null} if the attribute view
      *          type is not available
      */
-    public abstract <V extends FileAttributeView> V getFileAttributeView(Class<V> type);
+    <V extends FileAttributeView> V getFileAttributeView(Class<V> type);
 
     /**
      * Returns a new file attribute view to access the file attributes of a file
@@ -306,7 +300,7 @@
      *          type is not available
      *
      */
-    public abstract <V extends FileAttributeView> V getFileAttributeView(T path,
-                                                                         Class<V> type,
-                                                                         LinkOption... options);
+    <V extends FileAttributeView> V getFileAttributeView(T path,
+                                                         Class<V> type,
+                                                         LinkOption... options);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/nio/file/TempFileHelper.java	Fri Jan 28 09:28:43 2011 +0000
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+import java.util.Set;
+import java.util.EnumSet;
+import java.security.SecureRandom;
+import static java.security.AccessController.*;
+import java.io.IOException;
+import java.nio.file.attribute.FileAttribute;
+import java.nio.file.attribute.PosixFilePermission;
+import java.nio.file.attribute.PosixFilePermissions;
+import static java.nio.file.attribute.PosixFilePermission.*;
+import sun.security.action.GetPropertyAction;
+
+
+/**
+ * Helper class to support creation of temporary files and directories with
+ * initial attributes.
+ */
+
+class TempFileHelper {
+    private TempFileHelper() { }
+
+    // temporary directory location
+    private static final Path tmpdir =
+        Paths.get(doPrivileged(new GetPropertyAction("java.io.tmpdir")));
+
+    private static final boolean isPosix =
+        FileSystems.getDefault().supportedFileAttributeViews().contains("posix");
+
+    // file name generation, same as java.io.File for now
+    private static final SecureRandom random = new SecureRandom();
+    private static Path generatePath(String prefix, String suffix, Path dir) {
+        long n = random.nextLong();
+        n = (n == Long.MIN_VALUE) ? 0 : Math.abs(n);
+        Path name = dir.getFileSystem().getPath(prefix + Long.toString(n) + suffix);
+        // the generated name should be a simple file name
+        if (name.getParent() != null)
+            throw new IllegalArgumentException("Invalid prefix or suffix");
+        return dir.resolve(name);
+    }
+
+    // default file and directory permissions (lazily initialized)
+    private static class PosixPermissions {
+        static final FileAttribute<Set<PosixFilePermission>> filePermissions =
+            PosixFilePermissions.asFileAttribute(EnumSet.of(OWNER_READ, OWNER_WRITE));
+        static final FileAttribute<Set<PosixFilePermission>> dirPermissions =
+            PosixFilePermissions.asFileAttribute(EnumSet
+                .of(OWNER_READ, OWNER_WRITE, OWNER_EXECUTE));
+    }
+
+    /**
+     * Creates a file or directory in in the given given directory (or in the
+     * temporary directory if dir is {@code null}).
+     */
+    private static Path create(Path dir,
+                               String prefix,
+                               String suffix,
+                               boolean createDirectory,
+                               FileAttribute[] attrs)
+        throws IOException
+    {
+        if (prefix == null)
+            prefix = "";
+        if (suffix == null)
+            suffix = (createDirectory) ? "" : ".tmp";
+        if (dir == null)
+            dir = tmpdir;
+
+        // in POSIX environments use default file and directory permissions
+        // if initial permissions not given by caller.
+        if (isPosix && (dir.getFileSystem() == FileSystems.getDefault())) {
+            if (attrs.length == 0) {
+                // no attributes so use default permissions
+                attrs = new FileAttribute<?>[1];
+                attrs[0] = (createDirectory) ? PosixPermissions.dirPermissions :
+                                               PosixPermissions.filePermissions;
+            } else {
+                // check if posix permissions given; if not use default
+                boolean hasPermissions = false;
+                for (int i=0; i<attrs.length; i++) {
+                    if (attrs[i].name().equals("posix:permissions")) {
+                        hasPermissions = true;
+                        break;
+                    }
+                }
+                if (!hasPermissions) {
+                    FileAttribute<?>[] copy = new FileAttribute<?>[attrs.length+1];
+                    System.arraycopy(attrs, 0, copy, 0, attrs.length);
+                    attrs = copy;
+                    attrs[attrs.length-1] = (createDirectory) ?
+                        PosixPermissions.dirPermissions :
+                        PosixPermissions.filePermissions;
+                }
+            }
+        }
+
+        // loop generating random names until file or directory can be created
+        SecurityManager sm = System.getSecurityManager();
+        for (;;) {
+            Path f;
+            try {
+                f = generatePath(prefix, suffix, dir);
+            } catch (InvalidPathException e) {
+                // don't reveal temporary directory location
+                if (sm != null)
+                    throw new IllegalArgumentException("Invalid prefix or suffix");
+                throw e;
+            }
+            try {
+                if (createDirectory) {
+                    return Files.createDirectory(f, attrs);
+                } else {
+                    return Files.createFile(f, attrs);
+                }
+            } catch (SecurityException e) {
+                // don't reveal temporary directory location
+                if (dir == tmpdir && sm != null)
+                    throw new SecurityException("Unable to create temporary file or directory");
+                throw e;
+            } catch (FileAlreadyExistsException e) {
+                // ignore
+            }
+        }
+    }
+
+    /**
+     * Creates a temporary file in the given directory, or in in the
+     * temporary directory if dir is {@code null}.
+     */
+    static Path createTempFile(Path dir,
+                               String prefix,
+                               String suffix,
+                               FileAttribute[] attrs)
+        throws IOException
+    {
+        return create(dir, prefix, suffix, false, attrs);
+    }
+
+    /**
+     * Creates a temporary directory in the given directory, or in in the
+     * temporary directory if dir is {@code null}.
+     */
+    static Path createTempDirectory(Path dir,
+                                    String prefix,
+                                    FileAttribute[] attrs)
+        throws IOException
+    {
+        return create(dir, prefix, null, true, attrs);
+    }
+}
--- a/jdk/src/share/classes/java/nio/file/WatchEvent.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/WatchEvent.java	Fri Jan 28 09:28:43 2011 +0000
@@ -44,7 +44,7 @@
  * @since 1.7
  */
 
-public abstract class WatchEvent<T> {
+public interface WatchEvent<T> {
 
     /**
      * An event kind, for the purposes of identification.
@@ -65,11 +65,6 @@
     }
 
     /**
-     * Initializes a new instance of this class.
-     */
-    protected WatchEvent() { }
-
-    /**
      * An event modifier that qualifies how a {@link Watchable} is registered
      * with a {@link WatchService}.
      *
@@ -90,7 +85,7 @@
      *
      * @return  the event kind
      */
-    public abstract Kind<T> kind();
+    Kind<T> kind();
 
     /**
      * Returns the event count. If the event count is greater than {@code 1}
@@ -98,7 +93,7 @@
      *
      * @return  the event count
      */
-    public abstract int count();
+    int count();
 
     /**
      * Returns the context for the event.
@@ -112,5 +107,5 @@
      *
      * @return  the event context; may be {@code null}
      */
-    public abstract T context();
+    T context();
 }
--- a/jdk/src/share/classes/java/nio/file/WatchKey.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/WatchKey.java	Fri Jan 28 09:28:43 2011 +0000
@@ -81,11 +81,7 @@
  * @since 1.7
  */
 
-public abstract class WatchKey {
-    /**
-     * Initializes a new instance of this class.
-     */
-    protected WatchKey() { }
+public interface WatchKey {
 
     /**
      * Tells whether or not this watch key is valid.
@@ -95,7 +91,7 @@
      *
      * @return  {@code true} if, and only if, this watch key is valid
      */
-    public abstract boolean isValid();
+    boolean isValid();
 
     /**
      * Retrieves and removes all pending events for this watch key, returning
@@ -105,7 +101,7 @@
      *
      * @return  the list of the events retrieved; may be empty
      */
-    public abstract List<WatchEvent<?>> pollEvents();
+    List<WatchEvent<?>> pollEvents();
 
     /**
      * Resets this watch key.
@@ -121,7 +117,7 @@
      *          {@code false} if the watch key could not be reset because it is
      *          no longer {@link #isValid valid}
      */
-    public abstract boolean reset();
+    boolean reset();
 
     /**
      * Cancels the registration with the watch service. Upon return the watch key
@@ -134,5 +130,21 @@
      * <p> If this watch key has already been cancelled then invoking this
      * method has no effect.  Once cancelled, a watch key remains forever invalid.
      */
-    public abstract void cancel();
+    void cancel();
+
+    /**
+     * Returns the object for which this watch key was created. This method will
+     * continue to return the object even after the key is cancelled.
+     *
+     * <p> As the {@code WatchService} is intended to map directly on to the
+     * native file event notification facility (where available) then many of
+     * details on how registered objects are watched is highly implementation
+     * specific. When watching a directory for changes for example, and the
+     * directory is moved or renamed in the file system, there is no guarantee
+     * that the watch key will be cancelled and so the object returned by this
+     * method may no longer be a valid path to the directory.
+     *
+     * @return the object for which this watch key was created
+     */
+    //T watchable();
 }
--- a/jdk/src/share/classes/java/nio/file/WatchService.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/WatchService.java	Fri Jan 28 09:28:43 2011 +0000
@@ -103,13 +103,9 @@
  * @see FileSystem#newWatchService
  */
 
-public abstract class WatchService
-    implements Closeable
+public interface WatchService
+    extends Closeable
 {
-    /**
-     * Initializes a new instance of this class.
-     */
-    protected WatchService() { }
 
     /**
      * Closes this watch service.
@@ -129,7 +125,7 @@
      *          if an I/O error occurs
      */
     @Override
-    public abstract void close() throws IOException;
+    void close() throws IOException;
 
     /**
      * Retrieves and removes the next watch key, or {@code null} if none are
@@ -140,7 +136,7 @@
      * @throws  ClosedWatchServiceException
      *          if this watch service is closed
      */
-    public abstract WatchKey poll();
+    WatchKey poll();
 
     /**
      * Retrieves and removes the next watch key, waiting if necessary up to the
@@ -160,7 +156,7 @@
      * @throws  InterruptedException
      *          if interrupted while waiting
      */
-    public abstract WatchKey poll(long timeout, TimeUnit unit)
+    WatchKey poll(long timeout, TimeUnit unit)
         throws InterruptedException;
 
     /**
@@ -174,5 +170,5 @@
      * @throws  InterruptedException
      *          if interrupted while waiting
      */
-    public abstract WatchKey take() throws InterruptedException;
+    WatchKey take() throws InterruptedException;
 }
--- a/jdk/src/share/classes/java/nio/file/attribute/AclEntry.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/AclEntry.java	Fri Jan 28 09:28:43 2011 +0000
@@ -176,7 +176,7 @@
          */
         public Builder setPermissions(Set<AclEntryPermission> perms) {
             // copy and check for erroneous elements
-            perms = new HashSet<AclEntryPermission>(perms);
+            perms = EnumSet.copyOf(perms);
             checkSet(perms, AclEntryPermission.class);
             this.perms = perms;
             return this;
@@ -190,8 +190,7 @@
          * @return  this builder
          */
         public Builder setPermissions(AclEntryPermission... perms) {
-            Set<AclEntryPermission> set =
-                new HashSet<AclEntryPermission>(perms.length);
+            Set<AclEntryPermission> set = EnumSet.noneOf(AclEntryPermission.class);
             // copy and check for null elements
             for (AclEntryPermission p: perms) {
                 if (p == null)
@@ -214,7 +213,7 @@
          */
         public Builder setFlags(Set<AclEntryFlag> flags) {
             // copy and check for erroneous elements
-            flags = new HashSet<AclEntryFlag>(flags);
+            flags = EnumSet.copyOf(flags);
             checkSet(flags, AclEntryFlag.class);
             this.flags = flags;
             return this;
@@ -228,7 +227,7 @@
          * @return  this builder
          */
         public Builder setFlags(AclEntryFlag... flags) {
-            Set<AclEntryFlag> set = new HashSet<AclEntryFlag>(flags.length);
+            Set<AclEntryFlag> set = EnumSet.noneOf(AclEntryFlag.class);
             // copy and check for null elements
             for (AclEntryFlag f: flags) {
                 if (f == null)
--- a/jdk/src/share/classes/java/nio/file/attribute/AclFileAttributeView.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/AclFileAttributeView.java	Fri Jan 28 09:28:43 2011 +0000
@@ -65,7 +65,7 @@
  * UserPrincipalLookupService} may be used to obtain a {@link UserPrincipal}
  * to represent these special identities by invoking the {@link
  * UserPrincipalLookupService#lookupPrincipalByName lookupPrincipalByName}
- * method.
+ * method. </p>
  *
  * <p> <b>Usage Example:</b>
  * Suppose we wish to add an entry to an existing ACL to grant "joe" access:
@@ -75,7 +75,7 @@
  *         .lookupPrincipalByName("joe");
  *
  *     // get view
- *     AclFileAttributeView view = file.getFileAttributeView(AclFileAttributeView.class);
+ *     AclFileAttributeView view = Files.getFileAttributeView(file, AclFileAttributeView.class);
  *
  *     // create ACE to give "joe" read access
  *     AclEntry entry = AclEntry.newBuilder()
@@ -110,11 +110,11 @@
  * </table>
  * </blockquote>
  *
- * <p> The {@link FileRef#getAttribute getAttribute} method may be used to read
+ * <p> The {@link Files#getAttribute getAttribute} method may be used to read
  * the ACL or owner attributes as if by invoking the {@link #getAcl getAcl} or
  * {@link #getOwner getOwner} methods.
  *
- * <p> The {@link FileRef#setAttribute setAttribute} method may be used to
+ * <p> The {@link Files#setAttribute setAttribute} method may be used to
  * update the ACL or owner attributes as if by invoking the {@link #setAcl setAcl}
  * or {@link #setOwner setOwner} methods.
  *
@@ -122,8 +122,8 @@
  *
  * <p> Implementations supporting this attribute view may also support setting
  * the initial ACL when creating a file or directory. The initial ACL
- * may be provided to methods such as {@link Path#createFile createFile} or {@link
- * Path#createDirectory createDirectory} as an {@link FileAttribute} with {@link
+ * may be provided to methods such as {@link Files#createFile createFile} or {@link
+ * Files#createDirectory createDirectory} as an {@link FileAttribute} with {@link
  * FileAttribute#name name} {@code "acl:acl"} and a {@link FileAttribute#value
  * value} that is the list of {@code AclEntry} objects.
  *
@@ -135,8 +135,6 @@
  * translation.
  *
  * @since 1.7
- * @see Attributes#getAcl
- * @see Attributes#setAcl
  */
 
 public interface AclFileAttributeView
--- a/jdk/src/share/classes/java/nio/file/attribute/Attributes.java	Thu Jan 13 22:21:58 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,460 +0,0 @@
-/*
- * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.nio.file.attribute;
-
-import java.nio.file.*;
-import java.io.IOException;
-import java.util.*;
-
-/**
- * This class consists exclusively of static methods that operate on or return
- * the attributes of files or file stores. These methods provide for convenient
- * use of the {@link AttributeView attribute-views} defined in this package.
- *
- * @since 1.7
- */
-
-public final class Attributes {
-    private Attributes() { }
-
-    /**
-     * Reads the basic file attributes of a file.
-     *
-     * <p> The {@code options} array may be used to indicate how symbolic links
-     * are handled for the case that the file is a symbolic link. By default,
-     * symbolic links are followed and the file attributes of the final target
-     * of the link are read. If the option {@link LinkOption#NOFOLLOW_LINKS
-     * NOFOLLOW_LINKS} is present then symbolic links are not followed and so
-     * the method returns the file attributes of the symbolic link itself.
-     * This option should be used where there is a need to determine if a
-     * file is a symbolic link:
-     * <pre>
-     *    boolean isSymbolicLink = Attributes.readBasicFileAttributes(file, NOFOLLOW_LINKS).isSymbolicLink();
-     * </pre>
-     *
-     * <p> It is implementation specific if all file attributes are read as an
-     * atomic operation with respect to other file system operations.
-     *
-     * @param   file
-     *          A file reference that locates the file
-     * @param   options
-     *          Options indicating how symbolic links are handled
-     *
-     * @return  The basic file attributes
-     *
-     * @throws  IOException
-     *          If an I/O error occurs
-     * @throws  SecurityException
-     *          In the case of the default provider, the security manager's {@link
-     *          SecurityManager#checkRead(String) checkRead} method is invoked
-     *          to check read access to file
-     *
-     * @see BasicFileAttributeView#readAttributes
-     */
-    public static BasicFileAttributes readBasicFileAttributes(FileRef file,
-                                                              LinkOption... options)
-        throws IOException
-    {
-        return file.getFileAttributeView(BasicFileAttributeView.class, options)
-            .readAttributes();
-    }
-
-    /**
-     * Reads the POSIX file attributes of a file.
-     *
-     * <p> The {@code file} parameter locates a file that supports the {@link
-     * PosixFileAttributeView}. This file attribute view provides access to a
-     * subset of the file attributes commonly associated with files on file
-     * systems used by operating systems that implement the Portable Operating
-     * System Interface (POSIX) family of standards. It is implementation
-     * specific if all file attributes are read as an atomic operation with
-     * respect to other file system operations.
-     *
-     * <p> The {@code options} array may be used to indicate how symbolic links
-     * are handled for the case that the file is a symbolic link. By default,
-     * symbolic links are followed and the file attributes of the final target
-     * of the link are read. If the option {@link LinkOption#NOFOLLOW_LINKS
-     * NOFOLLOW_LINKS} is present then symbolic links are not followed and so
-     * the method returns the file attributes of the symbolic link itself.
-     *
-     * @param   file
-     *          A file reference that locates the file
-     * @param   options
-     *          Options indicating how symbolic links are handled
-     *
-     * @return  The POSIX file attributes
-     *
-     * @throws  UnsupportedOperationException
-     *          If the {@code PosixFileAttributeView} is not available
-     * @throws  IOException
-     *          If an I/O error occurs
-     * @throws  SecurityException
-     *          In the case of the default provider, and a security manager is
-     *          installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
-     *          or its {@link SecurityManager#checkRead(String) checkRead} method
-     *          denies read access to the file.
-     *
-     * @see PosixFileAttributeView#readAttributes
-     */
-    public static PosixFileAttributes readPosixFileAttributes(FileRef file,
-                                                              LinkOption... options)
-        throws IOException
-    {
-        PosixFileAttributeView view =
-            file.getFileAttributeView(PosixFileAttributeView.class, options);
-        if (view == null)
-            throw new UnsupportedOperationException();
-        return view.readAttributes();
-    }
-
-    /**
-     * Reads the DOS file attributes of a file.
-     *
-     * <p> The {@code file} parameter locates a file that supports the {@link
-     * DosFileAttributeView}. This file attribute view provides access to
-     * legacy "DOS" attributes supported by the file systems such as File
-     * Allocation Table (FAT), commonly used in <em>consumer devices</em>. It is
-     * implementation specific if all file attributes are read as an atomic
-     * operation with respect to other file system operations.
-     *
-     * <p> The {@code options} array may be used to indicate how symbolic links
-     * are handled for the case that the file is a symbolic link. By default,
-     * symbolic links are followed and the file attributes of the final target
-     * of the link are read. If the option {@link LinkOption#NOFOLLOW_LINKS
-     * NOFOLLOW_LINKS} is present then symbolic links are not followed and so
-     * the method returns the file attributes of the symbolic link itself.
-     *
-     * @param   file
-     *          A file reference that locates the file
-     * @param   options
-     *          Options indicating how symbolic links are handled
-     *
-     * @return  The DOS file attributes
-     *
-     * @throws  UnsupportedOperationException
-     *          If the {@code DosFileAttributeView} is not available
-     * @throws  IOException
-     *          If an I/O error occurs
-     * @throws  SecurityException
-     *          In the case of the default provider, the security manager's {@link
-     *          SecurityManager#checkRead(String) checkRead} method is invoked
-     *          to check read access to file
-     *
-     * @see DosFileAttributeView#readAttributes
-     */
-    public static DosFileAttributes readDosFileAttributes(FileRef file,
-                                                          LinkOption... options)
-        throws IOException
-    {
-        DosFileAttributeView view =
-            file.getFileAttributeView(DosFileAttributeView.class, options);
-        if (view == null)
-            throw new UnsupportedOperationException();
-        return view.readAttributes();
-    }
-
-    /**
-     * Returns the owner of a file.
-     *
-     * <p> The {@code file} parameter locates a file that supports the {@link
-     * FileOwnerAttributeView}. This file attribute view provides access to
-     * a file attribute that is the owner of the file.
-     *
-     * @param   file
-     *          A file reference that locates the file
-     *
-     * @return  A user principal representing the owner of the file
-     *
-     * @throws  UnsupportedOperationException
-     *          If the {@code FileOwnerAttributeView} is not available
-     * @throws  IOException
-     *          If an I/O error occurs
-     * @throws  SecurityException
-     *          In the case of the default provider, and a security manager is
-     *          installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
-     *          or its {@link SecurityManager#checkRead(String) checkRead} method
-     *          denies read access to the file.
-     *
-     * @see FileOwnerAttributeView#getOwner
-     */
-    public static UserPrincipal getOwner(FileRef file) throws IOException {
-        FileOwnerAttributeView view =
-            file.getFileAttributeView(FileOwnerAttributeView.class);
-        if (view == null)
-            throw new UnsupportedOperationException();
-        return view.getOwner();
-    }
-
-    /**
-     * Updates the file owner.
-     *
-     * <p> The {@code file} parameter locates a file that supports the {@link
-     * FileOwnerAttributeView}. This file attribute view provides access to
-     * a file attribute that is the owner of the file.
-     *
-     * @param   file
-     *          A file reference that locates the file
-     * @param   owner
-     *          The new file owner
-     *
-     * @throws  UnsupportedOperationException
-     *          If the {@code FileOwnerAttributeView} is not available
-     * @throws  IOException
-     *          If an I/O error occurs
-     * @throws  SecurityException
-     *          In the case of the default provider, and a security manager is
-     *          installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
-     *          or its {@link SecurityManager#checkWrite(String) checkWrite}
-     *          method denies write access to the file.
-     *
-     * @see FileOwnerAttributeView#setOwner
-     */
-    public static void setOwner(FileRef file, UserPrincipal owner)
-            throws IOException
-    {
-        FileOwnerAttributeView view =
-            file.getFileAttributeView(FileOwnerAttributeView.class);
-        if (view == null)
-            throw new UnsupportedOperationException();
-        view.setOwner(owner);
-    }
-
-    /**
-     * Reads a file's Access Control List (ACL).
-     *
-     * <p> The {@code file} parameter locates a file that supports the {@link
-     * AclFileAttributeView}. This file attribute view provides access to ACLs
-     * based on the ACL model specified in
-     *  <a href="http://www.ietf.org/rfc/rfc3530.txt"><i>RFC&nbsp;3530</i></a>.
-     *
-     * @param   file
-     *          A file reference that locates the file
-     *
-     * @return  An ordered list of {@link AclEntry entries} representing the
-     *          ACL. The returned list is modifiable.
-     *
-     * @throws  UnsupportedOperationException
-     *          If the {@code AclAttributeView} is not available
-     * @throws  IOException
-     *          If an I/O error occurs
-     * @throws  SecurityException
-     *          In the case of the default provider, and a security manager is
-     *          installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
-     *          or its {@link SecurityManager#checkRead(String) checkRead} method
-     *          denies read access to the file.
-     *
-     * @see AclFileAttributeView#getAcl
-     */
-    public static List<AclEntry> getAcl(FileRef file) throws IOException {
-        AclFileAttributeView view =
-            file.getFileAttributeView(AclFileAttributeView.class);
-        if (view == null)
-            throw new UnsupportedOperationException();
-        return view.getAcl();
-    }
-
-    /**
-     * Updates a file's Access Control List (ACL).
-     *
-     * <p> The {@code file} parameter locates a file that supports the {@link
-     * AclFileAttributeView}. This file attribute view provides access to ACLs
-     * based on the ACL model specified in
-     *  <a href="http://www.ietf.org/rfc/rfc3530.txt"><i>RFC&nbsp;3530</i></a>.
-     *
-     * @param   file
-     *          A file reference that locates the file
-     * @param   acl
-     *          The new file ACL
-     *
-     * @throws  UnsupportedOperationException
-     *          If the {@code AclFileAttributeView} is not available
-     * @throws  IOException
-     *          If an I/O error occurs
-     * @throws  SecurityException
-     *          In the case of the default provider, and a security manager is
-     *          installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
-     *          or its {@link SecurityManager#checkWrite(String) checkWrite}
-     *          method denies write access to the file.
-     *
-     * @see AclFileAttributeView#setAcl
-     */
-    public static void setAcl(FileRef file, List<AclEntry> acl)
-        throws IOException
-    {
-        AclFileAttributeView view =
-            file.getFileAttributeView(AclFileAttributeView.class);
-        if (view == null)
-            throw new UnsupportedOperationException();
-        view.setAcl(acl);
-    }
-
-    /**
-     * Updates a file's last modified time attribute. The file time is converted
-     * to the epoch and precision supported by the file system. Converting from
-     * finer to coarser granularities result in precision loss. The behavior of
-     * this method when attempting to set a timestamp to a value that is outside
-     * the range supported by the underlying file store is not defined. It may
-     * or not fail by throwing an {@code IOException}.
-     *
-     * <p> If the file system does not support a last modified time attribute
-     * then this method has no effect.
-     *
-     * <p> <b>Usage Example:</b>
-     * Suppose we want to set the last modified time to the current time:
-     * <pre>
-     *    FileTime now = FileTime.fromMillis(System.currentTimeMillis());
-     *    Attributes.setLastModifiedTime(file, now);
-     * </pre>
-     *
-     * @param   file
-     *          A file reference that locates the file
-     * @param   lastModifiedTime
-     *          The new last modified time
-     *
-     * @throws  IOException
-     *          If an I/O error occurs
-     * @throws  SecurityException
-     *          In the case of the default provider, the security manager's {@link
-     *          SecurityManager#checkWrite(String) checkWrite} method is invoked
-     *          to check write access to file
-     *
-     * @see BasicFileAttributeView#setTimes
-     */
-    public static void setLastModifiedTime(FileRef file,
-                                           FileTime lastModifiedTime)
-        throws IOException
-    {
-        if (lastModifiedTime == null)
-            throw new NullPointerException("'lastModifiedTime' is null");
-        file.getFileAttributeView(BasicFileAttributeView.class)
-            .setTimes(lastModifiedTime, null, null);
-    }
-
-    /**
-     * Updates a file's last access time attribute. The file time is converted
-     * to the epoch and precision supported by the file system. Converting from
-     * finer to coarser granularities result in precision loss. The behavior of
-     * this method when attempting to set a timestamp to a value that is outside
-     * the range supported by the underlying file store is not defined. It may
-     * or not fail by throwing an {@code IOException}.
-     *
-     * <p> If the file system does not support a last access time attribute then
-     * this method has no effect.
-     *
-     * @param   file
-     *          A file reference that locates the file
-     * @param   lastAccessTime
-     *          The new last access time
-     *
-     * @throws  IOException
-     *          If an I/O error occurs
-     * @throws  SecurityException
-     *          In the case of the default provider, the security manager's {@link
-     *          SecurityManager#checkWrite(String) checkWrite} method is invoked
-     *          to check write access to file
-     *
-     * @see BasicFileAttributeView#setTimes
-     */
-    public static void setLastAccessTime(FileRef file,
-                                         FileTime lastAccessTime)
-        throws IOException
-    {
-        if (lastAccessTime == null)
-            throw new NullPointerException("'lastAccessTime' is null");
-        file.getFileAttributeView(BasicFileAttributeView.class)
-            .setTimes(null, lastAccessTime, null);
-    }
-
-    /**
-     * Sets a file's POSIX permissions.
-     *
-     * <p> The {@code file} parameter is a reference to an existing file. It
-     * supports the {@link PosixFileAttributeView} that provides access to file
-     * attributes commonly associated with files on file systems used by
-     * operating systems that implement the Portable Operating System Interface
-     * (POSIX) family of standards.
-     *
-     * @param   file
-     *          A file reference that locates the file
-     * @param   perms
-     *          The new set of permissions
-     *
-     * @throws  UnsupportedOperationException
-     *          If {@code PosixFileAttributeView} is not available
-     * @throws  ClassCastException
-     *          If the sets contains elements that are not of type {@code
-     *          PosixFilePermission}
-     * @throws  IOException
-     *          If an I/O error occurs
-     * @throws  SecurityException
-     *          In the case of the default provider, and a security manager is
-     *          installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
-     *          or its {@link SecurityManager#checkWrite(String) checkWrite}
-     *          method denies write access to the file.
-     *
-     * @see PosixFileAttributeView#setPermissions
-     */
-    public static void setPosixFilePermissions(FileRef file,
-                                               Set<PosixFilePermission> perms)
-        throws IOException
-    {
-        PosixFileAttributeView view =
-            file.getFileAttributeView(PosixFileAttributeView.class);
-        if (view == null)
-            throw new UnsupportedOperationException();
-        view.setPermissions(perms);
-    }
-
-    /**
-     * Reads the space attributes of a file store.
-     *
-     * <p> The {@code store} parameter is a file store that supports the
-     * {@link FileStoreSpaceAttributeView} providing access to the space related
-     * attributes of the file store. It is implementation specific if all attributes
-     * are read as an atomic operation with respect to other file system operations.
-     *
-     * @param   store
-     *          The file store
-     *
-     * @return  The file store space attributes
-     *
-     * @throws  UnsupportedOperationException
-     *          If the file store space attribute view is not supported
-     * @throws  IOException
-     *          If an I/O error occurs
-     *
-     * @see FileStoreSpaceAttributeView#readAttributes()
-     */
-    public static FileStoreSpaceAttributes readFileStoreSpaceAttributes(FileStore store)
-        throws IOException
-    {
-        FileStoreSpaceAttributeView view =
-            store.getFileStoreAttributeView(FileStoreSpaceAttributeView.class);
-        if (view == null)
-            throw new UnsupportedOperationException();
-        return view.readAttributes();
-    }
-}
--- a/jdk/src/share/classes/java/nio/file/attribute/BasicFileAttributeView.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/BasicFileAttributeView.java	Fri Jan 28 09:28:43 2011 +0000
@@ -85,16 +85,15 @@
  * </table>
  * </blockquote>
  *
- * <p> The {@link java.nio.file.FileRef#getAttribute getAttribute} method may be
+ * <p> The {@link java.nio.file.Files#getAttribute getAttribute} method may be
  * used to read any of these attributes as if by invoking the {@link
  * #readAttributes() readAttributes()} method.
  *
- * <p> The {@link java.nio.file.FileRef#setAttribute setAttribute} method may be
+ * <p> The {@link java.nio.file.Files#setAttribute setAttribute} method may be
  * used to update the file's last modified time, last access time or create time
  * attributes as if by invoking the {@link #setTimes setTimes} method.
  *
  * @since 1.7
- * @see Attributes
  */
 
 public interface BasicFileAttributeView
@@ -131,9 +130,10 @@
      * <p> This method updates the file's timestamp attributes. The values are
      * converted to the epoch and precision supported by the file system.
      * Converting from finer to coarser granularities result in precision loss.
-     * The behavior of this method when attempting to set a timestamp to a value
-     * that is outside the range supported by the underlying file store is not
-     * defined. It may or not fail by throwing an {@code IOException}.
+     * The behavior of this method when attempting to set a timestamp that is
+     * not supported or to a value that is outside the range supported by the
+     * underlying file store is not defined. It may or not fail by throwing an
+     * {@code IOException}.
      *
      * <p> If any of the {@code lastModifiedTime}, {@code lastAccessTime},
      * or {@code createTime} parameters has the value {@code null} then the
@@ -146,6 +146,14 @@
      * lastAccessTime} and {@code createTime} parameters are {@code null} then
      * this method has no effect.
      *
+     * <p> <b>Usage Example:</b>
+     * Suppose we want to change a file's creation time.
+     * <pre>
+     *    Path path = ...
+     *    FileTime time = ...
+     *    Files.getFileAttributeView(path, BasicFileAttributeView.class).setTimes(null, null, time);
+     * </pre>
+     *
      * @param   lastModifiedTime
      *          the new last modified time, or {@code null} to not change the
      *          value
@@ -160,6 +168,8 @@
      *          In the case of the default provider, a security manager is
      *          installed, its  {@link SecurityManager#checkWrite(String) checkWrite}
      *          method is invoked to check write access to the file
+     *
+     * @see java.nio.file.Files#setLastModifiedTime
      */
     void setTimes(FileTime lastModifiedTime,
                   FileTime lastAccessTime,
--- a/jdk/src/share/classes/java/nio/file/attribute/BasicFileAttributes.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/BasicFileAttributes.java	Fri Jan 28 09:28:43 2011 +0000
@@ -34,8 +34,8 @@
  *
  * <p> <b>Usage Example:</b>
  * <pre>
- *    FileRef file = ...
- *    BasicFileAttributes attrs = Attributes.readBasicFileAttributes(file);
+ *    Path file = ...
+ *    BasicFileAttributes attrs = Files.readAttributes(file, BasicFileAttributes.class);
  * </pre>
  *
  * @since 1.7
@@ -48,25 +48,40 @@
     /**
      * Returns the time of last modification.
      *
+     * <p> If the file system implementation does not support a time stamp
+     * to indicate the time of last modification then this method returns an
+     * implementation specific default value, typically a {@code FileTime}
+     * representing the epoch (1970-01-01T00:00:00Z).
+     *
      * @return  a {@code FileTime} representing the time the file was last
-     *          modified or {@code null} if the attribute is not supported.
+     *          modified
      */
     FileTime lastModifiedTime();
 
     /**
-     * Returns the time of last access if supported.
+     * Returns the time of last access.
      *
-     * @return  a {@code FileTime} representing the time of last access or
-     *          {@code null} if the attribute is not supported.
+     * <p> If the file system implementation does not support a time stamp
+     * to indicate the time of last access then this method returns
+     * an implementation specific default value, typically the {@link
+     * #lastModifiedTime() last-modified-time} or a {@code FileTime}
+     * representing the epoch (1970-01-01T00:00:00Z).
+     *
+     * @return  a {@code FileTime} representing the time of last access
      */
     FileTime lastAccessTime();
 
     /**
-     * Returns the creation time if supported. The creation time is the time
-     * that the file was created.
+     * Returns the creation time. The creation time is the time that the file
+     * was created.
      *
-     * @return   a {@code FileTime} representing the time  the file was created
-     *           or {@code null} if the attribute is not supported.
+     * <p> If the file system implementation does not support a time stamp
+     * to indicate the time when the file was created then this method returns
+     * an implementation specific default value, typically the {@link
+     * #lastModifiedTime() last-modified-time} or a {@code FileTime}
+     * representing the epoch (1970-01-01T00:00:00Z).
+     *
+     * @return   a {@code FileTime} representing the time the file was created
      */
     FileTime creationTime();
 
@@ -120,7 +135,7 @@
      *
      * <p> File keys returned by this method can be compared for equality and are
      * suitable for use in collections. If the file system and files remain static,
-     * and two files are the {@link java.nio.file.Path#isSameFile same} with
+     * and two files are the {@link java.nio.file.Files#isSameFile same} with
      * non-{@code null} file keys, then their file keys are equal.
      *
      * @see java.nio.file.Files#walkFileTree
--- a/jdk/src/share/classes/java/nio/file/attribute/DosFileAttributeView.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/DosFileAttributeView.java	Fri Jan 28 09:28:43 2011 +0000
@@ -65,12 +65,12 @@
  * </table>
  * </blockquote>
  *
- * <p> The {@link java.nio.file.FileRef#getAttribute getAttribute} method may
+ * <p> The {@link java.nio.file.Files#getAttribute getAttribute} method may
  * be used to read any of these attributes, or any of the attributes defined by
  * {@link BasicFileAttributeView} as if by invoking the {@link #readAttributes
  * readAttributes()} method.
  *
- * <p> The {@link java.nio.file.FileRef#setAttribute setAttribute} method may
+ * <p> The {@link java.nio.file.Files#setAttribute setAttribute} method may
  * be used to update the file's last modified time, last access time or create
  * time attributes as defined by {@link BasicFileAttributeView}. It may also be
  * used to update the DOS attributes as if by invoking the {@link #setReadOnly
--- a/jdk/src/share/classes/java/nio/file/attribute/DosFileAttributes.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/DosFileAttributes.java	Fri Jan 28 09:28:43 2011 +0000
@@ -29,13 +29,13 @@
  * File attributes associated with a file in a file system that supports
  * legacy "DOS" attributes.
  *
- * <p> The DOS attributes of a file are retrieved using a {@link
- * DosFileAttributeView} by invoking its {@link DosFileAttributeView#readAttributes
- * readAttributes} method.
+ * <p> <b>Usage Example:</b>
+ * <pre>
+ *    Path file = ...
+ *    DosFileAttributes attrs = Files.readAttributes(file, DosFileAttributes.class);
+ * </pre>
  *
  * @since 1.7
- *
- * @see Attributes#readDosFileAttributes
  */
 
 public interface DosFileAttributes
--- a/jdk/src/share/classes/java/nio/file/attribute/FileAttribute.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/FileAttribute.java	Fri Jan 28 09:28:43 2011 +0000
@@ -28,8 +28,8 @@
 /**
  * An object that encapsulates the value of a file attribute that can be set
  * atomically when creating a new file or directory by invoking the {@link
- * java.nio.file.Path#createFile createFile} or {@link
- * java.nio.file.Path#createDirectory createDirectory} methods.
+ * java.nio.file.Files#createFile createFile} or {@link
+ * java.nio.file.Files#createDirectory createDirectory} methods.
  *
  * @param <T> The type of the file attribute value
  *
--- a/jdk/src/share/classes/java/nio/file/attribute/FileAttributeView.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/FileAttributeView.java	Fri Jan 28 09:28:43 2011 +0000
@@ -33,7 +33,7 @@
  *
  * @since 1.7
  *
- * @see java.nio.file.FileRef#getFileAttributeView(Class,java.nio.file.LinkOption[])
+ * @see java.nio.file.Files#getFileAttributeView(Path,Class,java.nio.file.LinkOption[])
  */
 
 public interface FileAttributeView
--- a/jdk/src/share/classes/java/nio/file/attribute/FileOwnerAttributeView.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/FileOwnerAttributeView.java	Fri Jan 28 09:28:43 2011 +0000
@@ -37,8 +37,8 @@
  * <p> The {@link #getOwner getOwner} or {@link #setOwner setOwner} methods may
  * be used to read or update the owner of the file.
  *
- * <p> The {@link java.nio.file.FileRef#getAttribute getAttribute} and
- * {@link java.nio.file.FileRef#setAttribute setAttribute} methods may also be
+ * <p> The {@link java.nio.file.Files#getAttribute getAttribute} and
+ * {@link java.nio.file.Files#setAttribute setAttribute} methods may also be
  * used to read or update the owner. In that case, the owner attribute is
  * identified by the name {@code "owner"}, and the value of the attribute is
  * a {@link UserPrincipal}.
--- a/jdk/src/share/classes/java/nio/file/attribute/FileStoreSpaceAttributeView.java	Thu Jan 13 22:21:58 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.nio.file.attribute;
-
-import java.io.IOException;
-
-/**
- * A file store attribute view that supports reading of space attributes.
- *
- * <p> Where dynamic access to file attributes is required, the attributes
- * supported by this attribute view have the following names and types:
- * <blockquote>
- * <table border="1" cellpadding="8">
- *   <tr>
- *     <th> Name </th>
- *     <th> Type </th>
- *   </tr>
- *  <tr>
- *     <td> "totalSpace" </td>
- *     <td> {@link Long} </td>
- *   </tr>
- *  <tr>
- *     <td> "usableSpace" </td>
- *     <td> {@link Long} </td>
- *   </tr>
- *  <tr>
- *     <td> "unallocatedSpace" </td>
- *     <td> {@link Long} </td>
- *   </tr>
- * </table>
- * </blockquote>
- * <p> The {@link java.nio.file.FileStore#getAttribute getAttribute} method may
- * be used to read any of these attributes.
- *
- * @since 1.7
- */
-
-public interface FileStoreSpaceAttributeView
-    extends FileStoreAttributeView
-{
-    /**
-     * Returns the name of the attribute view. Attribute views of this type
-     * have the name {@code "space"}.
-     */
-    @Override
-    String name();
-
-    /**
-     * Reads the disk space attributes as a bulk operation.
-     *
-     * <p> It is file system specific if all attributes are read as an
-     * atomic operation with respect to other file system operations.
-     *
-     * @return  The disk space attributes
-     *
-     * @throws  IOException
-     *          If an I/O error occurs
-     */
-    FileStoreSpaceAttributes readAttributes() throws IOException;
-}
--- a/jdk/src/share/classes/java/nio/file/attribute/FileStoreSpaceAttributes.java	Thu Jan 13 22:21:58 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.nio.file.attribute;
-
-/**
- * Space related attributes of a file store.
- *
- * @since 1.7
- *
- * @see Attributes#readFileStoreSpaceAttributes
- */
-
-public interface FileStoreSpaceAttributes {
-    /**
-     * Returns the size, in bytes, of the file store.
-     */
-    long totalSpace();
-
-    /**
-     * Returns the number of bytes available to this Java virtual machine on the
-     * file store.
-     *
-     * <p> The returned number of available bytes is a hint, but not a
-     * guarantee, that it is possible to use most or any of these bytes.  The
-     * number of usable bytes is most likely to be accurate immediately
-     * after the space attributes are obtained. It is likely to be made inaccurate
-     * by any external I/O operations including those made on the system outside
-     * of this Java virtual machine.
-     */
-    long usableSpace();
-
-    /**
-     * Returns the number of unallocated bytes in the file store.
-     *
-     * <p> The returned number of unallocated bytes is a hint, but not a
-     * guarantee, that it is possible to use most or any of these bytes.  The
-     * number of unallocated bytes is most likely to be accurate immediately
-     * after the space attributes are obtained. It is likely to be
-     * made inaccurate by any external I/O operations including those made on
-     * the system outside of this virtual machine.
-     */
-    long unallocatedSpace();
-}
--- a/jdk/src/share/classes/java/nio/file/attribute/FileTime.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/FileTime.java	Fri Jan 28 09:28:43 2011 +0000
@@ -35,20 +35,53 @@
 
 /**
  * Represents the value of a file's time stamp attribute. For example, it may
- * represent the time that the file was last modified, accessed, or created.
+ * represent the time that the file was last
+ * {@link BasicFileAttributes#lastModifiedTime() modified},
+ * {@link BasicFileAttributes#lastAccessTime() accessed},
+ * or {@link BasicFileAttributes#creationTime() created}.
  *
  * <p> Instances of this class are immutable.
  *
  * @since 1.7
- * @see BasicFileAttributes
- * @see Attributes#setLastModifiedTime
+ * @see java.nio.file.Files#setLastModifiedTime
+ * @see java.nio.file.Files#getLastModifiedTime
  */
 
-public final class FileTime implements Comparable<FileTime> {
+public final class FileTime
+    implements Comparable<FileTime>
+{
+    /**
+     * The value since the epoch; can be negative.
+     */
     private final long value;
+
+    /**
+     * The unit of granularity to interpret the value.
+     */
     private final TimeUnit unit;
-    private String valueAsString;  // created lazily
+
+    /**
+     * The value return by toString (created lazily)
+     */
+    private String valueAsString;
+
+    /**
+     * The value in days and excess nanos (created lazily)
+     */
+    private DaysAndNanos daysAndNanos;
 
+    /**
+     * Returns a DaysAndNanos object representing the value.
+     */
+    private DaysAndNanos asDaysAndNanos() {
+        if (daysAndNanos == null)
+            daysAndNanos = new DaysAndNanos(value, unit);
+        return daysAndNanos;
+    }
+
+    /**
+     * Initializes a new instance of this class.
+     */
     private FileTime(long value, TimeUnit unit) {
         if (unit == null)
             throw new NullPointerException();
@@ -143,9 +176,8 @@
      */
     @Override
     public int hashCode() {
-        // hash value for fixed granularity to satisfy contract with equals
-        long ms = toMillis();
-        return (int)(ms ^ (ms >>> 32));
+        // hashcode of days/nanos representation to satisfy contract with equals
+        return asDaysAndNanos().hashCode();
     }
 
     /**
@@ -162,46 +194,12 @@
     @Override
     public int compareTo(FileTime other) {
         // same granularity
-        if (unit == other.unit)
+        if (unit == other.unit) {
             return (value < other.value) ? -1 : (value == other.value ? 0 : 1);
-
-        // compare in days
-        long thisValueInDays = unit.toDays(value);
-        long otherValueInDays = other.unit.toDays(other.value);
-        if (thisValueInDays != otherValueInDays)
-            return (thisValueInDays < otherValueInDays) ? -1 : 1;
-
-        // compare remainder in nanoseconds
-        long thisRemainder = remainderInNanos(thisValueInDays);
-        long otherRemainder = other.remainderInNanos(otherValueInDays);
-        return (thisRemainder < otherRemainder) ? -1 :
-            (thisRemainder == otherRemainder) ? 0 : 1;
-    }
-
-    private long remainderInNanos(long days) {
-        // constants for conversion
-        final long C0 = 1L;
-        final long C1 = C0 * 24L;
-        final long C2 = C1 * 60L;
-        final long C3 = C2 * 60L;
-        final long C4 = C3 * 1000L;
-        final long C5 = C4 * 1000L;
-        final long C6 = C5 * 1000L;
-
-        long scale;
-        switch (unit) {
-            case DAYS         : scale = C0; break;
-            case HOURS        : scale = C1; break;
-            case MINUTES      : scale = C2; break;
-            case SECONDS      : scale = C3; break;
-            case MILLISECONDS : scale = C4; break;
-            case MICROSECONDS : scale = C5; break;
-            case NANOSECONDS  : scale = C6; break;
-            default:
-                throw new AssertionError("Unit not handled");
+        } else {
+            // compare using days/nanos representation when unit differs
+            return asDaysAndNanos().compareTo(other.asDaysAndNanos());
         }
-        long rem = value - (days * scale);
-        return unit.toNanos(rem);
     }
 
     /**
@@ -239,26 +237,12 @@
             // nothing to do when seconds/minutes/hours/days
             String fractionAsString = "";
             if (unit.compareTo(TimeUnit.SECONDS) < 0) {
-                // constants for conversion
-                final long C0 = 1L;
-                final long C1 = C0 * 1000L;
-                final long C2 = C1 * 1000L;
-                final long C3 = C2 * 1000L;
-
-                long scale;
-                int width;
-                switch (unit) {
-                    case MILLISECONDS : scale = C1; width = 3; break;
-                    case MICROSECONDS : scale = C2; width = 6; break;
-                    case NANOSECONDS  : scale = C3; width = 9; break;
-                    default:
-                        throw new AssertionError("Unit not handled");
-                }
-                long fraction = value % scale;
+                long fraction = asDaysAndNanos().fractionOfSecondInNanos();
                 if (fraction != 0L) {
                     // fraction must be positive
                     if (fraction < 0L) {
-                        fraction += scale;
+                        final long MAX_FRACTION_PLUS_1 = 1000L * 1000L * 1000L;
+                        fraction += MAX_FRACTION_PLUS_1;
                         if (ms != Long.MIN_VALUE) ms--;
                     }
 
@@ -266,7 +250,7 @@
                     // stripping any trailing zeros
                     String s = Long.toString(fraction);
                     int len = s.length();
-                    width -= len;
+                    int width = 9 - len;
                     StringBuilder sb = new StringBuilder(".");
                     while (width-- > 0) {
                         sb.append('0');
@@ -302,4 +286,76 @@
         }
         return v;
     }
+
+    /**
+     * Represents a FileTime's value as two longs: the number of days since
+     * the epoch, and the excess (in nanoseconds). This is used for comparing
+     * values with different units of granularity.
+     */
+    private static class DaysAndNanos implements Comparable<DaysAndNanos> {
+        // constants for conversion
+        private static final long C0 = 1L;
+        private static final long C1 = C0 * 24L;
+        private static final long C2 = C1 * 60L;
+        private static final long C3 = C2 * 60L;
+        private static final long C4 = C3 * 1000L;
+        private static final long C5 = C4 * 1000L;
+        private static final long C6 = C5 * 1000L;
+
+        /**
+         * The value (in days) since the epoch; can be negative.
+         */
+        private final long days;
+
+        /**
+         * The excess (in nanoseconds); can be negative if days <= 0.
+         */
+        private final long excessNanos;
+
+        /**
+         * Initializes a new instance of this class.
+         */
+        DaysAndNanos(long value, TimeUnit unit) {
+            long scale;
+            switch (unit) {
+                case DAYS         : scale = C0; break;
+                case HOURS        : scale = C1; break;
+                case MINUTES      : scale = C2; break;
+                case SECONDS      : scale = C3; break;
+                case MILLISECONDS : scale = C4; break;
+                case MICROSECONDS : scale = C5; break;
+                case NANOSECONDS  : scale = C6; break;
+                default : throw new AssertionError("Unit not handled");
+            }
+            this.days = unit.toDays(value);
+            this.excessNanos = unit.toNanos(value - (this.days * scale));
+        }
+
+        /**
+         * Returns the fraction of a second, in nanoseconds.
+         */
+        long fractionOfSecondInNanos() {
+            return excessNanos % (1000L * 1000L * 1000L);
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            return (obj instanceof DaysAndNanos) ?
+                compareTo((DaysAndNanos)obj) == 0 : false;
+        }
+
+        @Override
+        public int hashCode() {
+            return (int)(days ^ (days >>> 32) ^
+                         excessNanos ^ (excessNanos >>> 32));
+        }
+
+        @Override
+        public int compareTo(DaysAndNanos other) {
+            if (this.days != other.days)
+                return (this.days < other.days) ? -1 : 1;
+            return (this.excessNanos < other.excessNanos) ? -1 :
+                   (this.excessNanos == other.excessNanos) ? 0 : 1;
+        }
+    }
 }
--- a/jdk/src/share/classes/java/nio/file/attribute/PosixFileAttributeView.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/PosixFileAttributeView.java	Fri Jan 28 09:28:43 2011 +0000
@@ -60,8 +60,8 @@
  * <p> <b>Usage Example:</b>
  * Suppose we need to print out the owner and access permissions of a file:
  * <pre>
- *     FileRef file = ...
- *     PosixFileAttributes attrs = file.getFileAttributeView(PosixFileAttributeView.class)
+ *     Path file = ...
+ *     PosixFileAttributes attrs = Files.getFileAttributeView(file, PosixFileAttributeView.class)
  *         .readAttributes();
  *     System.out.format("%s %s%n",
  *         attrs.owner().getName(),
@@ -90,12 +90,12 @@
  * </table>
  * </blockquote>
  *
- * <p> The {@link FileRef#getAttribute getAttribute} method may be used to read
+ * <p> The {@link Files#getAttribute getAttribute} method may be used to read
  * any of these attributes, or any of the attributes defined by {@link
  * BasicFileAttributeView} as if by invoking the {@link #readAttributes
  * readAttributes()} method.
  *
- * <p> The {@link FileRef#setAttribute setAttribute} method may be used to update
+ * <p> The {@link Files#setAttribute setAttribute} method may be used to update
  * the file's last modified time, last access time or create time attributes as
  * defined by {@link BasicFileAttributeView}. It may also be used to update
  * the permissions, owner, or group-owner as if by invoking the {@link
@@ -105,8 +105,8 @@
  * <h4> Setting Initial Permissions </h4>
  * <p> Implementations supporting this attribute view may also support setting
  * the initial permissions when creating a file or directory. The
- * initial permissions are provided to the  {@link Path#createFile createFile}
- * or {@link Path#createDirectory createDirectory} methods as a {@link
+ * initial permissions are provided to the {@link Files#createFile createFile}
+ * or {@link Files#createDirectory createDirectory} methods as a {@link
  * FileAttribute} with {@link FileAttribute#name name} {@code "posix:permissions"}
  * and a {@link FileAttribute#value value} that is the set of permissions. The
  * following example uses the {@link PosixFilePermissions#asFileAttribute
@@ -117,7 +117,7 @@
  *     Path path = ...
  *     Set&lt;PosixFilePermission&gt; perms =
  *         EnumSet.of(OWNER_READ, OWNER_WRITE, OWNER_EXECUTE, GROUP_READ);
- *     path.createFile(PosixFilePermissions.asFileAttribute(perms));
+ *     Files.createFile(path, PosixFilePermissions.asFileAttribute(perms));
  * </pre>
  *
  * <p> When the access permissions are set at file creation time then the actual
@@ -128,13 +128,11 @@
  * the access permissions, and the underlying file system supports access
  * permissions, then it is required that the value of the actual access
  * permissions will be equal or less than the value of the attribute
- * provided to the {@link java.nio.file.Path#createFile createFile} or
- * {@link java.nio.file.Path#createDirectory createDirectory} methods. In
- * other words, the file may be more secure than requested.
+ * provided to the {@link Files#createFile createFile} or {@link
+ * Files#createDirectory createDirectory} methods. In other words, the file may
+ * be more secure than requested.
  *
  * @since 1.7
- *
- * @see Attributes#readPosixFileAttributes
  */
 
 public interface PosixFileAttributeView
--- a/jdk/src/share/classes/java/nio/file/attribute/PosixFileAttributes.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/PosixFileAttributes.java	Fri Jan 28 09:28:43 2011 +0000
@@ -37,8 +37,6 @@
  * PosixFileAttributeView#readAttributes readAttributes} method.
  *
  * @since 1.7
- *
- * @see Attributes#readPosixFileAttributes
  */
 
 public interface PosixFileAttributes
--- a/jdk/src/share/classes/java/nio/file/attribute/PosixFilePermission.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/PosixFilePermission.java	Fri Jan 28 09:28:43 2011 +0000
@@ -25,14 +25,12 @@
 
 package java.nio.file.attribute;
 
-import java.util.*;
-
 /**
  * Defines the bits for use with the {@link PosixFileAttributes#permissions()
  * permissions} attribute.
  *
- * <p> The {@link PosixFileAttributes} class defines method methods for
- * manipulating {@link Set sets} of permissions.
+ * <p> The {@link PosixFilePermissions} class defines methods for manipulating
+ * set of permissions.
  *
  * @since 1.7
  */
--- a/jdk/src/share/classes/java/nio/file/attribute/PosixFilePermissions.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/PosixFilePermissions.java	Fri Jan 28 09:28:43 2011 +0000
@@ -126,7 +126,7 @@
     public static Set<PosixFilePermission> fromString(String perms) {
         if (perms.length() != 9)
             throw new IllegalArgumentException("Invalid mode");
-        Set<PosixFilePermission> result = new HashSet<PosixFilePermission>();
+        Set<PosixFilePermission> result = EnumSet.noneOf(PosixFilePermission.class);
         if (isR(perms.charAt(0))) result.add(OWNER_READ);
         if (isW(perms.charAt(1))) result.add(OWNER_WRITE);
         if (isX(perms.charAt(2))) result.add(OWNER_EXECUTE);
@@ -141,8 +141,8 @@
 
     /**
      * Creates a {@link FileAttribute}, encapsulating a copy of the given file
-     * permissions, suitable for passing to the {@link java.nio.file.Path#createFile
-     * createFile} or {@link java.nio.file.Path#createDirectory createDirectory}
+     * permissions, suitable for passing to the {@link java.nio.file.Files#createFile
+     * createFile} or {@link java.nio.file.Files#createDirectory createDirectory}
      * methods.
      *
      * @param   perms
--- a/jdk/src/share/classes/java/nio/file/attribute/UserDefinedFileAttributeView.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/UserDefinedFileAttributeView.java	Fri Jan 28 09:28:43 2011 +0000
@@ -59,9 +59,9 @@
  * attributes.
  *
  * <p> Where dynamic access to file attributes is required, the {@link
- * java.nio.file.FileRef#getAttribute getAttribute} method may be used to read
+ * java.nio.file.Files#getAttribute getAttribute} method may be used to read
  * the attribute value. The attribute value is returned as a byte array (byte[]).
- * The {@link java.nio.file.FileRef#setAttribute setAttribute} method may be used
+ * The {@link java.nio.file.Files#setAttribute setAttribute} method may be used
  * to write the value of a user-defined attribute from a buffer (as if by
  * invoking the {@link #write write} method), or byte array (byte[]).
  *
@@ -132,8 +132,8 @@
      * Suppose we want to read a file's MIME type that is stored as a user-defined
      * attribute with the name "{@code user.mimetype}".
      * <pre>
-     *    UserDefinedFileAttributeView view = file
-     *        .getFileAttributeView(UserDefinedFileAttributeView.class);
+     *    UserDefinedFileAttributeView view =
+     *        Files.getFileAttributeView(path, UserDefinedFileAttributeView.class);
      *    String name = "user.mimetype";
      *    ByteBuffer buf = ByteBuffer.allocate(view.size(name));
      *    view.read(name, buf);
@@ -189,8 +189,8 @@
      * <p> <b>Usage Example:</b>
      * Suppose we want to write a file's MIME type as a user-defined attribute:
      * <pre>
-     *    UserDefinedFileAttributeView view = file
-     *        .getFileAttributeView(UserDefinedFileAttributeView.class);
+     *    UserDefinedFileAttributeView view =
+     *        FIles.getFileAttributeView(path, UserDefinedFileAttributeView.class);
      *    view.write("user.mimetype", Charset.defaultCharset().encode("text/html"));
      * </pre>
      *
--- a/jdk/src/share/classes/java/nio/file/attribute/package-info.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/attribute/package-info.java	Fri Jan 28 09:28:43 2011 +0000
@@ -46,8 +46,6 @@
  *     <td>Can read or update user-defined file attributes</td></tr>
  * <tr><td valign=top><tt>&nbsp;&nbsp;<i>{@link java.nio.file.attribute.FileStoreAttributeView}</i></tt></td>
  *     <td>Can read or update file system attributes</td></tr>
- * <tr><td valign=top><tt>&nbsp;&nbsp;&nbsp;&nbsp;<i>{@link java.nio.file.attribute.FileStoreSpaceAttributeView}&nbsp;&nbsp;</i></tt></td>
- *     <td>Can read file system <em>space usage</em> related attributes</td></tr>
  * </table></blockquote>
  *
  * <p> An attribute view provides a read-only or updatable view of the non-opaque
@@ -55,7 +53,7 @@
  * The {@link java.nio.file.attribute.FileAttributeView} interface is
  * extended by several other interfaces that that views to specific sets of file
  * attributes. {@code FileAttributeViews} are selected by invoking the {@link
- * java.nio.file.FileRef#getFileAttributeView} method with a
+ * java.nio.file.Files#getFileAttributeView} method with a
  * <em>type-token</em> to identify the required view. Views can also be identified
  * by name. The {@link java.nio.file.attribute.FileStoreAttributeView} interface
  * provides access to file store attributes. A {@code FileStoreAttributeView} of
@@ -83,13 +81,6 @@
  * on the model defined by <a href="http://www.ietf.org/rfc/rfc3530.txt">
  * <i>RFC&nbsp;3530: Network File System (NFS) version 4 Protocol</i></a>.
  *
- * <p> The {@link java.nio.file.attribute.FileStoreSpaceAttributeView} class
- * defines methods to read file system space usage related attributes of a file system.
- *
- * <p> The {@link java.nio.file.attribute.Attributes} utility class defines
- * static methods to access file or file system attribute using the above
- * attribute views.
- *
  * <p> In addition to attribute views, this package also defines classes and
  * interfaces that are used when accessing attributes:
  *
--- a/jdk/src/share/classes/java/nio/file/package-info.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/package-info.java	Fri Jan 28 09:28:43 2011 +0000
@@ -31,7 +31,7 @@
  * systems. The API to access file and file system attributes is defined in the
  * {@link java.nio.file.attribute} package. The {@link java.nio.file.spi}
  * package is used by service provider implementors wishing to extend the
- * platform default provider, or to construct other provider implementations.
+ * platform default provider, or to construct other provider implementations. </p>
  *
  * <a name="links"><h3>Symbolic Links</h3></a>
  * Many operating systems and file systems support for <em>symbolic links</em>.
@@ -43,7 +43,7 @@
  * target of the link. This package includes support for symbolic links where
  * implementations provide these semantics. File systems may support other types
  * that are semantically close but support for these other types of links is
- * not included in this package.
+ * not included in this package. </p>
  *
  * <a name="interop"><h3>Interoperability</h3></a>
  * The {@link java.io.File} class defines the {@link java.io.File#toPath
@@ -52,7 +52,7 @@
  * {@code Path} can be used to operate on the same file as the {@code File}
  * object. The {@code Path} specification provides further information
  * on the <a href="Path.html#interop">interoperability</a> between {@code Path}
- * and {@code java.io.File} objects.
+ * and {@code java.io.File} objects. </p>
  *
  * <h3>Visibility</h3>
  * The view of the files and file system provided by classes in this package are
@@ -63,7 +63,7 @@
  * network-filesystem protocols. This is true regardless of the language in which
  * these other programs are written, and whether they are running on the same machine
  * or on some other machine.  The exact nature of any such inconsistencies are
- * system-dependent and are therefore unspecified.
+ * system-dependent and are therefore unspecified. </p>
  *
  * <a name="integrity"><h3>Synchronized I/O File Integrity</h3></a>
  * The {@link java.nio.file.StandardOpenOption#SYNC SYNC} and {@link
@@ -80,14 +80,14 @@
  * crash. If the file does not reside on a local device then no such guarantee
  * is made. Whether this guarantee is possible with other {@link
  * java.nio.file.spi.FileSystemProvider provider} implementations is provider
- * specific.
+ * specific. </p>
  *
  * <h3>General Exceptions</h3>
  * Unless otherwise noted, passing a {@code null} argument to a constructor
  * or method of any class or interface in this package will cause a {@link
  * java.lang.NullPointerException NullPointerException} to be thrown. Additionally,
  * invoking a method with a collection containing a {@code null} element will
- * cause a {@code NullPointerException}, unless otherwise specified.
+ * cause a {@code NullPointerException}, unless otherwise specified. </p>
  *
  * <p> Unless otherwise noted, methods that attempt to access the file system
  * will throw {@link java.nio.file.ClosedFileSystemException} when invoked on
@@ -95,12 +95,13 @@
  * {@link java.nio.file.FileSystem#close closed}. Additionally, any methods
  * that attempt write access to a file system will throw {@link
  * java.nio.file.ReadOnlyFileSystemException} when invoked on an object associated
- * with a {@link java.nio.file.FileSystem} that only provides read-only access.
+ * with a {@link java.nio.file.FileSystem} that only provides read-only
+ * access. </p>
  *
  * <p> Unless otherwise noted, invoking a method of any class or interface in
  * this package created by one {@link java.nio.file.spi.FileSystemProvider
  * provider} with a parameter that is an object created by another provider,
- * will throw {@link java.nio.file.ProviderMismatchException}.
+ * will throw {@link java.nio.file.ProviderMismatchException}. </p>
  *
  * <h3>Optional Specific Exceptions</h3>
  * Most of the methods defined by classes in this package that access the
--- a/jdk/src/share/classes/java/nio/file/spi/FileSystemProvider.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/spi/FileSystemProvider.java	Fri Jan 28 09:28:43 2011 +0000
@@ -26,17 +26,21 @@
 package java.nio.file.spi;
 
 import java.nio.file.*;
-import java.nio.file.attribute.FileAttribute;
+import java.nio.file.attribute.*;
 import java.nio.channels.*;
 import java.net.URI;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.IOException;
 import java.util.*;
 import java.util.concurrent.ExecutorService;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
-import java.io.IOException;
 
 /**
- * Service-provider class for file systems.
+ * Service-provider class for file systems. The methods defined by the {@link
+ * java.nio.file.Files} class will typically delegate to an instance of this
+ * class.
  *
  * <p> A file system provider is a concrete implementation of this class that
  * implements the abstract methods defined by this class. A provider is
@@ -64,13 +68,6 @@
  * the {@code newFileSystem} method is invoked. In the case of the default
  * provider, the {@code FileSystem} is created when the provider is initialized.
  *
- * <p> In addition to file systems, a provider is also a factory for {@link
- * FileChannel} and {@link AsynchronousFileChannel} channels. The {@link
- * #newFileChannel newFileChannel} and {@link #newAsynchronousFileChannel
- * AsynchronousFileChannel} methods are defined to open or create files, returning
- * a channel to access the file. These methods are invoked by static factory
- * methods defined in the {@link java.nio.channels} package.
- *
  * <p> All of the methods in this class are safe for use by multiple concurrent
  * threads.
  *
@@ -202,9 +199,10 @@
      *
      * <p> This method throws {@link FileSystemAlreadyExistsException} if the
      * file system already exists because it was previously created by an
-     * invocation of this method. Once a file system is {@link FileSystem#close
-     * closed} it is provider-dependent if the provider allows a new file system
-     * to be created with the same URI as a file system it previously created.
+     * invocation of this method. Once a file system is {@link
+     * java.nio.file.FileSystem#close closed} it is provider-dependent if the
+     * provider allows a new file system to be created with the same URI as a
+     * file system it previously created.
      *
      * @param   uri
      *          URI reference
@@ -234,20 +232,21 @@
      *
      * <p> This method returns a reference to a {@code FileSystem} that was
      * created by invoking the {@link #newFileSystem(URI,Map) newFileSystem(URI,Map)}
-     * method. File systems created the {@link #newFileSystem(FileRef,Map)
-     * newFileSystem(FileRef,Map)} method are not returned by this method.
+     * method. File systems created the {@link #newFileSystem(Path,Map)
+     * newFileSystem(Path,Map)} method are not returned by this method.
      * The file system is identified by its {@code URI}. Its exact form
      * is highly provider dependent. In the case of the default provider the URI's
      * path component is {@code "/"} and the authority, query and fragment components
      * are undefined (Undefined components are represented by {@code null}).
      *
-     * <p> Once a file system created by this provider is {@link FileSystem#close
-     * closed} it is provider-dependent if this method returns a reference to
-     * the closed file system or throws {@link FileSystemNotFoundException}.
-     * If the provider allows a new file system to be created with the same URI
-     * as a file system it previously created then this method throws the
-     * exception if invoked after the file system is closed (and before a new
-     * instance is created by the {@link #newFileSystem newFileSystem} method).
+     * <p> Once a file system created by this provider is {@link
+     * java.nio.file.FileSystem#close closed} it is provider-dependent if this
+     * method returns a reference to the closed file system or throws {@link
+     * FileSystemNotFoundException}. If the provider allows a new file system to
+     * be created with the same URI as a file system it previously created then
+     * this method throws the exception if invoked after the file system is
+     * closed (and before a new instance is created by the {@link #newFileSystem
+     * newFileSystem} method).
      *
      * <p> If a security manager is installed then a provider implementation
      * may require to check a permission before returning a reference to an
@@ -306,17 +305,16 @@
      *
      * <p> This method is intended for specialized providers of pseudo file
      * systems where the contents of one or more files is treated as a file
-     * system. The {@code file} parameter is a reference to an existing file
-     * and the {@code env} parameter is a map of provider specific properties to
-     * configure the file system.
+     * system. The {@code env} parameter is a map of provider specific properties
+     * to configure the file system.
      *
      * <p> If this provider does not support the creation of such file systems
      * or if the provider does not recognize the file type of the given file then
      * it throws {@code UnsupportedOperationException}. The default implementation
      * of this method throws {@code UnsupportedOperationException}.
      *
-     * @param   file
-     *          The file
+     * @param   path
+     *          The path to the file
      * @param   env
      *          A map of provider specific properties to configure the file system;
      *          may be empty
@@ -336,32 +334,121 @@
      *          If a security manager is installed and it denies an unspecified
      *          permission.
      */
-    public FileSystem newFileSystem(FileRef file, Map<String,?> env)
+    public FileSystem newFileSystem(Path path, Map<String,?> env)
         throws IOException
     {
         throw new UnsupportedOperationException();
     }
 
     /**
-     * Opens or creates a file for reading and/or writing, returning a file
-     * channel to access the file.
+     * Opens a file, returning an input stream to read from the file. This
+     * method works in exactly the manner specified by the {@link
+     * Files#newInputStream} method.
+     *
+     * <p> The default implementation of this method opens a channel to the file
+     * as if by invoking the {@link #newByteChannel} method and constructs a
+     * stream that reads bytes from the channel. This method should be overridden
+     * where appropriate.
+     *
+     * @param   path
+     *          the path to the file to open
+     * @param   options
+     *          options specifying how the file is opened
+     *
+     * @return  a new input stream
      *
-     * <p> This method is invoked by the {@link FileChannel#open(Path,Set,FileAttribute[])
-     * FileChannel.open} method to open a file channel. A provider that does not
-     * support all the features required to construct a file channel throws
-     * {@code UnsupportedOperationException}. The default provider is required
-     * to support the creation of file channels. When not overridden, the
-     * default implementation throws {@code UnsupportedOperationException}.
+     * @throws  IllegalArgumentException
+     *          if an invalid combination of options is specified
+     * @throws  UnsupportedOperationException
+     *          if an unsupported option is specified
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the file.
+     */
+    public InputStream newInputStream(Path path, OpenOption... options)
+        throws IOException
+    {
+        if (options.length > 0) {
+            for (OpenOption opt: options) {
+                if (opt != StandardOpenOption.READ)
+                    throw new UnsupportedOperationException("'" + opt + "' not allowed");
+            }
+        }
+        return Channels.newInputStream(Files.newByteChannel(path));
+    }
+
+    /**
+     * Opens or creates a file, returning an output stream that may be used to
+     * write bytes to the file. This method works in exactly the manner
+     * specified by the {@link Files#newOutputStream} method.
+     *
+     * <p> The default implementation of this method opens a channel to the file
+     * as if by invoking the {@link #newByteChannel} method and constructs a
+     * stream that writes bytes to the channel. This method should be overridden
+     * where appropriate.
      *
      * @param   path
-     *          The path of the file to open or create
+     *          the path to the file to open or create
      * @param   options
-     *          Options specifying how the file is opened
+     *          options specifying how the file is opened
+     *
+     * @return  a new output stream
+     *
+     * @throws  IllegalArgumentException
+     *          if {@code options} contains an invalid combination of options
+     * @throws  UnsupportedOperationException
+     *          if an unsupported option is specified
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method is invoked to check write access to the file. The {@link
+     *          SecurityManager#checkDelete(String) checkDelete} method is
+     *          invoked to check delete access if the file is opened with the
+     *          {@code DELETE_ON_CLOSE} option.
+     */
+    public OutputStream newOutputStream(Path path, OpenOption... options)
+        throws IOException
+    {
+        int len = options.length;
+        Set<OpenOption> opts = new HashSet<OpenOption>(len + 3);
+        if (len == 0) {
+            opts.add(StandardOpenOption.CREATE);
+            opts.add(StandardOpenOption.TRUNCATE_EXISTING);
+        } else {
+            for (OpenOption opt: options) {
+                if (opt == StandardOpenOption.READ)
+                    throw new IllegalArgumentException("READ not allowed");
+                opts.add(opt);
+            }
+        }
+        opts.add(StandardOpenOption.WRITE);
+        return Channels.newOutputStream(newByteChannel(path, opts));
+    }
+
+    /**
+     * Opens or creates a file for reading and/or writing, returning a file
+     * channel to access the file. This method works in exactly the manner
+     * specified by the {@link FileChannel#open(Path,Set,FileAttribute[])
+     * FileChannel.open} method. A provider that does not support all the
+     * features required to construct a file channel throws {@code
+     * UnsupportedOperationException}. The default provider is required to
+     * support the creation of file channels. When not overridden, the default
+     * implementation throws {@code UnsupportedOperationException}.
+     *
+     * @param   path
+     *          the path of the file to open or create
+     * @param   options
+     *          options specifying how the file is opened
      * @param   attrs
-     *          An optional list of file attributes to set atomically when
+     *          an optional list of file attributes to set atomically when
      *          creating the file
      *
-     * @return  A new file channel
+     * @return  a new file channel
      *
      * @throws  IllegalArgumentException
      *          If the set contains an invalid combination of options
@@ -387,11 +474,10 @@
 
     /**
      * Opens or creates a file for reading and/or writing, returning an
-     * asynchronous file channel to access the file.
-     *
-     * <p> This method is invoked by the {@link
+     * asynchronous file channel to access the file. This method works in
+     * exactly the manner specified by the {@link
      * AsynchronousFileChannel#open(Path,Set,ExecutorService,FileAttribute[])
-     * AsynchronousFileChannel.open} method to open an asynchronous file channel.
+     * AsynchronousFileChannel.open} method.
      * A provider that does not support all the features required to construct
      * an asynchronous file channel throws {@code UnsupportedOperationException}.
      * The default provider is required to support the creation of asynchronous
@@ -399,17 +485,17 @@
      * method throws {@code UnsupportedOperationException}.
      *
      * @param   path
-     *          The path of the file to open or create
+     *          the path of the file to open or create
      * @param   options
-     *          Options specifying how the file is opened
+     *          options specifying how the file is opened
      * @param   executor
-     *          The thread pool or {@code null} to associate the channel with
+     *          the thread pool or {@code null} to associate the channel with
      *          the default thread pool
      * @param   attrs
-     *          An optional list of file attributes to set atomically when
+     *          an optional list of file attributes to set atomically when
      *          creating the file
      *
-     * @return  A new asynchronous file channel
+     * @return  a new asynchronous file channel
      *
      * @throws  IllegalArgumentException
      *          If the set contains an invalid combination of options
@@ -434,4 +520,569 @@
     {
         throw new UnsupportedOperationException();
     }
+
+    /**
+     * Opens or creates a file, returning a seekable byte channel to access the
+     * file. This method works in exactly the manner specified by the {@link
+     * Files#newByteChannel(Path,Set,FileAttribute[])} method.
+     *
+     * @param   path
+     *          the path to the file to open or create
+     * @param   options
+     *          options specifying how the file is opened
+     * @param   attrs
+     *          an optional list of file attributes to set atomically when
+     *          creating the file
+     *
+     * @return  a new seekable byte channel
+     *
+     * @throws  IllegalArgumentException
+     *          if the set contains an invalid combination of options
+     * @throws  UnsupportedOperationException
+     *          if an unsupported open option is specified or the array contains
+     *          attributes that cannot be set atomically when creating the file
+     * @throws  FileAlreadyExistsException
+     *          if a file of that name already exists and the {@link
+     *          StandardOpenOption#CREATE_NEW CREATE_NEW} option is specified
+     *          <i>(optional specific exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the path if the file is
+     *          opened for reading. The {@link SecurityManager#checkWrite(String)
+     *          checkWrite} method is invoked to check write access to the path
+     *          if the file is opened for writing. The {@link
+     *          SecurityManager#checkDelete(String) checkDelete} method is
+     *          invoked to check delete access if the file is opened with the
+     *          {@code DELETE_ON_CLOSE} option.
+     */
+    public abstract SeekableByteChannel newByteChannel(Path path,
+        Set<? extends OpenOption> options, FileAttribute<?>... attrs) throws IOException;
+
+    /**
+     * Opens a directory, returning a {@code DirectoryStream} to iterate over
+     * the entries in the directory. This method works in exactly the manner
+     * specified by the {@link
+     * Files#newDirectoryStream(java.nio.file.Path, java.nio.file.DirectoryStream.Filter)}
+     * method.
+     *
+     * @param   dir
+     *          the path to the directory
+     * @param   filter
+     *          the directory stream filter
+     *
+     * @return  a new and open {@code DirectoryStream} object
+     *
+     * @throws  NotDirectoryException
+     *          if the file could not otherwise be opened because it is not
+     *          a directory <i>(optional specific exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the directory.
+     */
+    public abstract DirectoryStream<Path> newDirectoryStream(Path dir,
+         DirectoryStream.Filter<? super Path> filter) throws IOException;
+
+    /**
+     * Creates a new directory. This method works in exactly the manner
+     * specified by the {@link Files#createDirectory} method.
+     *
+     * @param   dir
+     *          the directory to create
+     * @param   attrs
+     *          an optional list of file attributes to set atomically when
+     *          creating the directory
+     *
+     * @throws  UnsupportedOperationException
+     *          if the array contains an attribute that cannot be set atomically
+     *          when creating the directory
+     * @throws  FileAlreadyExistsException
+     *          if a directory could not otherwise be created because a file of
+     *          that name already exists <i>(optional specific exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs or the parent directory does not exist
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method is invoked to check write access to the new directory.
+     */
+    public abstract void createDirectory(Path dir, FileAttribute<?>... attrs)
+        throws IOException;
+
+    /**
+     * Creates a symbolic link to a target. This method works in exactly the
+     * manner specified by the {@link Files#createSymbolicLink} method.
+     *
+     * <p> The default implementation of this method throws {@code
+     * UnsupportedOperationException}.
+     *
+     * @param   link
+     *          the path of the symbolic link to create
+     * @param   target
+     *          the target of the symbolic link
+     * @param   attrs
+     *          the array of attributes to set atomically when creating the
+     *          symbolic link
+     *
+     * @throws  UnsupportedOperationException
+     *          if the implementation does not support symbolic links or the
+     *          array contains an attribute that cannot be set atomically when
+     *          creating the symbolic link
+     * @throws  FileAlreadyExistsException
+     *          if a file with the name already exists <i>(optional specific
+     *          exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager
+     *          is installed, it denies {@link LinkPermission}<tt>("symbolic")</tt>
+     *          or its {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method denies write access to the path of the symbolic link.
+     */
+    public void createSymbolicLink(Path link, Path target, FileAttribute<?>... attrs)
+        throws IOException
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Creates a new link (directory entry) for an existing file. This method
+     * works in exactly the manner specified by the {@link Files#createLink}
+     * method.
+     *
+     * <p> The default implementation of this method throws {@code
+     * UnsupportedOperationException}.
+     *
+     * @param   link
+     *          the link (directory entry) to create
+     * @param   existing
+     *          a path to an existing file
+     *
+     * @throws  UnsupportedOperationException
+     *          if the implementation does not support adding an existing file
+     *          to a directory
+     * @throws  FileAlreadyExistsException
+     *          if the entry could not otherwise be created because a file of
+     *          that name already exists <i>(optional specific exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager
+     *          is installed, it denies {@link LinkPermission}<tt>("hard")</tt>
+     *          or its {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method denies write access to either the  link or the
+     *          existing file.
+     */
+    public void createLink(Path link, Path existing) throws IOException {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Deletes a file. This method works in exactly the  manner specified by the
+     * {@link Files#delete} method.
+     *
+     * @param   path
+     *          the path to the file to delete
+     *
+     * @throws  NoSuchFileException
+     *          if the file does not exist <i>(optional specific exception)</i>
+     * @throws  DirectoryNotEmptyException
+     *          if the file is a directory and could not otherwise be deleted
+     *          because the directory is not empty <i>(optional specific
+     *          exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkDelete(String)} method
+     *          is invoked to check delete access to the file
+     */
+    public abstract void delete(Path path) throws IOException;
+
+    /**
+     * Deletes a file if it exists. This method works in exactly the manner
+     * specified by the {@link Files#deleteIfExists} method.
+     *
+     * <p> The default implementation of this method simply invokes {@link
+     * #delete} ignoring the {@code NoSuchFileException} when the file does not
+     * exist. It may be overridden where appropriate.
+     *
+     * @param   path
+     *          the path to the file to delete
+     *
+     * @return  {@code true} if the file was deleted by this method; {@code
+     *          false} if the file could not be deleted because it did not
+     *          exist
+     *
+     * @throws  DirectoryNotEmptyException
+     *          if the file is a directory and could not otherwise be deleted
+     *          because the directory is not empty <i>(optional specific
+     *          exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkDelete(String)} method
+     *          is invoked to check delete access to the file
+     */
+    public boolean deleteIfExists(Path path) throws IOException {
+        try {
+            delete(path);
+            return true;
+        } catch (NoSuchFileException ignore) {
+            return false;
+        }
+    }
+
+    /**
+     * Reads the target of a symbolic link. This method works in exactly the
+     * manner specified by the {@link Files#readSymbolicLink} method.
+     *
+     * <p> The default implementation of this method throws {@code
+     * UnsupportedOperationException}.
+     *
+     * @param   link
+     *          the path to the symbolic link
+     *
+     * @throws  UnsupportedOperationException
+     *          if the implementation does not support symbolic links
+     * @throws  NotLinkException
+     *          if the target could otherwise not be read because the file
+     *          is not a symbolic link <i>(optional specific exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager
+     *          is installed, it checks that {@code FilePermission} has been
+     *          granted with the "{@code readlink}" action to read the link.
+     */
+    public Path readSymbolicLink(Path link) throws IOException {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Copy a file to a target file. This method works in exactly the manner
+     * specified by the {@link Files#copy(Path,Path,CopyOption[])} method
+     * except that both the source and target paths must be associated with
+     * this provider.
+     *
+     * @param   source
+     *          the path to the file to copy
+     * @param   target
+     *          the path to the target file
+     * @param   options
+     *          options specifying how the copy should be done
+     *
+     * @throws  UnsupportedOperationException
+     *          if the array contains a copy option that is not supported
+     * @throws  FileAlreadyExistsException
+     *          if the target file exists but cannot be replaced because the
+     *          {@code REPLACE_EXISTING} option is not specified <i>(optional
+     *          specific exception)</i>
+     * @throws  DirectoryNotEmptyException
+     *          the {@code REPLACE_EXISTING} option is specified but the file
+     *          cannot be replaced because it is a non-empty directory
+     *          <i>(optional specific exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the source file, the
+     *          {@link SecurityManager#checkWrite(String) checkWrite} is invoked
+     *          to check write access to the target file. If a symbolic link is
+     *          copied the security manager is invoked to check {@link
+     *          LinkPermission}{@code ("symbolic")}.
+     */
+    public abstract void copy(Path source, Path target, CopyOption... options)
+        throws IOException;
+
+    /**
+     * Move or rename a file to a target file. This method works in exactly the
+     * manner specified by the {@link Files#move} method except that both the
+     * source and target paths must be associated with this provider.
+     *
+     * @param   source
+     *          the path to the file to move
+     * @param   target
+     *          the path to the target file
+     * @param   options
+     *          options specifying how the move should be done
+     *
+     * @throws  UnsupportedOperationException
+     *          if the array contains a copy option that is not supported
+     * @throws  FileAlreadyExistsException
+     *          if the target file exists but cannot be replaced because the
+     *          {@code REPLACE_EXISTING} option is not specified <i>(optional
+     *          specific exception)</i>
+     * @throws  DirectoryNotEmptyException
+     *          the {@code REPLACE_EXISTING} option is specified but the file
+     *          cannot be replaced because it is a non-empty directory
+     *          <i>(optional specific exception)</i>
+     * @throws  AtomicMoveNotSupportedException
+     *          if the options array contains the {@code ATOMIC_MOVE} option but
+     *          the file cannot be moved as an atomic file system operation.
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method is invoked to check write access to both the source and
+     *          target file.
+     */
+    public abstract void move(Path source, Path target, CopyOption... options)
+        throws IOException;
+
+    /**
+     * Tests if two paths locate the same file. This method works in exactly the
+     * manner specified by the {@link Files#isSameFile} method.
+     *
+     * @param   path
+     *          one path to the file
+     * @param   path2
+     *          the other path
+     *
+     * @return  {@code true} if, and only if, the two paths locate the same file
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to both files.
+     */
+    public abstract boolean isSameFile(Path path, Path path2)
+        throws IOException;
+
+    /**
+     * Tells whether or not a file is considered <em>hidden</em>. This method
+     * works in exactly the manner specified by the {@link Files#isHidden}
+     * method.
+     *
+     * <p> This method is invoked by the {@link Files#isHidden isHidden} method.
+     *
+     * @param   path
+     *          the path to the file to test
+     *
+     * @return  {@code true} if the file is considered hidden
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the file.
+     */
+    public abstract boolean isHidden(Path path) throws IOException;
+
+    /**
+     * Returns the {@link FileStore} representing the file store where a file
+     * is located. This method works in exactly the manner specified by the
+     * {@link Files#getFileStore} method.
+     *
+     * @param   path
+     *          the path to the file
+     *
+     * @return  the file store where the file is stored
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the file, and in
+     *          addition it checks {@link RuntimePermission}<tt>
+     *          ("getFileStoreAttributes")</tt>
+     */
+    public abstract FileStore getFileStore(Path path) throws IOException;
+
+    /**
+     * Checks the existence, and optionally the accessibility, of a file.
+     *
+     * <p> This method may be used by the {@link Files#isReadable isReadable},
+     * {@link Files#isWritable isWritable} and {@link Files#isExecutable
+     * isExecutable} methods to check the accessibility of a file.
+     *
+     * <p> This method checks the existence of a file and that this Java virtual
+     * machine has appropriate privileges that would allow it access the file
+     * according to all of access modes specified in the {@code modes} parameter
+     * as follows:
+     *
+     * <table border=1 cellpadding=5 summary="">
+     * <tr> <th>Value</th> <th>Description</th> </tr>
+     * <tr>
+     *   <td> {@link AccessMode#READ READ} </td>
+     *   <td> Checks that the file exists and that the Java virtual machine has
+     *     permission to read the file. </td>
+     * </tr>
+     * <tr>
+     *   <td> {@link AccessMode#WRITE WRITE} </td>
+     *   <td> Checks that the file exists and that the Java virtual machine has
+     *     permission to write to the file, </td>
+     * </tr>
+     * <tr>
+     *   <td> {@link AccessMode#EXECUTE EXECUTE} </td>
+     *   <td> Checks that the file exists and that the Java virtual machine has
+     *     permission to {@link Runtime#exec execute} the file. The semantics
+     *     may differ when checking access to a directory. For example, on UNIX
+     *     systems, checking for {@code EXECUTE} access checks that the Java
+     *     virtual machine has permission to search the directory in order to
+     *     access file or subdirectories. </td>
+     * </tr>
+     * </table>
+     *
+     * <p> If the {@code modes} parameter is of length zero, then the existence
+     * of the file is checked.
+     *
+     * <p> This method follows symbolic links if the file referenced by this
+     * object is a symbolic link. Depending on the implementation, this method
+     * may require to read file permissions, access control lists, or other
+     * file attributes in order to check the effective access to the file. To
+     * determine the effective access to a file may require access to several
+     * attributes and so in some implementations this method may not be atomic
+     * with respect to other file system operations.
+     *
+     * @param   path
+     *          the path to the file to check
+     * @param   modes
+     *          The access modes to check; may have zero elements
+     *
+     * @throws  UnsupportedOperationException
+     *          an implementation is required to support checking for
+     *          {@code READ}, {@code WRITE}, and {@code EXECUTE} access. This
+     *          exception is specified to allow for the {@code Access} enum to
+     *          be extended in future releases.
+     * @throws  NoSuchFileException
+     *          if a file does not exist <i>(optional specific exception)</i>
+     * @throws  AccessDeniedException
+     *          the requested access would be denied or the access cannot be
+     *          determined because the Java virtual machine has insufficient
+     *          privileges or other reasons. <i>(optional specific exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          is invoked when checking read access to the file or only the
+     *          existence of the file, the {@link SecurityManager#checkWrite(String)
+     *          checkWrite} is invoked when checking write access to the file,
+     *          and {@link SecurityManager#checkExec(String) checkExec} is invoked
+     *          when checking execute access.
+     */
+    public abstract void checkAccess(Path path, AccessMode... modes)
+        throws IOException;
+
+    /**
+     * Returns a file attribute view of a given type. This method works in
+     * exactly the manner specified by the {@link Files#getFileAttributeView}
+     * method.
+     *
+     * @param   path
+     *          the path to the file
+     * @param   type
+     *          the {@code Class} object corresponding to the file attribute view
+     * @param   options
+     *          options indicating how symbolic links are handled
+     *
+     * @return  a file attribute view of the specified type, or {@code null} if
+     *          the attribute view type is not available
+     */
+    public abstract <V extends FileAttributeView> V
+        getFileAttributeView(Path path, Class<V> type, LinkOption... options);
+
+    /**
+     * Reads a file's attributes as a bulk operation. This method works in
+     * exactly the manner specified by the {@link
+     * Files#readAttributes(Path,Class,LinkOption[])} method.
+     *
+     * @param   path
+     *          the path to the file
+     * @param   type
+     *          the {@code Class} of the file attributes required
+     *          to read
+     * @param   options
+     *          options indicating how symbolic links are handled
+     *
+     * @return  the file attributes
+     *
+     * @throws  UnsupportedOperationException
+     *          if an attributes of the given type are not supported
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, a security manager is
+     *          installed, its {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the file
+     */
+    public abstract <A extends BasicFileAttributes> A
+        readAttributes(Path path, Class<A> type, LinkOption... options) throws IOException;
+
+    /**
+     * Reads a set of file attributes as a bulk operation. This method works in
+     * exactly the manner specified by the {@link
+     * Files#readAttributes(Path,String,LinkOption[])} method.
+     *
+     * @param   path
+     *          the path to the file
+     * @param   attributes
+     *          the attributes to read
+     * @param   options
+     *          options indicating how symbolic links are handled
+     *
+     * @return  a map of the attributes returned; may be empty. The map's keys
+     *          are the attribute names, its values are the attribute values
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, its {@link SecurityManager#checkRead(String) checkRead}
+     *          method denies read access to the file. If this method is invoked
+     *          to read security sensitive attributes then the security manager
+     *          may be invoke to check for additional permissions.
+     */
+    public abstract Map<String,Object> readAttributes(Path path, String attributes,
+                                                      LinkOption... options)
+        throws IOException;
+
+    /**
+     * Sets the value of a file attribute. This method works in exactly the
+     * manner specified by the {@link Files#setAttribute} method.
+     *
+     * @param   path
+     *          the path to the file
+     * @param   attribute
+     *          the attribute to set
+     * @param   value
+     *          the attribute value
+     * @param   options
+     *          options indicating how symbolic links are handled
+     *
+     * @throws  UnsupportedOperationException
+     *          if the attribute view is not available or it does not support
+     *          updating the attribute
+     * @throws  IllegalArgumentException
+     *          if the attribute value is of the correct type but has an
+     *          inappropriate value
+     * @throws  ClassCastException
+     *          If the attribute value is not of the expected type or is a
+     *          collection containing elements that are not of the expected
+     *          type
+     * @throws  IOException
+     *          If an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, its {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method denies write access to the file. If this method is invoked
+     *          to set security sensitive attributes then the security manager
+     *          may be invoked to check for additional permissions.
+     */
+    public abstract void setAttribute(Path path, String attribute,
+                                      Object value, LinkOption... options)
+        throws IOException;
 }
--- a/jdk/src/share/classes/java/nio/file/spi/FileTypeDetector.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/nio/file/spi/FileTypeDetector.java	Fri Jan 28 09:28:43 2011 +0000
@@ -25,7 +25,7 @@
 
 package java.nio.file.spi;
 
-import java.nio.file.FileRef;
+import java.nio.file.Path;
 import java.io.IOException;
 
 /**
@@ -42,7 +42,7 @@
  * href="../attribute/package-summary.html"> attribute</a> or the bytes in a
  * file may be examined to guess its file type.
  *
- * @see java.nio.file.Files#probeContentType(FileRef)
+ * @see java.nio.file.Files#probeContentType(Path)
  *
  * @since 1.7
  */
@@ -83,8 +83,8 @@
      * Message Bodies</i></a>. The string must be parsable according to the
      * grammar in the RFC 2045.
      *
-     * @param   file
-     *          The file to probe
+     * @param   path
+     *          the path to the file to probe
      *
      * @return  The content type or {@code null} if the file type is not
      *          recognized
@@ -101,6 +101,6 @@
      *
      * @see java.nio.file.Files#probeContentType
      */
-    public abstract String probeContentType(FileRef file)
+    public abstract String probeContentType(Path path)
         throws IOException;
 }
--- a/jdk/src/share/classes/java/util/Scanner.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/java/util/Scanner.java	Fri Jan 28 09:28:43 2011 +0000
@@ -25,7 +25,8 @@
 
 package java.util;
 
-import java.nio.file.FileRef;
+import java.nio.file.Path;
+import java.nio.file.Files;
 import java.util.regex.*;
 import java.io.*;
 import java.math.*;
@@ -699,16 +700,16 @@
      * {@linkplain java.nio.charset.Charset#defaultCharset() default charset}.
      *
      * @param   source
-     *          A file to be scanned
+     *          the path to the file to be scanned
      * @throws  IOException
      *          if an I/O error occurs opening source
      *
      * @since   1.7
      */
-    public Scanner(FileRef source)
+    public Scanner(Path source)
         throws IOException
     {
-        this(source.newInputStream());
+        this(Files.newInputStream(source));
     }
 
     /**
@@ -717,7 +718,7 @@
      * characters using the specified charset.
      *
      * @param   source
-     *          A file to be scanned
+     *          the path to the file to be scanned
      * @param   charsetName
      *          The encoding type used to convert bytes from the file
      *          into characters to be scanned
@@ -727,12 +728,12 @@
      *          if the specified encoding is not found
      * @since   1.7
      */
-    public Scanner(FileRef source, String charsetName) throws IOException {
+    public Scanner(Path source, String charsetName) throws IOException {
         this(Objects.nonNull(source), toCharset(charsetName));
     }
 
-    private Scanner(FileRef source, Charset charset)  throws IOException {
-        this(makeReadable(source.newInputStream(), charset));
+    private Scanner(Path source, Charset charset)  throws IOException {
+        this(makeReadable(Files.newInputStream(source), charset));
     }
 
     /**
--- a/jdk/src/share/classes/sun/nio/fs/AbstractAclFileAttributeView.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/sun/nio/fs/AbstractAclFileAttributeView.java	Fri Jan 28 09:28:43 2011 +0000
@@ -45,15 +45,6 @@
     }
 
     @Override
-    public final Object getAttribute(String attribute) throws IOException {
-        if (attribute.equals(OWNER_NAME))
-            return getOwner();
-        if (attribute.equals(ACL_NAME))
-            return getAcl();
-        return null;
-    }
-
-    @Override
     @SuppressWarnings("unchecked")
     public final void setAttribute(String attribute, Object value)
         throws IOException
@@ -71,7 +62,7 @@
     }
 
     @Override
-    public final Map<String,?> readAttributes(String[] attributes)
+    public final Map<String,Object> readAttributes(String[] attributes)
         throws IOException
     {
         boolean acl = false;
@@ -91,7 +82,7 @@
                 continue;
             }
         }
-        Map<String,Object> result = new HashMap<String,Object>(2);
+        Map<String,Object> result = new HashMap<>(2);
         if (acl)
             result.put(ACL_NAME, getAcl());
         if (owner)
--- a/jdk/src/share/classes/sun/nio/fs/AbstractBasicFileAttributeView.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/sun/nio/fs/AbstractBasicFileAttributeView.java	Fri Jan 28 09:28:43 2011 +0000
@@ -54,30 +54,6 @@
     }
 
     @Override
-    public Object getAttribute(String attribute) throws IOException {
-        BasicFileAttributes attrs = readAttributes();
-        if (attribute.equals(SIZE_NAME))
-            return attrs.size();
-        if (attribute.equals(CREATION_TIME_NAME))
-            return attrs.creationTime();
-        if (attribute.equals(LAST_ACCESS_TIME_NAME))
-            return attrs.lastAccessTime();
-        if (attribute.equals(LAST_MODIFIED_TIME_NAME))
-            return attrs.lastModifiedTime();
-        if (attribute.equals(FILE_KEY_NAME))
-            return attrs.fileKey();
-        if (attribute.equals(IS_DIRECTORY_NAME))
-            return attrs.isDirectory();
-        if (attribute.equals(IS_REGULAR_FILE_NAME))
-            return attrs.isRegularFile();
-        if (attribute.equals(IS_SYMBOLIC_LINK_NAME))
-            return attrs.isSymbolicLink();
-        if (attribute.equals(IS_OTHER_NAME))
-            return attrs.isOther();
-        return null;
-    }
-
-    @Override
     public void setAttribute(String attribute, Object value)
         throws IOException
     {
@@ -101,8 +77,8 @@
      * Used to build a map of attribute name/values.
      */
     static class AttributesBuilder {
-        private Set<String> set = new HashSet<String>();
-        private Map<String,Object> map = new HashMap<String,Object>();
+        private Set<String> set = new HashSet<>();
+        private Map<String,Object> map = new HashMap<>();
         private boolean copyAll;
 
         private AttributesBuilder(String[] attributes) {
@@ -172,7 +148,7 @@
     }
 
     @Override
-    public Map<String,?> readAttributes(String[] attributes) throws IOException {
+    public Map<String,Object> readAttributes(String[] attributes) throws IOException {
         AttributesBuilder builder = AttributesBuilder.create(attributes);
         addBasicAttributesToBuilder(readAttributes(), builder);
         return builder.unmodifiableMap();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/nio/fs/AbstractFileSystemProvider.java	Fri Jan 28 09:28:43 2011 +0000
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.*;
+import java.nio.file.spi.FileSystemProvider;
+import java.io.IOException;
+import java.util.Map;
+import java.util.Collections;
+
+/**
+ * Base implementation class of FileSystemProvider
+ */
+
+abstract class AbstractFileSystemProvider extends FileSystemProvider {
+    protected AbstractFileSystemProvider() { }
+
+    /**
+     * Splits the given attribute name into the name of an attribute view and
+     * the attribute. If the attribute view is not identified then it assumed
+     * to be "basic".
+     */
+    private static String[] split(String attribute) {
+        String[] s = new String[2];
+        int pos = attribute.indexOf(':');
+        if (pos == -1) {
+            s[0] = "basic";
+            s[1] = attribute;
+        } else {
+            s[0] = attribute.substring(0, pos++);
+            s[1] = (pos == attribute.length()) ? "" : attribute.substring(pos);
+        }
+        return s;
+    }
+
+    /**
+     * Gets a DynamicFileAttributeView by name. Returns {@code null} if the
+     * view is not available.
+     */
+    abstract DynamicFileAttributeView getFileAttributeView(Path file,
+                                                           String name,
+                                                           LinkOption... options);
+
+    @Override
+    public final void setAttribute(Path file,
+                                   String attribute,
+                                   Object value,
+                                   LinkOption... options)
+        throws IOException
+    {
+        String[] s = split(attribute);
+        DynamicFileAttributeView view = getFileAttributeView(file, s[0], options);
+        if (view == null)
+            throw new UnsupportedOperationException("View '" + s[0] + "' not available");
+        view.setAttribute(s[1], value);
+    }
+
+    @Override
+    public final Map<String,Object> readAttributes(Path file, String attributes, LinkOption... options)
+        throws IOException
+    {
+        String[] s = split(attributes);
+        DynamicFileAttributeView view = getFileAttributeView(file, s[0], options);
+        if (view == null)
+            return Collections.emptyMap();
+        return view.readAttributes(s[1].split(","));
+    }
+
+    /**
+     * Deletes a file. The {@code failIfNotExists} parameters determines if an
+     * {@code IOException} is thrown when the file does not exist.
+     */
+    abstract boolean implDelete(Path file, boolean failIfNotExists) throws IOException;
+
+    @Override
+    public final void delete(Path file) throws IOException {
+        implDelete(file, true);
+    }
+
+    @Override
+    public final boolean deleteIfExists(Path file) throws IOException {
+        return implDelete(file, false);
+    }
+}
--- a/jdk/src/share/classes/sun/nio/fs/AbstractFileTypeDetector.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/sun/nio/fs/AbstractFileTypeDetector.java	Fri Jan 28 09:28:43 2011 +0000
@@ -25,7 +25,7 @@
 
 package sun.nio.fs;
 
-import java.nio.file.FileRef;
+import java.nio.file.Path;
 import java.nio.file.spi.FileTypeDetector;
 import java.util.Locale;
 import java.io.IOException;
@@ -46,7 +46,7 @@
      * and checks that the content type's syntax is valid.
      */
     @Override
-    public final String probeContentType(FileRef file) throws IOException {
+    public final String probeContentType(Path file) throws IOException {
         if (file == null)
             throw new NullPointerException("'file' is null");
         String result = implProbeContentType(file);
@@ -56,7 +56,7 @@
     /**
      * Probes the given file to guess its content type.
      */
-    protected abstract String implProbeContentType(FileRef file)
+    protected abstract String implProbeContentType(Path file)
         throws IOException;
 
     /**
--- a/jdk/src/share/classes/sun/nio/fs/AbstractPath.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/sun/nio/fs/AbstractPath.java	Fri Jan 28 09:28:43 2011 +0000
@@ -26,391 +26,81 @@
 package sun.nio.fs;
 
 import java.nio.file.*;
-import static java.nio.file.StandardOpenOption.*;
-import java.nio.file.attribute.*;
-import java.nio.channels.*;
-import java.nio.ByteBuffer;
-import java.io.*;
-import java.util.*;
+import java.io.File;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
 
 /**
- * Base implementation class for a {@code Path}.
+ * Base implementation class of {@code Path}.
  */
 
-abstract class AbstractPath extends Path {
+abstract class AbstractPath implements Path {
     protected AbstractPath() { }
 
     @Override
-    public final Path createFile(FileAttribute<?>... attrs)
-        throws IOException
-    {
-        EnumSet<StandardOpenOption> options = EnumSet.of(CREATE_NEW, WRITE);
-        SeekableByteChannel sbc = newByteChannel(options, attrs);
-        try {
-            sbc.close();
-        } catch (IOException x) {
-            // ignore
-        }
-        return this;
-    }
-
-    /**
-     * Deletes a file. The {@code failIfNotExists} parameters determines if an
-     * {@code IOException} is thrown when the file does not exist.
-     */
-    abstract void implDelete(boolean failIfNotExists) throws IOException;
-
-    @Override
-    public final void delete() throws IOException {
-        implDelete(true);
+    public final boolean startsWith(String other) {
+        return startsWith(getFileSystem().getPath(other));
     }
 
     @Override
-    public final void deleteIfExists() throws IOException {
-        implDelete(false);
+    public final boolean endsWith(String other) {
+        return endsWith(getFileSystem().getPath(other));
     }
 
     @Override
-    public final InputStream newInputStream(OpenOption... options)
-        throws IOException
-    {
-        if (options.length > 0) {
-            for (OpenOption opt: options) {
-                if (opt != READ)
-                    throw new UnsupportedOperationException("'" + opt + "' not allowed");
-            }
-        }
-        return Channels.newInputStream(newByteChannel());
+    public final Path resolve(String other) {
+        return resolve(getFileSystem().getPath(other));
     }
 
     @Override
-    public final OutputStream newOutputStream(OpenOption... options)
-        throws IOException
-    {
-        int len = options.length;
-        Set<OpenOption> opts = new HashSet<OpenOption>(len + 3);
-        if (len == 0) {
-            opts.add(CREATE);
-            opts.add(TRUNCATE_EXISTING);
-        } else {
-            for (OpenOption opt: options) {
-                if (opt == READ)
-                    throw new IllegalArgumentException("READ not allowed");
-                opts.add(opt);
-            }
-        }
-        opts.add(WRITE);
-        return Channels.newOutputStream(newByteChannel(opts));
+    public final Path resolveSibling(Path other) {
+        if (other == null)
+            throw new NullPointerException();
+        Path parent = getParent();
+        return (parent == null) ? other : parent.resolve(other);
     }
 
     @Override
-    public final SeekableByteChannel newByteChannel(OpenOption... options)
-        throws IOException
-    {
-        Set<OpenOption> set = new HashSet<OpenOption>(options.length);
-        Collections.addAll(set, options);
-        return newByteChannel(set);
-    }
-
-    private static final DirectoryStream.Filter<Path> acceptAllFilter =
-        new DirectoryStream.Filter<Path>() {
-            @Override public boolean accept(Path entry) { return true; }
-        };
-
-    @Override
-    public final DirectoryStream<Path> newDirectoryStream() throws IOException {
-        return newDirectoryStream(acceptAllFilter);
+    public final Path resolveSibling(String other) {
+        return resolveSibling(getFileSystem().getPath(other));
     }
 
     @Override
-    public final DirectoryStream<Path> newDirectoryStream(String glob)
-        throws IOException
-    {
-        // avoid creating a matcher if all entries are required.
-        if (glob.equals("*"))
-            return newDirectoryStream();
-
-        // create a matcher and return a filter that uses it.
-        final PathMatcher matcher = getFileSystem().getPathMatcher("glob:" + glob);
-        DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
+    public final Iterator<Path> iterator() {
+        return new Iterator<Path>() {
+            private int i = 0;
+            @Override
+            public boolean hasNext() {
+                return (i < getNameCount());
+            }
             @Override
-            public boolean accept(Path entry)  {
-                return matcher.matches(entry.getName());
+            public Path next() {
+                if (i < getNameCount()) {
+                    Path result = getName(i);
+                    i++;
+                    return result;
+                } else {
+                    throw new NoSuchElementException();
+                }
+            }
+            @Override
+            public void remove() {
+                throw new UnsupportedOperationException();
             }
         };
-        return newDirectoryStream(filter);
     }
 
     @Override
-    public final boolean exists() {
-        try {
-            checkAccess();
-            return true;
-        } catch (IOException x) {
-            // unable to determine if file exists
-        }
-        return false;
+    public final File toFile() {
+        return new File(toString());
     }
 
     @Override
-    public final boolean notExists() {
-        try {
-            checkAccess();
-            return false;
-        } catch (NoSuchFileException x) {
-            // file confirmed not to exist
-            return true;
-        } catch (IOException x) {
-            return false;
-        }
-    }
-
-    private static final WatchEvent.Modifier[] NO_MODIFIERS = new WatchEvent.Modifier[0];
-
-    @Override
     public final WatchKey register(WatchService watcher,
                                    WatchEvent.Kind<?>... events)
         throws IOException
     {
-        return register(watcher, events, NO_MODIFIERS);
-    }
-
-    abstract void implCopyTo(Path target, CopyOption... options)
-        throws IOException;
-
-    @Override
-    public final Path copyTo(Path target, CopyOption... options)
-        throws IOException
-    {
-        if ((getFileSystem().provider() == target.getFileSystem().provider())) {
-            implCopyTo(target, options);
-        } else {
-            copyToForeignTarget(target, options);
-        }
-        return target;
-    }
-
-    abstract void implMoveTo(Path target, CopyOption... options)
-        throws IOException;
-
-    @Override
-    public final Path moveTo(Path target, CopyOption... options)
-        throws IOException
-    {
-        if ((getFileSystem().provider() == target.getFileSystem().provider())) {
-            implMoveTo(target, options);
-        } else {
-            // different providers so copy + delete
-            copyToForeignTarget(target, convertMoveToCopyOptions(options));
-            delete();
-        }
-        return target;
-    }
-
-    /**
-     * Converts the given array of options for moving a file to options suitable
-     * for copying the file when a move is implemented as copy + delete.
-     */
-    private static CopyOption[] convertMoveToCopyOptions(CopyOption... options)
-        throws AtomicMoveNotSupportedException
-    {
-        int len = options.length;
-        CopyOption[] newOptions = new CopyOption[len+2];
-        for (int i=0; i<len; i++) {
-            CopyOption option = options[i];
-            if (option == StandardCopyOption.ATOMIC_MOVE) {
-                throw new AtomicMoveNotSupportedException(null, null,
-                    "Atomic move between providers is not supported");
-            }
-            newOptions[i] = option;
-        }
-        newOptions[len] = LinkOption.NOFOLLOW_LINKS;
-        newOptions[len+1] = StandardCopyOption.COPY_ATTRIBUTES;
-        return newOptions;
-    }
-
-    /**
-     * Parses the arguments for a file copy operation.
-     */
-    private static class CopyOptions {
-        boolean replaceExisting = false;
-        boolean copyAttributes = false;
-        boolean followLinks = true;
-
-        private CopyOptions() { }
-
-        static CopyOptions parse(CopyOption... options) {
-            CopyOptions result = new CopyOptions();
-            for (CopyOption option: options) {
-                if (option == StandardCopyOption.REPLACE_EXISTING) {
-                    result.replaceExisting = true;
-                    continue;
-                }
-                if (option == LinkOption.NOFOLLOW_LINKS) {
-                    result.followLinks = false;
-                    continue;
-                }
-                if (option == StandardCopyOption.COPY_ATTRIBUTES) {
-                    result.copyAttributes = true;
-                    continue;
-                }
-                if (option == null)
-                    throw new NullPointerException();
-                throw new UnsupportedOperationException("'" + option +
-                    "' is not a recognized copy option");
-            }
-            return result;
-        }
-    }
-
-    /**
-     * Simple cross-provider copy where the target is a Path.
-     */
-    private void copyToForeignTarget(Path target, CopyOption... options)
-        throws IOException
-    {
-        CopyOptions opts = CopyOptions.parse(options);
-        LinkOption[] linkOptions = (opts.followLinks) ? new LinkOption[0] :
-            new LinkOption[] { LinkOption.NOFOLLOW_LINKS };
-
-        // attributes of source file
-        BasicFileAttributes attrs = Attributes
-            .readBasicFileAttributes(this, linkOptions);
-        if (attrs.isSymbolicLink())
-            throw new IOException("Copying of symbolic links not supported");
-
-        // check if target exists
-        boolean exists;
-        if (opts.replaceExisting) {
-            try {
-                target.deleteIfExists();
-                exists = false;
-            } catch (DirectoryNotEmptyException x) {
-                // let exception translate to FileAlreadyExistsException (6895012)
-                exists = true;
-            }
-        } else {
-            exists = target.exists();
-        }
-        if (exists)
-            throw new FileAlreadyExistsException(target.toString());
-
-        // create directory or file
-        if (attrs.isDirectory()) {
-            target.createDirectory();
-        } else {
-            copyRegularFileToForeignTarget(target);
-        }
-
-        // copy basic attributes to target
-        if (opts.copyAttributes) {
-            BasicFileAttributeView view = target
-                .getFileAttributeView(BasicFileAttributeView.class, linkOptions);
-            try {
-                view.setTimes(attrs.lastModifiedTime(),
-                              attrs.lastAccessTime(),
-                              attrs.creationTime());
-            } catch (IOException x) {
-                // rollback
-                try {
-                    target.delete();
-                } catch (IOException ignore) { }
-                throw x;
-            }
-        }
-    }
-
-
-   /**
-     * Simple copy of regular file to a target file that exists.
-     */
-    private void copyRegularFileToForeignTarget(Path target)
-        throws IOException
-    {
-        ReadableByteChannel rbc = newByteChannel();
-        try {
-            // open target file for writing
-            SeekableByteChannel sbc = target.newByteChannel(CREATE_NEW, WRITE);
-
-            // simple copy loop
-            try {
-                ByteBuffer buf = ByteBuffer.wrap(new byte[8192]);
-                int n = 0;
-                for (;;) {
-                    n = rbc.read(buf);
-                    if (n < 0)
-                        break;
-                    assert n > 0;
-                    buf.flip();
-                    while (buf.hasRemaining()) {
-                        sbc.write(buf);
-                    }
-                    buf.rewind();
-                }
-
-            } finally {
-                sbc.close();
-            }
-        } finally {
-            rbc.close();
-        }
-    }
-
-    /**
-     * Splits the given attribute name into the name of an attribute view and
-     * the attribute. If the attribute view is not identified then it assumed
-     * to be "basic".
-     */
-    private static String[] split(String attribute) {
-        String[] s = new String[2];
-        int pos = attribute.indexOf(':');
-        if (pos == -1) {
-            s[0] = "basic";
-            s[1] = attribute;
-        } else {
-            s[0] = attribute.substring(0, pos++);
-            s[1] = (pos == attribute.length()) ? "" : attribute.substring(pos);
-        }
-        return s;
-    }
-
-    /**
-     * Gets a DynamicFileAttributeView by name. Returns {@code null} if the
-     * view is not available.
-     */
-    abstract DynamicFileAttributeView getFileAttributeView(String name,
-                                                           LinkOption... options);
-
-    @Override
-    public final void setAttribute(String attribute,
-                                   Object value,
-                                   LinkOption... options)
-        throws IOException
-    {
-        String[] s = split(attribute);
-        DynamicFileAttributeView view = getFileAttributeView(s[0], options);
-        if (view == null)
-            throw new UnsupportedOperationException("View '" + s[0] + "' not available");
-        view.setAttribute(s[1], value);
-    }
-
-    @Override
-    public final Object getAttribute(String attribute, LinkOption... options)
-        throws IOException
-    {
-        String[] s = split(attribute);
-        DynamicFileAttributeView view = getFileAttributeView(s[0], options);
-        return (view == null) ? null : view.getAttribute(s[1]);
-    }
-
-    @Override
-    public final Map<String,?> readAttributes(String attributes, LinkOption... options)
-        throws IOException
-    {
-        String[] s = split(attributes);
-        DynamicFileAttributeView view = getFileAttributeView(s[0], options);
-        if (view == null)
-            return Collections.emptyMap();
-        return view.readAttributes(s[1].split(","));
+        return register(watcher, events, new WatchEvent.Modifier[0]);
     }
 }
--- a/jdk/src/share/classes/sun/nio/fs/AbstractPoller.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/sun/nio/fs/AbstractPoller.java	Fri Jan 28 09:28:43 2011 +0000
@@ -92,7 +92,7 @@
     /**
      * Requests, and waits on, poller thread to register given file.
      */
-    final WatchKey register(FileRef dir,
+    final WatchKey register(Path dir,
                             WatchEvent.Kind<?>[] events,
                             WatchEvent.Modifier... modifiers)
         throws IOException
@@ -102,7 +102,7 @@
             throw new NullPointerException();
         if (events.length == 0)
             throw new IllegalArgumentException("No events to register");
-        Set<WatchEvent.Kind<?>> eventSet = new HashSet<WatchEvent.Kind<?>>(events.length);
+        Set<WatchEvent.Kind<?>> eventSet = new HashSet<>(events.length);
         for (WatchEvent.Kind<?> event: events) {
             // standard events
             if (event == StandardWatchEventKind.ENTRY_CREATE ||
--- a/jdk/src/share/classes/sun/nio/fs/AbstractUserDefinedFileAttributeView.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/sun/nio/fs/AbstractUserDefinedFileAttributeView.java	Fri Jan 28 09:28:43 2011 +0000
@@ -59,8 +59,7 @@
         return "user";
     }
 
-    @Override
-    public final Object getAttribute(String attribute) throws IOException {
+    private Object getAttribute(String attribute) throws IOException {
         int size;
         try {
             size = size(attribute);
@@ -90,11 +89,11 @@
     }
 
     @Override
-    public final Map<String,?> readAttributes(String[] attributes)
+    public final Map<String,Object> readAttributes(String[] attributes)
         throws IOException
     {
         // names of attributes to return
-        List<String> names = new ArrayList<String>();
+        List<String> names = new ArrayList<>();
 
         for (String name: attributes) {
             if (name.equals("*")) {
@@ -106,7 +105,7 @@
         }
 
         // read each value and return in map
-        Map<String,Object> result = new HashMap<String,Object>();
+        Map<String,Object> result = new HashMap<>();
         for (String name: names) {
             Object value = getAttribute(name);
             if (value != null)
--- a/jdk/src/share/classes/sun/nio/fs/AbstractWatchKey.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/sun/nio/fs/AbstractWatchKey.java	Fri Jan 28 09:28:43 2011 +0000
@@ -32,7 +32,7 @@
  * Base implementation class for watch keys.
  */
 
-abstract class AbstractWatchKey extends WatchKey {
+abstract class AbstractWatchKey implements WatchKey {
 
     /**
      * Maximum size of event list (in the future this may be tunable)
@@ -53,6 +53,9 @@
     // reference to watcher
     private final AbstractWatchService watcher;
 
+    // reference to the original directory
+    private final Path dir;
+
     // key state
     private State state;
 
@@ -63,8 +66,9 @@
     // event for the context is an ENTRY_MODIFY event).
     private Map<Object,WatchEvent<?>> lastModifyEvents;
 
-    protected AbstractWatchKey(AbstractWatchService watcher) {
+    protected AbstractWatchKey(Path dir, AbstractWatchService watcher) {
         this.watcher = watcher;
+        this.dir = dir;
         this.state = State.READY;
         this.events = new ArrayList<WatchEvent<?>>();
         this.lastModifyEvents = new HashMap<Object,WatchEvent<?>>();
@@ -75,6 +79,13 @@
     }
 
     /**
+     * Return the original watchable (Path)
+     */
+    Path watchable() {
+        return dir;
+    }
+
+    /**
      * Enqueues this key to the watch service
      */
     final void signal() {
@@ -175,7 +186,7 @@
     /**
      * WatchEvent implementation
      */
-    private static class Event<T> extends WatchEvent<T> {
+    private static class Event<T> implements WatchEvent<T> {
         private final WatchEvent.Kind<T> kind;
         private final T context;
 
--- a/jdk/src/share/classes/sun/nio/fs/AbstractWatchService.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/sun/nio/fs/AbstractWatchService.java	Fri Jan 28 09:28:43 2011 +0000
@@ -33,7 +33,7 @@
  * Base implementation class for watch services.
  */
 
-abstract class AbstractWatchService extends WatchService {
+abstract class AbstractWatchService implements WatchService {
 
     // signaled keys waiting to be dequeued
     private final LinkedBlockingDeque<WatchKey> pendingKeys =
@@ -41,7 +41,7 @@
 
     // special key to indicate that watch service is closed
     private final WatchKey CLOSE_KEY =
-        new AbstractWatchKey(null) {
+        new AbstractWatchKey(null, null) {
             @Override
             public boolean isValid() {
                 return true;
@@ -54,7 +54,7 @@
 
     // used when closing watch service
     private volatile boolean closed;
-    private Object closeLock = new Object();
+    private final Object closeLock = new Object();
 
     protected AbstractWatchService() {
     }
@@ -93,7 +93,7 @@
     }
 
     @Override
-    public final WatchKey  poll() {
+    public final WatchKey poll() {
         checkOpen();
         WatchKey key = pendingKeys.poll();
         checkKey(key);
--- a/jdk/src/share/classes/sun/nio/fs/DynamicFileAttributeView.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/sun/nio/fs/DynamicFileAttributeView.java	Fri Jan 28 09:28:43 2011 +0000
@@ -35,11 +35,6 @@
 
 interface DynamicFileAttributeView {
     /**
-     * Reads the value of an attribute.
-     */
-    Object getAttribute(String attribute) throws IOException;
-
-    /**
      * Sets/updates the value of an attribute.
      */
     void setAttribute(String attribute, Object value) throws IOException;
@@ -47,5 +42,5 @@
     /**
      * Reads a set of file attributes as a bulk operation.
      */
-    Map<String,?> readAttributes(String[] attributes) throws IOException;
+    Map<String,Object> readAttributes(String[] attributes) throws IOException;
 }
--- a/jdk/src/share/classes/sun/nio/fs/FileOwnerAttributeViewImpl.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/sun/nio/fs/FileOwnerAttributeViewImpl.java	Fri Jan 28 09:28:43 2011 +0000
@@ -58,13 +58,6 @@
     }
 
     @Override
-    public Object getAttribute(String attribute) throws IOException {
-        if (attribute.equals(OWNER_NAME))
-            return getOwner();
-        return null;
-    }
-
-    @Override
     public void setAttribute(String attribute, Object value)
         throws IOException
     {
@@ -77,8 +70,8 @@
     }
 
     @Override
-    public Map<String,?> readAttributes(String[] attributes) throws IOException {
-        Map<String,Object> result = new HashMap<String,Object>();
+    public Map<String,Object> readAttributes(String[] attributes) throws IOException {
+        Map<String,Object> result = new HashMap<>();
         for (String attribute: attributes) {
             if (attribute.equals("*") || attribute.equals(OWNER_NAME)) {
                 result.put(OWNER_NAME, getOwner());
--- a/jdk/src/share/classes/sun/nio/fs/PollingWatchService.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/sun/nio/fs/PollingWatchService.java	Fri Jan 28 09:28:43 2011 +0000
@@ -146,7 +146,7 @@
         throws IOException
     {
         // check file is a directory and get its file key if possible
-        BasicFileAttributes attrs = Attributes.readBasicFileAttributes(path);
+        BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class);
         if (!attrs.isDirectory()) {
             throw new NotDirectoryException(path.toString());
         }
@@ -164,7 +164,7 @@
                 watchKey = map.get(fileKey);
                 if (watchKey == null) {
                     // new registration
-                    watchKey = new PollingWatchKey(this, path, fileKey);
+                    watchKey = new PollingWatchKey(path, this, fileKey);
                     map.put(fileKey, watchKey);
                 } else {
                     // update to existing registration
@@ -228,7 +228,6 @@
      * directory and queue keys when entries are added, modified, or deleted.
      */
     private class PollingWatchKey extends AbstractWatchKey {
-        private final Path dir;
         private final Object fileKey;
 
         // current event set
@@ -246,44 +245,28 @@
         // map of entries in directory
         private Map<Path,CacheEntry> entries;
 
-        PollingWatchKey(PollingWatchService watcher,
-                        Path dir,
-                        Object fileKey)
+        PollingWatchKey(Path dir, PollingWatchService watcher, Object fileKey)
             throws IOException
         {
-            super(watcher);
-            this.dir = dir;
+            super(dir, watcher);
             this.fileKey = fileKey;
             this.valid = true;
             this.tickCount = 0;
             this.entries = new HashMap<Path,CacheEntry>();
 
             // get the initial entries in the directory
-            DirectoryStream<Path> stream = dir.newDirectoryStream();
-            try {
+            try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
                 for (Path entry: stream) {
                     // don't follow links
-                    long lastModified = Attributes
-                        .readBasicFileAttributes(entry, LinkOption.NOFOLLOW_LINKS)
-                        .lastModifiedTime().toMillis();
-                    entries.put(entry.getName(),
-                                new CacheEntry(lastModified, tickCount));
+                    long lastModified =
+                        Files.getLastModifiedTime(entry, LinkOption.NOFOLLOW_LINKS).toMillis();
+                    entries.put(entry.getFileName(), new CacheEntry(lastModified, tickCount));
                 }
-            } catch (ConcurrentModificationException cme) {
-                // thrown if directory iteration fails
-                Throwable cause = cme.getCause();
-                if (cause != null && cause instanceof IOException)
-                    throw (IOException)cause;
-                throw new AssertionError(cme);
-            } finally {
-                stream.close();
+            } catch (DirectoryIteratorException e) {
+                throw e.getCause();
             }
         }
 
-        FileRef directory() {
-            return dir;
-        }
-
         Object fileKey() {
             return fileKey;
         }
@@ -342,7 +325,7 @@
             // open directory
             DirectoryStream<Path> stream = null;
             try {
-                stream = dir.newDirectoryStream();
+                stream = Files.newDirectoryStream(watchable());
             } catch (IOException x) {
                 // directory is no longer accessible so cancel key
                 cancel();
@@ -355,9 +338,8 @@
                 for (Path entry: stream) {
                     long lastModified = 0L;
                     try {
-                        lastModified = Attributes
-                            .readBasicFileAttributes(entry, LinkOption.NOFOLLOW_LINKS)
-                            .lastModifiedTime().toMillis();
+                        lastModified =
+                            Files.getLastModifiedTime(entry, LinkOption.NOFOLLOW_LINKS).toMillis();
                     } catch (IOException x) {
                         // unable to get attributes of entry. If file has just
                         // been deleted then we'll report it as deleted on the
@@ -366,15 +348,15 @@
                     }
 
                     // lookup cache
-                    CacheEntry e = entries.get(entry.getName());
+                    CacheEntry e = entries.get(entry.getFileName());
                     if (e == null) {
                         // new file found
-                        entries.put(entry.getName(),
+                        entries.put(entry.getFileName(),
                                      new CacheEntry(lastModified, tickCount));
 
                         // queue ENTRY_CREATE if event enabled
                         if (events.contains(StandardWatchEventKind.ENTRY_CREATE)) {
-                            signalEvent(StandardWatchEventKind.ENTRY_CREATE, entry.getName());
+                            signalEvent(StandardWatchEventKind.ENTRY_CREATE, entry.getFileName());
                             continue;
                         } else {
                             // if ENTRY_CREATE is not enabled and ENTRY_MODIFY is
@@ -382,7 +364,7 @@
                             // modifications to the file immediately after it is
                             // created.
                             if (events.contains(StandardWatchEventKind.ENTRY_MODIFY)) {
-                                signalEvent(StandardWatchEventKind.ENTRY_MODIFY, entry.getName());
+                                signalEvent(StandardWatchEventKind.ENTRY_MODIFY, entry.getFileName());
                             }
                         }
                         continue;
@@ -391,15 +373,17 @@
                     // check if file has changed
                     if (e.lastModified != lastModified) {
                         if (events.contains(StandardWatchEventKind.ENTRY_MODIFY)) {
-                            signalEvent(StandardWatchEventKind.ENTRY_MODIFY, entry.getName());
+                            signalEvent(StandardWatchEventKind.ENTRY_MODIFY,
+                                        entry.getFileName());
                         }
                     }
                     // entry in cache so update poll time
                     e.update(lastModified, tickCount);
 
                 }
-            } catch (ConcurrentModificationException x) {
-                // FIXME - should handle this
+            } catch (DirectoryIteratorException e) {
+                // ignore for now; if the directory is no longer accessible
+                // then the key will be cancelled on the next poll
             } finally {
 
                 // close directory stream
--- a/jdk/src/share/classes/sun/security/provider/SeedGenerator.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/sun/security/provider/SeedGenerator.java	Fri Jan 28 09:28:43 2011 +0000
@@ -63,13 +63,14 @@
  * @author Gadi Guy
  */
 
-import java.lang.reflect.Method;
-import java.lang.reflect.InvocationTargetException;
 import java.security.*;
 import java.io.*;
 import java.util.Properties;
 import java.util.Enumeration;
 import java.net.*;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.util.Random;
 import sun.security.util.Debug;
 
@@ -177,37 +178,21 @@
 
                         // The temporary dir
                         File f = new File(p.getProperty("java.io.tmpdir"));
-
-                        // Go thru files in the tmp dir using NIO's
-                        // DirectoryStream. Fallback to File.list()
-                        // if NIO is not available.
-                        if (NIODirectoryStream.isAvailable()) {
-                            int count = 0;
-                            Iterable<?> stream =
-                                    NIODirectoryStream.newDirectoryStream(f);
+                        int count = 0;
+                        try (DirectoryStream<Path> stream = Files.newDirectoryStream(f.toPath())) {
                             // We use a Random object to choose what file names
                             // should be used. Otherwise on a machine with too
                             // many files, the same first 1024 files always get
                             // used. Any, We make sure the first 512 files are
                             // always used.
                             Random r = new Random();
-                            try {
-                                for (Object entry: stream) {
-                                    if (count < 512 || r.nextBoolean()) {
-                                        md.update(NIODirectoryStream.getName(
-                                                entry).getBytes());
-                                    }
-                                    if (count++ > 1024) {
-                                        break;
-                                    }
+                            for (Path entry: stream) {
+                                if (count < 512 || r.nextBoolean()) {
+                                    md.update(entry.getFileName().toString().getBytes());
                                 }
-                            } finally {
-                                ((Closeable)stream).close();
-                            }
-                        } else {
-                            String[] sa = f.list();
-                            for(int i = 0; i < sa.length; i++) {
-                                md.update(sa[i].getBytes());
+                                if (count++ > 1024) {
+                                    break;
+                                }
                             }
                         }
                     } catch (Exception ex) {
@@ -553,77 +538,4 @@
         }
 
     }
-
-    /**
-     * A wrapper of NIO DirectoryStream using reflection.
-     */
-    private static class NIODirectoryStream {
-        private static final Class<?> pathClass =
-                getClass("java.nio.file.Path");
-
-        private static final Method toPathMethod =
-                (pathClass == null) ? null : getMethod(File.class, "toPath");
-        private static final Method getNameMethod =
-                getMethod(pathClass, "getName");
-        private static final Method newDirectoryStreamMethod =
-                getMethod(pathClass, "newDirectoryStream");
-
-        private static Class<?> getClass(String name) {
-            try {
-                return Class.forName(name, true, null);
-            } catch (ClassNotFoundException e) {
-                return null;
-            }
-        }
-
-        private static Method getMethod(Class<?> clazz,
-                                        String name,
-                                        Class<?>... paramTypes) {
-            if (clazz != null) {
-                try {
-                    return clazz.getMethod(name, paramTypes);
-                } catch (NoSuchMethodException e) {
-                    throw new AssertionError(e);
-                }
-            } else {
-                return null;
-            }
-        }
-
-        static boolean isAvailable() {
-            return pathClass != null;
-        }
-
-        static Iterable<?> newDirectoryStream(File dir) throws IOException {
-            assert pathClass != null;
-            try {
-                Object path = toPathMethod.invoke(dir);
-                return (Iterable<?>)newDirectoryStreamMethod.invoke(path);
-            } catch (InvocationTargetException e) {
-                Throwable cause = e.getCause();
-                if (cause instanceof IOException)
-                    throw (IOException)cause;
-                if (cause instanceof RuntimeException)
-                    throw (RuntimeException)cause;
-                if (cause instanceof Error)
-                    throw (Error)cause;
-                throw new AssertionError(e);
-            } catch (IllegalAccessException iae) {
-                throw new AssertionError(iae);
-            }
-        }
-
-        static String getName(Object path) {
-            assert pathClass != null;
-            try {
-                Object name = getNameMethod.invoke(path);
-                return name.toString();
-            } catch (InvocationTargetException e) {
-                throw new AssertionError(e);
-            } catch (IllegalAccessException iae) {
-                throw new AssertionError(iae);
-            }
-        }
-    }
 }
-
--- a/jdk/src/share/classes/sun/tools/jar/Main.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/classes/sun/tools/jar/Main.java	Fri Jan 28 09:28:43 2011 +0000
@@ -27,6 +27,7 @@
 
 import java.io.*;
 import java.nio.file.Path;
+import java.nio.file.Files;
 import java.util.*;
 import java.util.zip.*;
 import java.util.jar.*;
@@ -1017,17 +1018,17 @@
         Path jarPath = jarFile.toPath();
         Path tmpPath = createTempFileInSameDirectoryAs(jarFile).toPath();
         try {
-            if (update(jarPath.newInputStream(),
-                       tmpPath.newOutputStream(),
+            if (update(Files.newInputStream(jarPath),
+                       Files.newOutputStream(tmpPath),
                        null, index)) {
                 try {
-                    tmpPath.moveTo(jarPath, REPLACE_EXISTING);
+                    Files.move(tmpPath, jarPath, REPLACE_EXISTING);
                 } catch (IOException e) {
                     throw new IOException(getMsg("error.write.file"), e);
                 }
             }
         } finally {
-            tmpPath.deleteIfExists();
+            Files.deleteIfExists(tmpPath);
         }
     }
 
--- a/jdk/src/share/sample/nio/file/AclEdit.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/sample/nio/file/AclEdit.java	Fri Jan 28 09:28:43 2011 +0000
@@ -239,7 +239,7 @@
 
         // read file's ACL
         AclFileAttributeView view =
-            file.getFileAttributeView(AclFileAttributeView.class);
+            Files.getFileAttributeView(file, AclFileAttributeView.class);
         if (view == null) {
             System.err.println("ACLs not supported on this platform");
             System.exit(-1);
--- a/jdk/src/share/sample/nio/file/Chmod.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/sample/nio/file/Chmod.java	Fri Jan 28 09:28:43 2011 +0000
@@ -264,11 +264,10 @@
     /**
      * Changes the permissions of the file using the given Changer.
      */
-    static void chmod(FileRef file, Changer changer) {
+    static void chmod(Path file, Changer changer) {
         try {
-            Set<PosixFilePermission> perms = Attributes
-                .readPosixFileAttributes(file).permissions();
-            Attributes.setPosixFilePermissions(file, changer.change(perms));
+            Set<PosixFilePermission> perms = Files.getPosixFilePermissions(file);
+            Files.setPosixFilePermissions(file, changer.change(perms));
         } catch (IOException x) {
             System.err.println(x);
         }
@@ -277,7 +276,7 @@
     /**
      * Changes the permission of each file and directory visited
      */
-    static class TreeVisitor implements FileVisitor<FileRef> {
+    static class TreeVisitor implements FileVisitor<Path> {
         private final Changer changer;
 
         TreeVisitor(Changer changer) {
@@ -285,26 +284,26 @@
         }
 
         @Override
-        public FileVisitResult preVisitDirectory(FileRef dir, BasicFileAttributes attrs) {
+        public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
             chmod(dir, changer);
             return CONTINUE;
         }
 
         @Override
-        public FileVisitResult visitFile(FileRef file, BasicFileAttributes attrs) {
+        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
             chmod(file, changer);
             return CONTINUE;
         }
 
         @Override
-        public FileVisitResult postVisitDirectory(FileRef dir, IOException exc) {
+        public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
             if (exc != null)
                 System.err.println("WARNING: " + exc);
             return CONTINUE;
         }
 
         @Override
-        public FileVisitResult visitFileFailed(FileRef file, IOException exc) {
+        public FileVisitResult visitFileFailed(Path file, IOException exc) {
             System.err.println("WARNING: " + exc);
             return CONTINUE;
         }
--- a/jdk/src/share/sample/nio/file/Copy.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/sample/nio/file/Copy.java	Fri Jan 28 09:28:43 2011 +0000
@@ -45,7 +45,7 @@
     /**
      * Returns {@code true} if okay to overwrite a  file ("cp -i")
      */
-    static boolean okayToOverwrite(FileRef file) {
+    static boolean okayToOverwrite(Path file) {
         String answer = System.console().readLine("overwrite %s (yes/no)? ", file);
         return (answer.equalsIgnoreCase("y") || answer.equalsIgnoreCase("yes"));
     }
@@ -59,9 +59,9 @@
         CopyOption[] options = (preserve) ?
             new CopyOption[] { COPY_ATTRIBUTES, REPLACE_EXISTING } :
             new CopyOption[] { REPLACE_EXISTING };
-        if (!prompt || target.notExists() || okayToOverwrite(target)) {
+        if (!prompt || Files.notExists(target) || okayToOverwrite(target)) {
             try {
-                source.copyTo(target, options);
+                Files.copy(source, target, options);
             } catch (IOException x) {
                 System.err.format("Unable to copy: %s: %s%n", source, x);
             }
@@ -93,7 +93,7 @@
 
             Path newdir = target.resolve(source.relativize(dir));
             try {
-                dir.copyTo(newdir, options);
+                Files.copy(dir, newdir, options);
             } catch (FileAlreadyExistsException x) {
                 // ignore
             } catch (IOException x) {
@@ -116,8 +116,8 @@
             if (exc == null && preserve) {
                 Path newdir = target.resolve(source.relativize(dir));
                 try {
-                    BasicFileAttributes attrs = Attributes.readBasicFileAttributes(dir);
-                    Attributes.setLastModifiedTime(newdir, attrs.lastModifiedTime());
+                    FileTime time = Files.getLastModifiedTime(dir);
+                    Files.setLastModifiedTime(newdir, time);
                 } catch (IOException x) {
                     System.err.format("Unable to copy all attributes to: %s: %s%n", newdir, x);
                 }
@@ -180,16 +180,11 @@
         Path target = Paths.get(args[argi]);
 
         // check if target is a directory
-        boolean isDir = false;
-        try {
-            isDir = Attributes.readBasicFileAttributes(target).isDirectory();
-        } catch (IOException x) {
-            // ignore (probably target does not exist)
-        }
+        boolean isDir = Files.isDirectory(target);
 
         // copy each source file/directory to target
         for (i=0; i<source.length; i++) {
-            Path dest = (isDir) ? target.resolve(source[i].getName()) : target;
+            Path dest = (isDir) ? target.resolve(source[i].getFileName()) : target;
 
             if (recursive) {
                 // follow links when copying files
@@ -198,13 +193,9 @@
                 Files.walkFileTree(source[i], opts, Integer.MAX_VALUE, tc);
             } else {
                 // not recursive so source must not be a directory
-                try {
-                    if (Attributes.readBasicFileAttributes(source[i]).isDirectory()) {
-                        System.err.format("%s: is a directory%n", source[i]);
-                        continue;
-                    }
-                } catch (IOException x) {
-                    // assume not directory
+                if (Files.isDirectory(source[i])) {
+                    System.err.format("%s: is a directory%n", source[i]);
+                    continue;
                 }
                 copyFile(source[i], dest, prompt, preserve);
             }
--- a/jdk/src/share/sample/nio/file/DiskUsage.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/sample/nio/file/DiskUsage.java	Fri Jan 28 09:28:43 2011 +0000
@@ -43,11 +43,9 @@
     static final long K = 1024;
 
     static void printFileStore(FileStore store) throws IOException {
-        FileStoreSpaceAttributes attrs = Attributes.readFileStoreSpaceAttributes(store);
-
-        long total = attrs.totalSpace() / K;
-        long used = (attrs.totalSpace() - attrs.unallocatedSpace()) / K;
-        long avail = attrs.usableSpace() / K;
+        long total = store.getTotalSpace() / K;
+        long used = (store.getTotalSpace() - store.getUnallocatedSpace()) / K;
+        long avail = store.getUsableSpace() / K;
 
         String s = store.toString();
         if (s.length() > 20) {
@@ -66,7 +64,7 @@
             }
         } else {
             for (String file: args) {
-                FileStore store = Paths.get(file).getFileStore();
+                FileStore store = Files.getFileStore(Paths.get(file));
                 printFileStore(store);
             }
         }
--- a/jdk/src/share/sample/nio/file/FileType.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/sample/nio/file/FileType.java	Fri Jan 28 09:28:43 2011 +0000
@@ -30,7 +30,6 @@
  */
 
 import java.nio.file.*;
-import java.nio.file.attribute.*;
 import java.io.IOException;
 
 public class FileType {
@@ -41,10 +40,8 @@
         }
         for (String arg: args) {
             Path file = Paths.get(arg);
-            BasicFileAttributes attrs = Attributes.readBasicFileAttributes(file);
-
             String type;
-            if (attrs.isDirectory()) {
+            if (Files.isDirectory(file)) {
                 type = "directory";
             } else {
                 type = Files.probeContentType(file);
--- a/jdk/src/share/sample/nio/file/WatchDir.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/sample/nio/file/WatchDir.java	Fri Jan 28 09:28:43 2011 +0000
@@ -58,7 +58,7 @@
     private void register(Path dir) throws IOException {
         WatchKey key = dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
         if (trace) {
-            FileRef prev = keys.get(key);
+            Path prev = keys.get(key);
             if (prev == null) {
                 System.out.format("register: %s\n", dir);
             } else {
@@ -147,7 +147,7 @@
                 // register it and its sub-directories
                 if (recursive && (kind == ENTRY_CREATE)) {
                     try {
-                        if (Attributes.readBasicFileAttributes(child, NOFOLLOW_LINKS).isDirectory()) {
+                        if (Files.isDirectory(child, NOFOLLOW_LINKS)) {
                             registerAll(child);
                         }
                     } catch (IOException x) {
--- a/jdk/src/share/sample/nio/file/Xdd.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/share/sample/nio/file/Xdd.java	Fri Jan 28 09:28:43 2011 +0000
@@ -58,14 +58,14 @@
             Paths.get(args[0]) : Paths.get(args[2]);
 
         // check that user defined attributes are supported by the file store
-        FileStore store = file.getFileStore();
+        FileStore store = Files.getFileStore(file);
         if (!store.supportsFileAttributeView(UserDefinedFileAttributeView.class)) {
             System.err.format("UserDefinedFileAttributeView not supported on %s\n", store);
             System.exit(-1);
 
         }
-        UserDefinedFileAttributeView view = file.
-            getFileAttributeView(UserDefinedFileAttributeView.class);
+        UserDefinedFileAttributeView view =
+            Files.getFileAttributeView(file, UserDefinedFileAttributeView.class);
 
         // list user defined attributes
         if (args.length == 1) {
--- a/jdk/src/solaris/classes/sun/nio/fs/GnomeFileTypeDetector.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/GnomeFileTypeDetector.java	Fri Jan 28 09:28:43 2011 +0000
@@ -25,7 +25,7 @@
 
 package sun.nio.fs;
 
-import java.nio.file.FileRef;
+import java.nio.file.Path;
 import java.io.IOException;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
@@ -57,7 +57,7 @@
     }
 
     @Override
-    public String implProbeContentType(FileRef obj) throws IOException {
+    public String implProbeContentType(Path obj) throws IOException {
         if (!gioAvailable && !gnomeVfsAvailable)
             return null;
         if (!(obj instanceof UnixPath))
--- a/jdk/src/solaris/classes/sun/nio/fs/LinuxDosFileAttributeView.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/LinuxDosFileAttributeView.java	Fri Jan 28 09:28:43 2011 +0000
@@ -67,19 +67,6 @@
     }
 
     @Override
-    public Object getAttribute(String attribute) throws IOException {
-        if (attribute.equals(READONLY_NAME))
-            return readAttributes().isReadOnly();
-        if (attribute.equals(ARCHIVE_NAME))
-            return readAttributes().isArchive();
-        if (attribute.equals(SYSTEM_NAME))
-            return readAttributes().isSystem();
-        if (attribute.equals(HIDDEN_NAME))
-            return readAttributes().isHidden();
-        return super.getAttribute(attribute);
-    }
-
-    @Override
     public void setAttribute(String attribute, Object value)
         throws IOException
     {
@@ -103,7 +90,7 @@
     }
 
     @Override
-    public Map<String,?> readAttributes(String[] attributes)
+    public Map<String,Object> readAttributes(String[] attributes)
         throws IOException
     {
         AttributesBuilder builder = AttributesBuilder.create(attributes);
--- a/jdk/src/solaris/classes/sun/nio/fs/LinuxFileSystem.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/LinuxFileSystem.java	Fri Jan 28 09:28:43 2011 +0000
@@ -26,7 +26,6 @@
 package sun.nio.fs;
 
 import java.nio.file.*;
-import java.nio.file.attribute.*;
 import java.io.IOException;
 import java.util.*;
 import java.security.AccessController;
@@ -76,39 +75,14 @@
         }
     }
 
-    @Override
-    @SuppressWarnings("unchecked")
-    public <V extends FileAttributeView> V newFileAttributeView(Class<V> view,
-                                                                UnixPath file,
-                                                                LinkOption... options)
-    {
-        if (view == DosFileAttributeView.class)
-            return (V) new LinuxDosFileAttributeView(file, followLinks(options));
-        if (view == UserDefinedFileAttributeView.class)
-            return (V) new LinuxUserDefinedFileAttributeView(file, followLinks(options));
-        return super.newFileAttributeView(view, file, options);
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public DynamicFileAttributeView newFileAttributeView(String name,
-                                                         UnixPath file,
-                                                         LinkOption... options)
-    {
-        if (name.equals("dos"))
-            return new LinuxDosFileAttributeView(file, followLinks(options));
-        if (name.equals("user"))
-            return new LinuxUserDefinedFileAttributeView(file, followLinks(options));
-        return super.newFileAttributeView(name, file, options);
-    }
 
     // lazy initialization of the list of supported attribute views
     private static class SupportedFileFileAttributeViewsHolder {
         static final Set<String> supportedFileAttributeViews =
             supportedFileAttributeViews();
         private static Set<String> supportedFileAttributeViews() {
-            Set<String> result = new HashSet<String>();
-            result.addAll(UnixFileSystem.standardFileAttributeViews());
+            Set<String> result = new HashSet<>();
+            result.addAll(standardFileAttributeViews());
             // additional Linux-specific views
             result.add("dos");
             result.add("user");
@@ -130,7 +104,7 @@
      * Returns object to iterate over the mount entries in the given fstab file.
      */
     Iterable<UnixMountEntry> getMountEntries(String fstab) {
-        ArrayList<UnixMountEntry> entries = new ArrayList<UnixMountEntry>();
+        ArrayList<UnixMountEntry> entries = new ArrayList<>();
         try {
             long fp = setmntent(fstab.getBytes(), "r".getBytes());
             try {
@@ -159,10 +133,7 @@
         return getMountEntries("/etc/mtab");
     }
 
-    @Override
-    FileStore getFileStore(UnixPath path) throws IOException {
-        return new LinuxFileStore(path);
-    }
+
 
     @Override
     FileStore getFileStore(UnixMountEntry entry) throws IOException {
--- a/jdk/src/solaris/classes/sun/nio/fs/LinuxFileSystemProvider.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/LinuxFileSystemProvider.java	Fri Jan 28 09:28:43 2011 +0000
@@ -25,6 +25,10 @@
 
 package sun.nio.fs;
 
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.io.IOException;
+
 /**
  * Linux implementation of FileSystemProvider
  */
@@ -38,4 +42,58 @@
     LinuxFileSystem newFileSystem(String dir) {
         return new LinuxFileSystem(this, dir);
     }
+
+    @Override
+    LinuxFileStore getFileStore(UnixPath path) throws IOException {
+        return new LinuxFileStore(path);
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public <V extends FileAttributeView> V getFileAttributeView(Path obj,
+                                                                Class<V> type,
+                                                                LinkOption... options)
+    {
+        if (type == DosFileAttributeView.class) {
+            return (V) new LinuxDosFileAttributeView(UnixPath.toUnixPath(obj),
+                                                     followLinks(options));
+        }
+        if (type == UserDefinedFileAttributeView.class) {
+            return (V) new LinuxUserDefinedFileAttributeView(UnixPath.toUnixPath(obj),
+                                                             followLinks(options));
+        }
+        return super.getFileAttributeView(obj, type, options);
+    }
+
+    @Override
+    public DynamicFileAttributeView getFileAttributeView(Path obj,
+                                                         String name,
+                                                         LinkOption... options)
+    {
+        if (name.equals("dos")) {
+            return new LinuxDosFileAttributeView(UnixPath.toUnixPath(obj),
+                                                 followLinks(options));
+        }
+        if (name.equals("user")) {
+            return new LinuxUserDefinedFileAttributeView(UnixPath.toUnixPath(obj),
+                                                         followLinks(options));
+        }
+        return super.getFileAttributeView(obj, name, options);
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public <A extends BasicFileAttributes> A readAttributes(Path file,
+                                                            Class<A> type,
+                                                            LinkOption... options)
+        throws IOException
+    {
+        if (type == DosFileAttributes.class) {
+            DosFileAttributeView view =
+                getFileAttributeView(file, DosFileAttributeView.class, options);
+            return (A) view.readAttributes();
+        } else {
+            return super.readAttributes(file, type, options);
+        }
+    }
 }
--- a/jdk/src/solaris/classes/sun/nio/fs/LinuxUserDefinedFileAttributeView.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/LinuxUserDefinedFileAttributeView.java	Fri Jan 28 09:28:43 2011 +0000
@@ -63,7 +63,7 @@
 
     // Parses buffer as array of NULL-terminated C strings.
     private List<String> asList(long address, int size) {
-        final List<String> list = new ArrayList<String>();
+        List<String> list = new ArrayList<>();
         int start = 0;
         int pos = 0;
         while (pos < size) {
--- a/jdk/src/solaris/classes/sun/nio/fs/LinuxWatchService.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/LinuxWatchService.java	Fri Jan 28 09:28:43 2011 +0000
@@ -102,8 +102,8 @@
         // watch descriptor
         private volatile int wd;
 
-        LinuxWatchKey(LinuxWatchService watcher, int ifd, int wd) {
-            super(watcher);
+        LinuxWatchKey(UnixPath dir, LinuxWatchService watcher, int ifd, int wd) {
+            super(dir, watcher);
             this.ifd = ifd;
             this.wd = wd;
         }
@@ -266,7 +266,7 @@
             // ensure watch descriptor is in map
             LinuxWatchKey key = wdToKey.get(wd);
             if (key == null) {
-                key = new LinuxWatchKey(watcher, ifd, wd);
+                key = new LinuxWatchKey(dir, watcher, ifd, wd);
                 wdToKey.put(wd, key);
             }
             return key;
--- a/jdk/src/solaris/classes/sun/nio/fs/SolarisAclFileAttributeView.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/SolarisAclFileAttributeView.java	Fri Jan 28 09:28:43 2011 +0000
@@ -198,7 +198,7 @@
      * Decode the buffer, returning an ACL
      */
     private static List<AclEntry> decode(long address, int n) {
-        ArrayList<AclEntry> acl = new ArrayList<AclEntry>(n);
+        ArrayList<AclEntry> acl = new ArrayList<>(n);
         for (int i=0; i<n; i++) {
             long offset = address + i*SIZEOF_ACE_T;
 
@@ -244,7 +244,7 @@
                     assert false;
             }
 
-            HashSet<AclEntryPermission> aceMask = new HashSet<AclEntryPermission>();
+            Set<AclEntryPermission> aceMask = EnumSet.noneOf(AclEntryPermission.class);
             if ((mask & ACE_READ_DATA) > 0)
                 aceMask.add(AclEntryPermission.READ_DATA);
             if ((mask & ACE_WRITE_DATA) > 0)
@@ -274,7 +274,7 @@
             if ((mask & ACE_SYNCHRONIZE) > 0)
                 aceMask.add(AclEntryPermission.SYNCHRONIZE);
 
-            HashSet<AclEntryFlag> aceFlags = new HashSet<AclEntryFlag>();
+            Set<AclEntryFlag> aceFlags = EnumSet.noneOf(AclEntryFlag.class);
             if ((flags & ACE_FILE_INHERIT_ACE) > 0)
                 aceFlags.add(AclEntryFlag.FILE_INHERIT);
             if ((flags & ACE_DIRECTORY_INHERIT_ACE) > 0)
--- a/jdk/src/solaris/classes/sun/nio/fs/SolarisFileSystem.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/SolarisFileSystem.java	Fri Jan 28 09:28:43 2011 +0000
@@ -26,7 +26,6 @@
 package sun.nio.fs;
 
 import java.nio.file.*;
-import java.nio.file.attribute.*;
 import java.io.IOException;
 import java.util.*;
 import java.security.AccessController;
@@ -71,38 +70,14 @@
         }
     }
 
-    @Override
-    @SuppressWarnings("unchecked")
-    public <V extends FileAttributeView> V newFileAttributeView(Class<V> view,
-                                                                UnixPath file, LinkOption... options)
-    {
-        if (view == AclFileAttributeView.class)
-            return (V) new SolarisAclFileAttributeView(file, followLinks(options));
-        if (view == UserDefinedFileAttributeView.class) {
-            return(V) new SolarisUserDefinedFileAttributeView(file, followLinks(options));
-        }
-        return super.newFileAttributeView(view, file, options);
-    }
-
-    @Override
-    protected DynamicFileAttributeView newFileAttributeView(String name,
-                                                            UnixPath file,
-                                                            LinkOption... options)
-    {
-        if (name.equals("acl"))
-            return new SolarisAclFileAttributeView(file, followLinks(options));
-        if (name.equals("user"))
-            return new SolarisUserDefinedFileAttributeView(file, followLinks(options));
-        return super.newFileAttributeView(name, file, options);
-    }
 
     // lazy initialization of the list of supported attribute views
     private static class SupportedFileFileAttributeViewsHolder {
         static final Set<String> supportedFileAttributeViews =
             supportedFileAttributeViews();
         private static Set<String> supportedFileAttributeViews() {
-            Set<String> result = new HashSet<String>();
-            result.addAll(UnixFileSystem.standardFileAttributeViews());
+            Set<String> result = new HashSet<>();
+            result.addAll(standardFileAttributeViews());
             // additional Solaris-specific views
             result.add("acl");
             result.add("user");
@@ -126,7 +101,7 @@
      */
     @Override
     Iterable<UnixMountEntry> getMountEntries() {
-        ArrayList<UnixMountEntry> entries = new ArrayList<UnixMountEntry>();
+        ArrayList<UnixMountEntry> entries = new ArrayList<>();
         try {
             UnixPath mnttab = new UnixPath(this, "/etc/mnttab");
             long fp = fopen(mnttab, "r");
@@ -148,11 +123,6 @@
     }
 
     @Override
-    FileStore getFileStore(UnixPath path) throws IOException {
-        return new SolarisFileStore(path);
-    }
-
-    @Override
     FileStore getFileStore(UnixMountEntry entry) throws IOException {
         return new SolarisFileStore(this, entry);
     }
--- a/jdk/src/solaris/classes/sun/nio/fs/SolarisFileSystemProvider.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/SolarisFileSystemProvider.java	Fri Jan 28 09:28:43 2011 +0000
@@ -25,6 +25,10 @@
 
 package sun.nio.fs;
 
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.io.IOException;
+
 /**
  * Solaris implementation of FileSystemProvider
  */
@@ -38,4 +42,41 @@
     SolarisFileSystem newFileSystem(String dir) {
         return new SolarisFileSystem(this, dir);
     }
+
+    @Override
+    SolarisFileStore getFileStore(UnixPath path) throws IOException {
+        return new SolarisFileStore(path);
+    }
+
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public <V extends FileAttributeView> V getFileAttributeView(Path obj,
+                                                                Class<V> type,
+                                                                LinkOption... options)
+    {
+        if (type == AclFileAttributeView.class) {
+            return (V) new SolarisAclFileAttributeView(UnixPath.toUnixPath(obj),
+                                                       followLinks(options));
+        }
+        if (type == UserDefinedFileAttributeView.class) {
+            return(V) new SolarisUserDefinedFileAttributeView(UnixPath.toUnixPath(obj),
+                                                              followLinks(options));
+        }
+        return super.getFileAttributeView(obj, type, options);
+    }
+
+    @Override
+    public DynamicFileAttributeView getFileAttributeView(Path obj,
+                                                         String name,
+                                                         LinkOption... options)
+    {
+        if (name.equals("acl"))
+            return new SolarisAclFileAttributeView(UnixPath.toUnixPath(obj),
+                                                   followLinks(options));
+        if (name.equals("user"))
+            return new SolarisUserDefinedFileAttributeView(UnixPath.toUnixPath(obj),
+                                                           followLinks(options));
+        return super.getFileAttributeView(obj, name, options);
+    }
 }
--- a/jdk/src/solaris/classes/sun/nio/fs/SolarisUserDefinedFileAttributeView.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/SolarisUserDefinedFileAttributeView.java	Fri Jan 28 09:28:43 2011 +0000
@@ -83,7 +83,7 @@
                 }
 
                 // read list of extended attributes
-                final List<String> list = new ArrayList<String>();
+                List<String> list = new ArrayList<>();
                 try {
                     byte[] name;
                     while ((name = readdir(dp)) != null) {
--- a/jdk/src/solaris/classes/sun/nio/fs/SolarisWatchService.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/SolarisWatchService.java	Fri Jan 28 09:28:43 2011 +0000
@@ -128,7 +128,6 @@
     private class SolarisWatchKey extends AbstractWatchKey
         implements DirectoryNode
     {
-        private final UnixPath dir;
         private final UnixFileKey fileKey;
 
         // pointer to native file_obj object
@@ -147,15 +146,14 @@
                         long object,
                         Set<? extends WatchEvent.Kind<?>> events)
         {
-            super(watcher);
-            this.dir = dir;
+            super(dir, watcher);
             this.fileKey = fileKey;
             this.object = object;
             this.events = events;
         }
 
-        UnixPath getFileRef() {
-            return dir;
+        UnixPath getDirectory() {
+            return (UnixPath)watchable();
         }
 
         UnixFileKey getFileKey() {
@@ -487,7 +485,7 @@
          */
         void processDirectoryEvents(SolarisWatchKey key, int mask) {
             if ((mask & (FILE_MODIFIED | FILE_ATTRIB)) != 0) {
-                registerChildren(key.getFileRef(), key,
+                registerChildren(key.getDirectory(), key,
                     key.events().contains(StandardWatchEventKind.ENTRY_CREATE));
             }
         }
@@ -524,7 +522,7 @@
                 boolean removed = true;
                 try {
                     UnixFileAttributes
-                        .get(key.getFileRef().resolve(node.name()), false);
+                        .get(key.getDirectory().resolve(node.name()), false);
                     removed = false;
                 } catch (UnixException x) { }
 
@@ -554,14 +552,14 @@
 
             DirectoryStream<Path> stream = null;
             try {
-                stream = dir.newDirectoryStream();
+                stream = Files.newDirectoryStream(dir);
             } catch (IOException x) {
                 // nothing we can do
                 return;
             }
             try {
                 for (Path entry: stream) {
-                    Path name = entry.getName();
+                    Path name = entry.getFileName();
 
                     // skip entry if already registered
                     if (parent.getChild(name) != null)
@@ -582,9 +580,9 @@
                     }
 
                     // create node
-                    EntryNode node = new EntryNode(object, entry.getName(), parent);
+                    EntryNode node = new EntryNode(object, entry.getFileName(), parent);
                     // tell the parent about it
-                    parent.addChild(entry.getName(), node);
+                    parent.addChild(entry.getFileName(), node);
                     object2Node.put(object, node);
                 }
             } catch (ConcurrentModificationException x) {
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixCopyFile.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixCopyFile.java	Fri Jan 28 09:28:43 2011 +0000
@@ -237,7 +237,7 @@
                 fo = open(target,
                            (O_WRONLY |
                             O_CREAT |
-                            O_TRUNC),
+                            O_EXCL),
                            attrs.mode());
             } catch (UnixException x) {
                 x.rethrowAsIOException(target);
@@ -435,10 +435,8 @@
                 if (targetAttrs.isDirectory() &&
                    (x.errno() == EEXIST || x.errno() == ENOTEMPTY))
                 {
-                    throw new FileAlreadyExistsException(
-                        source.getPathForExecptionMessage(),
-                        target.getPathForExecptionMessage(),
-                        x.getMessage());
+                    throw new DirectoryNotEmptyException(
+                        target.getPathForExecptionMessage());
                 }
                 x.rethrowAsIOException(target);
             }
@@ -556,10 +554,8 @@
                 if (targetAttrs.isDirectory() &&
                    (x.errno() == EEXIST || x.errno() == ENOTEMPTY))
                 {
-                    throw new FileAlreadyExistsException(
-                        source.getPathForExecptionMessage(),
-                        target.getPathForExecptionMessage(),
-                        x.getMessage());
+                    throw new DirectoryNotEmptyException(
+                        target.getPathForExecptionMessage());
                 }
                 x.rethrowAsIOException(target);
             }
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixFileAttributeViews.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixFileAttributeViews.java	Fri Jan 28 09:28:43 2011 +0000
@@ -149,17 +149,6 @@
         }
 
         @Override
-        public Object getAttribute(String attribute) throws IOException {
-            if (attribute.equals(PERMISSIONS_NAME))
-                return readAttributes().permissions();
-            if (attribute.equals(OWNER_NAME))
-                return readAttributes().owner();
-            if (attribute.equals(GROUP_NAME))
-                return readAttributes().group();
-            return super.getAttribute(attribute);
-        }
-
-        @Override
         @SuppressWarnings("unchecked")
         public void setAttribute(String attribute, Object value)
             throws IOException
@@ -195,7 +184,7 @@
         }
 
         @Override
-        public Map<String,?> readAttributes(String[] attributes)
+        public Map<String,Object> readAttributes(String[] attributes)
             throws IOException
         {
             AttributesBuilder builder = AttributesBuilder.create(attributes);
@@ -308,27 +297,6 @@
         }
 
         @Override
-        public Object getAttribute(String attribute) throws IOException {
-            if (attribute.equals(MODE_NAME))
-                return readAttributes().mode();
-            if (attribute.equals(INO_NAME))
-                return readAttributes().ino();
-            if (attribute.equals(DEV_NAME))
-                return readAttributes().dev();
-            if (attribute.equals(RDEV_NAME))
-                return readAttributes().rdev();
-            if (attribute.equals(NLINK_NAME))
-                return readAttributes().nlink();
-            if (attribute.equals(UID_NAME))
-                return readAttributes().uid();
-            if (attribute.equals(GID_NAME))
-                return readAttributes().gid();
-            if (attribute.equals(CTIME_NAME))
-                return readAttributes().ctime();
-            return super.getAttribute(attribute);
-        }
-
-        @Override
         public void setAttribute(String attribute, Object value)
             throws IOException
         {
@@ -348,7 +316,7 @@
         }
 
         @Override
-        public Map<String,?> readAttributes(String[] attributes)
+        public Map<String,Object> readAttributes(String[] attributes)
             throws IOException
         {
             AttributesBuilder builder = AttributesBuilder.create(attributes);
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixFileAttributes.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixFileAttributes.java	Fri Jan 28 09:28:43 2011 +0000
@@ -124,7 +124,7 @@
 
     @Override
     public FileTime creationTime() {
-        return null;
+        return lastModifiedTime();
     }
 
     @Override
@@ -194,7 +194,7 @@
     @Override
     public Set<PosixFilePermission> permissions() {
         int bits = (st_mode & UnixConstants.S_IAMB);
-        HashSet<PosixFilePermission> perms = new HashSet<PosixFilePermission>();
+        HashSet<PosixFilePermission> perms = new HashSet<>();
 
         if ((bits & UnixConstants.S_IRUSR) > 0)
             perms.add(PosixFilePermission.OWNER_READ);
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixFileStore.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixFileStore.java	Fri Jan 28 09:28:43 2011 +0000
@@ -103,28 +103,50 @@
         return entry.isReadOnly();
     }
 
+    // uses statvfs to read the file system information
+    private UnixFileStoreAttributes readAttributes() throws IOException {
+        try {
+            return UnixFileStoreAttributes.get(file);
+        } catch (UnixException x) {
+            x.rethrowAsIOException(file);
+            return null;    // keep compile happy
+        }
+    }
+
     @Override
-    @SuppressWarnings("unchecked")
+    public long getTotalSpace() throws IOException {
+        UnixFileStoreAttributes attrs = readAttributes();
+        return attrs.blockSize() * attrs.totalBlocks();
+    }
+
+    @Override
+    public long getUsableSpace() throws IOException {
+       UnixFileStoreAttributes attrs = readAttributes();
+       return attrs.blockSize() * attrs.availableBlocks();
+    }
+
+    @Override
+    public long getUnallocatedSpace() throws IOException {
+        UnixFileStoreAttributes attrs = readAttributes();
+        return attrs.blockSize() * attrs.freeBlocks();
+    }
+
+    @Override
     public <V extends FileStoreAttributeView> V getFileStoreAttributeView(Class<V> view)
     {
         if (view == null)
             throw new NullPointerException();
-        if (view == FileStoreSpaceAttributeView.class)
-            return (V) new UnixFileStoreSpaceAttributeView(this);
         return (V) null;
     }
 
     @Override
     public Object getAttribute(String attribute) throws IOException {
-        if (attribute.equals("space:totalSpace"))
-            return new UnixFileStoreSpaceAttributeView(this)
-                .readAttributes().totalSpace();
-        if (attribute.equals("space:usableSpace"))
-            return new UnixFileStoreSpaceAttributeView(this)
-                 .readAttributes().usableSpace();
-        if (attribute.equals("space:unallocatedSpace"))
-            return new UnixFileStoreSpaceAttributeView(this)
-                 .readAttributes().unallocatedSpace();
+        if (attribute.equals("totalSpace"))
+            return getTotalSpace();
+        if (attribute.equals("usableSpace"))
+            return getUsableSpace();
+        if (attribute.equals("unallocatedSpace"))
+            return getUnallocatedSpace();
         throw new UnsupportedOperationException("'" + attribute + "' not recognized");
     }
 
@@ -181,50 +203,6 @@
         return sb.toString();
     }
 
-    private static class UnixFileStoreSpaceAttributeView
-        implements FileStoreSpaceAttributeView
-    {
-        private final UnixFileStore fs;
-
-        UnixFileStoreSpaceAttributeView(UnixFileStore fs) {
-            this.fs = fs;
-        }
-
-        @Override
-        public String name() {
-            return "space";
-        }
-
-        @Override
-        public FileStoreSpaceAttributes readAttributes()
-            throws IOException
-        {
-            UnixPath file = fs.file();
-            final UnixFileStoreAttributes attrs;
-            try {
-                attrs = UnixFileStoreAttributes.get(file);
-            } catch (UnixException x) {
-                x.rethrowAsIOException(file);
-                return null;    // keep compile happy
-            }
-
-            return new FileStoreSpaceAttributes() {
-                @Override
-                public long totalSpace() {
-                    return attrs.blockSize() * attrs.totalBlocks();
-                }
-                @Override
-                public long usableSpace() {
-                    return attrs.blockSize() * attrs.availableBlocks();
-                }
-                @Override
-                public long unallocatedSpace() {
-                    return attrs.blockSize() * attrs.freeBlocks();
-                }
-            };
-        }
-    }
-
     // -- fstypes.properties --
 
     private static final Object loadLock = new Object();
@@ -277,11 +255,8 @@
         String fstypes = System.getProperty("java.home") + "/lib/fstypes.properties";
         Path file = Paths.get(fstypes);
         try {
-            ReadableByteChannel rbc = file.newByteChannel();
-            try {
+            try (ReadableByteChannel rbc = Files.newByteChannel(file)) {
                 result.load(Channels.newReader(rbc, "UTF-8"));
-            } finally {
-                rbc.close();
             }
         } catch (IOException x) {
         }
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixFileSystem.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixFileSystem.java	Fri Jan 28 09:28:43 2011 +0000
@@ -98,6 +98,10 @@
         return false;
     }
 
+    static List<String> standardFileAttributeViews() {
+        return Arrays.asList("basic", "posix", "unix", "owner");
+    }
+
     @Override
     public final FileSystemProvider provider() {
         return provider;
@@ -169,12 +173,6 @@
     abstract Iterable<UnixMountEntry> getMountEntries();
 
     /**
-     * Returns a FileStore to represent the file system where the given file
-     * reside.
-     */
-    abstract FileStore getFileStore(UnixPath path) throws IOException;
-
-    /**
      * Returns a FileStore to represent the file system for the given mount
      * mount.
      */
@@ -264,7 +262,22 @@
     }
 
     @Override
-    public final UnixPath getPath(String path) {
+    public final Path getPath(String first, String... more) {
+        String path;
+        if (more.length == 0) {
+            path = first;
+        } else {
+            StringBuilder sb = new StringBuilder();
+            sb.append(first);
+            for (String segment: more) {
+                if (segment.length() > 0) {
+                    if (sb.length() > 0)
+                        sb.append('/');
+                    sb.append(segment);
+                }
+            }
+            path = sb.toString();
+        }
         return new UnixPath(this, path);
     }
 
@@ -300,77 +313,30 @@
     private static final String GLOB_SYNTAX = "glob";
     private static final String REGEX_SYNTAX = "regex";
 
-    protected boolean followLinks(LinkOption... options) {
-        boolean followLinks = true;
-        for (LinkOption option: options) {
-            if (option == LinkOption.NOFOLLOW_LINKS) {
-                followLinks = false;
-                continue;
-            }
-            if (option == null)
-                throw new NullPointerException();
-            throw new AssertionError("Should not get here");
-        }
-        return followLinks;
-    }
 
-    @SuppressWarnings("unchecked")
-    protected <V extends FileAttributeView> V newFileAttributeView(Class<V> view,
-                                                                   UnixPath file,
-                                                                   LinkOption... options)
-    {
-        if (view == null)
-            throw new NullPointerException();
-        boolean followLinks = followLinks(options);
-        Class<?> c = view;
-        if (c == BasicFileAttributeView.class)
-            return (V) UnixFileAttributeViews.createBasicView(file, followLinks);
-        if (c == PosixFileAttributeView.class)
-            return (V) UnixFileAttributeViews.createPosixView(file, followLinks);
-        if (c == FileOwnerAttributeView.class)
-            return (V) UnixFileAttributeViews.createOwnerView(file, followLinks);
-        return (V) null;
-    }
-
-    static List<String> standardFileAttributeViews() {
-        return Arrays.asList("basic", "posix", "unix", "owner");
-    }
-
-    protected DynamicFileAttributeView newFileAttributeView(String name,
-                                                            UnixPath file,
-                                                            LinkOption... options)
-    {
-        boolean followLinks = followLinks(options);
-        if (name.equals("basic"))
-            return UnixFileAttributeViews.createBasicView(file, followLinks);
-        if (name.equals("posix"))
-            return UnixFileAttributeViews.createPosixView(file, followLinks);
-        if (name.equals("unix"))
-            return UnixFileAttributeViews.createUnixView(file, followLinks);
-        if (name.equals("owner"))
-            return UnixFileAttributeViews.createOwnerView(file, followLinks);
-        return null;
-    }
 
     @Override
     public final UserPrincipalLookupService getUserPrincipalLookupService() {
-        return theLookupService;
+        return LookupService.instance;
     }
 
-    private static final UserPrincipalLookupService theLookupService =
-        new UserPrincipalLookupService() {
-            @Override
-            public UserPrincipal lookupPrincipalByName(String name)
-                throws IOException
-            {
-                return UnixUserPrincipals.lookupUser(name);
-            }
+    private static class LookupService {
+        static final UserPrincipalLookupService instance =
+            new UserPrincipalLookupService() {
+                @Override
+                public UserPrincipal lookupPrincipalByName(String name)
+                    throws IOException
+                {
+                    return UnixUserPrincipals.lookupUser(name);
+                }
 
-            @Override
-            public GroupPrincipal lookupPrincipalByGroupName(String group)
-                throws IOException
-            {
-                return UnixUserPrincipals.lookupGroup(group);
-            }
-        };
+                @Override
+                public GroupPrincipal lookupPrincipalByGroupName(String group)
+                    throws IOException
+                {
+                    return UnixUserPrincipals.lookupGroup(group);
+                }
+            };
+    }
+
 }
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixFileSystemProvider.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixFileSystemProvider.java	Fri Jan 28 09:28:43 2011 +0000
@@ -27,21 +27,25 @@
 
 import java.nio.file.*;
 import java.nio.file.attribute.*;
-import java.nio.file.spi.FileSystemProvider;
 import java.nio.channels.*;
 import java.net.URI;
 import java.util.concurrent.ExecutorService;
 import java.io.IOException;
+import java.io.FilePermission;
 import java.util.*;
+import java.security.AccessController;
 
 import sun.nio.ch.ThreadPool;
+import sun.security.util.SecurityConstants;
+import static sun.nio.fs.UnixNativeDispatcher.*;
+import static sun.nio.fs.UnixConstants.*;
 
 /**
  * Base implementation of FileSystemProvider
  */
 
 public abstract class UnixFileSystemProvider
-    extends FileSystemProvider
+    extends AbstractFileSystemProvider
 {
     private static final String USER_DIR = "user.dir";
     private final UnixFileSystem theFileSystem;
@@ -93,7 +97,7 @@
         return UnixUriUtils.fromUri(theFileSystem, uri);
     }
 
-    protected UnixPath checkPath(Path obj) {
+    UnixPath checkPath(Path obj) {
         if (obj == null)
             throw new NullPointerException();
         if (!(obj instanceof UnixPath))
@@ -101,6 +105,76 @@
         return (UnixPath)obj;
     }
 
+    boolean followLinks(LinkOption... options) {
+        boolean followLinks = true;
+        for (LinkOption option: options) {
+            if (option == LinkOption.NOFOLLOW_LINKS) {
+                followLinks = false;
+                continue;
+            }
+            if (option == null)
+                throw new NullPointerException();
+            throw new AssertionError("Should not get here");
+        }
+        return followLinks;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public <V extends FileAttributeView> V getFileAttributeView(Path obj,
+                                                                Class<V> type,
+                                                                LinkOption... options)
+    {
+        UnixPath file = UnixPath.toUnixPath(obj);
+        boolean followLinks =  followLinks(options);
+        if (type == BasicFileAttributeView.class)
+            return (V) UnixFileAttributeViews.createBasicView(file, followLinks);
+        if (type == PosixFileAttributeView.class)
+            return (V) UnixFileAttributeViews.createPosixView(file, followLinks);
+        if (type == FileOwnerAttributeView.class)
+            return (V) UnixFileAttributeViews.createOwnerView(file, followLinks);
+        if (type == null)
+            throw new NullPointerException();
+        return (V) null;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public <A extends BasicFileAttributes> A readAttributes(Path file,
+                                                               Class<A> type,
+                                                               LinkOption... options)
+        throws IOException
+    {
+        Class<? extends BasicFileAttributeView> view;
+        if (type == BasicFileAttributes.class)
+            view = BasicFileAttributeView.class;
+        else if (type == PosixFileAttributes.class)
+            view = PosixFileAttributeView.class;
+        else if (type == null)
+            throw new NullPointerException();
+        else
+            throw new UnsupportedOperationException();
+        return (A) getFileAttributeView(file, view, options).readAttributes();
+    }
+
+    @Override
+    protected DynamicFileAttributeView getFileAttributeView(Path obj,
+                                                            String name,
+                                                            LinkOption... options)
+    {
+        UnixPath file = UnixPath.toUnixPath(obj);
+        boolean followLinks = followLinks(options);
+        if (name.equals("basic"))
+            return UnixFileAttributeViews.createBasicView(file, followLinks);
+        if (name.equals("posix"))
+            return UnixFileAttributeViews.createPosixView(file, followLinks);
+        if (name.equals("unix"))
+            return UnixFileAttributeViews.createUnixView(file, followLinks);
+        if (name.equals("owner"))
+            return UnixFileAttributeViews.createOwnerView(file, followLinks);
+        return null;
+    }
+
     @Override
     public FileChannel newFileChannel(Path obj,
                                       Set<? extends OpenOption> options,
@@ -136,4 +210,303 @@
             return null;
         }
     }
+
+
+    @Override
+    public SeekableByteChannel newByteChannel(Path obj,
+                                              Set<? extends OpenOption> options,
+                                              FileAttribute<?>... attrs)
+         throws IOException
+    {
+        UnixPath file = UnixPath.toUnixPath(obj);
+        int mode = UnixFileModeAttribute
+            .toUnixMode(UnixFileModeAttribute.ALL_READWRITE, attrs);
+        try {
+            return UnixChannelFactory.newFileChannel(file, options, mode);
+        } catch (UnixException x) {
+            x.rethrowAsIOException(file);
+            return null;  // keep compiler happy
+        }
+    }
+
+    @Override
+    boolean implDelete(Path obj, boolean failIfNotExists) throws IOException {
+        UnixPath file = UnixPath.toUnixPath(obj);
+        file.checkDelete();
+
+        // need file attributes to know if file is directory
+        UnixFileAttributes attrs = null;
+        try {
+            attrs = UnixFileAttributes.get(file, false);
+            if (attrs.isDirectory()) {
+                rmdir(file);
+            } else {
+                unlink(file);
+            }
+            return true;
+        } catch (UnixException x) {
+            // no-op if file does not exist
+            if (!failIfNotExists && x.errno() == ENOENT)
+                return false;
+
+            // DirectoryNotEmptyException if not empty
+            if (attrs != null && attrs.isDirectory() &&
+                (x.errno() == EEXIST || x.errno() == ENOTEMPTY))
+                throw new DirectoryNotEmptyException(file.getPathForExecptionMessage());
+
+            x.rethrowAsIOException(file);
+            return false;
+        }
+    }
+
+    @Override
+    public void copy(Path source, Path target, CopyOption... options)
+        throws IOException
+    {
+        UnixCopyFile.copy(UnixPath.toUnixPath(source),
+                          UnixPath.toUnixPath(target),
+                          options);
+    }
+
+    @Override
+    public void move(Path source, Path target, CopyOption... options)
+        throws IOException
+    {
+        UnixCopyFile.move(UnixPath.toUnixPath(source),
+                          UnixPath.toUnixPath(target),
+                          options);
+    }
+
+    @Override
+    public void checkAccess(Path obj, AccessMode... modes) throws IOException {
+        UnixPath file = UnixPath.toUnixPath(obj);
+        boolean e = false;
+        boolean r = false;
+        boolean w = false;
+        boolean x = false;
+
+        if (modes.length == 0) {
+            e = true;
+        } else {
+            for (AccessMode mode: modes) {
+                switch (mode) {
+                    case READ : r = true; break;
+                    case WRITE : w = true; break;
+                    case EXECUTE : x = true; break;
+                    default: throw new AssertionError("Should not get here");
+                }
+            }
+        }
+
+        int mode = 0;
+        if (e || r) {
+            file.checkRead();
+            mode |= (r) ? R_OK : F_OK;
+        }
+        if (w) {
+            file.checkWrite();
+            mode |= W_OK;
+        }
+        if (x) {
+            SecurityManager sm = System.getSecurityManager();
+            if (sm != null) {
+                // not cached
+                sm.checkExec(file.getPathForPermissionCheck());
+            }
+            mode |= X_OK;
+        }
+        try {
+            access(file, mode);
+        } catch (UnixException exc) {
+            exc.rethrowAsIOException(file);
+        }
+    }
+
+    @Override
+    public boolean isSameFile(Path obj1, Path obj2) throws IOException {
+        UnixPath file1 = UnixPath.toUnixPath(obj1);
+        if (file1.equals(obj2))
+            return true;
+        if (obj2 == null)
+            throw new NullPointerException();
+        if (!(obj2 instanceof UnixPath))
+            return false;
+        UnixPath file2 = (UnixPath)obj2;
+
+        // check security manager access to both files
+        file1.checkRead();
+        file2.checkRead();
+
+        UnixFileAttributes attrs1;
+        UnixFileAttributes attrs2;
+        try {
+             attrs1 = UnixFileAttributes.get(file1, true);
+        } catch (UnixException x) {
+            x.rethrowAsIOException(file1);
+            return false;    // keep compiler happy
+        }
+        try {
+            attrs2 = UnixFileAttributes.get(file2, true);
+        } catch (UnixException x) {
+            x.rethrowAsIOException(file2);
+            return false;    // keep compiler happy
+        }
+        return attrs1.isSameFile(attrs2);
+    }
+
+    @Override
+    public boolean isHidden(Path obj) {
+        UnixPath file = UnixPath.toUnixPath(obj);
+        file.checkRead();
+        UnixPath name = file.getFileName();
+        if (name == null)
+            return false;
+        return (name.asByteArray()[0] == '.');
+    }
+
+    /**
+     * Returns a FileStore to represent the file system where the given file
+     * reside.
+     */
+    abstract FileStore getFileStore(UnixPath path) throws IOException;
+
+    @Override
+    public FileStore getFileStore(Path obj) throws IOException {
+        UnixPath file = UnixPath.toUnixPath(obj);
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(new RuntimePermission("getFileStoreAttributes"));
+            file.checkRead();
+        }
+        return getFileStore(file);
+    }
+
+    @Override
+    public void createDirectory(Path obj, FileAttribute<?>... attrs)
+        throws IOException
+    {
+        UnixPath dir = UnixPath.toUnixPath(obj);
+        dir.checkWrite();
+
+        int mode = UnixFileModeAttribute
+            .toUnixMode(UnixFileModeAttribute.ALL_PERMISSIONS, attrs);
+        try {
+            mkdir(dir, mode);
+        } catch (UnixException x) {
+            x.rethrowAsIOException(dir);
+        }
+    }
+
+
+    @Override
+    public DirectoryStream<Path> newDirectoryStream(Path obj, DirectoryStream.Filter<? super Path> filter)
+        throws IOException
+    {
+        UnixPath dir = UnixPath.toUnixPath(obj);
+        dir.checkRead();
+        if (filter == null)
+            throw new NullPointerException();
+
+        // can't return SecureDirectoryStream on kernels that don't support
+        // openat, etc.
+        if (!supportsAtSysCalls()) {
+            try {
+                long ptr = opendir(dir);
+                return new UnixDirectoryStream(dir, ptr, filter);
+            } catch (UnixException x) {
+                if (x.errno() == ENOTDIR)
+                    throw new NotDirectoryException(dir.getPathForExecptionMessage());
+                x.rethrowAsIOException(dir);
+            }
+        }
+
+        // open directory and dup file descriptor for use by
+        // opendir/readdir/closedir
+        int dfd1 = -1;
+        int dfd2 = -1;
+        long dp = 0L;
+        try {
+            dfd1 = open(dir, O_RDONLY, 0);
+            dfd2 = dup(dfd1);
+            dp = fdopendir(dfd1);
+        } catch (UnixException x) {
+            if (dfd1 != -1)
+                UnixNativeDispatcher.close(dfd1);
+            if (dfd2 != -1)
+                UnixNativeDispatcher.close(dfd2);
+            if (x.errno() == UnixConstants.ENOTDIR)
+                throw new NotDirectoryException(dir.getPathForExecptionMessage());
+            x.rethrowAsIOException(dir);
+        }
+        return new UnixSecureDirectoryStream(dir, dp, dfd2, filter);
+    }
+
+    @Override
+    public void createSymbolicLink(Path obj1, Path obj2, FileAttribute<?>... attrs)
+        throws IOException
+    {
+        UnixPath link = UnixPath.toUnixPath(obj1);
+        UnixPath target = UnixPath.toUnixPath(obj2);
+
+        // no attributes supported when creating links
+        if (attrs.length > 0) {
+            UnixFileModeAttribute.toUnixMode(0, attrs);  // may throw NPE or UOE
+            throw new UnsupportedOperationException("Initial file attributes" +
+                "not supported when creating symbolic link");
+        }
+
+        // permission check
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(new LinkPermission("symbolic"));
+            link.checkWrite();
+        }
+
+        // create link
+        try {
+            symlink(target.asByteArray(), link);
+        } catch (UnixException x) {
+            x.rethrowAsIOException(link);
+        }
+    }
+
+    @Override
+    public void createLink(Path obj1, Path obj2) throws IOException {
+        UnixPath link = UnixPath.toUnixPath(obj1);
+        UnixPath existing = UnixPath.toUnixPath(obj2);
+
+        // permission check
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(new LinkPermission("hard"));
+            link.checkWrite();
+            existing.checkWrite();
+        }
+        try {
+            link(existing, link);
+        } catch (UnixException x) {
+            x.rethrowAsIOException(link, existing);
+        }
+    }
+
+    @Override
+    public Path readSymbolicLink(Path obj1) throws IOException {
+        UnixPath link = UnixPath.toUnixPath(obj1);
+        // permission check
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            FilePermission perm = new FilePermission(link.getPathForPermissionCheck(),
+                SecurityConstants.FILE_READLINK_ACTION);
+            AccessController.checkPermission(perm);
+        }
+        try {
+            byte[] target = readlink(link);
+            return new UnixPath(link.getFileSystem(), target);
+        } catch (UnixException x) {
+           if (x.errno() == UnixConstants.EINVAL)
+                throw new NotLinkException(link.getPathForExecptionMessage());
+            x.rethrowAsIOException(link);
+            return null;    // keep compiler happy
+        }
+    }
 }
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixPath.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixPath.java	Fri Jan 28 09:28:43 2011 +0000
@@ -27,15 +27,11 @@
 
 import java.nio.*;
 import java.nio.file.*;
-import java.nio.file.attribute.*;
 import java.nio.charset.*;
-import java.nio.channels.*;
-import java.security.AccessController;
 import java.io.*;
 import java.net.URI;
 import java.util.*;
 import java.lang.ref.SoftReference;
-import sun.security.util.SecurityConstants;
 
 import static sun.nio.fs.UnixNativeDispatcher.*;
 import static sun.nio.fs.UnixConstants.*;
@@ -79,8 +75,6 @@
     // removes redundant slashes and check input for invalid characters
     static String normalizeAndCheck(String input) {
         int n = input.length();
-        if (n == 0)
-            throw new InvalidPathException(input, "Path is empty");
         char prevChar = 0;
         for (int i=0; i < n; i++) {
             char c = input.charAt(i);
@@ -174,7 +168,13 @@
         if (getFileSystem().needToResolveAgainstDefaultDirectory()) {
             return resolve(getFileSystem().defaultDirectory(), path);
         } else {
-            return path;
+            if (!isEmpty()) {
+                return path;
+            } else {
+                // empty path case will access current directory
+                byte[] here = { '.' };
+                return here;
+            }
         }
     }
 
@@ -193,7 +193,7 @@
     }
 
     // Checks that the given file is a UnixPath
-    private UnixPath checkPath(FileRef obj) {
+    static UnixPath toUnixPath(Path obj) {
         if (obj == null)
             throw new NullPointerException();
         if (!(obj instanceof UnixPath))
@@ -209,12 +209,17 @@
             // count names
             count = 0;
             index = 0;
-            while (index < path.length) {
-                byte c = path[index++];
-                if (c != '/') {
-                    count++;
-                    while (index < path.length && path[index] != '/')
-                        index++;
+            if (isEmpty()) {
+                // empty path has one name
+                count = 1;
+            } else {
+                while (index < path.length) {
+                    byte c = path[index++];
+                    if (c != '/') {
+                        count++;
+                        while (index < path.length && path[index] != '/')
+                            index++;
+                    }
                 }
             }
 
@@ -239,6 +244,16 @@
         }
     }
 
+    // returns {@code true} if this path is an empty path
+    private boolean isEmpty() {
+        return path.length == 0;
+    }
+
+    // returns an empty path
+    private UnixPath emptyPath() {
+        return new UnixPath(getFileSystem(), new byte[0]);
+    }
+
     @Override
     public UnixFileSystem getFileSystem() {
         return fs;
@@ -246,7 +261,7 @@
 
     @Override
     public UnixPath getRoot() {
-        if (path[0] == '/') {
+        if (path.length > 0 && path[0] == '/') {
             return getFileSystem().rootDirectory();
         } else {
             return null;
@@ -254,14 +269,17 @@
     }
 
     @Override
-    public UnixPath getName() {
+    public UnixPath getFileName() {
         initOffsets();
 
         int count = offsets.length;
+
+        // no elements so no name
         if (count == 0)
-            return null;  // no elements so no name
+            return null;
 
-        if (count == 1 && path[0] != '/')
+        // one name element and no root component
+        if (count == 1 && path.length > 0 && path[0] != '/')
             return this;
 
         int lastOffset = offsets[count-1];
@@ -349,57 +367,58 @@
 
     @Override
     public boolean isAbsolute() {
-        return (path[0] == '/');
+        return (path.length > 0 && path[0] == '/');
     }
 
     // Resolve child against given base
     private static byte[] resolve(byte[] base, byte[] child) {
-        if (child[0] == '/')
+        int baseLength = base.length;
+        int childLength = child.length;
+        if (childLength == 0)
+            return base;
+        if (baseLength == 0 || child[0] == '/')
             return child;
         byte[] result;
-        if (base.length == 1 && base[0] == '/') {
-            result = new byte[child.length + 1];
+        if (baseLength == 1 && base[0] == '/') {
+            result = new byte[childLength + 1];
             result[0] = '/';
-            System.arraycopy(child, 0, result, 1, child.length);
+            System.arraycopy(child, 0, result, 1, childLength);
         } else {
-            result = new byte[base.length + 1 + child.length];
-            System.arraycopy(base, 0, result, 0, base.length);
+            result = new byte[baseLength + 1 + childLength];
+            System.arraycopy(base, 0, result, 0, baseLength);
             result[base.length] = '/';
-            System.arraycopy(child, 0, result,  base.length+1, child.length);
+            System.arraycopy(child, 0, result, baseLength+1, childLength);
         }
         return result;
     }
 
     @Override
     public UnixPath resolve(Path obj) {
-        if (obj == null)
-            return this;
-        byte[] other = checkPath(obj).path;
-        if (other[0] == '/')
+        byte[] other = toUnixPath(obj).path;
+        if (other.length > 0 && other[0] == '/')
             return ((UnixPath)obj);
         byte[] result = resolve(path, other);
         return new UnixPath(getFileSystem(), result);
     }
 
-    @Override
-    public UnixPath resolve(String other) {
-        return resolve(new UnixPath(getFileSystem(), other));
-    }
-
     UnixPath resolve(byte[] other) {
         return resolve(new UnixPath(getFileSystem(), other));
     }
 
     @Override
     public UnixPath relativize(Path obj) {
-        UnixPath other = checkPath(obj);
+        UnixPath other = toUnixPath(obj);
         if (other.equals(this))
-            return null;
+            return emptyPath();
 
         // can only relativize paths of the same type
         if (this.isAbsolute() != other.isAbsolute())
             throw new IllegalArgumentException("'other' is different type of Path");
 
+        // this path is the empty path
+        if (this.isEmpty())
+            return other;
+
         int bn = this.getNameCount();
         int cn = other.getNameCount();
 
@@ -419,14 +438,27 @@
             if (dotdots == 0)
                 return remainder;
 
+            // other is the empty path
+            boolean isOtherEmpty = other.isEmpty();
+
             // result is a  "../" for each remaining name in base
-            // followed by the remaining names in other
-            byte[] result = new byte[dotdots*3 + remainder.path.length];
+            // followed by the remaining names in other. If the remainder is
+            // the empty path then we don't add the final trailing slash.
+            int len = dotdots*3 + remainder.path.length;
+            if (isOtherEmpty) {
+                assert remainder.isEmpty();
+                len--;
+            }
+            byte[] result = new byte[len];
             int pos = 0;
             while (dotdots > 0) {
                 result[pos++] = (byte)'.';
                 result[pos++] = (byte)'.';
-                result[pos++] = (byte)'/';
+                if (isOtherEmpty) {
+                    if (dotdots > 1) result[pos++] = (byte)'/';
+                } else {
+                    result[pos++] = (byte)'/';
+                }
                 dotdots--;
             }
             System.arraycopy(remainder.path, 0, result, pos, remainder.path.length);
@@ -457,7 +489,7 @@
         int[] size = new int[count];                // length of name
         int remaining = count;                      // number of names remaining
         boolean hasDotDot = false;                  // has at least one ..
-        boolean isAbsolute = path[0] == '/';
+        boolean isAbsolute = isAbsolute();
 
         // first pass:
         //   1. compute length of names
@@ -542,7 +574,7 @@
 
         // corner case - all names removed
         if (remaining == 0) {
-            return isAbsolute ? getFileSystem().rootDirectory() : null;
+            return isAbsolute ? getFileSystem().rootDirectory() : emptyPath();
         }
 
         // compute length of result
@@ -574,7 +606,7 @@
 
     @Override
     public boolean startsWith(Path other) {
-        UnixPath that = checkPath(other);
+        UnixPath that = toUnixPath(other);
 
         // other path is longer
         if (that.path.length > path.length)
@@ -584,8 +616,9 @@
         int thatOffsetCount = that.getNameCount();
 
         // other path has no name elements
-        if (thatOffsetCount == 0 && this.isAbsolute())
-            return true;
+        if (thatOffsetCount == 0 && this.isAbsolute()) {
+            return that.isEmpty() ? false : true;
+        }
 
         // given path has more elements that this path
         if (thatOffsetCount > thisOffsetCount)
@@ -622,7 +655,7 @@
 
     @Override
     public boolean endsWith(Path other) {
-        UnixPath that = checkPath(other);
+        UnixPath that = toUnixPath(other);
 
         int thisLen = path.length;
         int thatLen = that.path.length;
@@ -631,6 +664,10 @@
         if (thatLen > thisLen)
             return false;
 
+        // other path is the empty path
+        if (thisLen > 0 && thatLen == 0)
+            return false;
+
         // other path is absolute so this path must be absolute
         if (that.isAbsolute() && !this.isAbsolute())
             return false;
@@ -721,32 +758,6 @@
         return stringValue;
     }
 
-    @Override
-    public Iterator<Path> iterator() {
-        initOffsets();
-        return new Iterator<Path>() {
-            int i = 0;
-            @Override
-            public boolean hasNext() {
-                return (i < offsets.length);
-            }
-            @Override
-            public Path next() {
-                if (i < offsets.length) {
-                    Path result = getName(i);
-                    i++;
-                    return result;
-                } else {
-                    throw new NoSuchElementException();
-                }
-            }
-            @Override
-            public void remove() {
-                throw new UnsupportedOperationException();
-            }
-        };
-    }
-
     // -- file operations --
 
     // package-private
@@ -770,7 +781,6 @@
         }
     }
 
-
     void checkRead() {
         SecurityManager sm = System.getSecurityManager();
         if (sm != null)
@@ -790,296 +800,6 @@
     }
 
     @Override
-    public FileStore getFileStore()
-        throws IOException
-    {
-        SecurityManager sm = System.getSecurityManager();
-        if (sm != null) {
-            sm.checkPermission(new RuntimePermission("getFileStoreAttributes"));
-            checkRead();
-        }
-        return getFileSystem().getFileStore(this);
-    }
-
-    @Override
-    public void checkAccess(AccessMode... modes) throws IOException {
-        boolean e = false;
-        boolean r = false;
-        boolean w = false;
-        boolean x = false;
-
-        if (modes.length == 0) {
-            e = true;
-        } else {
-            for (AccessMode mode: modes) {
-                switch (mode) {
-                    case READ : r = true; break;
-                    case WRITE : w = true; break;
-                    case EXECUTE : x = true; break;
-                    default: throw new AssertionError("Should not get here");
-                }
-            }
-        }
-
-        int mode = 0;
-        if (e || r) {
-            checkRead();
-            mode |= (r) ? R_OK : F_OK;
-        }
-        if (w) {
-            checkWrite();
-            mode |= W_OK;
-        }
-        if (x) {
-            SecurityManager sm = System.getSecurityManager();
-            if (sm != null) {
-                // not cached
-                sm.checkExec(getPathForPermissionCheck());
-            }
-            mode |= X_OK;
-        }
-        try {
-            access(this, mode);
-        } catch (UnixException exc) {
-            exc.rethrowAsIOException(this);
-        }
-    }
-
-    @Override
-    void implDelete(boolean failIfNotExists) throws IOException {
-        checkDelete();
-
-        // need file attributes to know if file is directory
-        UnixFileAttributes attrs = null;
-        try {
-            attrs = UnixFileAttributes.get(this, false);
-            if (attrs.isDirectory()) {
-                rmdir(this);
-            } else {
-                unlink(this);
-            }
-        } catch (UnixException x) {
-            // no-op if file does not exist
-            if (!failIfNotExists && x.errno() == ENOENT)
-                return;
-
-            // DirectoryNotEmptyException if not empty
-            if (attrs != null && attrs.isDirectory() &&
-                (x.errno() == EEXIST || x.errno() == ENOTEMPTY))
-                throw new DirectoryNotEmptyException(getPathForExecptionMessage());
-
-            x.rethrowAsIOException(this);
-        }
-    }
-
-    @Override
-    public DirectoryStream<Path> newDirectoryStream(DirectoryStream.Filter<? super Path> filter)
-        throws IOException
-    {
-        if (filter == null)
-            throw new NullPointerException();
-        checkRead();
-
-        // can't return SecureDirectoryStream on kernels that don't support
-        // openat, etc.
-        if (!supportsAtSysCalls()) {
-            try {
-                long ptr = opendir(this);
-                return new UnixDirectoryStream(this, ptr, filter);
-            } catch (UnixException x) {
-                if (x.errno() == ENOTDIR)
-                    throw new NotDirectoryException(getPathForExecptionMessage());
-                x.rethrowAsIOException(this);
-            }
-        }
-
-        // open directory and dup file descriptor for use by
-        // opendir/readdir/closedir
-        int dfd1 = -1;
-        int dfd2 = -1;
-        long dp = 0L;
-        try {
-            dfd1 = open(this, O_RDONLY, 0);
-            dfd2 = dup(dfd1);
-            dp = fdopendir(dfd1);
-        } catch (UnixException x) {
-            if (dfd1 != -1)
-                close(dfd1);
-            if (dfd2 != -1)
-                close(dfd2);
-            if (x.errno() == UnixConstants.ENOTDIR)
-                throw new NotDirectoryException(getPathForExecptionMessage());
-            x.rethrowAsIOException(this);
-        }
-        return new UnixSecureDirectoryStream(this, dp, dfd2, filter);
-    }
-
-    // invoked by AbstractPath#copyTo
-    @Override
-    public void implCopyTo(Path obj, CopyOption... options)
-        throws IOException
-    {
-        UnixPath target = (UnixPath)obj;
-        UnixCopyFile.copy(this, target, options);
-    }
-
-    @Override
-    public void implMoveTo(Path obj, CopyOption... options)
-        throws IOException
-    {
-        UnixPath target = (UnixPath)obj;
-        UnixCopyFile.move(this, target, options);
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public <V extends FileAttributeView> V
-        getFileAttributeView(Class<V> type, LinkOption... options)
-    {
-        FileAttributeView view = getFileSystem()
-            .newFileAttributeView(type, this, options);
-        if (view == null)
-            return null;
-        return (V) view;
-    }
-
-    @Override
-    public DynamicFileAttributeView getFileAttributeView(String name,
-                                                         LinkOption... options)
-    {
-        return getFileSystem().newFileAttributeView(name, this, options);
-    }
-
-    @Override
-    public Path createDirectory(FileAttribute<?>... attrs)
-        throws IOException
-    {
-        checkWrite();
-
-        int mode = UnixFileModeAttribute
-            .toUnixMode(UnixFileModeAttribute.ALL_PERMISSIONS, attrs);
-        try {
-            mkdir(this, mode);
-        } catch (UnixException x) {
-            x.rethrowAsIOException(this);
-        }
-        return this;
-    }
-
-    @Override
-    public SeekableByteChannel newByteChannel(Set<? extends OpenOption> options,
-                                              FileAttribute<?>... attrs)
-         throws IOException
-    {
-        int mode = UnixFileModeAttribute
-            .toUnixMode(UnixFileModeAttribute.ALL_READWRITE, attrs);
-        try {
-            return UnixChannelFactory.newFileChannel(this, options, mode);
-        } catch (UnixException x) {
-            x.rethrowAsIOException(this);
-            return null;  // keep compiler happy
-        }
-    }
-
-    @Override
-    public boolean isSameFile(Path obj) throws IOException {
-        if (this.equals(obj))
-            return true;
-        if (!(obj instanceof UnixPath))  // includes null check
-            return false;
-        UnixPath other = (UnixPath)obj;
-
-        // check security manager access to both files
-        this.checkRead();
-        other.checkRead();
-
-        UnixFileAttributes thisAttrs;
-        UnixFileAttributes otherAttrs;
-        try {
-             thisAttrs = UnixFileAttributes.get(this, true);
-        } catch (UnixException x) {
-            x.rethrowAsIOException(this);
-            return false;    // keep compiler happy
-        }
-        try {
-            otherAttrs = UnixFileAttributes.get(other, true);
-        } catch (UnixException x) {
-            x.rethrowAsIOException(other);
-            return false;    // keep compiler happy
-        }
-        return thisAttrs.isSameFile(otherAttrs);
-    }
-
-    @Override
-    public Path createSymbolicLink(Path obj, FileAttribute<?>... attrs)
-        throws IOException
-    {
-        UnixPath target = checkPath(obj);
-
-        // no attributes supported when creating links
-        if (attrs.length > 0) {
-            UnixFileModeAttribute.toUnixMode(0, attrs);  // may throw NPE or UOE
-            throw new UnsupportedOperationException("Initial file attributes" +
-                "not supported when creating symbolic link");
-        }
-
-        // permission check
-        SecurityManager sm = System.getSecurityManager();
-        if (sm != null) {
-            sm.checkPermission(new LinkPermission("symbolic"));
-            checkWrite();
-        }
-
-        // create link
-        try {
-            symlink(target.asByteArray(), this);
-        } catch (UnixException x) {
-            x.rethrowAsIOException(this);
-        }
-
-        return this;
-    }
-
-    @Override
-    public Path createLink(Path obj) throws IOException {
-        UnixPath existing = checkPath(obj);
-
-        // permission check
-        SecurityManager sm = System.getSecurityManager();
-        if (sm != null) {
-            sm.checkPermission(new LinkPermission("hard"));
-            this.checkWrite();
-            existing.checkWrite();
-        }
-        try {
-            link(existing, this);
-        } catch (UnixException x) {
-            x.rethrowAsIOException(this, existing);
-        }
-        return this;
-    }
-
-    @Override
-    public Path readSymbolicLink() throws IOException {
-        // permission check
-        SecurityManager sm = System.getSecurityManager();
-        if (sm != null) {
-            FilePermission perm = new FilePermission(getPathForPermissionCheck(),
-                SecurityConstants.FILE_READLINK_ACTION);
-            AccessController.checkPermission(perm);
-        }
-        try {
-            byte[] target = readlink(this);
-            return new UnixPath(getFileSystem(), target);
-        } catch (UnixException x) {
-           if (x.errno() == UnixConstants.EINVAL)
-                throw new NotLinkException(getPathForExecptionMessage());
-            x.rethrowAsIOException(this);
-            return null;    // keep compiler happy
-        }
-    }
-
-    @Override
     public UnixPath toAbsolutePath() {
         if (isAbsolute()) {
             return this;
@@ -1095,7 +815,7 @@
     }
 
     @Override
-    public UnixPath toRealPath(boolean resolveLinks) throws IOException {
+    public Path toRealPath(boolean resolveLinks) throws IOException {
         checkRead();
 
         UnixPath absolute = toAbsolutePath();
@@ -1112,8 +832,7 @@
 
         // if resolveLinks is false then eliminate "." and also ".."
         // where the previous element is not a link.
-        UnixPath root = getFileSystem().rootDirectory();
-        UnixPath result = root;
+        UnixPath result = fs.rootDirectory();
         for (int i=0; i<absolute.getNameCount(); i++) {
             UnixPath element = absolute.getName(i);
 
@@ -1134,7 +853,7 @@
                 if (!attrs.isSymbolicLink()) {
                     result = result.getParent();
                     if (result == null) {
-                        result = root;
+                        result = fs.rootDirectory();
                     }
                     continue;
                 }
@@ -1152,15 +871,6 @@
     }
 
     @Override
-    public boolean isHidden() {
-        checkRead();
-        UnixPath name = getName();
-        if (name == null)
-            return false;
-        return (name.asByteArray()[0] == '.');
-    }
-
-    @Override
     public URI toUri() {
         return UnixUriUtils.toUri(this);
     }
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixSecureDirectoryStream.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixSecureDirectoryStream.java	Fri Jan 28 09:28:43 2011 +0000
@@ -40,7 +40,7 @@
  */
 
 class UnixSecureDirectoryStream
-    extends SecureDirectoryStream<Path>
+    implements SecureDirectoryStream<Path>
 {
     private final UnixDirectoryStream ds;
     private final int dfd;
@@ -81,6 +81,20 @@
         return (UnixPath)obj;
     }
 
+    private boolean followLinks(LinkOption... options) {
+        boolean followLinks = true;
+        for (LinkOption option: options) {
+            if (option == LinkOption.NOFOLLOW_LINKS) {
+                followLinks = false;
+                continue;
+            }
+            if (option == null)
+                throw new NullPointerException();
+            throw new AssertionError("Should not get here");
+        }
+        return followLinks;
+    }
+
     /**
      * Opens sub-directory in this directory
      */
@@ -91,7 +105,7 @@
     {
         UnixPath file = getName(obj);
         UnixPath child = ds.directory().resolve(file);
-        boolean followLinks = file.getFileSystem().followLinks(options);
+        boolean followLinks = followLinks(options);
 
         // permission check using name resolved against original path of directory
         SecurityManager sm = System.getSecurityManager();
@@ -302,7 +316,7 @@
                                                                 LinkOption... options)
     {
         UnixPath file = getName(obj);
-        boolean followLinks = file.getFileSystem().followLinks(options);
+        boolean followLinks = followLinks(options);
         return getFileAttributeViewImpl(file, type, followLinks);
     }
 
@@ -336,7 +350,11 @@
         private void checkWriteAccess() {
             SecurityManager sm = System.getSecurityManager();
             if (sm != null) {
-                ds.directory().resolve(file).checkWrite();
+                if (file == null) {
+                    ds.directory().checkWrite();
+                } else {
+                    ds.directory().resolve(file).checkWrite();
+                }
             }
         }
 
--- a/jdk/src/windows/classes/sun/nio/fs/RegistryFileTypeDetector.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/windows/classes/sun/nio/fs/RegistryFileTypeDetector.java	Fri Jan 28 09:28:43 2011 +0000
@@ -42,12 +42,12 @@
     }
 
     @Override
-    public String implProbeContentType(FileRef file) throws IOException {
+    public String implProbeContentType(Path file) throws IOException {
         if (!(file instanceof Path))
             return null;
 
         // get file extension
-        Path name = ((Path)file).getName();
+        Path name = file.getFileName();
         if (name == null)
             return null;
         String filename = name.toString();
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsFileAttributeViews.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsFileAttributeViews.java	Fri Jan 28 09:28:43 2011 +0000
@@ -167,22 +167,6 @@
         }
 
         @Override
-        public Object getAttribute(String attribute) throws IOException {
-            if (attribute.equals(READONLY_NAME))
-                return readAttributes().isReadOnly();
-            if (attribute.equals(ARCHIVE_NAME))
-                return readAttributes().isArchive();
-            if (attribute.equals(SYSTEM_NAME))
-                return readAttributes().isSystem();
-            if (attribute.equals(HIDDEN_NAME))
-                return readAttributes().isHidden();
-            // implementation specific
-            if (attribute.equals(ATTRIBUTES_NAME))
-                return readAttributes().attributes();
-            return super.getAttribute(attribute);
-        }
-
-        @Override
         public void setAttribute(String attribute, Object value)
             throws IOException
         {
@@ -206,7 +190,7 @@
         }
 
         @Override
-        public Map<String,?> readAttributes(String[] attributes)
+        public Map<String,Object> readAttributes(String[] attributes)
             throws IOException
         {
             AttributesBuilder builder = AttributesBuilder.create(attributes);
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsFileCopy.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsFileCopy.java	Fri Jan 28 09:28:43 2011 +0000
@@ -158,7 +158,7 @@
                     if (x.lastError() == ERROR_DIR_NOT_EMPTY ||
                         x.lastError() == ERROR_ALREADY_EXISTS)
                     {
-                        throw new FileAlreadyExistsException(
+                        throw new DirectoryNotEmptyException(
                             target.getPathForExceptionMessage());
                     }
                 }
@@ -369,7 +369,7 @@
                     if (x.lastError() == ERROR_DIR_NOT_EMPTY ||
                         x.lastError() == ERROR_ALREADY_EXISTS)
                     {
-                        throw new FileAlreadyExistsException(
+                        throw new DirectoryNotEmptyException(
                             target.getPathForExceptionMessage());
                     }
                 }
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsFileStore.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsFileStore.java	Fri Jan 28 09:28:43 2011 +0000
@@ -117,28 +117,47 @@
         return ((volInfo.flags() & FILE_READ_ONLY_VOLUME) != 0);
     }
 
+    // read the free space info
+    private DiskFreeSpace readDiskFreeSpace() throws IOException {
+        try {
+            return GetDiskFreeSpaceEx(root);
+        } catch (WindowsException x) {
+            x.rethrowAsIOException(root);
+            return null;
+        }
+    }
+
     @Override
-    @SuppressWarnings("unchecked")
+    public long getTotalSpace() throws IOException {
+        return readDiskFreeSpace().totalNumberOfBytes();
+    }
+
+    @Override
+    public long getUsableSpace() throws IOException {
+        return readDiskFreeSpace().freeBytesAvailable();
+    }
+
+    @Override
+    public long getUnallocatedSpace() throws IOException {
+        return readDiskFreeSpace().freeBytesAvailable();
+    }
+
+    @Override
     public <V extends FileStoreAttributeView> V getFileStoreAttributeView(Class<V> type) {
         if (type == null)
             throw new NullPointerException();
-        if (type == FileStoreSpaceAttributeView.class)
-            return (V) new WindowsFileStoreAttributeView(this);
         return (V) null;
     }
 
     @Override
     public Object getAttribute(String attribute) throws IOException {
         // standard
-        if (attribute.equals("space:totalSpace"))
-            return new WindowsFileStoreAttributeView(this)
-                .readAttributes().totalSpace();
-        if (attribute.equals("space:usableSpace"))
-            return new WindowsFileStoreAttributeView(this)
-                 .readAttributes().usableSpace();
-        if (attribute.equals("space:unallocatedSpace"))
-            return new WindowsFileStoreAttributeView(this)
-                 .readAttributes().unallocatedSpace();
+        if (attribute.equals("totalSpace"))
+            return getTotalSpace();
+        if (attribute.equals("usableSpace"))
+            return getUsableSpace();
+        if (attribute.equals("unallocatedSpace"))
+            return getUnallocatedSpace();
         // windows specific for testing purposes
         if (attribute.equals("volume:vsn"))
             return volInfo.volumeSerialNumber();
@@ -202,48 +221,4 @@
         sb.append(")");
         return sb.toString();
     }
-
-    static class WindowsFileStoreAttributeView
-        implements FileStoreSpaceAttributeView
-    {
-        private final WindowsFileStore fs;
-
-        WindowsFileStoreAttributeView(WindowsFileStore fs) {
-            this.fs = fs;
-        }
-
-        @Override
-        public String name() {
-            return "space";
-        }
-
-        @Override
-        public FileStoreSpaceAttributes readAttributes()
-            throws IOException
-        {
-            // read the free space info
-            DiskFreeSpace info = null;
-            try {
-                info = GetDiskFreeSpaceEx(fs.root);
-            } catch (WindowsException x) {
-                x.rethrowAsIOException(fs.root);
-            }
-
-            final DiskFreeSpace result = info;
-            return new FileStoreSpaceAttributes() {
-                @Override
-                public long totalSpace() {
-                    return result.totalNumberOfBytes();
-                }
-                @Override
-                public long usableSpace() {
-                    return result.freeBytesAvailable();
-                }
-                @Override
-                public long unallocatedSpace() {
-                    return result.totalNumberOfFreeBytes();
-                }
-            };
-        }
-    }
  }
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsFileSystem.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsFileSystem.java	Fri Jan 28 09:28:43 2011 +0000
@@ -127,7 +127,7 @@
         }
 
         // iterate over roots, ignoring those that the security manager denies
-        ArrayList<Path> result = new ArrayList<Path>();
+        ArrayList<Path> result = new ArrayList<>();
         SecurityManager sm = System.getSecurityManager();
         for (int i = 0; i <= 25; i++) {  // 0->A, 1->B, 2->C...
             if ((drives & (1 << i)) != 0) {
@@ -235,33 +235,50 @@
     }
 
     @Override
-    public Path getPath(String path) {
+    public final Path getPath(String first, String... more) {
+        String path;
+        if (more.length == 0) {
+            path = first;
+        } else {
+            StringBuilder sb = new StringBuilder();
+            sb.append(first);
+            for (String segment: more) {
+                if (segment.length() > 0) {
+                    if (sb.length() > 0)
+                        sb.append('\\');
+                    sb.append(segment);
+                }
+            }
+            path = sb.toString();
+        }
         return WindowsPath.parse(this, path);
     }
 
     @Override
     public UserPrincipalLookupService getUserPrincipalLookupService() {
-        return theLookupService;
+        return LookupService.instance;
     }
 
-    private static final UserPrincipalLookupService theLookupService =
-        new UserPrincipalLookupService() {
-            @Override
-            public UserPrincipal lookupPrincipalByName(String name)
-                throws IOException
-            {
-                return WindowsUserPrincipals.lookup(name);
-            }
-            @Override
-            public GroupPrincipal lookupPrincipalByGroupName(String group)
-                throws IOException
-            {
-                UserPrincipal user = WindowsUserPrincipals.lookup(group);
-                if (!(user instanceof GroupPrincipal))
-                    throw new UserPrincipalNotFoundException(group);
-                return (GroupPrincipal)user;
-            }
-        };
+    private static class LookupService {
+        static final UserPrincipalLookupService instance =
+            new UserPrincipalLookupService() {
+                @Override
+                public UserPrincipal lookupPrincipalByName(String name)
+                    throws IOException
+                {
+                    return WindowsUserPrincipals.lookup(name);
+                }
+                @Override
+                public GroupPrincipal lookupPrincipalByGroupName(String group)
+                    throws IOException
+                {
+                    UserPrincipal user = WindowsUserPrincipals.lookup(group);
+                    if (!(user instanceof GroupPrincipal))
+                        throw new UserPrincipalNotFoundException(group);
+                    return (GroupPrincipal)user;
+                }
+            };
+    }
 
     @Override
     public PathMatcher getPathMatcher(String syntaxAndInput) {
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java	Fri Jan 28 09:28:43 2011 +0000
@@ -26,19 +26,25 @@
 package sun.nio.fs;
 
 import java.nio.file.*;
-import java.nio.file.spi.*;
 import java.nio.file.attribute.*;
 import java.nio.channels.*;
 import java.net.URI;
 import java.util.concurrent.ExecutorService;
-import java.io.IOException;
+import java.io.*;
 import java.util.*;
+import java.security.AccessController;
+import sun.misc.Unsafe;
+import sun.nio.ch.ThreadPool;
+import sun.security.util.SecurityConstants;
 
-import sun.nio.ch.ThreadPool;
+import static sun.nio.fs.WindowsNativeDispatcher.*;
+import static sun.nio.fs.WindowsConstants.*;
 
 public class WindowsFileSystemProvider
-    extends FileSystemProvider
+    extends AbstractFileSystemProvider
 {
+    private static final Unsafe unsafe = Unsafe.getUnsafe();
+
     private static final String USER_DIR = "user.dir";
     private final WindowsFileSystem theFileSystem;
 
@@ -143,4 +149,505 @@
                 sd.release();
         }
     }
+
+    private boolean followLinks(LinkOption... options) {
+        boolean followLinks = true;
+        for (LinkOption option: options) {
+            if (option == LinkOption.NOFOLLOW_LINKS) {
+                followLinks = false;
+                continue;
+            }
+            if (option == null)
+                throw new NullPointerException();
+            throw new AssertionError("Should not get here");
+        }
+        return followLinks;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public <V extends FileAttributeView> V
+        getFileAttributeView(Path obj, Class<V> view, LinkOption... options)
+    {
+        WindowsPath file = WindowsPath.toWindowsPath(obj);
+        if (view == null)
+            throw new NullPointerException();
+        boolean followLinks = followLinks(options);
+        if (view == BasicFileAttributeView.class)
+            return (V) WindowsFileAttributeViews.createBasicView(file, followLinks);
+        if (view == DosFileAttributeView.class)
+            return (V) WindowsFileAttributeViews.createDosView(file, followLinks);
+        if (view == AclFileAttributeView.class)
+            return (V) new WindowsAclFileAttributeView(file, followLinks);
+        if (view == FileOwnerAttributeView.class)
+            return (V) new FileOwnerAttributeViewImpl(
+                new WindowsAclFileAttributeView(file, followLinks));
+        if (view == UserDefinedFileAttributeView.class)
+            return (V) new WindowsUserDefinedFileAttributeView(file, followLinks);
+        return (V) null;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public <A extends BasicFileAttributes> A readAttributes(Path file,
+                                                            Class<A> type,
+                                                            LinkOption... options)
+        throws IOException
+    {
+        Class<? extends BasicFileAttributeView> view;
+        if (type == BasicFileAttributes.class)
+            view = BasicFileAttributeView.class;
+        else if (type == DosFileAttributes.class)
+            view = DosFileAttributeView.class;
+        else if (type == null)
+            throw new NullPointerException();
+        else
+            throw new UnsupportedOperationException();
+        return (A) getFileAttributeView(file, view, options).readAttributes();
+    }
+
+    @Override
+    public DynamicFileAttributeView getFileAttributeView(Path obj, String name, LinkOption... options) {
+        WindowsPath file = WindowsPath.toWindowsPath(obj);
+        boolean followLinks = followLinks(options);
+        if (name.equals("basic"))
+            return WindowsFileAttributeViews.createBasicView(file, followLinks);
+        if (name.equals("dos"))
+            return WindowsFileAttributeViews.createDosView(file, followLinks);
+        if (name.equals("acl"))
+            return new WindowsAclFileAttributeView(file, followLinks);
+        if (name.equals("owner"))
+            return new FileOwnerAttributeViewImpl(
+                new WindowsAclFileAttributeView(file, followLinks));
+        if (name.equals("user"))
+            return new WindowsUserDefinedFileAttributeView(file, followLinks);
+        return null;
+    }
+
+    @Override
+    public SeekableByteChannel newByteChannel(Path obj,
+                                              Set<? extends OpenOption> options,
+                                              FileAttribute<?>... attrs)
+         throws IOException
+    {
+        WindowsPath file = WindowsPath.toWindowsPath(obj);
+        WindowsSecurityDescriptor sd =
+            WindowsSecurityDescriptor.fromAttribute(attrs);
+        try {
+            return WindowsChannelFactory
+                .newFileChannel(file.getPathForWin32Calls(),
+                                file.getPathForPermissionCheck(),
+                                options,
+                                sd.address());
+        } catch (WindowsException x) {
+            x.rethrowAsIOException(file);
+            return null;  // keep compiler happy
+        } finally {
+            sd.release();
+        }
+    }
+
+    @Override
+    boolean implDelete(Path obj, boolean failIfNotExists) throws IOException {
+        WindowsPath file = WindowsPath.toWindowsPath(obj);
+        file.checkDelete();
+
+        WindowsFileAttributes attrs = null;
+        try {
+             // need to know if file is a directory or junction
+             attrs = WindowsFileAttributes.get(file, false);
+             if (attrs.isDirectory() || attrs.isDirectoryLink()) {
+                RemoveDirectory(file.getPathForWin32Calls());
+             } else {
+                DeleteFile(file.getPathForWin32Calls());
+             }
+             return true;
+        } catch (WindowsException x) {
+
+            // no-op if file does not exist
+            if (!failIfNotExists &&
+                (x.lastError() == ERROR_FILE_NOT_FOUND ||
+                 x.lastError() == ERROR_PATH_NOT_FOUND)) return false;
+
+            if (attrs != null && attrs.isDirectory()) {
+                // ERROR_ALREADY_EXISTS is returned when attempting to delete
+                // non-empty directory on SAMBA servers.
+                if (x.lastError() == ERROR_DIR_NOT_EMPTY ||
+                    x.lastError() == ERROR_ALREADY_EXISTS)
+                {
+                    throw new DirectoryNotEmptyException(
+                        file.getPathForExceptionMessage());
+                }
+            }
+            x.rethrowAsIOException(file);
+            return false;
+        }
+    }
+
+    @Override
+    public void copy(Path source, Path target, CopyOption... options)
+        throws IOException
+    {
+        WindowsFileCopy.copy(WindowsPath.toWindowsPath(source),
+                             WindowsPath.toWindowsPath(target),
+                             options);
+    }
+
+    @Override
+    public void move(Path source, Path target, CopyOption... options)
+        throws IOException
+    {
+        WindowsFileCopy.move(WindowsPath.toWindowsPath(source),
+                             WindowsPath.toWindowsPath(target),
+                             options);
+    }
+
+    /**
+     * Returns buffer with SID_AND_ATTRIBUTES structure representing the user
+     * associated with the current thread access token.
+     * FIXME - this should be cached.
+     */
+    private static NativeBuffer getUserInfo(WindowsPath file) throws IOException {
+        try {
+            long hToken = WindowsSecurity.processTokenWithQueryAccess;
+            int size = GetTokenInformation(hToken, TokenUser, 0L, 0);
+            assert size > 0;
+
+            NativeBuffer buffer = NativeBuffers.getNativeBuffer(size);
+            try {
+                int newsize = GetTokenInformation(hToken, TokenUser,
+                                                  buffer.address(), size);
+                if (newsize != size)
+                    throw new AssertionError();
+                return buffer;
+            } catch (WindowsException x) {
+                buffer.release();
+                throw x;
+            }
+        } catch (WindowsException x) {
+            throw new IOException(x.getMessage());
+        }
+    }
+
+    /**
+     * Reads the file ACL and return the effective access as ACCESS_MASK
+     */
+    private static int getEffectiveAccess(WindowsPath file) throws IOException {
+        // read security descriptor continaing ACL (symlinks are followed)
+        String target = WindowsLinkSupport.getFinalPath(file, true);
+        NativeBuffer aclBuffer = WindowsAclFileAttributeView
+            .getFileSecurity(target, DACL_SECURITY_INFORMATION);
+
+        // retrieves DACL from security descriptor
+        long pAcl = GetSecurityDescriptorDacl(aclBuffer.address());
+
+        // Use GetEffectiveRightsFromAcl to get effective access to file
+        try {
+            NativeBuffer userBuffer = getUserInfo(file);
+            try {
+                try {
+                    // SID_AND_ATTRIBUTES->pSid
+                    long pSid = unsafe.getAddress(userBuffer.address());
+                    long pTrustee = BuildTrusteeWithSid(pSid);
+                    try {
+                        return GetEffectiveRightsFromAcl(pAcl, pTrustee);
+                    } finally {
+                        LocalFree(pTrustee);
+                    }
+                } catch (WindowsException x) {
+                    throw new IOException("Unable to get effective rights from ACL: " +
+                        x.getMessage());
+                }
+            } finally {
+                userBuffer.release();
+            }
+        } finally {
+            aclBuffer.release();
+        }
+    }
+
+    @Override
+    public void checkAccess(Path obj, AccessMode... modes) throws IOException {
+        WindowsPath file = WindowsPath.toWindowsPath(obj);
+        // if no access modes then simply file attributes
+        if (modes.length == 0) {
+            file.checkRead();
+            try {
+                WindowsFileAttributes.get(file, true);
+            } catch (WindowsException exc) {
+                exc.rethrowAsIOException(file);
+            }
+            return;
+        }
+
+        boolean r = false;
+        boolean w = false;
+        boolean x = false;
+        for (AccessMode mode: modes) {
+            switch (mode) {
+                case READ : r = true; break;
+                case WRITE : w = true; break;
+                case EXECUTE : x = true; break;
+                default: throw new AssertionError("Should not get here");
+            }
+        }
+
+        int mask = 0;
+        if (r) {
+            file.checkRead();
+            mask |= FILE_READ_DATA;
+        }
+        if (w) {
+            file.checkWrite();
+            mask |= FILE_WRITE_DATA;
+        }
+        if (x) {
+            SecurityManager sm = System.getSecurityManager();
+            if (sm != null)
+                sm.checkExec(file.getPathForPermissionCheck());
+            mask |= FILE_EXECUTE;
+        }
+
+        if ((getEffectiveAccess(file) & mask) == 0)
+            throw new AccessDeniedException(
+                file.getPathForExceptionMessage(), null,
+                "Effective permissions does not allow requested access");
+
+        // for write access we neeed to check if the DOS readonly attribute
+        // and if the volume is read-only
+        if (w) {
+            try {
+                WindowsFileAttributes attrs = WindowsFileAttributes.get(file, true);
+                if (!attrs.isDirectory() && attrs.isReadOnly())
+                    throw new AccessDeniedException(
+                        file.getPathForExceptionMessage(), null,
+                        "DOS readonly attribute is set");
+            } catch (WindowsException exc) {
+                exc.rethrowAsIOException(file);
+            }
+
+            if (WindowsFileStore.create(file).isReadOnly()) {
+                throw new AccessDeniedException(
+                    file.getPathForExceptionMessage(), null, "Read-only file system");
+            }
+            return;
+        }
+    }
+
+    @Override
+    public boolean isSameFile(Path obj1, Path obj2) throws IOException {
+        WindowsPath file1 = WindowsPath.toWindowsPath(obj1);
+        if (file1.equals(obj2))
+            return true;
+        if (obj2 == null)
+            throw new NullPointerException();
+        if (!(obj2 instanceof WindowsPath))
+            return false;
+        WindowsPath file2 = (WindowsPath)obj2;
+
+        // check security manager access to both files
+        file1.checkRead();
+        file2.checkRead();
+
+        // open both files and see if they are the same
+        long h1 = 0L;
+        try {
+            h1 = file1.openForReadAttributeAccess(true);
+        } catch (WindowsException x) {
+            x.rethrowAsIOException(file1);
+        }
+        try {
+            WindowsFileAttributes attrs1 = null;
+            try {
+                attrs1 = WindowsFileAttributes.readAttributes(h1);
+            } catch (WindowsException x) {
+                x.rethrowAsIOException(file1);
+            }
+            long h2 = 0L;
+            try {
+                h2 = file2.openForReadAttributeAccess(true);
+            } catch (WindowsException x) {
+                x.rethrowAsIOException(file2);
+            }
+            try {
+                WindowsFileAttributes attrs2 = null;
+                try {
+                    attrs2 = WindowsFileAttributes.readAttributes(h2);
+                } catch (WindowsException x) {
+                    x.rethrowAsIOException(file2);
+                }
+                return WindowsFileAttributes.isSameFile(attrs1, attrs2);
+            } finally {
+                CloseHandle(h2);
+            }
+        } finally {
+            CloseHandle(h1);
+        }
+    }
+
+    @Override
+    public boolean isHidden(Path obj) throws IOException {
+        WindowsPath file = WindowsPath.toWindowsPath(obj);
+        file.checkRead();
+        WindowsFileAttributes attrs = null;
+        try {
+            attrs = WindowsFileAttributes.get(file, true);
+        } catch (WindowsException x) {
+            x.rethrowAsIOException(file);
+        }
+        // DOS hidden attribute not meaningful when set on directories
+        if (attrs.isDirectory())
+            return false;
+        return attrs.isHidden();
+    }
+
+    @Override
+    public FileStore getFileStore(Path obj) throws IOException {
+        WindowsPath file = WindowsPath.toWindowsPath(obj);
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(new RuntimePermission("getFileStoreAttributes"));
+            file.checkRead();
+        }
+        return WindowsFileStore.create(file);
+    }
+
+
+    @Override
+    public void createDirectory(Path obj, FileAttribute<?>... attrs)
+        throws IOException
+    {
+        WindowsPath dir = WindowsPath.toWindowsPath(obj);
+        dir.checkWrite();
+        WindowsSecurityDescriptor sd = WindowsSecurityDescriptor.fromAttribute(attrs);
+        try {
+            CreateDirectory(dir.getPathForWin32Calls(), sd.address());
+        } catch (WindowsException x) {
+            x.rethrowAsIOException(dir);
+        } finally {
+            sd.release();
+        }
+    }
+
+    @Override
+    public DirectoryStream<Path> newDirectoryStream(Path obj, DirectoryStream.Filter<? super Path> filter)
+        throws IOException
+    {
+        WindowsPath dir = WindowsPath.toWindowsPath(obj);
+        dir.checkRead();
+        if (filter == null)
+            throw new NullPointerException();
+        return new WindowsDirectoryStream(dir, filter);
+    }
+
+    @Override
+    public void createSymbolicLink(Path obj1, Path obj2, FileAttribute<?>... attrs)
+        throws IOException
+    {
+        WindowsPath link = WindowsPath.toWindowsPath(obj1);
+        WindowsPath target = WindowsPath.toWindowsPath(obj2);
+
+        if (!link.getFileSystem().supportsLinks()) {
+            throw new UnsupportedOperationException("Symbolic links not supported "
+                + "on this operating system");
+        }
+
+        // no attributes allowed
+        if (attrs.length > 0) {
+            WindowsSecurityDescriptor.fromAttribute(attrs);  // may throw NPE or UOE
+            throw new UnsupportedOperationException("Initial file attributes" +
+                "not supported when creating symbolic link");
+        }
+
+        // permission check
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(new LinkPermission("symbolic"));
+            link.checkWrite();
+        }
+
+        /**
+         * Throw I/O exception for the drive-relative case because Windows
+         * creates a link with the resolved target for this case.
+         */
+        if (target.type() == WindowsPathType.DRIVE_RELATIVE) {
+            throw new IOException("Cannot create symbolic link to working directory relative target");
+        }
+
+        /*
+         * Windows treates symbolic links to directories differently than it
+         * does to other file types. For that reason we need to check if the
+         * target is a directory (or a directory junction).
+         */
+        WindowsPath resolvedTarget;
+        if (target.type() == WindowsPathType.RELATIVE) {
+            WindowsPath parent = link.getParent();
+            resolvedTarget = (parent == null) ? target : parent.resolve(target);
+        } else {
+            resolvedTarget = link.resolve(target);
+        }
+        int flags = 0;
+        try {
+            WindowsFileAttributes wattrs = WindowsFileAttributes.get(resolvedTarget, false);
+            if (wattrs.isDirectory() || wattrs.isDirectoryLink())
+                flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
+        } catch (WindowsException x) {
+            // unable to access target so assume target is not a directory
+        }
+
+        // create the link
+        try {
+            CreateSymbolicLink(link.getPathForWin32Calls(),
+                               WindowsPath.addPrefixIfNeeded(target.toString()),
+                               flags);
+        } catch (WindowsException x) {
+            if (x.lastError() == ERROR_INVALID_REPARSE_DATA) {
+                x.rethrowAsIOException(link, target);
+            } else {
+                x.rethrowAsIOException(link);
+            }
+        }
+    }
+
+    @Override
+    public void createLink(Path obj1, Path obj2) throws IOException {
+        WindowsPath link = WindowsPath.toWindowsPath(obj1);
+        WindowsPath existing = WindowsPath.toWindowsPath(obj2);
+
+        // permission check
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(new LinkPermission("hard"));
+            link.checkWrite();
+            existing.checkWrite();
+        }
+
+        // create hard link
+        try {
+            CreateHardLink(link.getPathForWin32Calls(),
+                           existing.getPathForWin32Calls());
+        } catch (WindowsException x) {
+            x.rethrowAsIOException(link, existing);
+        }
+    }
+
+    @Override
+    public Path readSymbolicLink(Path obj1) throws IOException {
+        WindowsPath link = WindowsPath.toWindowsPath(obj1);
+        WindowsFileSystem fs = link.getFileSystem();
+        if (!fs.supportsLinks()) {
+            throw new UnsupportedOperationException("symbolic links not supported");
+        }
+
+        // permission check
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            FilePermission perm = new FilePermission(link.getPathForPermissionCheck(),
+                SecurityConstants.FILE_READLINK_ACTION);
+            AccessController.checkPermission(perm);
+        }
+
+        String target = WindowsLinkSupport.readLink(link);
+        return WindowsPath.createFromNormalizedPath(fs, target);
+    }
 }
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsPath.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsPath.java	Fri Jan 28 09:28:43 2011 +0000
@@ -27,18 +27,13 @@
 
 import java.nio.file.*;
 import java.nio.file.attribute.*;
-import java.nio.channels.*;
 import java.io.*;
 import java.net.URI;
-import java.security.AccessController;
 import java.util.*;
 import java.lang.ref.WeakReference;
 
 import com.sun.nio.file.ExtendedWatchEventModifier;
 
-import sun.security.util.SecurityConstants;
-import sun.misc.Unsafe;
-
 import static sun.nio.fs.WindowsNativeDispatcher.*;
 import static sun.nio.fs.WindowsConstants.*;
 
@@ -47,7 +42,6 @@
  */
 
 class WindowsPath extends AbstractPath {
-    private static final Unsafe unsafe = Unsafe.getUnsafe();
 
     // The maximum path that does not require long path prefix. On Windows
     // the maximum path is 260 minus 1 (NUL) but for directories it is 260
@@ -229,6 +223,8 @@
         // Relative path ("foo" for example)
         if (type == WindowsPathType.RELATIVE) {
             String defaultDirectory = getFileSystem().defaultDirectory();
+            if (isEmpty())
+                return defaultDirectory;
             if (defaultDirectory.endsWith("\\")) {
                 return defaultDirectory + path;
             } else {
@@ -286,7 +282,7 @@
     }
 
     // Add long path prefix to path if required
-    private static String addPrefixIfNeeded(String path) {
+    static String addPrefixIfNeeded(String path) {
         if (path.length() > 248) {
             if (path.startsWith("\\\\")) {
                 path = "\\\\?\\UNC" + path.substring(1, path.length());
@@ -304,10 +300,22 @@
 
     // -- Path operations --
 
+    private boolean isEmpty() {
+        return path.length() == 0;
+    }
+
+    private WindowsPath emptyPath() {
+        return new WindowsPath(getFileSystem(), WindowsPathType.RELATIVE, "", "");
+    }
+
     @Override
-    public Path getName() {
+    public Path getFileName() {
+        int len = path.length();
+        // represents empty path
+        if (len == 0)
+            return this;
         // represents root component only
-        if (root.length() == path.length())
+        if (root.length() == len)
             return null;
         int off = path.lastIndexOf('\\');
         if (off < root.length())
@@ -340,6 +348,11 @@
     }
 
     // package-private
+    WindowsPathType type() {
+        return type;
+    }
+
+    // package-private
     boolean isUnc() {
         return type == WindowsPathType.UNC;
     }
@@ -355,7 +368,7 @@
         return type == WindowsPathType.ABSOLUTE || type == WindowsPathType.UNC;
     }
 
-    private WindowsPath checkPath(FileRef path) {
+    static WindowsPath toWindowsPath(Path path) {
         if (path == null)
             throw new NullPointerException();
         if (!(path instanceof WindowsPath)) {
@@ -366,9 +379,9 @@
 
     @Override
     public WindowsPath relativize(Path obj) {
-        WindowsPath other = checkPath(obj);
+        WindowsPath other = toWindowsPath(obj);
         if (this.equals(other))
-            return null;
+            return emptyPath();
 
         // can only relativize paths of the same type
         if (this.type != other.type)
@@ -410,7 +423,7 @@
     @Override
     public Path normalize() {
         final int count = getNameCount();
-        if (count == 0)
+        if (count == 0 || isEmpty())
             return this;
 
         boolean[] ignore = new boolean[count];      // true => ignore name
@@ -488,7 +501,7 @@
 
         // corner case - all names removed
         if (remaining == 0) {
-            return getRoot();
+            return (root.length() == 0) ? emptyPath() : getRoot();
         }
 
         // re-constitute the path from the remaining names.
@@ -497,7 +510,7 @@
             result.append(root);
         for (int i=0; i<count; i++) {
             if (!ignore[i]) {
-                result.append(getName(i).toString());
+                result.append(getName(i));
                 result.append("\\");
             }
         }
@@ -509,9 +522,9 @@
 
     @Override
     public WindowsPath resolve(Path obj) {
-        if (obj == null)
+        WindowsPath other = toWindowsPath(obj);
+        if (other.isEmpty())
             return this;
-        WindowsPath other = checkPath(obj);
         if (other.isAbsolute())
             return other;
 
@@ -559,27 +572,27 @@
         }
     }
 
-    @Override
-    public WindowsPath resolve(String other) {
-        return resolve(getFileSystem().getPath(other));
-    }
-
     // generate offset array
     private void initOffsets() {
         if (offsets == null) {
-            ArrayList<Integer> list = new ArrayList<Integer>();
-            int start = root.length();
-            int off = root.length();
-            while (off < path.length()) {
-                if (path.charAt(off) != '\\') {
-                    off++;
-                } else {
+            ArrayList<Integer> list = new ArrayList<>();
+            if (isEmpty()) {
+                // empty path considered to have one name element
+                list.add(0);
+            } else {
+                int start = root.length();
+                int off = root.length();
+                while (off < path.length()) {
+                    if (path.charAt(off) != '\\') {
+                        off++;
+                    } else {
+                        list.add(start);
+                        start = ++off;
+                    }
+                }
+                if (start != off)
                     list.add(start);
-                    start = ++off;
-                }
             }
-            if (start != off)
-                list.add(start);
             synchronized (this) {
                 if (offsets == null)
                     offsets = list.toArray(new Integer[list.size()]);
@@ -633,11 +646,16 @@
 
     @Override
     public boolean startsWith(Path obj) {
-        WindowsPath other = checkPath(obj);
+        WindowsPath other = toWindowsPath(obj);
 
         // if this path has a root component the given path's root must match
-        if (!this.root.equalsIgnoreCase(other.root))
+        if (!this.root.equalsIgnoreCase(other.root)) {
             return false;
+        }
+
+        // empty path starts with itself
+        if (other.isEmpty())
+            return this.isEmpty();
 
         // roots match so compare elements
         int thisCount = getNameCount();
@@ -657,13 +675,18 @@
 
     @Override
     public boolean endsWith(Path obj) {
-        WindowsPath other = checkPath(obj);
+        WindowsPath other = toWindowsPath(obj);
 
         // other path is longer
-        if (other.path.length() > path.length()) {
+        if (other.path.length() > this.path.length()) {
             return false;
         }
 
+        // empty path ends in itself
+        if (other.isEmpty()) {
+            return this.isEmpty();
+        }
+
         int thisCount = this.getNameCount();
         int otherCount = other.getNameCount();
 
@@ -742,31 +765,6 @@
         return path;
     }
 
-    @Override
-    public Iterator<Path> iterator() {
-        return new Iterator<Path>() {
-            private int i = 0;
-            @Override
-            public boolean hasNext() {
-                return (i < getNameCount());
-            }
-            @Override
-            public Path next() {
-                if (i < getNameCount()) {
-                    Path result = getName(i);
-                    i++;
-                    return result;
-                } else {
-                    throw new NoSuchElementException();
-                }
-            }
-            @Override
-            public void remove() {
-                throw new UnsupportedOperationException();
-            }
-        };
-    }
-
     // -- file operations --
 
     // package-private
@@ -806,453 +804,6 @@
     }
 
     @Override
-    public FileStore getFileStore()
-        throws IOException
-    {
-        SecurityManager sm = System.getSecurityManager();
-        if (sm != null) {
-            sm.checkPermission(new RuntimePermission("getFileStoreAttributes"));
-            checkRead();
-        }
-        return WindowsFileStore.create(this);
-    }
-
-    /**
-     * Returns buffer with SID_AND_ATTRIBUTES structure representing the user
-     * associated with the current thread access token.
-     * FIXME - this should be cached.
-     */
-    private NativeBuffer getUserInfo() throws IOException {
-        try {
-            long hToken = WindowsSecurity.processTokenWithQueryAccess;
-            int size = GetTokenInformation(hToken, TokenUser, 0L, 0);
-            assert size > 0;
-
-            NativeBuffer buffer = NativeBuffers.getNativeBuffer(size);
-            try {
-                int newsize = GetTokenInformation(hToken, TokenUser,
-                                                  buffer.address(), size);
-                if (newsize != size)
-                    throw new AssertionError();
-                return buffer;
-            } catch (WindowsException x) {
-                buffer.release();
-                throw x;
-            }
-        } catch (WindowsException x) {
-            throw new IOException(x.getMessage());
-        }
-    }
-
-    /**
-     * Reads the file ACL and return the effective access as ACCESS_MASK
-     */
-    private int getEffectiveAccess() throws IOException {
-        // read security descriptor continaing ACL (symlinks are followed)
-        String target = WindowsLinkSupport.getFinalPath(this, true);
-        NativeBuffer aclBuffer = WindowsAclFileAttributeView
-            .getFileSecurity(target, DACL_SECURITY_INFORMATION);
-
-        // retrieves DACL from security descriptor
-        long pAcl = GetSecurityDescriptorDacl(aclBuffer.address());
-
-        // Use GetEffectiveRightsFromAcl to get effective access to file
-        try {
-            NativeBuffer userBuffer = getUserInfo();
-            try {
-                try {
-                    // SID_AND_ATTRIBUTES->pSid
-                    long pSid = unsafe.getAddress(userBuffer.address());
-                    long pTrustee = BuildTrusteeWithSid(pSid);
-                    try {
-                        return GetEffectiveRightsFromAcl(pAcl, pTrustee);
-                    } finally {
-                        LocalFree(pTrustee);
-                    }
-                } catch (WindowsException x) {
-                    throw new IOException("Unable to get effective rights from ACL: " +
-                        x.getMessage());
-                }
-            } finally {
-                userBuffer.release();
-            }
-        } finally {
-            aclBuffer.release();
-        }
-    }
-
-    @Override
-    public void checkAccess(AccessMode... modes) throws IOException {
-        // if no access modes then simply file attributes
-        if (modes.length == 0) {
-            checkRead();
-            try {
-                WindowsFileAttributes.get(this, true);
-            } catch (WindowsException exc) {
-                exc.rethrowAsIOException(this);
-            }
-            return;
-        }
-
-        boolean r = false;
-        boolean w = false;
-        boolean x = false;
-        for (AccessMode mode: modes) {
-            switch (mode) {
-                case READ : r = true; break;
-                case WRITE : w = true; break;
-                case EXECUTE : x = true; break;
-                default: throw new AssertionError("Should not get here");
-            }
-        }
-
-        int mask = 0;
-        if (r) {
-            checkRead();
-            mask |= FILE_READ_DATA;
-        }
-        if (w) {
-            checkWrite();
-            mask |= FILE_WRITE_DATA;
-        }
-        if (x) {
-            SecurityManager sm = System.getSecurityManager();
-            if (sm != null)
-                sm.checkExec(getPathForPermissionCheck());
-            mask |= FILE_EXECUTE;
-        }
-
-        if ((getEffectiveAccess() & mask) == 0)
-            throw new AccessDeniedException(
-                this.getPathForExceptionMessage(), null,
-                "Effective permissions does not allow requested access");
-
-        // for write access we neeed to check if the DOS readonly attribute
-        // and if the volume is read-only
-        if (w) {
-            try {
-                WindowsFileAttributes attrs = WindowsFileAttributes.get(this, true);
-                if (!attrs.isDirectory() && attrs.isReadOnly())
-                    throw new AccessDeniedException(
-                        this.getPathForExceptionMessage(), null,
-                        "DOS readonly attribute is set");
-            } catch (WindowsException exc) {
-                exc.rethrowAsIOException(this);
-            }
-
-            if (WindowsFileStore.create(this).isReadOnly()) {
-                throw new AccessDeniedException(
-                    this.getPathForExceptionMessage(), null, "Read-only file system");
-            }
-            return;
-        }
-    }
-
-    @Override
-    void implDelete(boolean failIfNotExists) throws IOException {
-        checkDelete();
-
-        WindowsFileAttributes attrs = null;
-        try {
-             // need to know if file is a directory or junction
-             attrs = WindowsFileAttributes.get(this, false);
-             if (attrs.isDirectory() || attrs.isDirectoryLink()) {
-                RemoveDirectory(getPathForWin32Calls());
-             } else {
-                DeleteFile(getPathForWin32Calls());
-             }
-        } catch (WindowsException x) {
-
-            // no-op if file does not exist
-            if (!failIfNotExists &&
-                (x.lastError() == ERROR_FILE_NOT_FOUND ||
-                 x.lastError() == ERROR_PATH_NOT_FOUND)) return;
-
-            if (attrs != null && attrs.isDirectory()) {
-                // ERROR_ALREADY_EXISTS is returned when attempting to delete
-                // non-empty directory on SAMBA servers.
-                if (x.lastError() == ERROR_DIR_NOT_EMPTY ||
-                    x.lastError() == ERROR_ALREADY_EXISTS)
-                {
-                    throw new DirectoryNotEmptyException(
-                        getPathForExceptionMessage());
-                }
-            }
-            x.rethrowAsIOException(this);
-        }
-    }
-
-    @Override
-    public DirectoryStream<Path> newDirectoryStream(DirectoryStream.Filter<? super Path> filter)
-        throws IOException
-    {
-        checkRead();
-        if (filter == null)
-            throw new NullPointerException();
-        return new WindowsDirectoryStream(this, filter);
-    }
-
-    @Override
-    public void implCopyTo(Path obj, CopyOption... options) throws IOException {
-        WindowsPath target = (WindowsPath)obj;
-        WindowsFileCopy.copy(this, target, options);
-    }
-
-    @Override
-    public void implMoveTo(Path obj, CopyOption... options) throws IOException {
-        WindowsPath target = (WindowsPath)obj;
-        WindowsFileCopy.move(this, target, options);
-    }
-
-    private boolean followLinks(LinkOption... options) {
-        boolean followLinks = true;
-        for (LinkOption option: options) {
-            if (option == LinkOption.NOFOLLOW_LINKS) {
-                followLinks = false;
-                continue;
-            }
-            if (option == null)
-                throw new NullPointerException();
-            throw new AssertionError("Should not get here");
-        }
-        return followLinks;
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public <V extends FileAttributeView> V
-        getFileAttributeView(Class<V> view, LinkOption... options)
-    {
-        if (view == null)
-            throw new NullPointerException();
-        boolean followLinks = followLinks(options);
-        if (view == BasicFileAttributeView.class)
-            return (V) WindowsFileAttributeViews.createBasicView(this, followLinks);
-        if (view == DosFileAttributeView.class)
-            return (V) WindowsFileAttributeViews.createDosView(this, followLinks);
-        if (view == AclFileAttributeView.class)
-            return (V) new WindowsAclFileAttributeView(this, followLinks);
-        if (view == FileOwnerAttributeView.class)
-            return (V) new FileOwnerAttributeViewImpl(
-                new WindowsAclFileAttributeView(this, followLinks));
-        if (view == UserDefinedFileAttributeView.class)
-            return (V) new WindowsUserDefinedFileAttributeView(this, followLinks);
-        return (V) null;
-    }
-
-    @Override
-    public DynamicFileAttributeView getFileAttributeView(String name, LinkOption... options) {
-        boolean followLinks = followLinks(options);
-        if (name.equals("basic"))
-            return WindowsFileAttributeViews.createBasicView(this, followLinks);
-        if (name.equals("dos"))
-            return WindowsFileAttributeViews.createDosView(this, followLinks);
-        if (name.equals("acl"))
-            return new WindowsAclFileAttributeView(this, followLinks);
-        if (name.equals("owner"))
-            return new FileOwnerAttributeViewImpl(
-                new WindowsAclFileAttributeView(this, followLinks));
-        if (name.equals("user"))
-            return new WindowsUserDefinedFileAttributeView(this, followLinks);
-        return null;
-    }
-
-    @Override
-    public WindowsPath createDirectory(FileAttribute<?>... attrs)
-        throws IOException
-    {
-        checkWrite();
-        WindowsSecurityDescriptor sd = WindowsSecurityDescriptor.fromAttribute(attrs);
-        try {
-            CreateDirectory(getPathForWin32Calls(), sd.address());
-        } catch (WindowsException x) {
-            x.rethrowAsIOException(this);
-        } finally {
-            sd.release();
-        }
-        return this;
-    }
-
-    @Override
-    public SeekableByteChannel newByteChannel(Set<? extends OpenOption> options,
-                                              FileAttribute<?>... attrs)
-         throws IOException
-    {
-        WindowsSecurityDescriptor sd =
-            WindowsSecurityDescriptor.fromAttribute(attrs);
-        try {
-            return WindowsChannelFactory
-                .newFileChannel(getPathForWin32Calls(),
-                                getPathForPermissionCheck(),
-                                options,
-                                sd.address());
-        } catch (WindowsException x) {
-            x.rethrowAsIOException(this);
-            return null;  // keep compiler happy
-        } finally {
-            sd.release();
-        }
-    }
-
-    @Override
-    public boolean isSameFile(Path obj) throws IOException {
-        if (this.equals(obj))
-            return true;
-        if (!(obj instanceof WindowsPath))  // includes null check
-            return false;
-        WindowsPath other = (WindowsPath)obj;
-
-        // check security manager access to both files
-        this.checkRead();
-        other.checkRead();
-
-        // open both files and see if they are the same
-        long h1 = 0L;
-        try {
-            h1 = this.openForReadAttributeAccess(true);
-        } catch (WindowsException x) {
-            x.rethrowAsIOException(this);
-        }
-        try {
-            WindowsFileAttributes attrs1 = null;
-            try {
-                attrs1 = WindowsFileAttributes.readAttributes(h1);
-            } catch (WindowsException x) {
-                x.rethrowAsIOException(this);
-            }
-            long h2 = 0L;
-            try {
-                h2 = other.openForReadAttributeAccess(true);
-            } catch (WindowsException x) {
-                x.rethrowAsIOException(other);
-            }
-            try {
-                WindowsFileAttributes attrs2 = null;
-                try {
-                    attrs2 = WindowsFileAttributes.readAttributes(h2);
-                } catch (WindowsException x) {
-                    x.rethrowAsIOException(other);
-                }
-                return WindowsFileAttributes.isSameFile(attrs1, attrs2);
-            } finally {
-                CloseHandle(h2);
-            }
-        } finally {
-            CloseHandle(h1);
-        }
-    }
-
-    @Override
-    public WindowsPath createSymbolicLink(Path obj, FileAttribute<?>... attrs)
-        throws IOException
-    {
-        if (!getFileSystem().supportsLinks()) {
-            throw new UnsupportedOperationException("Symbolic links not supported "
-                + "on this operating system");
-        }
-
-        WindowsPath target = checkPath(obj);
-
-        // no attributes allowed
-        if (attrs.length > 0) {
-            WindowsSecurityDescriptor.fromAttribute(attrs);  // may throw NPE or UOE
-            throw new UnsupportedOperationException("Initial file attributes" +
-                "not supported when creating symbolic link");
-        }
-
-        // permission check
-        SecurityManager sm = System.getSecurityManager();
-        if (sm != null) {
-            sm.checkPermission(new LinkPermission("symbolic"));
-            this.checkWrite();
-        }
-
-        /**
-         * Throw I/O exception for the drive-relative case because Windows
-         * creates a link with the resolved target for this case.
-         */
-        if (target.type == WindowsPathType.DRIVE_RELATIVE) {
-            throw new IOException("Cannot create symbolic link to working directory relative target");
-        }
-
-        /*
-         * Windows treates symbolic links to directories differently than it
-         * does to other file types. For that reason we need to check if the
-         * target is a directory (or a directory junction).
-         */
-        WindowsPath resolvedTarget;
-        if (target.type == WindowsPathType.RELATIVE) {
-            WindowsPath parent = getParent();
-            resolvedTarget = (parent == null) ? target : parent.resolve(target);
-        } else {
-            resolvedTarget = resolve(target);
-        }
-        int flags = 0;
-        try {
-            WindowsFileAttributes wattrs = WindowsFileAttributes.get(resolvedTarget, false);
-            if (wattrs.isDirectory() || wattrs.isDirectoryLink())
-                flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
-        } catch (WindowsException x) {
-            // unable to access target so assume target is not a directory
-        }
-
-        // create the link
-        try {
-            CreateSymbolicLink(getPathForWin32Calls(),
-                               addPrefixIfNeeded(target.toString()),
-                               flags);
-        } catch (WindowsException x) {
-            if (x.lastError() == ERROR_INVALID_REPARSE_DATA) {
-                x.rethrowAsIOException(this, target);
-            } else {
-                x.rethrowAsIOException(this);
-            }
-        }
-        return this;
-    }
-
-    @Override
-    public Path createLink(Path obj) throws IOException {
-        WindowsPath existing = checkPath(obj);
-
-        // permission check
-        SecurityManager sm = System.getSecurityManager();
-        if (sm != null) {
-            sm.checkPermission(new LinkPermission("hard"));
-            this.checkWrite();
-            existing.checkWrite();
-        }
-
-        // create hard link
-        try {
-            CreateHardLink(this.getPathForWin32Calls(),
-                           existing.getPathForWin32Calls());
-        } catch (WindowsException x) {
-            x.rethrowAsIOException(this, existing);
-        }
-
-        return this;
-    }
-
-    @Override
-    public WindowsPath readSymbolicLink() throws IOException {
-        if (!getFileSystem().supportsLinks()) {
-            throw new UnsupportedOperationException("symbolic links not supported");
-        }
-
-        // permission check
-        SecurityManager sm = System.getSecurityManager();
-        if (sm != null) {
-            FilePermission perm = new FilePermission(getPathForPermissionCheck(),
-                SecurityConstants.FILE_READLINK_ACTION);
-            AccessController.checkPermission(perm);
-        }
-
-        String target = WindowsLinkSupport.readLink(this);
-        return createFromNormalizedPath(getFileSystem(), target);
-    }
-
-    @Override
     public URI toUri() {
         return WindowsUriSupport.toUri(this);
     }
@@ -1283,21 +834,6 @@
     }
 
     @Override
-    public boolean isHidden() throws IOException {
-        checkRead();
-        WindowsFileAttributes attrs = null;
-        try {
-            attrs = WindowsFileAttributes.get(this, true);
-        } catch (WindowsException x) {
-            x.rethrowAsIOException(this);
-        }
-        // DOS hidden attribute not meaningful when set on directories
-        if (attrs.isDirectory())
-            return false;
-        return attrs.isHidden();
-    }
-
-    @Override
     public WatchKey register(WatchService watcher,
                              WatchEvent.Kind<?>[] events,
                              WatchEvent.Modifier... modifiers)
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsPathParser.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsPathParser.java	Fri Jan 28 09:28:43 2011 +0000
@@ -74,8 +74,6 @@
      * Parses the given input as a Windows path
      */
     static Result parse(String input) {
-        if (input == null || input.length() == 0)
-            throw new InvalidPathException(input, "Empty or null path");
         return parse(input, true);
     }
 
@@ -135,7 +133,7 @@
             }
         }
         if (off == 0) {
-            if (isSlash(input.charAt(0))) {
+            if (len > 0 && isSlash(input.charAt(0))) {
                 type = WindowsPathType.DIRECTORY_RELATIVE;
                 root = "\\";
             } else {
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsSecurityDescriptor.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsSecurityDescriptor.java	Fri Jan 28 09:28:43 2011 +0000
@@ -214,7 +214,7 @@
 
         // map flags
         byte aceFlags = unsafe.getByte(aceAddress + OFFSETOF_FLAGS);
-        Set<AclEntryFlag> flags = new HashSet<AclEntryFlag>();
+        Set<AclEntryFlag> flags = EnumSet.noneOf(AclEntryFlag.class);
         if ((aceFlags & OBJECT_INHERIT_ACE) != 0)
             flags.add(AclEntryFlag.FILE_INHERIT);
         if ((aceFlags & CONTAINER_INHERIT_ACE) != 0)
@@ -226,7 +226,7 @@
 
         // map access mask
         int mask = unsafe.getInt(aceAddress + OFFSETOF_ACCESS_MASK);
-        Set<AclEntryPermission> perms = new HashSet<AclEntryPermission>();
+        Set<AclEntryPermission> perms = EnumSet.noneOf(AclEntryPermission.class);
         if ((mask & FILE_READ_DATA) > 0)
             perms.add(AclEntryPermission.READ_DATA);
         if ((mask & FILE_WRITE_DATA) > 0)
@@ -378,7 +378,7 @@
             AclInformation aclInfo = GetAclInformation(aclAddress);
             aceCount = aclInfo.aceCount();
         }
-        ArrayList<AclEntry> result = new ArrayList<AclEntry>(aceCount);
+        ArrayList<AclEntry> result = new ArrayList<>(aceCount);
 
         // decode each of the ACEs to AclEntry objects
         for (int i=0; i<aceCount; i++) {
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsUserDefinedFileAttributeView.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsUserDefinedFileAttributeView.java	Fri Jan 28 09:28:43 2011 +0000
@@ -65,7 +65,7 @@
 
     // enumerates the file streams using FindFirstStream/FindNextStream APIs.
     private List<String> listUsingStreamEnumeration() throws IOException {
-        List<String> list = new ArrayList<String>();
+        List<String> list = new ArrayList<>();
         try {
             FirstStream first = FindFirstStream(file.getPathForWin32Calls());
             if (first != null) {
@@ -114,7 +114,7 @@
         NativeBuffer buffer = null;
 
         // result with names of alternative data streams
-        final List<String> list = new ArrayList<String>();
+        final List<String> list = new ArrayList<>();
 
         try {
             buffer = NativeBuffers.getNativeBuffer(BUFFER_SIZE);
@@ -216,7 +216,7 @@
         // wrap with channel
         FileChannel fc = null;
         try {
-            Set<OpenOption> opts = new HashSet<OpenOption>();
+            Set<OpenOption> opts = new HashSet<>();
             opts.add(READ);
             if (!followLinks)
                 opts.add(WindowsChannelFactory.OPEN_REPARSE_POINT);
@@ -243,7 +243,7 @@
         // wrap with channel
         FileChannel fc = null;
         try {
-            Set<OpenOption> opts = new HashSet<OpenOption>();
+            Set<OpenOption> opts = new HashSet<>();
             opts.add(READ);
             if (!followLinks)
                 opts.add(WindowsChannelFactory.OPEN_REPARSE_POINT);
@@ -298,7 +298,7 @@
             x.rethrowAsIOException(file);
         }
         try {
-            Set<OpenOption> opts = new HashSet<OpenOption>();
+            Set<OpenOption> opts = new HashSet<>();
             if (!followLinks)
                 opts.add(WindowsChannelFactory.OPEN_REPARSE_POINT);
             opts.add(CREATE);
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsWatchService.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsWatchService.java	Fri Jan 28 09:28:43 2011 +0000
@@ -106,8 +106,11 @@
         // completion key (used to map I/O completion to WatchKey)
         private int completionKey;
 
-        WindowsWatchKey(AbstractWatchService watcher, FileKey fileKey) {
-            super(watcher);
+        WindowsWatchKey(Path dir,
+                        AbstractWatchService watcher,
+                        FileKey fileKey)
+        {
+            super(dir, watcher);
             this.fileKey = fileKey;
         }
 
@@ -405,7 +408,7 @@
                 WindowsWatchKey watchKey;
                 if (existing == null) {
                     // not registered so create new watch key
-                    watchKey = new WindowsWatchKey(watcher, fk)
+                    watchKey = new WindowsWatchKey(dir, watcher, fk)
                         .init(handle, events, watchSubtree, buffer, countAddress,
                               overlappedAddress, completionKey);
                     // map file key to watch key
--- a/jdk/test/demo/zipfs/basic.sh	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/test/demo/zipfs/basic.sh	Fri Jan 28 09:28:43 2011 +0000
@@ -22,6 +22,7 @@
 #
 # @test
 # @bug 6990846
+# @ignore Until zipfs updated (7015391)
 # @summary Test ZipFileSystem demo
 # @build Basic PathOps ZipFSTester
 # @run shell basic.sh
--- a/jdk/test/java/io/File/IsHidden.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/test/java/io/File/IsHidden.java	Fri Jan 28 09:28:43 2011 +0000
@@ -27,6 +27,7 @@
  */
 
 import java.io.*;
+import java.nio.file.Files;
 import java.nio.file.attribute.DosFileAttributeView;
 
 public class IsHidden {
@@ -42,7 +43,7 @@
     }
 
     private static void setHidden(File f, boolean value) throws IOException {
-        f.toPath().getFileAttributeView(DosFileAttributeView.class).setHidden(value);
+        Files.getFileAttributeView(f.toPath(), DosFileAttributeView.class).setHidden(value);
     }
 
     private static void testWin32() throws Exception {
--- a/jdk/test/java/io/File/SetAccess.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/test/java/io/File/SetAccess.java	Fri Jan 28 09:28:43 2011 +0000
@@ -27,6 +27,7 @@
  */
 
 import java.io.*;
+import java.nio.file.*;
 import java.nio.file.attribute.*;
 
 public class SetAccess {
@@ -178,7 +179,7 @@
     }
 
     private static String permission(File f) throws Exception {
-        PosixFileAttributes attrs = Attributes.readPosixFileAttributes(f.toPath());
+        PosixFileAttributes attrs = Files.readAttributes(f.toPath(), PosixFileAttributes.class);
         String type = attrs.isDirectory() ? "d" : " ";
         return type + PosixFilePermissions.toString(attrs.permissions());
     }
--- a/jdk/test/java/io/File/SymLinks.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/test/java/io/File/SymLinks.java	Fri Jan 28 09:28:43 2011 +0000
@@ -27,7 +27,7 @@
  */
 
 import java.io.*;
-import java.nio.file.Path;
+import java.nio.file.*;
 import java.nio.file.attribute.*;
 import static java.nio.file.LinkOption.*;
 
@@ -80,39 +80,33 @@
         if (file != null)
             file.delete();
         if (link2file != null)
-            link2file.toPath().deleteIfExists();
+            Files.deleteIfExists(link2file.toPath());
         if (link2link2file != null)
-            link2link2file.toPath().deleteIfExists();
+            Files.deleteIfExists(link2link2file.toPath());
         if (dir != null)
             dir.delete();
         if (link2dir != null)
-            link2dir.toPath().deleteIfExists();
+            Files.deleteIfExists(link2dir.toPath());
         if (link2link2dir != null)
-            link2link2dir.toPath().deleteIfExists();
+            Files.deleteIfExists(link2link2dir.toPath());
         if (link2nobody != null)
-            link2nobody.toPath().deleteIfExists();
+            Files.deleteIfExists(link2nobody.toPath());
         if (link2link2nobody != null)
-            link2link2nobody.toPath().deleteIfExists();
+            Files.deleteIfExists(link2link2nobody.toPath());
     }
 
     /**
      * Creates a sym link source->target
      */
     static void mklink(File source, File target) throws IOException {
-        source.toPath().createSymbolicLink(target.toPath());
+        Files.createSymbolicLink(source.toPath(), target.toPath());
     }
 
     /**
      * Returns true if the "link" exists and is a sym link.
      */
     static boolean isSymLink(File link) {
-         try {
-            BasicFileAttributes attrs =
-                Attributes.readBasicFileAttributes(link.toPath(), NOFOLLOW_LINKS);
-            return attrs.isSymbolicLink();
-         } catch (IOException x) {
-             return false;
-         }
+         return Files.isSymbolicLink(link.toPath());
     }
 
     /**
@@ -120,7 +114,7 @@
      */
     static long lastModifiedOfSymLink(File link) throws IOException {
         BasicFileAttributes attrs =
-            Attributes.readBasicFileAttributes(link.toPath(), NOFOLLOW_LINKS);
+            Files.readAttributes(link.toPath(), BasicFileAttributes.class, NOFOLLOW_LINKS);
         assertTrue(attrs.isSymbolicLink());
         return attrs.lastModifiedTime().toMillis();
     }
@@ -133,8 +127,8 @@
         Path link = dir.toPath().resolve("link");
         Path target = dir.toPath().resolve("target");
         try {
-            link.createSymbolicLink(target);
-            link.delete();
+            Files.createSymbolicLink(link, target);
+            Files.delete(link);
             return true;
         } catch (UnsupportedOperationException x) {
             return false;
@@ -224,7 +218,7 @@
             assertTrue(isSymLink(link2nobody));
 
         } finally {
-            link.toPath().deleteIfExists();
+            Files.deleteIfExists(link.toPath());
         }
 
         header("renameTo");
@@ -287,8 +281,8 @@
 
         // on Windows we test with the DOS hidden attribute set
         if (System.getProperty("os.name").startsWith("Windows")) {
-            DosFileAttributeView view = file.toPath()
-                .getFileAttributeView(DosFileAttributeView.class);
+            DosFileAttributeView view = Files
+                .getFileAttributeView(file.toPath(), DosFileAttributeView.class);
             view.setHidden(true);
             try {
                 assertTrue(file.isHidden());
--- a/jdk/test/java/io/FileInputStream/LargeFileAvailable.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/test/java/io/FileInputStream/LargeFileAvailable.java	Fri Jan 28 09:28:43 2011 +0000
@@ -31,6 +31,7 @@
 import java.io.*;
 import java.nio.ByteBuffer;
 import java.nio.channels.*;
+import java.nio.file.Files;
 import static java.nio.file.StandardOpenOption.*;
 
 public class LargeFileAvailable {
@@ -85,7 +86,7 @@
         // Create a large file as a sparse file if possible
         File largefile = File.createTempFile("largefile", null);
         // re-create as a sparse file
-        largefile.toPath().delete();
+        Files.delete(largefile.toPath());
         try (FileChannel fc =
                 FileChannel.open(largefile.toPath(),
                                  CREATE_NEW, WRITE, SPARSE)) {
--- a/jdk/test/java/nio/channels/FileChannel/AtomicAppend.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/test/java/nio/channels/FileChannel/AtomicAppend.java	Fri Jan 28 09:28:43 2011 +0000
@@ -36,6 +36,7 @@
 import java.util.concurrent.TimeUnit;
 import java.nio.ByteBuffer;
 import java.nio.channels.FileChannel;
+import java.nio.file.Files;
 import static java.nio.file.StandardOpenOption.*;
 
 public class AtomicAppend {
@@ -55,7 +56,7 @@
         if (rand.nextBoolean()) {
             return new FileOutputStream(file, true);
         } else {
-            return file.toPath().newOutputStream(APPEND);
+            return Files.newOutputStream(file.toPath(), APPEND);
         }
     }
 
--- a/jdk/test/java/nio/channels/FileChannel/Transfer.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/test/java/nio/channels/FileChannel/Transfer.java	Fri Jan 28 09:28:43 2011 +0000
@@ -276,7 +276,7 @@
         while (fc == null) {
             sink = File.createTempFile("sink", null);
             // re-create as a sparse file
-            sink.toPath().delete();
+            sink.delete();
             try {
                 fc = FileChannel.open(sink.toPath(),
                                       StandardOpenOption.CREATE_NEW,
--- a/jdk/test/java/nio/file/DirectoryStream/Basic.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/test/java/nio/file/DirectoryStream/Basic.java	Fri Jan 28 09:28:43 2011 +0000
@@ -28,6 +28,7 @@
  */
 
 import java.nio.file.*;
+import static java.nio.file.Files.*;
 import java.util.*;
 import java.io.IOException;
 
@@ -38,29 +39,26 @@
         DirectoryStream<Path> stream;
 
         // test that directory is empty
-        stream = dir.newDirectoryStream();
-        try {
-            if (stream.iterator().hasNext())
+        try (DirectoryStream<Path> ds = newDirectoryStream(dir)) {
+            if (ds.iterator().hasNext())
                 throw new RuntimeException("directory not empty");
-        } finally {
-            stream.close();
         }
 
         // create file in directory
         final Path foo = Paths.get("foo");
-        dir.resolve(foo).createFile();
+        createFile(dir.resolve(foo));
 
         // iterate over directory and check there is one entry
-        stream = dir.newDirectoryStream();
+        stream = newDirectoryStream(dir);
         found = false;
         try {
             for (Path entry: stream) {
-                if (entry.getName().equals(foo)) {
+                if (entry.getFileName().equals(foo)) {
                     if (found)
                         throw new RuntimeException("entry already found");
                     found = true;
                 } else {
-                    throw new RuntimeException("entry " + entry.getName() +
+                    throw new RuntimeException("entry " + entry.getFileName() +
                         " not expected");
                 }
             }
@@ -71,21 +69,18 @@
             throw new RuntimeException("entry not found");
 
         // check filtering: f* should match foo
-        DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
+        DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<>() {
             private PathMatcher matcher =
                 dir.getFileSystem().getPathMatcher("glob:f*");
             public boolean accept(Path file) {
                 return matcher.matches(file);
             }
         };
-        stream = dir.newDirectoryStream(filter);
-        try {
-            for (Path entry: stream) {
-                if (!entry.getName().equals(foo))
+        try (DirectoryStream<Path> ds = newDirectoryStream(dir, filter)) {
+            for (Path entry: ds) {
+                if (!entry.getFileName().equals(foo))
                     throw new RuntimeException("entry not expected");
             }
-        } finally {
-            stream.close();
         }
 
         // check filtering: z* should not match any files
@@ -96,12 +91,9 @@
                 return matcher.matches(file);
             }
         };
-        stream = dir.newDirectoryStream(filter);
-        try {
-            if (stream.iterator().hasNext())
+        try (DirectoryStream<Path> ds = newDirectoryStream(dir, filter)) {
+            if (ds.iterator().hasNext())
                 throw new RuntimeException("no matching entries expected");
-        } finally {
-            stream.close();
         }
 
         // check that an IOException thrown by a filter is propagated
@@ -110,7 +102,7 @@
                 throw new java.util.zip.ZipException();
             }
         };
-        stream = dir.newDirectoryStream(filter);
+        stream = newDirectoryStream(dir, filter);
         try {
             stream.iterator().hasNext();
             throw new RuntimeException("DirectoryIteratorException expected");
@@ -124,7 +116,7 @@
 
         // check that exception or error thrown by filter is not thrown
         // by newDirectoryStream or iterator method.
-        stream = dir.newDirectoryStream(new DirectoryStream.Filter<Path>() {
+        stream = newDirectoryStream(dir, new DirectoryStream.Filter<Path>() {
             public boolean accept(Path file) {
                 throw new RuntimeException("Should not be visible");
             }
@@ -137,13 +129,13 @@
 
         // test NotDirectoryException
         try {
-            dir.resolve(foo).newDirectoryStream();
+            newDirectoryStream(dir.resolve(foo));
             throw new RuntimeException("NotDirectoryException not thrown");
         } catch (NotDirectoryException x) {
         }
 
         // test UnsupportedOperationException
-        stream =  dir.newDirectoryStream();
+        stream = newDirectoryStream(dir);
         Iterator<Path> i = stream.iterator();
         i.next();
         try {
@@ -153,7 +145,7 @@
         }
 
         // test IllegalStateException
-        stream =  dir.newDirectoryStream();
+        stream = newDirectoryStream(dir);
         stream.iterator();
         try {
             // attempt to obtain second iterator
@@ -163,7 +155,7 @@
         }
         stream.close();
 
-        stream =  dir.newDirectoryStream();
+        stream = newDirectoryStream(dir);
         stream.close();
         try {
             // attempt to obtain iterator after stream is closed
@@ -173,13 +165,13 @@
         }
 
         // test that iterator reads to end of stream when closed
-        stream =  dir.newDirectoryStream();
+        stream = newDirectoryStream(dir);
         i = stream.iterator();
         stream.close();
         while (i.hasNext())
             i.next();
 
-        stream =  dir.newDirectoryStream();
+        stream = newDirectoryStream(dir);
         i = stream.iterator();
         stream.close();
         try {
--- a/jdk/test/java/nio/file/DirectoryStream/DriveLetter.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/test/java/nio/file/DirectoryStream/DriveLetter.java	Fri Jan 28 09:28:43 2011 +0000
@@ -52,16 +52,14 @@
             Path expected = Paths.get(drive).resolve(tempFile.getName());
 
             boolean found = false;
-            DirectoryStream<Path> stream = Paths.get(drive).newDirectoryStream();
-            try {
+            Path dir = Paths.get(drive);
+            try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
                 for (Path file : stream) {
                     if (file.equals(expected)) {
                         found = true;
                         break;
                     }
                 }
-            } finally {
-                stream.close();
             }
             if (!found)
                 throw new RuntimeException("Temporary file not found???");
--- a/jdk/test/java/nio/file/DirectoryStream/SecureDS.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/test/java/nio/file/DirectoryStream/SecureDS.java	Fri Jan 28 09:28:43 2011 +0000
@@ -28,6 +28,7 @@
  */
 
 import java.nio.file.*;
+import static java.nio.file.Files.*;
 import static java.nio.file.StandardOpenOption.*;
 import static java.nio.file.LinkOption.*;
 import java.nio.file.attribute.*;
@@ -41,7 +42,7 @@
     public static void main(String[] args) throws IOException {
         Path dir = TestUtil.createTemporaryDirectory();
         try {
-            DirectoryStream<Path> stream = dir.newDirectoryStream();
+            DirectoryStream<Path> stream = newDirectoryStream(dir);
             stream.close();
             if (!(stream instanceof SecureDirectoryStream)) {
                 System.out.println("SecureDirectoryStream not supported.");
@@ -62,28 +63,28 @@
 
     // Exercise each of SecureDirectoryStream's method (except move)
     static void doBasicTests(Path dir) throws IOException {
-        Path dir1 = dir.resolve("dir1").createDirectory();
+        Path dir1 = createDirectory(dir.resolve("dir1"));
         Path dir2 = dir.resolve("dir2");
 
         // create a file, directory, and two sym links in the directory
         Path fileEntry = Paths.get("myfile");
-        dir1.resolve(fileEntry).createFile();
+        createFile(dir1.resolve(fileEntry));
         Path dirEntry = Paths.get("mydir");
-        dir1.resolve(dirEntry).createDirectory();
+        createDirectory(dir1.resolve(dirEntry));
         // myfilelink -> myfile
         Path link1Entry = Paths.get("myfilelink");
         if (supportsLinks)
-            dir1.resolve(link1Entry).createSymbolicLink(fileEntry);
+            createSymbolicLink(dir1.resolve(link1Entry), fileEntry);
         // mydirlink -> mydir
         Path link2Entry = Paths.get("mydirlink");
         if (supportsLinks)
-            dir1.resolve(link2Entry).createSymbolicLink(dirEntry);
+            createSymbolicLink(dir1.resolve(link2Entry), dirEntry);
 
         // open directory and then move it so that it is no longer accessible
         // via its original path.
         SecureDirectoryStream<Path> stream =
-            (SecureDirectoryStream<Path>)dir1.newDirectoryStream();
-        dir1.moveTo(dir2);
+            (SecureDirectoryStream<Path>)newDirectoryStream(dir1);
+        move(dir1, dir2);
 
         // Test: iterate over all entries
         int count = 0;
@@ -138,7 +139,7 @@
         if (supportsLinks) {
             stream.newByteChannel(link1Entry, opts).close();
             try {
-                Set<OpenOption> mixed = new HashSet<OpenOption>();
+                Set<OpenOption> mixed = new HashSet<>();
                 mixed.add(READ);
                 mixed.add(NOFOLLOW_LINKS);
                 stream.newByteChannel(link1Entry, mixed).close();
@@ -168,51 +169,48 @@
 
         // clean-up
         stream.close();
-        dir2.delete();
+        delete(dir2);
     }
 
     // Exercise SecureDirectoryStream's move method
     static void doMoveTests(Path dir) throws IOException {
-        Path dir1 = dir.resolve("dir1").createDirectory();
-        Path dir2 = dir.resolve("dir2").createDirectory();
+        Path dir1 = createDirectory(dir.resolve("dir1"));
+        Path dir2 = createDirectory(dir.resolve("dir2"));
 
         // create dir1/myfile, dir1/mydir, dir1/mylink
         Path fileEntry = Paths.get("myfile");
-        dir1.resolve(fileEntry).createFile();
+        createFile(dir1.resolve(fileEntry));
         Path dirEntry = Paths.get("mydir");
-        dir1.resolve(dirEntry).createDirectory();
+        createDirectory(dir1.resolve(dirEntry));
         Path linkEntry = Paths.get("mylink");
         if (supportsLinks)
-            dir1.resolve(linkEntry).createSymbolicLink(Paths.get("missing"));
+            createSymbolicLink(dir1.resolve(linkEntry), Paths.get("missing"));
 
         // target name
         Path target = Paths.get("newfile");
 
         // open stream to both directories
         SecureDirectoryStream<Path> stream1 =
-            (SecureDirectoryStream<Path>)dir1.newDirectoryStream();
+            (SecureDirectoryStream<Path>)newDirectoryStream(dir1);
         SecureDirectoryStream<Path> stream2 =
-            (SecureDirectoryStream<Path>)dir2.newDirectoryStream();
+            (SecureDirectoryStream<Path>)newDirectoryStream(dir2);
 
         // Test: move dir1/myfile -> dir2/newfile
         stream1.move(fileEntry, stream2, target);
-        assertTrue(dir1.resolve(fileEntry).notExists());
-        assertTrue(dir2.resolve(target).exists());
+        assertTrue(notExists(dir1.resolve(fileEntry)));
+        assertTrue(exists(dir2.resolve(target)));
         stream2.deleteFile(target);
 
         // Test: move dir1/mydir -> dir2/newfile
         stream1.move(dirEntry, stream2, target);
-        assertTrue(dir1.resolve(dirEntry).notExists());
-        assertTrue(dir2.resolve(target).exists());
+        assertTrue(notExists(dir1.resolve(dirEntry)));
+        assertTrue(exists(dir2.resolve(target)));
         stream2.deleteDirectory(target);
 
         // Test: move dir1/mylink -> dir2/newfile
         if (supportsLinks) {
             stream1.move(linkEntry, stream2, target);
-            assertTrue(dir2.resolve(target)
-                .getFileAttributeView(BasicFileAttributeView.class, NOFOLLOW_LINKS)
-                .readAttributes()
-                .isSymbolicLink());
+            assertTrue(isSymbolicLink(dir2.resolve(target)));
             stream2.deleteFile(target);
         }
 
@@ -220,10 +218,10 @@
         String testDirAsString = System.getProperty("test.dir");
         if (testDirAsString != null) {
             Path testDir = Paths.get(testDirAsString);
-            if (!dir1.getFileStore().equals(testDir.getFileStore())) {
+            if (!getFileStore(dir1).equals(getFileStore(testDir))) {
                 SecureDirectoryStream<Path> ts =
-                    (SecureDirectoryStream<Path>)testDir.newDirectoryStream();
-                dir1.resolve(fileEntry).createFile();
+                    (SecureDirectoryStream<Path>)newDirectoryStream(testDir);
+                createFile(dir1.resolve(fileEntry));
                 try {
                     stream1.move(fileEntry, ts, target);
                     shouldNotGetHere();
@@ -234,17 +232,17 @@
         }
 
         // clean-up
-        dir1.delete();
-        dir2.delete();
+        delete(dir1);
+        delete(dir2);
     }
 
     // null and ClosedDirectoryStreamException
     static void miscTests(Path dir) throws IOException {
         Path file = Paths.get("file");
-        dir.resolve(file).createFile();
+        createFile(dir.resolve(file));
 
         SecureDirectoryStream<Path> stream =
-            (SecureDirectoryStream<Path>)dir.newDirectoryStream();
+            (SecureDirectoryStream<Path>)newDirectoryStream(dir);
 
         // NullPointerException
         try {
@@ -319,7 +317,7 @@
         } catch (ClosedDirectoryStreamException x) { }
 
         // clean-up
-        dir.resolve(file).delete();
+        delete(dir.resolve(file));
     }
 
     static void assertTrue(boolean b) {
--- a/jdk/test/java/nio/file/FileStore/Basic.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/test/java/nio/file/FileStore/Basic.java	Fri Jan 28 09:28:43 2011 +0000
@@ -22,18 +22,21 @@
  */
 
 /* @test
- * @bug 4313887 6873621 6979526
+ * @bug 4313887 6873621 6979526 7006126
  * @summary Unit test for java.nio.file.FileStore
  * @library ..
  */
 
 import java.nio.file.*;
 import java.nio.file.attribute.*;
+import java.io.File;
 import java.io.IOException;
 import java.util.*;
 
 public class Basic {
 
+    static final long G = 1024L * 1024L * 1024L;
+
     public static void main(String[] args) throws IOException {
         Path dir = TestUtil.createTemporaryDirectory();
         try {
@@ -48,17 +51,25 @@
             throw new RuntimeException("Assertion failed");
     }
 
+    static void checkWithin1GB(long value1, long value2) {
+        long diff = Math.abs(value1 - value2);
+        if (diff > G)
+            throw new RuntimeException("values differ by more than 1GB");
+    }
+
     static void doTests(Path dir) throws IOException {
         /**
          * Test: Directory should be on FileStore that is writable
          */
-        assertTrue(!dir.getFileStore().isReadOnly());
+        assertTrue(!Files.getFileStore(dir).isReadOnly());
 
         /**
          * Test: Two files should have the same FileStore
          */
-        FileStore store1 = dir.resolve("foo").createFile().getFileStore();
-        FileStore store2 = dir.resolve("bar").createFile().getFileStore();
+        Path file1 = Files.createFile(dir.resolve("foo"));
+        Path file2 = Files.createFile(dir.resolve("bar"));
+        FileStore store1 = Files.getFileStore(file1);
+        FileStore store2 = Files.getFileStore(file2);
         assertTrue(store1.equals(store2));
         assertTrue(store2.equals(store1));
         assertTrue(store1.hashCode() == store2.hashCode());
@@ -78,6 +89,24 @@
             store1.supportsFileAttributeView(UserDefinedFileAttributeView.class));
 
         /**
+         * Test: Space atributes
+         */
+        File f = file1.toFile();
+        long total = f.getTotalSpace();
+        long free = f.getFreeSpace();
+        long usable = f.getUsableSpace();
+
+        // check values are "close"
+        checkWithin1GB(total,  store1.getTotalSpace());
+        checkWithin1GB(free,   store1.getUnallocatedSpace());
+        checkWithin1GB(usable, store1.getUsableSpace());
+
+        // get values by name
+        checkWithin1GB(total,  (Long)store1.getAttribute("totalSpace"));
+        checkWithin1GB(free,   (Long)store1.getAttribute("unallocatedSpace"));
+        checkWithin1GB(usable, (Long)store1.getAttribute("usableSpace"));
+
+        /**
          * Test: Enumerate all FileStores
          */
         FileStore prev = null;
@@ -85,8 +114,10 @@
             System.out.format("%s (name=%s type=%s)\n", store, store.name(),
                 store.type());
 
-            // check space attributes
-            Attributes.readFileStoreSpaceAttributes(store);
+            // check space attributes are accessible
+            store.getTotalSpace();
+            store.getUnallocatedSpace();
+            store.getUsableSpace();
 
             // two distinct FileStores should not be equal
             assertTrue(!store.equals(prev));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/BytesAndLines.java	Fri Jan 28 09:28:43 2011 +0000
@@ -0,0 +1,252 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 7006126
+ * @summary Unit test for methods for Files readAllBytes, readAllLines and
+ *     and write methods.
+ */
+
+import java.nio.file.*;
+import static java.nio.file.Files.*;
+import java.io.*;
+import java.util.*;
+import java.nio.charset.*;
+
+public class BytesAndLines {
+    static final Random rand = new Random();
+
+    static final Charset US_ASCII = Charset.forName("US-ASCII");
+
+    public static void main(String[] args) throws IOException {
+        testReadAndWriteBytes();
+        testReadLines();
+        testWriteLines();
+    }
+
+    /**
+     * Test readAllBytes(Path) and write(Path, byte[], OpenOption...)
+     */
+    static void testReadAndWriteBytes() throws IOException {
+        // exercise methods with various sizes
+        testReadAndWriteBytes(0);
+        for (int i=0; i<100; i++) {
+            testReadAndWriteBytes(rand.nextInt(32000));
+        }
+
+        // NullPointerException
+        Path file = Paths.get("foo");
+        List<String> lines = Collections.emptyList();
+        try {
+            readAllBytes(null);
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException ignore) { }
+        try {
+            write(null, lines, Charset.defaultCharset());
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException ignore) { }
+        try {
+            write(file, null, Charset.defaultCharset());
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException ignore) { }
+        try {
+            write(file, lines, null);
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException ignore) { }
+        try {
+            write(file, lines, Charset.defaultCharset(), (OpenOption[])null);
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException ignore) { }
+        try {
+            OpenOption[] opts = { null };
+            write(file, lines, Charset.defaultCharset(), opts);
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException ignore) { }
+    }
+
+
+    static void testReadAndWriteBytes(int size) throws IOException {
+        Path path = createTempFile("blah", null);
+        try {
+            boolean append = rand.nextBoolean();
+
+            byte[] b1 = new byte[size];
+            rand.nextBytes(b1);
+
+            byte[] b2 = (append) ? new byte[size] : new byte[0];
+            rand.nextBytes(b2);
+
+            // write method should create file if it doesn't exist
+            if (rand.nextBoolean())
+                delete(path);
+
+            // write bytes to file
+            Path target = write(path, b1);
+            assertTrue(target==path, "Unexpected path");
+            assertTrue(size(path) == b1.length, "Unexpected file size");
+
+            // append bytes to file (might be 0 bytes)
+            write(path, b2, StandardOpenOption.APPEND);
+            assertTrue(size(path) == b1.length + b2.length, "Unexpected file size");
+
+            // read entire file
+            byte[] read = readAllBytes(path);
+
+            // check bytes are correct
+            byte[] expected;
+            if (append) {
+                expected = new byte[b1.length + b2.length];
+                System.arraycopy(b1, 0, expected, 0, b1.length);
+                System.arraycopy(b2, 0, expected, b1.length, b2.length);
+            } else {
+                expected = b1;
+            }
+            assertTrue(Arrays.equals(read, expected),
+                       "Bytes read not the same as bytes written");
+        } finally {
+            deleteIfExists(path);
+        }
+    }
+
+    /**
+     * Test readAllLines(Path,Charset)
+     */
+    static void testReadLines() throws IOException {
+        Path tmpfile = createTempFile("blah", "txt");
+        try {
+            List<String> lines;
+
+            // zero lines
+            assertTrue(size(tmpfile) == 0, "File should be empty");
+            lines = readAllLines(tmpfile, US_ASCII);
+            assertTrue(lines.isEmpty(), "No line expected");
+
+            // one line
+            byte[] hi = { (byte)'h', (byte)'i' };
+            write(tmpfile, hi);
+            lines = readAllLines(tmpfile, US_ASCII);
+            assertTrue(lines.size() == 1, "One line expected");
+            assertTrue(lines.get(0).equals("hi"), "'Hi' expected");
+
+            // two lines using platform's line separator
+            List<String> expected = Arrays.asList("hi", "there");
+            write(tmpfile, expected, US_ASCII);
+            assertTrue(size(tmpfile) > 0, "File is empty");
+            lines = readAllLines(tmpfile, US_ASCII);
+            assertTrue(lines.equals(expected), "Unexpected lines");
+
+            // MalformedInputException
+            byte[] bad = { (byte)0xff, (byte)0xff };
+            write(tmpfile, bad);
+            try {
+                readAllLines(tmpfile, US_ASCII);
+                throw new RuntimeException("MalformedInputException expected");
+            } catch (MalformedInputException ignore) { }
+
+
+            // NullPointerException
+            try {
+                readAllLines(null, US_ASCII);
+                throw new RuntimeException("NullPointerException expected");
+            } catch (NullPointerException ignore) { }
+            try {
+                readAllLines(tmpfile, null);
+                throw new RuntimeException("NullPointerException expected");
+            } catch (NullPointerException ignore) { }
+
+        } finally {
+            delete(tmpfile);
+        }
+    }
+
+    /**
+     * Test write(Path,Iterable<? extends CharSequence>,Charset,OpenOption...)
+     */
+    static void testWriteLines() throws IOException {
+        Path tmpfile = createTempFile("blah", "txt");
+        try {
+            // write method should create file if it doesn't exist
+            if (rand.nextBoolean())
+                delete(tmpfile);
+
+            // zero lines
+            Path result = write(tmpfile, Collections.<String>emptyList(), US_ASCII);
+            assert(size(tmpfile) == 0);
+            assert(result == tmpfile);
+
+            // two lines
+            List<String> lines = Arrays.asList("hi", "there");
+            write(tmpfile, lines, US_ASCII);
+            List<String> actual = readAllLines(tmpfile, US_ASCII);
+            assertTrue(actual.equals(lines), "Unexpected lines");
+
+            // append two lines
+            write(tmpfile, lines, US_ASCII, StandardOpenOption.APPEND);
+            List<String> expected = new ArrayList<String>();
+            expected.addAll(lines);
+            expected.addAll(lines);
+            assertTrue(expected.size() == 4, "List should have 4 elements");
+            actual = readAllLines(tmpfile, US_ASCII);
+            assertTrue(actual.equals(expected), "Unexpected lines");
+
+            // UnmappableCharacterException
+            try {
+                String s = "\u00A0\u00A1";
+                write(tmpfile, Arrays.asList(s), US_ASCII);
+                throw new RuntimeException("UnmappableCharacterException expected");
+            } catch (UnmappableCharacterException ignore) { }
+
+            // NullPointerException
+            try {
+                write(null, lines, US_ASCII);
+                throw new RuntimeException("NullPointerException expected");
+            } catch (NullPointerException ignore) { }
+            try {
+                write(tmpfile, null, US_ASCII);
+                throw new RuntimeException("NullPointerException expected");
+            } catch (NullPointerException ignore) { }
+            try {
+                write(tmpfile, lines, null);
+                throw new RuntimeException("NullPointerException expected");
+            } catch (NullPointerException ignore) { }
+            try {
+                write(tmpfile, lines, US_ASCII, (OpenOption[])null);
+                throw new RuntimeException("NullPointerException expected");
+            } catch (NullPointerException ignore) { }
+            try {
+                OpenOption[] opts = { (OpenOption)null };
+                write(tmpfile, lines, US_ASCII, opts);
+                throw new RuntimeException("NullPointerException expected");
+            } catch (NullPointerException ignore) { }
+
+        } finally {
+            delete(tmpfile);
+        }
+
+    }
+
+    static void assertTrue(boolean expr, String errmsg) {
+        if (!expr)
+            throw new RuntimeException(errmsg);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/CheckPermissions.java	Fri Jan 28 09:28:43 2011 +0000
@@ -0,0 +1,723 @@
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 6866804 7006126
+ * @summary Unit test for java.nio.file.Files
+ * @library ..
+ * @build CheckPermissions
+ * @run main/othervm CheckPermissions
+ */
+
+import java.nio.ByteBuffer;
+import java.nio.file.*;
+import static java.nio.file.Files.*;
+import static java.nio.file.StandardOpenOption.*;
+import java.nio.file.attribute.*;
+import java.nio.channels.SeekableByteChannel;
+import java.security.Permission;
+import java.io.*;
+import java.util.*;
+
+/**
+ * Checks each method that accesses the file system does the right permission
+ * check when there is a security manager set.
+ */
+
+public class CheckPermissions {
+
+    static class Checks {
+        private List<Permission> permissionsChecked = new ArrayList<>();
+        private Set<String>  propertiesChecked = new HashSet<>();
+        private List<String> readsChecked   = new ArrayList<>();
+        private List<String> writesChecked  = new ArrayList<>();
+        private List<String> deletesChecked = new ArrayList<>();
+        private List<String> execsChecked   = new ArrayList<>();
+
+        List<Permission> permissionsChecked()  { return permissionsChecked; }
+        Set<String> propertiesChecked()        { return propertiesChecked; }
+        List<String> readsChecked()            { return readsChecked; }
+        List<String> writesChecked()           { return writesChecked; }
+        List<String> deletesChecked()          { return deletesChecked; }
+        List<String> execsChecked()            { return execsChecked; }
+    }
+
+    static ThreadLocal<Checks> myChecks =
+        new ThreadLocal<Checks>() {
+            @Override protected Checks initialValue() {
+                return null;
+            }
+        };
+
+    static void prepare() {
+        myChecks.set(new Checks());
+    }
+
+    static void assertCheckPermission(Class<? extends Permission> type,
+                                      String name)
+    {
+        for (Permission perm: myChecks.get().permissionsChecked()) {
+            if (type.isInstance(perm) && perm.getName().equals(name))
+                return;
+        }
+        throw new RuntimeException(type.getName() + "(\"" + name + "\") not checked");
+    }
+
+    static void assertCheckPropertyAccess(String key) {
+        if (!myChecks.get().propertiesChecked().contains(key))
+            throw new RuntimeException("Property " + key + " not checked");
+    }
+
+    static void assertChecked(Path file, List<String> list) {
+        String s = file.toString();
+        for (String f: list) {
+            if (f.endsWith(s))
+                return;
+        }
+        throw new RuntimeException("Access not checked");
+    }
+
+    static void assertCheckRead(Path file) {
+        assertChecked(file, myChecks.get().readsChecked());
+    }
+
+    static void assertCheckWrite(Path file) {
+        assertChecked(file, myChecks.get().writesChecked());
+    }
+
+    static void assertCheckWriteToDirectory(Path dir) {
+        String s = dir.toString();
+        List<String> list = myChecks.get().writesChecked();
+        for (String f: list) {
+            if (f.startsWith(s)) {
+                return;
+            }
+        }
+        throw new RuntimeException("Access not checked");
+    }
+
+    static void assertCheckDelete(Path file) {
+        assertChecked(file, myChecks.get().deletesChecked());
+    }
+
+    static void assertCheckExec(Path file) {
+        assertChecked(file, myChecks.get().execsChecked());
+    }
+
+    static class LoggingSecurityManager extends SecurityManager {
+        static void install() {
+            System.setSecurityManager(new LoggingSecurityManager());
+        }
+
+        @Override
+        public void checkPermission(Permission perm) {
+            Checks checks = myChecks.get();
+            if (checks != null)
+                checks.permissionsChecked().add(perm);
+        }
+
+        @Override
+        public void checkPropertyAccess(String key) {
+            Checks checks = myChecks.get();
+            if (checks != null)
+                checks.propertiesChecked().add(key);
+        }
+
+        @Override
+        public void checkRead(String file) {
+            Checks checks = myChecks.get();
+            if (checks != null)
+                checks.readsChecked().add(file);
+        }
+
+        @Override
+        public void checkWrite(String file) {
+            Checks checks = myChecks.get();
+            if (checks != null)
+                checks.writesChecked().add(file);
+        }
+
+        @Override
+        public void checkDelete(String file) {
+            Checks checks = myChecks.get();
+            if (checks != null)
+                checks.deletesChecked().add(file);
+        }
+
+        @Override
+        public void checkExec(String file) {
+            Checks checks = myChecks.get();
+            if (checks != null)
+                checks.execsChecked().add(file);
+        }
+    }
+
+    static void testBasicFileAttributeView(BasicFileAttributeView view, Path file)
+        throws IOException
+    {
+        prepare();
+        view.readAttributes();
+        assertCheckRead(file);
+
+        prepare();
+        FileTime now = FileTime.fromMillis(System.currentTimeMillis());
+        view.setTimes(null, now, now);
+        assertCheckWrite(file);
+    }
+
+    static void testPosixFileAttributeView(PosixFileAttributeView view, Path file)
+        throws IOException
+    {
+        prepare();
+        PosixFileAttributes attrs = view.readAttributes();
+        assertCheckRead(file);
+        assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+
+        prepare();
+        view.setPermissions(attrs.permissions());
+        assertCheckWrite(file);
+        assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+
+        prepare();
+        view.setOwner(attrs.owner());
+        assertCheckWrite(file);
+        assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+
+        prepare();
+        view.setOwner(attrs.owner());
+        assertCheckWrite(file);
+        assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+    }
+
+    public static void main(String[] args) throws IOException {
+        final Path testdir = Paths.get(System.getProperty("test.dir", ".")).toAbsolutePath();
+        final Path tmpdir = Paths.get(System.getProperty("java.io.tmpdir"));
+
+        Path file = createFile(testdir.resolve("file1234"));
+        try {
+            LoggingSecurityManager.install();
+
+            // -- check access --
+
+            prepare();
+            exists(file);
+            assertCheckRead(file);
+
+            prepare();
+            isReadable(file);
+            assertCheckRead(file);
+
+            prepare();
+            isWritable(file);
+            assertCheckWrite(file);
+
+            prepare();
+            isExecutable(file);
+            assertCheckExec(file);
+
+            // -- copy --
+
+            Path target = testdir.resolve("target1234");
+            prepare();
+            copy(file, target);
+            try {
+                assertCheckRead(file);
+                assertCheckWrite(target);
+            } finally {
+                delete(target);
+            }
+
+            if (TestUtil.supportsLinks(testdir)) {
+                Path link = testdir.resolve("link1234");
+                createSymbolicLink(link, file);
+                try {
+                    prepare();
+                    copy(link, target, LinkOption.NOFOLLOW_LINKS);
+                    try {
+                        assertCheckRead(link);
+                        assertCheckWrite(target);
+                        assertCheckPermission(LinkPermission.class, "symbolic");
+                    } finally {
+                        delete(target);
+                    }
+                } finally {
+                    delete(link);
+                }
+            }
+
+            // -- createDirectory --
+
+            Path subdir = testdir.resolve("subdir1234");
+            prepare();
+            createDirectory(subdir);
+            try {
+                assertCheckWrite(subdir);
+            } finally {
+                delete(subdir);
+            }
+
+            // -- createFile --
+
+            Path fileToCreate = testdir.resolve("file7890");
+            prepare();
+            createFile(fileToCreate);
+            try {
+                assertCheckWrite(fileToCreate);
+            } finally {
+                delete(fileToCreate);
+            }
+
+            // -- createSymbolicLink --
+
+            if (TestUtil.supportsLinks(testdir)) {
+                prepare();
+                Path link = testdir.resolve("link1234");
+                createSymbolicLink(link, file);
+                try {
+                    assertCheckWrite(link);
+                    assertCheckPermission(LinkPermission.class, "symbolic");
+                } finally {
+                    delete(link);
+                }
+            }
+
+            // -- createLink --
+
+            if (TestUtil.supportsLinks(testdir)) {
+                prepare();
+                Path link = testdir.resolve("entry234");
+                createLink(link, file);
+                try {
+                    assertCheckWrite(link);
+                    assertCheckPermission(LinkPermission.class, "hard");
+                } finally {
+                    delete(link);
+                }
+            }
+
+            // -- createTempFile --
+
+            prepare();
+            Path tmpfile1 = createTempFile("foo", null);
+            try {
+                assertCheckWriteToDirectory(tmpdir);
+            } finally {
+                delete(tmpfile1);
+            }
+            prepare();
+            Path tmpfile2 = createTempFile(testdir, "foo", ".tmp");
+            try {
+                assertCheckWriteToDirectory(testdir);
+            } finally {
+                delete(tmpfile2);
+            }
+
+            // -- createTempDirectory --
+
+            prepare();
+            Path tmpdir1 = createTempDirectory("foo");
+            try {
+                assertCheckWriteToDirectory(tmpdir);
+            } finally {
+                delete(tmpdir1);
+            }
+            prepare();
+            Path tmpdir2 = createTempDirectory(testdir, "foo");
+            try {
+                assertCheckWriteToDirectory(testdir);
+            } finally {
+                delete(tmpdir2);
+            }
+
+            // -- delete/deleteIfExists --
+
+            Path fileToDelete = testdir.resolve("file7890");
+
+            createFile(fileToDelete);
+            prepare();
+            delete(fileToDelete);
+            assertCheckDelete(fileToDelete);
+
+            createFile(fileToDelete);
+            prepare();
+            deleteIfExists(fileToDelete);   // file exists
+            assertCheckDelete(fileToDelete);
+
+            prepare();
+            deleteIfExists(fileToDelete);   // file does not exist
+            assertCheckDelete(fileToDelete);
+
+            // -- exists/notExists --
+
+            prepare();
+            exists(file);
+            assertCheckRead(file);
+
+            prepare();
+            notExists(file);
+            assertCheckRead(file);
+
+            // -- getFileStore --
+
+            prepare();
+            getFileStore(file);
+            assertCheckRead(file);
+            assertCheckPermission(RuntimePermission.class, "getFileStoreAttributes");
+
+            // -- isSameFile --
+
+            prepare();
+            isSameFile(file, testdir);
+            assertCheckRead(file);
+            assertCheckRead(testdir);
+
+            // -- move --
+
+            Path target2 = testdir.resolve("target1234");
+            prepare();
+            move(file, target2);
+            try {
+                assertCheckWrite(file);
+                assertCheckWrite(target2);
+            } finally {
+                // restore file
+                move(target2, file);
+            }
+
+            // -- newByteChannel --
+
+            prepare();
+            try (SeekableByteChannel sbc = newByteChannel(file)) {
+                assertCheckRead(file);
+            }
+            prepare();
+            try (SeekableByteChannel sbc = newByteChannel(file, WRITE)) {
+                assertCheckWrite(file);
+            }
+            prepare();
+            try (SeekableByteChannel sbc = newByteChannel(file, READ, WRITE)) {
+                assertCheckRead(file);
+                assertCheckWrite(file);
+            }
+
+            prepare();
+            try (SeekableByteChannel sbc = newByteChannel(file, DELETE_ON_CLOSE)) {
+                assertCheckRead(file);
+                assertCheckDelete(file);
+            }
+            createFile(file); // restore file
+
+
+            // -- newInputStream/newOutptuStream --
+
+            prepare();
+            try (InputStream in = newInputStream(file)) {
+                assertCheckRead(file);
+            }
+            prepare();
+            try (OutputStream out = newOutputStream(file)) {
+                assertCheckWrite(file);
+            }
+
+            // -- newDirectoryStream --
+
+            prepare();
+            try (DirectoryStream<Path> stream = newDirectoryStream(testdir)) {
+                assertCheckRead(testdir);
+
+                if (stream instanceof SecureDirectoryStream<?>) {
+                    Path entry;
+                    SecureDirectoryStream<Path> sds =
+                        (SecureDirectoryStream<Path>)stream;
+
+                    // newByteChannel
+                    entry = file.getFileName();
+                    prepare();
+                    try (SeekableByteChannel sbc = sds.newByteChannel(entry, EnumSet.of(READ))) {
+                        assertCheckRead(file);
+                    }
+                    prepare();
+                    try (SeekableByteChannel sbc = sds.newByteChannel(entry, EnumSet.of(WRITE))) {
+                        assertCheckWrite(file);
+                    }
+
+                    // deleteFile
+                    entry = file.getFileName();
+                    prepare();
+                    sds.deleteFile(entry);
+                    assertCheckDelete(file);
+                    createFile(testdir.resolve(entry));  // restore file
+
+                    // deleteDirectory
+                    entry = Paths.get("subdir1234");
+                    createDirectory(testdir.resolve(entry));
+                    prepare();
+                    sds.deleteDirectory(entry);
+                    assertCheckDelete(testdir.resolve(entry));
+
+                    // move
+                    entry = Paths.get("tempname1234");
+                    prepare();
+                    sds.move(file.getFileName(), sds, entry);
+                    assertCheckWrite(file);
+                    assertCheckWrite(testdir.resolve(entry));
+                    sds.move(entry, sds, file.getFileName());  // restore file
+
+                    // newDirectoryStream
+                    entry = Paths.get("subdir1234");
+                    createDirectory(testdir.resolve(entry));
+                    try {
+                        prepare();
+                        sds.newDirectoryStream(entry).close();
+                        assertCheckRead(testdir.resolve(entry));
+                    } finally {
+                        delete(testdir.resolve(entry));
+                    }
+
+                    // getFileAttributeView to access attributes of directory
+                    testBasicFileAttributeView(sds
+                        .getFileAttributeView(BasicFileAttributeView.class), testdir);
+                    testPosixFileAttributeView(sds
+                        .getFileAttributeView(PosixFileAttributeView.class), testdir);
+
+                    // getFileAttributeView to access attributes of entry
+                    entry = file.getFileName();
+                    testBasicFileAttributeView(sds
+                        .getFileAttributeView(entry, BasicFileAttributeView.class), file);
+                    testPosixFileAttributeView(sds
+                        .getFileAttributeView(entry, PosixFileAttributeView.class), file);
+
+                } else {
+                    System.out.println("SecureDirectoryStream not tested");
+                }
+            }
+
+            // -- toAbsolutePath --
+
+            prepare();
+            file.getFileName().toAbsolutePath();
+            assertCheckPropertyAccess("user.dir");
+
+            // -- toRealPath --
+
+            prepare();
+            file.toRealPath(true);
+            assertCheckRead(file);
+
+            prepare();
+            file.toRealPath(false);
+            assertCheckRead(file);
+
+            prepare();
+            Paths.get(".").toRealPath(true);
+            assertCheckPropertyAccess("user.dir");
+
+            prepare();
+            Paths.get(".").toRealPath(false);
+            assertCheckPropertyAccess("user.dir");
+
+            // -- register --
+
+            try (WatchService watcher = FileSystems.getDefault().newWatchService()) {
+                prepare();
+                testdir.register(watcher, StandardWatchEventKind.ENTRY_DELETE);
+                assertCheckRead(testdir);
+            }
+
+            // -- getAttribute/setAttribute/readAttributes --
+
+            prepare();
+            getAttribute(file, "size");
+            assertCheckRead(file);
+
+            prepare();
+            setAttribute(file, "lastModifiedTime",
+                FileTime.fromMillis(System.currentTimeMillis()));
+            assertCheckWrite(file);
+
+            prepare();
+            readAttributes(file, "*");
+            assertCheckRead(file);
+
+            // -- BasicFileAttributeView --
+            testBasicFileAttributeView(
+                getFileAttributeView(file, BasicFileAttributeView.class), file);
+
+            // -- PosixFileAttributeView --
+
+            {
+                PosixFileAttributeView view =
+                    getFileAttributeView(file, PosixFileAttributeView.class);
+                if (view != null &&
+                    getFileStore(file).supportsFileAttributeView(PosixFileAttributeView.class))
+                {
+                    testPosixFileAttributeView(view, file);
+                } else {
+                    System.out.println("PosixFileAttributeView not tested");
+                }
+            }
+
+            // -- DosFileAttributeView --
+
+            {
+                DosFileAttributeView view =
+                    getFileAttributeView(file, DosFileAttributeView.class);
+                if (view != null &&
+                    getFileStore(file).supportsFileAttributeView(DosFileAttributeView.class))
+                {
+                    prepare();
+                    view.readAttributes();
+                    assertCheckRead(file);
+
+                    prepare();
+                    view.setArchive(false);
+                    assertCheckWrite(file);
+
+                    prepare();
+                    view.setHidden(false);
+                    assertCheckWrite(file);
+
+                    prepare();
+                    view.setReadOnly(false);
+                    assertCheckWrite(file);
+
+                    prepare();
+                    view.setSystem(false);
+                    assertCheckWrite(file);
+                } else {
+                    System.out.println("DosFileAttributeView not tested");
+                }
+            }
+
+            // -- FileOwnerAttributeView --
+
+            {
+                FileOwnerAttributeView view =
+                    getFileAttributeView(file, FileOwnerAttributeView.class);
+                if (view != null &&
+                    getFileStore(file).supportsFileAttributeView(FileOwnerAttributeView.class))
+                {
+                    prepare();
+                    UserPrincipal owner = view.getOwner();
+                    assertCheckRead(file);
+                    assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+
+                    prepare();
+                    view.setOwner(owner);
+                    assertCheckWrite(file);
+                    assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+
+                } else {
+                    System.out.println("FileOwnerAttributeView not tested");
+                }
+            }
+
+            // -- UserDefinedFileAttributeView --
+
+            {
+                UserDefinedFileAttributeView view =
+                    getFileAttributeView(file, UserDefinedFileAttributeView.class);
+                if (view != null &&
+                    getFileStore(file).supportsFileAttributeView(UserDefinedFileAttributeView.class))
+                {
+                    prepare();
+                    view.write("test", ByteBuffer.wrap(new byte[100]));
+                    assertCheckWrite(file);
+                    assertCheckPermission(RuntimePermission.class,
+                                               "accessUserDefinedAttributes");
+
+                    prepare();
+                    view.read("test", ByteBuffer.allocate(100));
+                    assertCheckRead(file);
+                    assertCheckPermission(RuntimePermission.class,
+                                               "accessUserDefinedAttributes");
+
+                    prepare();
+                    view.size("test");
+                    assertCheckRead(file);
+                    assertCheckPermission(RuntimePermission.class,
+                                               "accessUserDefinedAttributes");
+
+                    prepare();
+                    view.list();
+                    assertCheckRead(file);
+                    assertCheckPermission(RuntimePermission.class,
+                                               "accessUserDefinedAttributes");
+
+                    prepare();
+                    view.delete("test");
+                    assertCheckWrite(file);
+                    assertCheckPermission(RuntimePermission.class,
+                                               "accessUserDefinedAttributes");
+                } else {
+                    System.out.println("UserDefinedFileAttributeView not tested");
+                }
+            }
+
+            // -- AclFileAttributeView --
+            {
+                AclFileAttributeView view =
+                    getFileAttributeView(file, AclFileAttributeView.class);
+                if (view != null &&
+                    getFileStore(file).supportsFileAttributeView(AclFileAttributeView.class))
+                {
+                    prepare();
+                    List<AclEntry> acl = view.getAcl();
+                    assertCheckRead(file);
+                    assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+                    prepare();
+                    view.setAcl(acl);
+                    assertCheckWrite(file);
+                    assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+                } else {
+                    System.out.println("AclFileAttributeView not tested");
+                }
+            }
+
+            // -- UserPrincipalLookupService
+
+            UserPrincipalLookupService lookupService =
+                FileSystems.getDefault().getUserPrincipalLookupService();
+            UserPrincipal owner = getOwner(file);
+
+            prepare();
+            lookupService.lookupPrincipalByName(owner.getName());
+            assertCheckPermission(RuntimePermission.class,
+                                       "lookupUserInformation");
+
+            try {
+                UserPrincipal group = readAttributes(file, PosixFileAttributes.class).group();
+                prepare();
+                lookupService.lookupPrincipalByGroupName(group.getName());
+                assertCheckPermission(RuntimePermission.class,
+                                           "lookupUserInformation");
+            } catch (UnsupportedOperationException ignore) {
+                System.out.println("lookupPrincipalByGroupName not tested");
+            }
+
+
+        } finally {
+            deleteIfExists(file);
+        }
+    }
+}
--- a/jdk/test/java/nio/file/Files/ContentType.java	Thu Jan 13 22:21:58 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/* @test
- * @bug 4313887
- * @summary Unit test for probeContentType method
- * @library ..
- * @build ContentType SimpleFileTypeDetector
- * @run main/othervm ContentType
- */
-
-import java.nio.file.*;
-import java.io.*;
-
-/**
- * Uses Files.probeContentType to probe html file and custom file type.
- */
-
-public class ContentType {
-
-    static Path createHtmlFile() throws IOException {
-        Path file = File.createTempFile("foo", ".html").toPath();
-        OutputStream out = file.newOutputStream();
-        try {
-            out.write("<html><body>foo</body></html>".getBytes());
-        } finally {
-            out.close();
-        }
-
-        return file;
-    }
-
-    static Path createGrapeFile() throws IOException {
-        return File.createTempFile("red", ".grape").toPath();
-    }
-
-    public static void main(String[] args) throws IOException {
-
-        // exercise default file type detector
-        Path file = createHtmlFile();
-        try {
-            String type = Files.probeContentType(file);
-            if (type == null) {
-                System.err.println("Content type cannot be determined - test skipped");
-            } else {
-                if (!type.equals("text/html"))
-                    throw new RuntimeException("Unexpected type: " + type);
-            }
-        } finally {
-            file.delete();
-        }
-
-        // exercise custom file type detector
-        file = createGrapeFile();
-        try {
-            String type = Files.probeContentType(file);
-            if (type == null)
-                throw new RuntimeException("Custom file type detector not installed?");
-            if (!type.equals("grape/unknown"))
-                throw new RuntimeException("Unexpected type: " + type);
-        } finally {
-            file.delete();
-        }
-
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/CopyAndMove.java	Fri Jan 28 09:28:43 2011 +0000
@@ -0,0 +1,1194 @@
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 4313887 6838333 6917021 7006126
+ * @summary Unit test for java.nio.file.Files copy and move methods
+ * @library ..
+ * @build CopyAndMove PassThroughFileSystem
+ * @run main/othervm CopyAndMove
+ */
+
+import java.nio.ByteBuffer;
+import java.nio.file.*;
+import static java.nio.file.Files.*;
+import static java.nio.file.StandardCopyOption.*;
+import static java.nio.file.LinkOption.*;
+import java.nio.file.attribute.*;
+import java.io.*;
+import java.util.*;
+
+public class CopyAndMove {
+    static final Random rand = new Random();
+    static boolean heads() { return rand.nextBoolean(); }
+
+    public static void main(String[] args) throws Exception {
+        Path dir1 = TestUtil.createTemporaryDirectory();
+        try {
+
+            // Same directory
+            testCopyFileToFile(dir1, dir1, TestUtil.supportsLinks(dir1));
+            testMove(dir1, dir1, TestUtil.supportsLinks(dir1));
+
+            // Different directories. Use test.dir if possible as it might be
+            // a different volume/file system and so improve test coverage.
+            String testDir = System.getProperty("test.dir", ".");
+            Path dir2 = TestUtil.createTemporaryDirectory(testDir);
+            try {
+                boolean testSymbolicLinks =
+                    TestUtil.supportsLinks(dir1) && TestUtil.supportsLinks(dir2);
+                testCopyFileToFile(dir1, dir2, testSymbolicLinks);
+                testMove(dir1, dir2, testSymbolicLinks);
+            } finally {
+                TestUtil.removeAll(dir2);
+            }
+
+            // Target is location associated with custom provider
+            Path dir3 = PassThroughFileSystem.create().getPath(dir1.toString());
+            testCopyFileToFile(dir1, dir3, false);
+            testMove(dir1, dir3, false);
+
+            // Test copy(InputStream,Path) and copy(Path,OutputStream)
+            testCopyInputStreamToFile();
+            testCopyFileToOuputStream();
+
+        } finally {
+            TestUtil.removeAll(dir1);
+        }
+    }
+
+    static void checkBasicAttributes(BasicFileAttributes attrs1,
+                                     BasicFileAttributes attrs2)
+    {
+        // check file type
+        assertTrue(attrs1.isRegularFile() == attrs2.isRegularFile());
+        assertTrue(attrs1.isDirectory() == attrs2.isDirectory());
+        assertTrue(attrs1.isSymbolicLink() == attrs2.isSymbolicLink());
+        assertTrue(attrs1.isOther() == attrs2.isOther());
+
+        // check last modified time
+        long time1 = attrs1.lastModifiedTime().toMillis();
+        long time2 = attrs2.lastModifiedTime().toMillis();
+        assertTrue(time1 == time2);
+
+        // check size
+        if (attrs1.isRegularFile())
+            assertTrue(attrs1.size() == attrs2.size());
+    }
+
+    static void checkPosixAttributes(PosixFileAttributes attrs1,
+                                     PosixFileAttributes attrs2)
+    {
+        assertTrue(attrs1.permissions().equals(attrs2.permissions()));
+        assertTrue(attrs1.owner().equals(attrs2.owner()));
+        assertTrue(attrs1.group().equals(attrs2.group()));
+    }
+
+    static void checkDosAttributes(DosFileAttributes attrs1,
+                                   DosFileAttributes attrs2)
+    {
+        assertTrue(attrs1.isReadOnly() == attrs2.isReadOnly());
+        assertTrue(attrs1.isHidden() == attrs2.isHidden());
+        assertTrue(attrs1.isSystem() == attrs2.isSystem());
+    }
+
+    static void checkUserDefinedFileAttributes(Map<String,ByteBuffer> attrs1,
+                                     Map<String,ByteBuffer> attrs2)
+    {
+        assert attrs1.size() == attrs2.size();
+        for (String name: attrs1.keySet()) {
+            ByteBuffer bb1 = attrs1.get(name);
+            ByteBuffer bb2 = attrs2.get(name);
+            assertTrue(bb2 != null);
+            assertTrue(bb1.equals(bb2));
+        }
+    }
+
+    static Map<String,ByteBuffer> readUserDefinedFileAttributes(Path file)
+        throws IOException
+    {
+        UserDefinedFileAttributeView view =
+            getFileAttributeView(file, UserDefinedFileAttributeView.class);
+        Map<String,ByteBuffer> result = new HashMap<>();
+        for (String name: view.list()) {
+            int size = view.size(name);
+            ByteBuffer bb = ByteBuffer.allocate(size);
+            int n = view.read(name, bb);
+            assertTrue(n == size);
+            bb.flip();
+            result.put(name, bb);
+        }
+        return result;
+    }
+
+    // move source to target with verification
+    static void moveAndVerify(Path source, Path target, CopyOption... options)
+        throws IOException
+    {
+        // read attributes before file is moved
+        BasicFileAttributes basicAttributes = null;
+        PosixFileAttributes posixAttributes = null;
+        DosFileAttributes dosAttributes = null;
+        Map<String,ByteBuffer> namedAttributes = null;
+
+        // get file attributes of source file
+        String os = System.getProperty("os.name");
+        if (os.equals("SunOS") || os.equals("Linux")) {
+            posixAttributes = readAttributes(source, PosixFileAttributes.class, NOFOLLOW_LINKS);
+            basicAttributes = posixAttributes;
+        }
+        if (os.startsWith("Windows")) {
+            dosAttributes = readAttributes(source, DosFileAttributes.class, NOFOLLOW_LINKS);
+            basicAttributes = dosAttributes;
+        }
+        if (basicAttributes == null)
+            basicAttributes = readAttributes(source, BasicFileAttributes.class, NOFOLLOW_LINKS);
+
+        // hash file contents if regular file
+        int hash = (basicAttributes.isRegularFile()) ? computeHash(source) : 0;
+
+        // record link target if symbolic link
+        Path linkTarget = null;
+        if (basicAttributes.isSymbolicLink())
+            linkTarget = readSymbolicLink(source);
+
+        // read named attributes if available (and file is not a sym link)
+        if (!basicAttributes.isSymbolicLink() &&
+            getFileStore(source).supportsFileAttributeView("xattr"))
+        {
+            namedAttributes = readUserDefinedFileAttributes(source);
+        }
+
+        // move file
+        Path result = move(source, target, options);
+        assertTrue(result == target);
+
+        // verify source does not exist
+        assertTrue(notExists(source));
+
+        // verify file contents
+        if (basicAttributes.isRegularFile()) {
+            if (computeHash(target) != hash)
+                throw new RuntimeException("Failed to verify move of regular file");
+        }
+
+        // verify link target
+        if (basicAttributes.isSymbolicLink()) {
+            if (!readSymbolicLink(target).equals(linkTarget))
+                throw new RuntimeException("Failed to verify move of symbolic link");
+        }
+
+        // verify basic attributes
+        checkBasicAttributes(basicAttributes,
+            readAttributes(target, BasicFileAttributes.class, NOFOLLOW_LINKS));
+
+        // verify other attributes when same provider
+        if (source.getFileSystem().provider() == target.getFileSystem().provider()) {
+
+            // verify POSIX attributes
+            if (posixAttributes != null && !basicAttributes.isSymbolicLink()) {
+                checkPosixAttributes(posixAttributes,
+                    readAttributes(target, PosixFileAttributes.class, NOFOLLOW_LINKS));
+            }
+
+            // verify DOS attributes
+            if (dosAttributes != null && !basicAttributes.isSymbolicLink()) {
+                DosFileAttributes attrs =
+                    readAttributes(target, DosFileAttributes.class, NOFOLLOW_LINKS);
+                checkDosAttributes(dosAttributes, attrs);
+            }
+
+            // verify named attributes
+            if (namedAttributes != null &&
+                getFileStore(target).supportsFileAttributeView("xattr"))
+            {
+                checkUserDefinedFileAttributes(namedAttributes,
+                                               readUserDefinedFileAttributes(target));
+            }
+        }
+    }
+
+    /**
+     * Tests all possible ways to invoke move
+     */
+    static void testMove(Path dir1, Path dir2, boolean supportsLinks)
+        throws IOException
+    {
+        Path source, target, entry;
+
+        boolean sameDevice = getFileStore(dir1).equals(getFileStore(dir2));
+
+        // -- regular file --
+
+        /**
+         * Test: move regular file, target does not exist
+         */
+        source = createSourceFile(dir1);
+        target = getTargetFile(dir2);
+        moveAndVerify(source, target);
+        delete(target);
+
+        /**
+         * Test: move regular file, target exists
+         */
+        source = createSourceFile(dir1);
+        target = getTargetFile(dir2);
+        createFile(target);
+        try {
+            moveAndVerify(source, target);
+            throw new RuntimeException("FileAlreadyExistsException expected");
+        } catch (FileAlreadyExistsException x) {
+        }
+        delete(target);
+        createDirectory(target);
+        try {
+            moveAndVerify(source, target);
+            throw new RuntimeException("FileAlreadyExistsException expected");
+        } catch (FileAlreadyExistsException x) {
+        }
+        delete(source);
+        delete(target);
+
+        /**
+         * Test: move regular file, target does not exist
+         */
+        source = createSourceFile(dir1);
+        target = getTargetFile(dir2);
+        moveAndVerify(source, target, REPLACE_EXISTING);
+        delete(target);
+
+        /**
+         * Test: move regular file, target exists
+         */
+        source = createSourceFile(dir1);
+        target = getTargetFile(dir2);
+        createFile(target);
+        moveAndVerify(source, target, REPLACE_EXISTING);
+        delete(target);
+
+        /**
+         * Test: move regular file, target exists and is empty directory
+         */
+        source = createSourceFile(dir1);
+        target = getTargetFile(dir2);
+        createDirectory(target);
+        moveAndVerify(source, target, REPLACE_EXISTING);
+        delete(target);
+
+        /**
+         * Test: move regular file, target exists and is non-empty directory
+         */
+        source = createSourceFile(dir1);
+        target = getTargetFile(dir2);
+        createDirectory(target);
+        entry = target.resolve("foo");
+        createFile(entry);
+        try {
+            moveAndVerify(source, target);
+            throw new RuntimeException("FileAlreadyExistsException expected");
+        } catch (FileAlreadyExistsException x) {
+        }
+        delete(entry);
+        delete(source);
+        delete(target);
+
+        /**
+         * Test atomic move of regular file (same file store)
+         */
+        source = createSourceFile(dir1);
+        target = getTargetFile(dir1);
+        moveAndVerify(source, target, ATOMIC_MOVE);
+        delete(target);
+
+        /**
+         * Test atomic move of regular file (different file store)
+         */
+        if (!sameDevice) {
+            source = createSourceFile(dir1);
+            target = getTargetFile(dir2);
+            try {
+                moveAndVerify(source, target, ATOMIC_MOVE);
+                throw new RuntimeException("AtomicMoveNotSupportedException expected");
+            } catch (AtomicMoveNotSupportedException x) {
+            }
+            delete(source);
+        }
+
+        // -- directories --
+
+        /*
+         * Test: move empty directory, target does not exist
+         */
+        source = createSourceDirectory(dir1);
+        target = getTargetFile(dir2);
+        moveAndVerify(source, target);
+        delete(target);
+
+        /**
+         * Test: move empty directory, target exists
+         */
+        source = createSourceDirectory(dir1);
+        target = getTargetFile(dir2);
+        createFile(target);
+        try {
+            moveAndVerify(source, target);
+            throw new RuntimeException("FileAlreadyExistsException expected");
+        } catch (FileAlreadyExistsException x) {
+        }
+        delete(target);
+        createDirectory(target);
+        try {
+            moveAndVerify(source, target);
+            throw new RuntimeException("FileAlreadyExistsException expected");
+        } catch (FileAlreadyExistsException x) {
+        }
+        delete(source);
+        delete(target);
+
+        /**
+         * Test: move empty directory, target does not exist
+         */
+        source = createSourceDirectory(dir1);
+        target = getTargetFile(dir2);
+        moveAndVerify(source, target, REPLACE_EXISTING);
+        delete(target);
+
+        /**
+         * Test: move empty directory, target exists
+         */
+        source = createSourceDirectory(dir1);
+        target = getTargetFile(dir2);
+        createFile(target);
+        moveAndVerify(source, target, REPLACE_EXISTING);
+        delete(target);
+
+        /**
+         * Test: move empty, target exists and is empty directory
+         */
+        source = createSourceDirectory(dir1);
+        target = getTargetFile(dir2);
+        createDirectory(target);
+        moveAndVerify(source, target, REPLACE_EXISTING);
+        delete(target);
+
+        /**
+         * Test: move empty directory, target exists and is non-empty directory
+         */
+        source = createSourceDirectory(dir1);
+        target = getTargetFile(dir2);
+        createDirectory(target);
+        entry = target.resolve("foo");
+        createFile(entry);
+        try {
+            moveAndVerify(source, target, REPLACE_EXISTING);
+            throw new RuntimeException("DirectoryNotEmptyException expected");
+        } catch (DirectoryNotEmptyException x) {
+        }
+        delete(entry);
+        delete(source);
+        delete(target);
+
+        /**
+         * Test: move non-empty directory (same file system)
+         */
+        source = createSourceDirectory(dir1);
+        createFile(source.resolve("foo"));
+        target = getTargetFile(dir1);
+        moveAndVerify(source, target);
+        delete(target.resolve("foo"));
+        delete(target);
+
+        /**
+         * Test: move non-empty directory (different file store)
+         */
+        if (!sameDevice) {
+            source = createSourceDirectory(dir1);
+            createFile(source.resolve("foo"));
+            target = getTargetFile(dir2);
+            try {
+                moveAndVerify(source, target);
+                throw new RuntimeException("IOException expected");
+            } catch (IOException x) {
+            }
+            delete(source.resolve("foo"));
+            delete(source);
+        }
+
+        /**
+         * Test atomic move of directory (same file store)
+         */
+        source = createSourceDirectory(dir1);
+        createFile(source.resolve("foo"));
+        target = getTargetFile(dir1);
+        moveAndVerify(source, target, ATOMIC_MOVE);
+        delete(target.resolve("foo"));
+        delete(target);
+
+        // -- symbolic links --
+
+        /**
+         * Test: Move symbolic link to file, target does not exist
+         */
+        if (supportsLinks) {
+            Path tmp = createSourceFile(dir1);
+            source = dir1.resolve("link");
+            createSymbolicLink(source, tmp);
+            target = getTargetFile(dir2);
+            moveAndVerify(source, target);
+            delete(target);
+            delete(tmp);
+        }
+
+        /**
+         * Test: Move symbolic link to directory, target does not exist
+         */
+        if (supportsLinks) {
+            source = dir1.resolve("link");
+            createSymbolicLink(source, dir2);
+            target = getTargetFile(dir2);
+            moveAndVerify(source, target);
+            delete(target);
+        }
+
+        /**
+         * Test: Move broken symbolic link, target does not exists
+         */
+        if (supportsLinks) {
+            Path tmp = Paths.get("doesnotexist");
+            source = dir1.resolve("link");
+            createSymbolicLink(source, tmp);
+            target = getTargetFile(dir2);
+            moveAndVerify(source, target);
+            delete(target);
+        }
+
+        /**
+         * Test: Move symbolic link, target exists
+         */
+        if (supportsLinks) {
+            source = dir1.resolve("link");
+            createSymbolicLink(source, dir2);
+            target = getTargetFile(dir2);
+            createFile(target);
+            try {
+                moveAndVerify(source, target);
+                throw new RuntimeException("FileAlreadyExistsException expected");
+            } catch (FileAlreadyExistsException x) {
+            }
+            delete(source);
+            delete(target);
+        }
+
+        /**
+         * Test: Move regular file, target exists
+         */
+        if (supportsLinks) {
+            source = dir1.resolve("link");
+            createSymbolicLink(source, dir2);
+            target = getTargetFile(dir2);
+            createFile(target);
+            moveAndVerify(source, target, REPLACE_EXISTING);
+            delete(target);
+        }
+
+        /**
+         * Test: move symbolic link, target exists and is empty directory
+         */
+        if (supportsLinks) {
+            source = dir1.resolve("link");
+            createSymbolicLink(source, dir2);
+            target = getTargetFile(dir2);
+            createDirectory(target);
+            moveAndVerify(source, target, REPLACE_EXISTING);
+            delete(target);
+        }
+
+        /**
+         * Test: symbolic link, target exists and is non-empty directory
+         */
+        if (supportsLinks) {
+            source = dir1.resolve("link");
+            createSymbolicLink(source, dir2);
+            target = getTargetFile(dir2);
+            createDirectory(target);
+            entry = target.resolve("foo");
+            createFile(entry);
+            try {
+                moveAndVerify(source, target);
+                throw new RuntimeException("FileAlreadyExistsException expected");
+            } catch (FileAlreadyExistsException x) {
+            }
+            delete(entry);
+            delete(source);
+            delete(target);
+        }
+
+        /**
+         * Test atomic move of symbolic link (same file store)
+         */
+        if (supportsLinks) {
+            source = dir1.resolve("link");
+            createSymbolicLink(source, dir1);
+            target = getTargetFile(dir2);
+            createFile(target);
+            moveAndVerify(source, target, REPLACE_EXISTING);
+            delete(target);
+        }
+
+        // -- misc. tests --
+
+        /**
+         * Test nulls
+         */
+        source = createSourceFile(dir1);
+        target = getTargetFile(dir2);
+        try {
+            move(null, target);
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException x) { }
+        try {
+            move(source, null);
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException x) { }
+        try {
+            move(source, target, (CopyOption[])null);
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException x) { }
+        try {
+            CopyOption[] opts = { REPLACE_EXISTING, null };
+            move(source, target, opts);
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException x) { }
+        delete(source);
+
+        /**
+         * Test UOE
+         */
+        source = createSourceFile(dir1);
+        target = getTargetFile(dir2);
+        try {
+            move(source, target, new CopyOption() { });
+        } catch (UnsupportedOperationException x) { }
+        try {
+            move(source, target, REPLACE_EXISTING,  new CopyOption() { });
+        } catch (UnsupportedOperationException x) { }
+        delete(source);
+    }
+
+    // copy source to target with verification
+    static void copyAndVerify(Path source, Path target, CopyOption... options)
+        throws IOException
+    {
+        Path result = copy(source, target, options);
+        assertTrue(result == target);
+
+        // get attributes of source and target file to verify copy
+        boolean followLinks = true;
+        LinkOption[] linkOptions = new LinkOption[0];
+        boolean copyAttributes = false;
+        for (CopyOption opt : options) {
+            if (opt == NOFOLLOW_LINKS) {
+                followLinks = false;
+                linkOptions = new LinkOption[] { NOFOLLOW_LINKS };
+            }
+            if (opt == COPY_ATTRIBUTES)
+                copyAttributes = true;
+        }
+        BasicFileAttributes basicAttributes =
+            readAttributes(source, BasicFileAttributes.class, linkOptions);
+
+        // check hash if regular file
+        if (basicAttributes.isRegularFile())
+            assertTrue(computeHash(source) == computeHash(target));
+
+        // check link target if symbolic link
+        if (basicAttributes.isSymbolicLink())
+            assert(readSymbolicLink(source).equals(readSymbolicLink(target)));
+
+        // check that attributes are copied
+        if (copyAttributes && followLinks) {
+            checkBasicAttributes(basicAttributes,
+                readAttributes(source, BasicFileAttributes.class, linkOptions));
+
+            // verify other attributes when same provider
+            if (source.getFileSystem().provider() == target.getFileSystem().provider()) {
+
+                // check POSIX attributes are copied
+                String os = System.getProperty("os.name");
+                if (os.equals("SunOS") || os.equals("Linux")) {
+                    checkPosixAttributes(
+                        readAttributes(source, PosixFileAttributes.class, linkOptions),
+                        readAttributes(target, PosixFileAttributes.class, linkOptions));
+                }
+
+                // check DOS attributes are copied
+                if (os.startsWith("Windows")) {
+                    checkDosAttributes(
+                        readAttributes(source, DosFileAttributes.class, linkOptions),
+                        readAttributes(target, DosFileAttributes.class, linkOptions));
+                }
+
+                // check named attributes are copied
+                if (followLinks &&
+                    getFileStore(source).supportsFileAttributeView("xattr") &&
+                    getFileStore(target).supportsFileAttributeView("xattr"))
+                {
+                    checkUserDefinedFileAttributes(readUserDefinedFileAttributes(source),
+                                                   readUserDefinedFileAttributes(target));
+                }
+            }
+        }
+    }
+
+    /**
+     * Tests all possible ways to invoke copy to copy a file to a file
+     */
+    static void testCopyFileToFile(Path dir1, Path dir2, boolean supportsLinks)
+        throws IOException
+    {
+        Path source, target, link, entry;
+
+        // -- regular file --
+
+        /**
+         * Test: move regular file, target does not exist
+         */
+        source = createSourceFile(dir1);
+        target = getTargetFile(dir2);
+        copyAndVerify(source, target);
+        delete(source);
+        delete(target);
+
+        /**
+         * Test: copy regular file, target exists
+         */
+        source = createSourceFile(dir1);
+        target = getTargetFile(dir2);
+        createFile(target);
+        try {
+            copyAndVerify(source, target);
+            throw new RuntimeException("FileAlreadyExistsException expected");
+        } catch (FileAlreadyExistsException x) {
+        }
+        delete(target);
+        createDirectory(target);
+        try {
+            copyAndVerify(source, target);
+            throw new RuntimeException("FileAlreadyExistsException expected");
+        } catch (FileAlreadyExistsException x) {
+        }
+        delete(source);
+        delete(target);
+
+        /**
+         * Test: copy regular file, target does not exist
+         */
+        source = createSourceFile(dir1);
+        target = getTargetFile(dir2);
+        copyAndVerify(source, target, REPLACE_EXISTING);
+        delete(source);
+        delete(target);
+
+        /**
+         * Test: copy regular file, target exists
+         */
+        source = createSourceFile(dir1);
+        target = getTargetFile(dir2);
+        createFile(target);
+        copyAndVerify(source, target, REPLACE_EXISTING);
+        delete(source);
+        delete(target);
+
+        /**
+         * Test: copy regular file, target exists and is empty directory
+         */
+        source = createSourceFile(dir1);
+        target = getTargetFile(dir2);
+        createDirectory(target);
+        copyAndVerify(source, target, REPLACE_EXISTING);
+        delete(source);
+        delete(target);
+
+        /**
+         * Test: copy regular file, target exists and is non-empty directory
+         */
+        source = createSourceFile(dir1);
+        target = getTargetFile(dir2);
+        createDirectory(target);
+        entry = target.resolve("foo");
+        createFile(entry);
+        try {
+            copyAndVerify(source, target);
+            throw new RuntimeException("FileAlreadyExistsException expected");
+        } catch (FileAlreadyExistsException x) {
+        }
+        delete(entry);
+        delete(source);
+        delete(target);
+
+        /**
+         * Test: copy regular file + attributes
+         */
+        source = createSourceFile(dir1);
+        target = getTargetFile(dir2);
+        copyAndVerify(source, target, COPY_ATTRIBUTES);
+        delete(source);
+        delete(target);
+
+
+        // -- directory --
+
+        /*
+         * Test: copy directory, target does not exist
+         */
+        source = createSourceDirectory(dir1);
+        target = getTargetFile(dir2);
+        copyAndVerify(source, target);
+        delete(source);
+        delete(target);
+
+        /**
+         * Test: copy directory, target exists
+         */
+        source = createSourceDirectory(dir1);
+        target = getTargetFile(dir2);
+        createFile(target);
+        try {
+            copyAndVerify(source, target);
+            throw new RuntimeException("FileAlreadyExistsException expected");
+        } catch (FileAlreadyExistsException x) {
+        }
+        delete(target);
+        createDirectory(target);
+        try {
+            copyAndVerify(source, target);
+            throw new RuntimeException("FileAlreadyExistsException expected");
+        } catch (FileAlreadyExistsException x) {
+        }
+        delete(source);
+        delete(target);
+
+        /**
+         * Test: copy directory, target does not exist
+         */
+        source = createSourceDirectory(dir1);
+        target = getTargetFile(dir2);
+        copyAndVerify(source, target, REPLACE_EXISTING);
+        delete(source);
+        delete(target);
+
+        /**
+         * Test: copy directory, target exists
+         */
+        source = createSourceDirectory(dir1);
+        target = getTargetFile(dir2);
+        createFile(target);
+        copyAndVerify(source, target, REPLACE_EXISTING);
+        delete(source);
+        delete(target);
+
+        /**
+         * Test: copy directory, target exists and is empty directory
+         */
+        source = createSourceDirectory(dir1);
+        target = getTargetFile(dir2);
+        createDirectory(target);
+        copyAndVerify(source, target, REPLACE_EXISTING);
+        delete(source);
+        delete(target);
+
+        /**
+         * Test: copy directory, target exists and is non-empty directory
+         */
+        source = createSourceDirectory(dir1);
+        target = getTargetFile(dir2);
+        createDirectory(target);
+        entry = target.resolve("foo");
+        createFile(entry);
+        try {
+            copyAndVerify(source, target, REPLACE_EXISTING);
+            throw new RuntimeException("DirectoryNotEmptyException expected");
+        } catch (DirectoryNotEmptyException x) {
+        }
+        delete(entry);
+        delete(source);
+        delete(target);
+
+        /*
+         * Test: copy directory + attributes
+         */
+        source = createSourceDirectory(dir1);
+        target = getTargetFile(dir2);
+        copyAndVerify(source, target, COPY_ATTRIBUTES);
+        delete(source);
+        delete(target);
+
+        // -- symbolic links --
+
+        /**
+         * Test: Follow link
+         */
+        if (supportsLinks) {
+            source = createSourceFile(dir1);
+            link = dir1.resolve("link");
+            createSymbolicLink(link, source);
+            target = getTargetFile(dir2);
+            copyAndVerify(link, target);
+            delete(link);
+            delete(source);
+        }
+
+        /**
+         * Test: Copy link (to file)
+         */
+        if (supportsLinks) {
+            source = createSourceFile(dir1);
+            link = dir1.resolve("link");
+            createSymbolicLink(link, source);
+            target = getTargetFile(dir2);
+            copyAndVerify(link, target, NOFOLLOW_LINKS);
+            delete(link);
+            delete(source);
+        }
+
+        /**
+         * Test: Copy link (to directory)
+         */
+        if (supportsLinks) {
+            source = dir1.resolve("mydir");
+            createDirectory(source);
+            link = dir1.resolve("link");
+            createSymbolicLink(link, source);
+            target = getTargetFile(dir2);
+            copyAndVerify(link, target, NOFOLLOW_LINKS);
+            delete(link);
+            delete(source);
+        }
+
+        /**
+         * Test: Copy broken link
+         */
+        if (supportsLinks) {
+            assertTrue(notExists(source));
+            link = dir1.resolve("link");
+            createSymbolicLink(link, source);
+            target = getTargetFile(dir2);
+            copyAndVerify(link, target, NOFOLLOW_LINKS);
+            delete(link);
+        }
+
+        /**
+         * Test: Copy link to UNC (Windows only)
+         */
+        if (supportsLinks &&
+            System.getProperty("os.name").startsWith("Windows"))
+        {
+            Path unc = Paths.get("\\\\rialto\\share\\file");
+            link = dir1.resolve("link");
+            createSymbolicLink(link, unc);
+            target = getTargetFile(dir2);
+            copyAndVerify(link, target, NOFOLLOW_LINKS);
+            delete(link);
+        }
+
+        // -- misc. tests --
+
+        /**
+         * Test nulls
+         */
+        source = createSourceFile(dir1);
+        target = getTargetFile(dir2);
+        try {
+            copy(source, null);
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException x) { }
+        try {
+            copy(source, target, (CopyOption[])null);
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException x) { }
+        try {
+            CopyOption[] opts = { REPLACE_EXISTING, null };
+            copy(source, target, opts);
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException x) { }
+        delete(source);
+
+        /**
+         * Test UOE
+         */
+        source = createSourceFile(dir1);
+        target = getTargetFile(dir2);
+        try {
+            copy(source, target, new CopyOption() { });
+        } catch (UnsupportedOperationException x) { }
+        try {
+            copy(source, target, REPLACE_EXISTING,  new CopyOption() { });
+        } catch (UnsupportedOperationException x) { }
+        delete(source);
+    }
+
+    /**
+     * Test copy from an input stream to a file
+     */
+    static void testCopyInputStreamToFile() throws IOException {
+        testCopyInputStreamToFile(0);
+        for (int i=0; i<100; i++) {
+            testCopyInputStreamToFile(rand.nextInt(32000));
+        }
+
+        // FileAlreadyExistsException
+        Path target = createTempFile("blah", null);
+        try {
+            InputStream in = new ByteArrayInputStream(new byte[0]);
+            try {
+                copy(in, target);
+                throw new RuntimeException("FileAlreadyExistsException expected");
+            } catch (FileAlreadyExistsException ignore) { }
+        } finally {
+            delete(target);
+        }
+        Path tmpdir = createTempDirectory("blah");
+        try {
+            if (TestUtil.supportsLinks(tmpdir)) {
+                Path link = createSymbolicLink(tmpdir.resolve("link"),
+                                                  tmpdir.resolve("target"));
+                try {
+                    InputStream in = new ByteArrayInputStream(new byte[0]);
+                    try {
+                        copy(in, link);
+                        throw new RuntimeException("FileAlreadyExistsException expected");
+                    } catch (FileAlreadyExistsException ignore) { }
+                } finally {
+                    delete(link);
+                }
+            }
+        } finally {
+            delete(tmpdir);
+        }
+
+
+        // nulls
+        try {
+            copy((InputStream)null, target);
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException ignore) { }
+        try {
+            copy(new ByteArrayInputStream(new byte[0]), (Path)null);
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException ignore) { }
+    }
+
+    static void testCopyInputStreamToFile(int size) throws IOException {
+        Path tmpdir = createTempDirectory("blah");
+        Path source = tmpdir.resolve("source");
+        Path target = tmpdir.resolve("target");
+        try {
+            boolean testReplaceExisting = rand.nextBoolean();
+
+            // create source file
+            byte[] b = new byte[size];
+            rand.nextBytes(b);
+            write(source, b);
+
+            // target file might already exist
+            if (testReplaceExisting && rand.nextBoolean()) {
+                write(target, new byte[rand.nextInt(512)]);
+            }
+
+            // copy from stream to file
+            InputStream in = new FileInputStream(source.toFile());
+            try {
+                long n;
+                if (testReplaceExisting) {
+                    n = copy(in, target, StandardCopyOption.REPLACE_EXISTING);
+                } else {
+                    n = copy(in, target);
+                }
+                assertTrue(in.read() == -1);   // EOF
+                assertTrue(n == size);
+                assertTrue(size(target) == size);
+            } finally {
+                in.close();
+            }
+
+            // check file
+            byte[] read = readAllBytes(target);
+            assertTrue(Arrays.equals(read, b));
+
+        } finally {
+            deleteIfExists(source);
+            deleteIfExists(target);
+            delete(tmpdir);
+        }
+    }
+
+    /**
+     * Test copy from file to output stream
+     */
+    static void testCopyFileToOuputStream() throws IOException {
+        testCopyFileToOuputStream(0);
+        for (int i=0; i<100; i++) {
+            testCopyFileToOuputStream(rand.nextInt(32000));
+        }
+
+        // nulls
+        try {
+            copy((Path)null, new ByteArrayOutputStream());
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException ignore) { }
+        try {
+            Path source = createTempFile("blah", null);
+            delete(source);
+            copy(source, (OutputStream)null);
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException ignore) { }
+    }
+
+    static void testCopyFileToOuputStream(int size) throws IOException {
+        Path source = createTempFile("blah", null);
+        try {
+            byte[] b = new byte[size];
+            rand.nextBytes(b);
+            write(source, b);
+
+            ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+            long n = copy(source, out);
+            assertTrue(n == size);
+            assertTrue(out.size() == size);
+
+            byte[] read = out.toByteArray();
+            assertTrue(Arrays.equals(read, b));
+
+            // check output stream is open
+            out.write(0);
+            assertTrue(out.size() == size+1);
+        } finally {
+            delete(source);
+        }
+    }
+
+    static void assertTrue(boolean value) {
+        if (!value)
+            throw new RuntimeException("Assertion failed");
+    }
+
+    // computes simple hash of the given file
+    static int computeHash(Path file) throws IOException {
+        int h = 0;
+
+        try (InputStream in = newInputStream(file)) {
+            byte[] buf = new byte[1024];
+            int n;
+            do {
+                n = in.read(buf);
+                for (int i=0; i<n; i++) {
+                    h = 31*h + (buf[i] & 0xff);
+                }
+            } while (n > 0);
+        }
+        return h;
+    }
+
+    // create file of random size in given directory
+    static Path createSourceFile(Path dir) throws IOException {
+        String name = "source" + Integer.toString(rand.nextInt());
+        Path file = dir.resolve(name);
+        createFile(file);
+        byte[] bytes = new byte[rand.nextInt(128*1024)];
+        rand.nextBytes(bytes);
+        try (OutputStream out = newOutputStream(file)) {
+            out.write(bytes);
+        }
+        randomizeAttributes(file);
+        return file;
+    }
+
+    // create directory in the given directory
+    static Path createSourceDirectory(Path dir) throws IOException {
+        String name = "sourcedir" + Integer.toString(rand.nextInt());
+        Path subdir = dir.resolve(name);
+        createDirectory(subdir);
+        randomizeAttributes(subdir);
+        return subdir;
+    }
+
+    // "randomize" the file attributes of the given file.
+    static void randomizeAttributes(Path file) throws IOException {
+        String os = System.getProperty("os.name");
+        boolean isWindows = os.startsWith("Windows");
+        boolean isUnix = os.equals("SunOS") || os.equals("Linux");
+        boolean isDirectory = isDirectory(file, NOFOLLOW_LINKS);
+
+        if (isUnix) {
+            Set<PosixFilePermission> perms =
+                getPosixFilePermissions(file, NOFOLLOW_LINKS);
+            PosixFilePermission[] toChange = {
+                PosixFilePermission.GROUP_READ,
+                PosixFilePermission.GROUP_WRITE,
+                PosixFilePermission.GROUP_EXECUTE,
+                PosixFilePermission.OTHERS_READ,
+                PosixFilePermission.OTHERS_WRITE,
+                PosixFilePermission.OTHERS_EXECUTE
+            };
+            for (PosixFilePermission perm: toChange) {
+                if (heads()) {
+                    perms.add(perm);
+                } else {
+                    perms.remove(perm);
+                }
+            }
+            setPosixFilePermissions(file, perms);
+        }
+
+        if (isWindows) {
+            DosFileAttributeView view =
+                getFileAttributeView(file, DosFileAttributeView.class, NOFOLLOW_LINKS);
+            // only set or unset the hidden attribute
+            view.setHidden(heads());
+        }
+
+        boolean addUserDefinedFileAttributes = heads() &&
+            getFileStore(file).supportsFileAttributeView("xattr");
+
+        // remove this when copying a direcory copies its named streams
+        if (isWindows && isDirectory) addUserDefinedFileAttributes = false;
+
+        if (addUserDefinedFileAttributes) {
+            UserDefinedFileAttributeView view =
+                getFileAttributeView(file, UserDefinedFileAttributeView.class);
+            int n = rand.nextInt(16);
+            while (n > 0) {
+                byte[] value = new byte[1 + rand.nextInt(100)];
+                view.write("user." + Integer.toString(n), ByteBuffer.wrap(value));
+                n--;
+            }
+        }
+    }
+
+    // create name for file in given directory
+    static Path getTargetFile(Path dir) throws IOException {
+        String name = "target" + Integer.toString(rand.nextInt());
+        return dir.resolve(name);
+    }
+ }
--- a/jdk/test/java/nio/file/Files/CreateFileTree.java	Thu Jan 13 22:21:58 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.nio.file.*;
-import java.io.IOException;
-import java.util.*;
-
-/**
- * Creates a file tree with possible cycles caused by symbolic links
- * to ancestor directories.
- */
-
-public class CreateFileTree {
-
-    static final Random rand = new Random();
-
-    public static Path createTemporaryDirectory() throws IOException {
-        Path tmpdir = Paths.get(System.getProperty("java.io.tmpdir"));
-        Path dir;
-        do {
-            dir = tmpdir.resolve("name" + rand.nextInt());
-        } while (dir.exists());
-        dir.createDirectory();
-        return dir;
-    }
-
-    public static void main(String[] args) throws IOException {
-        Path top = createTemporaryDirectory();
-        if (!top.isAbsolute())
-            top = top.toAbsolutePath();
-
-        List<Path> dirs = new ArrayList<Path>();
-
-        // create tree
-        Queue<Path> queue = new ArrayDeque<Path>();
-        queue.add(top);
-        int total = 1 + rand.nextInt(20);
-        int n = 0;
-        Path dir;
-        while (((dir = queue.poll()) != null) && (n < total)) {
-            int r = Math.min((total-n), (1+rand.nextInt(3)));
-            for (int i=0; i<r; i++) {
-                String name = "dir" + (++n);
-                Path subdir = dir.resolve(name).createDirectory();
-                queue.offer(subdir);
-                dirs.add(subdir);
-            }
-        }
-        assert dirs.size() >= 2;
-
-        // create a few regular files in the file tree
-        int files = dirs.size() * 3;
-        for (int i=0; i<files; i++) {
-            String name = "file" + (i+1);
-            int x = rand.nextInt(dirs.size());
-            dirs.get(x).resolve(name).createFile();
-        }
-
-        // create a few sym links in the file tree so as to create cycles
-        int links = 1 + rand.nextInt(5);
-        for (int i=0; i<links; i++) {
-            int x = rand.nextInt(dirs.size());
-            int y;
-            do {
-                y = rand.nextInt(dirs.size());
-            } while (y != x);
-            String name = "link" + (i+1);
-            Path link = dirs.get(x).resolve(name);
-            Path target = dirs.get(y);
-            link.createSymbolicLink(target);
-        }
-
-        // done
-        System.out.println(top);
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/DeleteOnClose.java	Fri Jan 28 09:28:43 2011 +0000
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.nio.file.*;
+import static java.nio.file.StandardOpenOption.*;
+import java.io.*;
+import java.util.*;
+
+public class DeleteOnClose {
+
+    public static void main(String[] args) throws IOException {
+        // open file but do not close it. Its existance will be checked by
+        // the calling script.
+        Files.newByteChannel(Paths.get(args[0]), READ, WRITE, DELETE_ON_CLOSE);
+
+        // check temporary file has been deleted after closing it
+        Path file = Files.createTempFile("blah", "tmp");
+        Files.newByteChannel(file, READ, WRITE, DELETE_ON_CLOSE).close();
+        if (Files.exists(file))
+            throw new RuntimeException("Temporary file was not deleted");
+
+        Path dir = Files.createTempDirectory("blah");
+        try {
+            // check that DELETE_ON_CLOSE fails when file is a sym link
+            if (TestUtil.supportsLinks(dir)) {
+                file = dir.resolve("foo");
+                Files.createFile(file);
+                Path link = dir.resolve("link");
+                Files.createSymbolicLink(link, file);
+                try {
+                    Files.newByteChannel(link, READ, WRITE, DELETE_ON_CLOSE);
+                    throw new RuntimeException("IOException expected");
+                } catch (IOException ignore) { }
+            }
+
+            // check that DELETE_ON_CLOSE works with files created via open
+            // directories
+            try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
+                if (stream instanceof SecureDirectoryStream) {
+                    SecureDirectoryStream<Path> secure = (SecureDirectoryStream<Path>)stream;
+                    file = Paths.get("foo");
+
+                    Set<OpenOption> opts = new HashSet<>();
+                    opts.add(WRITE);
+                    opts.add(DELETE_ON_CLOSE);
+                    secure.newByteChannel(file, opts).close();
+
+                    if (Files.exists(dir.resolve(file)))
+                        throw new RuntimeException("File not deleted");
+                }
+            }
+        } finally {
+            TestUtil.removeAll(dir);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/FileAttributes.java	Fri Jan 28 09:28:43 2011 +0000
@@ -0,0 +1,265 @@
+/*
+ * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 4313887 6838333
+ * @summary Unit test for java.nio.file.Files
+ * @library ..
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.io.IOException;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Exercises getAttribute/setAttribute/readAttributes methods.
+ */
+
+public class FileAttributes {
+
+    static void assertTrue(boolean okay) {
+        if (!okay)
+            throw new RuntimeException("Assertion Failed");
+    }
+
+    static void checkEqual(Object o1, Object o2) {
+        if (o1 == null) {
+            assertTrue(o2 == null);
+        } else {
+            assertTrue (o1.equals(o2));
+        }
+    }
+
+    // checks that two time values are within 1s of each other
+    static void checkNearEqual(FileTime t1, FileTime t2) {
+        long diff = Math.abs(t1.toMillis() - t2.toMillis());
+        assertTrue(diff <= 1000);
+    }
+
+    // Exercise getAttribute/setAttribute/readAttributes on basic attributes
+    static void checkBasicAttributes(Path file, BasicFileAttributes attrs)
+        throws IOException
+    {
+        // getAttribute
+        checkEqual(attrs.size(), Files.getAttribute(file, "size"));
+        checkEqual(attrs.lastModifiedTime(), Files.getAttribute(file, "basic:lastModifiedTime"));
+        checkEqual(attrs.lastAccessTime(), Files.getAttribute(file, "lastAccessTime"));
+        checkEqual(attrs.creationTime(), Files.getAttribute(file, "basic:creationTime"));
+        assertTrue((Boolean)Files.getAttribute(file, "isRegularFile"));
+        assertTrue(!(Boolean)Files.getAttribute(file, "basic:isDirectory"));
+        assertTrue(!(Boolean)Files.getAttribute(file, "isSymbolicLink"));
+        assertTrue(!(Boolean)Files.getAttribute(file, "basic:isOther"));
+        checkEqual(attrs.fileKey(), Files.getAttribute(file, "basic:fileKey"));
+
+        // setAttribute
+        FileTime modTime = attrs.lastModifiedTime();
+        Files.setAttribute(file, "basic:lastModifiedTime", FileTime.fromMillis(0L));
+        checkEqual(Files.getLastModifiedTime(file),
+                   FileTime.fromMillis(0L));
+        Files.setAttribute(file, "lastModifiedTime", modTime);
+        checkEqual(Files.getLastModifiedTime(file), modTime);
+
+        Map<String,Object> map;
+        map = Files.readAttributes(file, "*");
+        assertTrue(map.size() >= 9);
+        checkEqual(attrs.isRegularFile(), map.get("isRegularFile")); // check one
+
+        map = Files.readAttributes(file, "basic:*");
+        assertTrue(map.size() >= 9);
+        checkEqual(attrs.lastAccessTime(), map.get("lastAccessTime")); // check one
+
+        map = Files.readAttributes(file, "size,lastModifiedTime");
+        assertTrue(map.size() == 2);
+        checkEqual(attrs.size(), map.get("size"));
+        checkEqual(attrs.lastModifiedTime(), map.get("lastModifiedTime"));
+
+        map = Files.readAttributes(file,
+            "basic:lastModifiedTime,lastAccessTime,ShouldNotExist");
+        assertTrue(map.size() == 2);
+        checkEqual(attrs.lastModifiedTime(), map.get("lastModifiedTime"));
+        checkEqual(attrs.lastAccessTime(), map.get("lastAccessTime"));
+    }
+
+    // Exercise getAttribute/setAttribute/readAttributes on posix attributes
+    static void checkPosixAttributes(Path file, PosixFileAttributes attrs)
+        throws IOException
+    {
+        checkBasicAttributes(file, attrs);
+
+        // getAttribute
+        checkEqual(attrs.permissions(), Files.getAttribute(file, "posix:permissions"));
+        checkEqual(attrs.owner(), Files.getAttribute(file, "posix:owner"));
+        checkEqual(attrs.group(), Files.getAttribute(file, "posix:group"));
+
+        // setAttribute
+        Set<PosixFilePermission> orig = attrs.permissions();
+        Set<PosixFilePermission> newPerms = new HashSet<>(orig);
+        newPerms.remove(PosixFilePermission.OTHERS_READ);
+        newPerms.remove(PosixFilePermission.OTHERS_WRITE);
+        newPerms.remove(PosixFilePermission.OTHERS_EXECUTE);
+        Files.setAttribute(file, "posix:permissions", newPerms);
+        checkEqual(Files.getPosixFilePermissions(file), newPerms);
+        Files.setAttribute(file, "posix:permissions", orig);
+        checkEqual(Files.getPosixFilePermissions(file), orig);
+        Files.setAttribute(file, "posix:owner", attrs.owner());
+        Files.setAttribute(file, "posix:group", attrs.group());
+
+        // readAttributes
+        Map<String,Object> map;
+        map = Files.readAttributes(file, "posix:*");
+        assertTrue(map.size() >= 12);
+        checkEqual(attrs.permissions(), map.get("permissions")); // check one
+
+        map = Files.readAttributes(file, "posix:size,owner,ShouldNotExist");
+        assertTrue(map.size() == 2);
+        checkEqual(attrs.size(), map.get("size"));
+        checkEqual(attrs.owner(), map.get("owner"));
+    }
+
+    // Exercise getAttribute/readAttributes on unix attributes
+    static void checkUnixAttributes(Path file) throws IOException {
+        // getAttribute
+        int mode = (Integer)Files.getAttribute(file, "unix:mode");
+        long ino = (Long)Files.getAttribute(file, "unix:ino");
+        long dev = (Long)Files.getAttribute(file, "unix:dev");
+        long rdev = (Long)Files.getAttribute(file, "unix:rdev");
+        int nlink = (Integer)Files.getAttribute(file, "unix:nlink");
+        int uid = (Integer)Files.getAttribute(file, "unix:uid");
+        int gid = (Integer)Files.getAttribute(file, "unix:gid");
+        FileTime ctime = (FileTime)Files.getAttribute(file, "unix:ctime");
+
+        // readAttributes
+        Map<String,Object> map;
+        map = Files.readAttributes(file, "unix:*");
+        assertTrue(map.size() >= 20);
+
+        map = Files.readAttributes(file, "unix:size,uid,gid,ShouldNotExist");
+        assertTrue(map.size() == 3);
+        checkEqual(map.get("size"),
+                   Files.readAttributes(file, BasicFileAttributes.class).size());
+    }
+
+    // Exercise getAttribute/setAttribute on dos attributes
+    static void checkDosAttributes(Path file, DosFileAttributes attrs)
+        throws IOException
+    {
+        checkBasicAttributes(file, attrs);
+
+        // getAttribute
+        checkEqual(attrs.isReadOnly(), Files.getAttribute(file, "dos:readonly"));
+        checkEqual(attrs.isHidden(), Files.getAttribute(file, "dos:hidden"));
+        checkEqual(attrs.isSystem(), Files.getAttribute(file, "dos:system"));
+        checkEqual(attrs.isArchive(), Files.getAttribute(file, "dos:archive"));
+
+        // setAttribute
+        boolean value;
+
+        value = attrs.isReadOnly();
+        Files.setAttribute(file, "dos:readonly", !value);
+        checkEqual(Files.readAttributes(file, DosFileAttributes.class).isReadOnly(), !value);
+        Files.setAttribute(file, "dos:readonly", value);
+        checkEqual(Files.readAttributes(file, DosFileAttributes.class).isReadOnly(), value);
+
+        value = attrs.isHidden();
+        Files.setAttribute(file, "dos:hidden", !value);
+        checkEqual(Files.readAttributes(file, DosFileAttributes.class).isHidden(), !value);
+        Files.setAttribute(file, "dos:hidden", value);
+        checkEqual(Files.readAttributes(file, DosFileAttributes.class).isHidden(), value);
+
+        value = attrs.isSystem();
+        Files.setAttribute(file, "dos:system", !value);
+        checkEqual(Files.readAttributes(file, DosFileAttributes.class).isSystem(), !value);
+        Files.setAttribute(file, "dos:system", value);
+        checkEqual(Files.readAttributes(file, DosFileAttributes.class).isSystem(), value);
+
+        value = attrs.isArchive();
+        Files.setAttribute(file, "dos:archive", !value);
+        checkEqual(Files.readAttributes(file, DosFileAttributes.class).isArchive(), !value);
+        Files.setAttribute(file, "dos:archive", value);
+        checkEqual(Files.readAttributes(file, DosFileAttributes.class).isArchive(), value);
+
+        // readAttributes
+        Map<String,Object> map;
+        map = Files.readAttributes(file, "dos:*");
+        assertTrue(map.size() >= 13);
+        checkEqual(attrs.isReadOnly(), map.get("readonly")); // check one
+
+        map = Files.readAttributes(file, "dos:size,hidden,ShouldNotExist");
+        assertTrue(map.size() == 2);
+        checkEqual(attrs.size(), map.get("size"));
+        checkEqual(attrs.isHidden(), map.get("hidden"));
+    }
+
+    static void miscTests(Path file) throws IOException {
+        // NPE tests
+        try {
+            Files.getAttribute(file, null);
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException npe) { }
+        try {
+            Files.getAttribute(file, "isRegularFile", (LinkOption[])null);
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException npe) { }
+        try {
+            Files.setAttribute(file, null, 0L);
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException npe) { }
+    }
+
+    static void doTests(Path dir) throws IOException {
+        Path file = dir.resolve("foo");
+        Files.createFile(file);
+        FileStore store = Files.getFileStore(file);
+        try {
+            checkBasicAttributes(file,
+                Files.readAttributes(file, BasicFileAttributes.class));
+
+            if (store.supportsFileAttributeView("posix"))
+                checkPosixAttributes(file,
+                    Files.readAttributes(file, PosixFileAttributes.class));
+
+            if (store.supportsFileAttributeView("unix"))
+                checkUnixAttributes(file);
+
+            if (store.supportsFileAttributeView("dos"))
+                checkDosAttributes(file,
+                    Files.readAttributes(file, DosFileAttributes.class));
+
+            miscTests(file);
+        } finally {
+            Files.delete(file);
+        }
+    }
+
+
+    public static void main(String[] args) throws IOException {
+        Path dir = TestUtil.createTemporaryDirectory();
+        try {
+            doTests(dir);
+        } finally {
+            TestUtil.removeAll(dir);
+        }
+    }
+}
--- a/jdk/test/java/nio/file/Files/ForceLoad.java	Thu Jan 13 22:21:58 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/* @test
- * @bug 4313887
- * @summary Test library dependencies by invoking Files.probeContentType
- *     before other methods that would cause nio.dll to be loaded.
- */
-
-import java.nio.file.*;
-import java.io.IOException;
-
-public class ForceLoad {
-
-    public static void main(String[] args) throws IOException {
-        Files.probeContentType(Paths.get("."));
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/InterruptCopy.java	Fri Jan 28 09:28:43 2011 +0000
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 4313887 6993267
+ * @summary Unit test for Sun-specific ExtendedCopyOption.INTERRUPTIBLE option
+ * @library ..
+ * @run main/othervm -XX:-UseVMInterruptibleIO InterruptCopy
+ */
+
+import java.nio.file.*;
+import java.io.*;
+import java.util.concurrent.*;
+import com.sun.nio.file.ExtendedCopyOption;
+
+public class InterruptCopy {
+
+    private static final long FILE_SIZE_TO_COPY = 512L * 1024L * 1024L;
+    private static final int DELAY_IN_MS = 500;
+    private static final int DURATION_MAX_IN_MS = 5000;
+
+    public static void main(String[] args) throws Exception {
+        Path dir = TestUtil.createTemporaryDirectory();
+        try {
+            FileStore store = Files.getFileStore(dir);
+            System.out.format("Checking space (%s)\n", store);
+            long usableSpace = store.getUsableSpace();
+            if (usableSpace < 2*FILE_SIZE_TO_COPY) {
+                System.out.println("Insufficient disk space to run test.");
+                return;
+            }
+            doTest(dir);
+        } finally {
+            TestUtil.removeAll(dir);
+        }
+    }
+
+    static void doTest(Path dir) throws Exception {
+        final Path source = dir.resolve("foo");
+        final Path target = dir.resolve("bar");
+
+        // create source file (don't create it as sparse file because we
+        // require the copy to take a long time)
+        System.out.println("Creating source file...");
+        byte[] buf = new byte[32*1024];
+        long total = 0;
+        try (OutputStream out = Files.newOutputStream(source)) {
+            do {
+                out.write(buf);
+                total += buf.length;
+            } while (total < FILE_SIZE_TO_COPY);
+        }
+        System.out.println("Source file created.");
+
+        ScheduledExecutorService pool =
+            Executors.newSingleThreadScheduledExecutor();
+        try {
+            // copy source to target in main thread, interrupting it after a delay
+            final Thread me = Thread.currentThread();
+            Future<?> wakeup = pool.schedule(new Runnable() {
+                public void run() {
+                    me.interrupt();
+                }}, DELAY_IN_MS, TimeUnit.MILLISECONDS);
+            System.out.println("Copying file...");
+            try {
+                long start = System.currentTimeMillis();
+                Files.copy(source, target, ExtendedCopyOption.INTERRUPTIBLE);
+                long duration = System.currentTimeMillis() - start;
+                if (duration > DURATION_MAX_IN_MS)
+                    throw new RuntimeException("Copy was not interrupted");
+            } catch (IOException e) {
+                boolean interrupted = Thread.interrupted();
+                if (!interrupted)
+                    throw new RuntimeException("Interrupt status was not set");
+                System.out.println("Copy failed (this is expected)");
+            }
+            try {
+                wakeup.get();
+            } catch (InterruptedException ignore) { }
+            Thread.interrupted();
+
+            // copy source to target via task in thread pool, interrupting it after
+            // a delay using cancel(true)
+            Future<Void> result = pool.submit(new Callable<Void>() {
+                public Void call() throws IOException {
+                    System.out.println("Copying file...");
+                    Files.copy(source, target, ExtendedCopyOption.INTERRUPTIBLE,
+                        StandardCopyOption.REPLACE_EXISTING);
+                    return null;
+                }
+            });
+            Thread.sleep(DELAY_IN_MS);
+            boolean cancelled = result.cancel(true);
+            if (!cancelled)
+                result.get();
+            System.out.println("Copy cancelled.");
+        } finally {
+            pool.shutdown();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/Links.java	Fri Jan 28 09:28:43 2011 +0000
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 4313887 6838333 6863864
+ * @summary Unit test for java.nio.file.Files createSymbolicLink,
+ *     readSymbolicLink, and createLink methods
+ * @library ..
+ * @build Links
+ * @run main/othervm Links
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.io.*;
+
+public class Links {
+
+    static final boolean isWindows =
+        System.getProperty("os.name").startsWith("Windows");
+
+    static void assertTrue(boolean okay) {
+        if (!okay)
+            throw new RuntimeException("Assertion failed");
+    }
+
+    /**
+     * Exercise createSymbolicLink and readLink methods
+     */
+    static void testSymLinks(Path dir) throws IOException {
+        final Path link = dir.resolve("link");
+
+        // Check if sym links are supported
+        try {
+            Files.createSymbolicLink(link, Paths.get("foo"));
+            Files.delete(link);
+        } catch (UnsupportedOperationException x) {
+            // sym links not supported
+            return;
+        } catch (IOException x) {
+            // probably insufficient privileges to create sym links (Windows)
+            return;
+        }
+
+        // Test links to various targets
+        String[] windowsTargets =
+            { "foo", "C:\\foo", "\\foo", "\\\\server\\share\\foo" };
+        String[] otherTargets = { "relative", "/absolute" };
+
+        String[] targets = (isWindows) ? windowsTargets : otherTargets;
+        for (String s: targets) {
+            Path target = Paths.get(s);
+            Files.createSymbolicLink(link, target);
+            try {
+                assertTrue(Files.readSymbolicLink(link).equals(target));
+            } finally {
+                Files.delete(link);
+            }
+        }
+
+        // Test links to directory
+        Path mydir = dir.resolve("mydir");
+        Path myfile = mydir.resolve("myfile");
+        try {
+            Files.createDirectory(mydir);
+            Files.createFile(myfile);
+
+            // link -> "mydir"
+            Files.createSymbolicLink(link, mydir.getFileName());
+            assertTrue(Files.readSymbolicLink(link).equals(mydir.getFileName()));
+
+            // Test access to directory via link
+            try (DirectoryStream<Path> stream = Files.newDirectoryStream(link)) {
+                boolean found = false;
+                for (Path entry: stream) {
+                    if (entry.getFileName().equals(myfile.getFileName())) {
+                        found = true;
+                        break;
+                    }
+                }
+                assertTrue(found);
+            }
+
+            // Test link2 -> link -> mydir
+            final Path link2 = dir.resolve("link2");
+            Path target2 = link.getFileName();
+            Files.createSymbolicLink(link2, target2);
+            try {
+                assertTrue(Files.readSymbolicLink(link2).equals(target2));
+                Files.newDirectoryStream(link2).close();
+            } finally {
+                Files.delete(link2);
+            }
+
+            // Remove mydir and re-create link2 before re-creating mydir
+            // (This is a useful test on Windows to ensure that creating a
+            // sym link to a directory sym link creates the right type of link).
+            Files.delete(myfile);
+            Files.delete(mydir);
+            Files.createSymbolicLink(link2, target2);
+            try {
+                assertTrue(Files.readSymbolicLink(link2).equals(target2));
+                Files.createDirectory(mydir);
+                Files.newDirectoryStream(link2).close();
+            } finally {
+                Files.delete(link2);
+            }
+
+        } finally {
+            Files.deleteIfExists(myfile);
+            Files.deleteIfExists(mydir);
+            Files.deleteIfExists(link);
+        }
+    }
+
+    /**
+     * Exercise createLink method
+     */
+    static void testHardLinks(Path dir) throws IOException {
+        Path foo = dir.resolve("foo");
+        Files.createFile(foo);
+        try {
+            Path bar = dir.resolve("bar");
+            try {
+                Files.createLink(bar, foo);
+            } catch (UnsupportedOperationException x) {
+                return;
+            } catch (IOException x) {
+                // probably insufficient privileges (Windows)
+                return;
+            }
+            try {
+                Object key1 = Files.readAttributes(foo, BasicFileAttributes.class).fileKey();
+                Object key2 = Files.readAttributes(bar, BasicFileAttributes.class).fileKey();
+                assertTrue((key1 == null) || (key1.equals(key2)));
+            } finally {
+                Files.delete(bar);
+            }
+
+
+        } finally {
+            Files.delete(foo);
+        }
+    }
+
+    public static void main(String[] args) throws IOException {
+        Path dir = TestUtil.createTemporaryDirectory();
+        try {
+            testSymLinks(dir);
+            testHardLinks(dir);
+
+            // repeat tests on Windows with long path
+            if (isWindows) {
+                Path dirWithLongPath = null;
+                try {
+                    dirWithLongPath = TestUtil.createDirectoryWithLongPath(dir);
+                } catch (IOException x) {
+                    System.out.println("Unable to create long path: " + x);
+                }
+                if (dirWithLongPath != null) {
+                    System.out.println("");
+                    System.out.println("** REPEAT TESTS WITH LONG PATH **");
+                    testSymLinks(dirWithLongPath);
+                    testHardLinks(dirWithLongPath);
+                }
+            }
+        } finally {
+            TestUtil.removeAll(dir);
+        }
+    }
+}
--- a/jdk/test/java/nio/file/Files/META-INF/services/java.nio.file.spi.FileTypeDetector	Thu Jan 13 22:21:58 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-SimpleFileTypeDetector
--- a/jdk/test/java/nio/file/Files/MaxDepth.java	Thu Jan 13 22:21:58 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.nio.file.*;
-import java.nio.file.attribute.*;
-import java.io.IOException;
-import java.util.*;
-
-/**
- * Unit test for Files.walkFileTree to test maxDepth parameter
- */
-
-public class MaxDepth {
-    public static void main(String[] args) throws Exception {
-        final Path top = Paths.get(args[0]);
-
-        for (int i=0; i<5; i++) {
-            Set<FileVisitOption> opts = Collections.emptySet();
-            final int maxDepth = i;
-            Files.walkFileTree(top, opts, maxDepth, new SimpleFileVisitor<Path>() {
-                // compute depth based on relative path to top directory
-                private int depth(Path file) {
-                    Path rp = file.relativize(top);
-                    return (rp == null) ? 0 : rp.getNameCount();
-                }
-
-                @Override
-                public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
-                    int d = depth(dir);
-                    if (d == maxDepth)
-                        throw new RuntimeException("Should not open directories at maxDepth");
-                    if (d > maxDepth)
-                        throw new RuntimeException("Too deep");
-                    return FileVisitResult.CONTINUE;
-                }
-
-                @Override
-                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
-                    int d = depth(file);
-                    if (d > maxDepth)
-                        throw new RuntimeException("Too deep");
-                    return FileVisitResult.CONTINUE;
-                }
-            });
-        }
-    }
-}
--- a/jdk/test/java/nio/file/Files/Misc.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/test/java/nio/file/Files/Misc.java	Fri Jan 28 09:28:43 2011 +0000
@@ -22,122 +22,335 @@
  */
 
 /* @test
- * @bug 4313887 6838333 6865748
- * @summary Unit test for java.nio.file.Files for miscellenous cases not
- *   covered by other tests
+ * @bug 4313887 6838333
+ * @summary Unit test for miscellenous methods in java.nio.file.Files
  * @library ..
  */
 
 import java.nio.file.*;
-import java.nio.file.attribute.Attributes;
-import java.nio.file.attribute.BasicFileAttributes;
+import static java.nio.file.Files.*;
+import static java.nio.file.LinkOption.*;
+import java.nio.file.attribute.*;
 import java.io.IOException;
 import java.util.*;
 
 public class Misc {
 
-    static void npeExpected() {
-        throw new RuntimeException("NullPointerException expected");
-    }
-
     public static void main(String[] args) throws IOException {
-
-        // -- Files.createDirectories --
-
         Path dir = TestUtil.createTemporaryDirectory();
         try {
-            // no-op
-            Files.createDirectories(dir);
+            testCreateDirectories(dir);
+            testIsHidden(dir);
+            testIsSameFile(dir);
+            testFileTypeMethods(dir);
+            testAccessMethods(dir);
+        } finally {
+             TestUtil.removeAll(dir);
+        }
+    }
 
-            // create one directory
-            Path subdir = dir.resolve("a");
-            Files.createDirectories(subdir);
-            if (!subdir.exists())
-                throw new RuntimeException("directory not created");
+    /**
+     * Tests createDirectories
+     */
+    static void testCreateDirectories(Path tmpdir) throws IOException {
+        // a no-op
+        createDirectories(tmpdir);
+
+        // create one directory
+        Path subdir = tmpdir.resolve("a");
+        createDirectories(subdir);
+        assertTrue(exists(subdir));
 
-            // create parents
-            subdir = subdir.resolve("b/c/d");
-            Files.createDirectories(subdir);
-            if (!subdir.exists())
-                throw new RuntimeException("directory not created");
+        // create parents
+        subdir = subdir.resolve("b/c/d");
+        createDirectories(subdir);
+        assertTrue(exists(subdir));
 
-            // existing file is not a directory
-            Path file = dir.resolve("x").createFile();
+        // existing file is not a directory
+        Path file = createFile(tmpdir.resolve("x"));
+        try {
+            createDirectories(file);
+            throw new RuntimeException("failure expected");
+        } catch (FileAlreadyExistsException x) { }
+        try {
+            createDirectories(file.resolve("y"));
+            throw new RuntimeException("failure expected");
+        } catch (IOException x) { }
+    }
+
+    /**
+     * Tests isHidden
+     */
+    static void testIsHidden(Path tmpdir) throws IOException {
+        assertTrue(!isHidden(tmpdir));
+
+        Path file = tmpdir.resolve(".foo");
+        if (System.getProperty("os.name").startsWith("Windows")) {
+            createFile(file);
             try {
-                Files.createDirectories(file);
-                throw new RuntimeException("failure expected");
-            } catch (FileAlreadyExistsException x) { }
-            try {
-                Files.createDirectories(file.resolve("y"));
-                throw new RuntimeException("failure expected");
-            } catch (IOException x) { }
+                setAttribute(file, "dos:hidden", true);
+                try {
+                    assertTrue(isHidden(file));
+                } finally {
+                    setAttribute(file, "dos:hidden", false);
+                }
+            } finally {
+                delete(file);
+            }
+        } else {
+            assertTrue(isHidden(file));
+        }
+    }
 
-        } finally {
-            TestUtil.removeAll(dir);
-        }
+    /**
+     * Tests isSameFile
+     */
+    static void testIsSameFile(Path tmpdir) throws IOException {
+        Path thisFile = tmpdir.resolve("thisFile");
+        Path thatFile = tmpdir.resolve("thatFile");
 
-        // --- NullPointerException --
+        /**
+         * Test: isSameFile for self
+         */
+        assertTrue(isSameFile(thisFile, thisFile));
 
+        /**
+         * Test: Neither files exist
+         */
         try {
-            Files.probeContentType(null);
-            npeExpected();
-        } catch (NullPointerException e) {
+            isSameFile(thisFile, thatFile);
+            throw new RuntimeException("IOException not thrown");
+        } catch (IOException x) {
         }
         try {
-            Files.walkFileTree(null, EnumSet.noneOf(FileVisitOption.class),
-                Integer.MAX_VALUE, new SimpleFileVisitor<Path>(){});
-            npeExpected();
-        } catch (NullPointerException e) {
+            isSameFile(thatFile, thisFile);
+            throw new RuntimeException("IOException not thrown");
+        } catch (IOException x) {
         }
-        try {
-            Files.walkFileTree(Paths.get("."), null, Integer.MAX_VALUE,
-                new SimpleFileVisitor<Path>(){});
-            npeExpected();
-        } catch (NullPointerException e) {
-        }
+
+        createFile(thisFile);
         try {
-            Files.walkFileTree(Paths.get("."), EnumSet.noneOf(FileVisitOption.class),
-                -1, new SimpleFileVisitor<Path>(){});
-            throw new RuntimeException("IllegalArgumentExpected expected");
-        } catch (IllegalArgumentException e) {
-        }
-        try {
-            Set<FileVisitOption> opts = new HashSet<FileVisitOption>(1);
-            opts.add(null);
-            Files.walkFileTree(Paths.get("."), opts, Integer.MAX_VALUE,
-                new SimpleFileVisitor<Path>(){});
-            npeExpected();
-        } catch (NullPointerException e) {
-        }
-        try {
-            Files.walkFileTree(Paths.get("."), EnumSet.noneOf(FileVisitOption.class),
-                Integer.MAX_VALUE, null);
-            npeExpected();
-        } catch (NullPointerException e) {
+            /**
+             * Test: One file exists
+             */
+            try {
+                isSameFile(thisFile, thatFile);
+                throw new RuntimeException("IOException not thrown");
+            } catch (IOException x) {
+            }
+            try {
+                isSameFile(thatFile, thisFile);
+                throw new RuntimeException("IOException not thrown");
+            } catch (IOException x) {
+            }
+
+            /**
+             * Test: Both file exists
+             */
+            createFile(thatFile);
+            try {
+                assertTrue(!isSameFile(thisFile, thatFile));
+                assertTrue(!isSameFile(thatFile, thisFile));
+            } finally {
+                delete(thatFile);
+            }
+
+            /**
+             * Test: Symbolic links
+             */
+            if (TestUtil.supportsLinks(tmpdir)) {
+                createSymbolicLink(thatFile, thisFile);
+                try {
+                    assertTrue(isSameFile(thisFile, thatFile));
+                    assertTrue(isSameFile(thatFile, thisFile));
+                } finally {
+                    TestUtil.deleteUnchecked(thatFile);
+                }
+            }
+        } finally {
+            delete(thisFile);
         }
 
-        SimpleFileVisitor<Path> visitor = new SimpleFileVisitor<Path>() { };
-        boolean ranTheGauntlet = false;
-        BasicFileAttributes attrs = Attributes.readBasicFileAttributes(Paths.get("."));
+        // nulls
+        try {
+            isSameFile(thisFile, null);
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException ignore) { }
+        try {
+            isSameFile(null, thatFile);
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException ignore) { }
+    }
+
+    /**
+     * Exercise isRegularFile, isDirectory, isSymbolicLink
+     */
+    static void testFileTypeMethods(Path tmpdir) throws IOException {
+        assertTrue(!isRegularFile(tmpdir));
+        assertTrue(!isRegularFile(tmpdir, NOFOLLOW_LINKS));
+        assertTrue(isDirectory(tmpdir));
+        assertTrue(isDirectory(tmpdir, NOFOLLOW_LINKS));
+        assertTrue(!isSymbolicLink(tmpdir));
+
+        Path file = createFile(tmpdir.resolve("foo"));
+        try {
+            assertTrue(isRegularFile(file));
+            assertTrue(isRegularFile(file, NOFOLLOW_LINKS));
+            assertTrue(!isDirectory(file));
+            assertTrue(!isDirectory(file, NOFOLLOW_LINKS));
+            assertTrue(!isSymbolicLink(file));
+
+            if (TestUtil.supportsLinks(tmpdir)) {
+                Path link = tmpdir.resolve("link");
+
+                createSymbolicLink(link, tmpdir);
+                try {
+                    assertTrue(!isRegularFile(link));
+                    assertTrue(!isRegularFile(link, NOFOLLOW_LINKS));
+                    assertTrue(isDirectory(link));
+                    assertTrue(!isDirectory(link, NOFOLLOW_LINKS));
+                    assertTrue(isSymbolicLink(link));
+                } finally {
+                    delete(link);
+                }
+
+                createSymbolicLink(link, file);
+                try {
+                    assertTrue(isRegularFile(link));
+                    assertTrue(!isRegularFile(link, NOFOLLOW_LINKS));
+                    assertTrue(!isDirectory(link));
+                    assertTrue(!isDirectory(link, NOFOLLOW_LINKS));
+                    assertTrue(isSymbolicLink(link));
+                } finally {
+                    delete(link);
+                }
+
+                createLink(link, file);
+                try {
+                    assertTrue(isRegularFile(link));
+                    assertTrue(isRegularFile(link, NOFOLLOW_LINKS));
+                    assertTrue(!isDirectory(link));
+                    assertTrue(!isDirectory(link, NOFOLLOW_LINKS));
+                    assertTrue(!isSymbolicLink(link));
+                } finally {
+                    delete(link);
+                }
+            }
+
+        } finally {
+            delete(file);
+        }
+    }
+
+    /**
+     * Exercise isReadbale, isWritable, isExecutable, exists, notExists
+     */
+    static void testAccessMethods(Path tmpdir) throws IOException {
+        // should return false when file does not exist
+        Path doesNotExist = tmpdir.resolve("doesNotExist");
+        assertTrue(!isReadable(doesNotExist));
+        assertTrue(!isWritable(doesNotExist));
+        assertTrue(!isExecutable(doesNotExist));
+        assertTrue(!exists(doesNotExist));
+        assertTrue(notExists(doesNotExist));
 
-        try { visitor.preVisitDirectory(null, attrs);
-        } catch (NullPointerException x0) {
-        try { visitor.preVisitDirectory(dir, null);
-        } catch (NullPointerException x1) {
-        try { visitor.visitFile(null, attrs);
-        } catch (NullPointerException x2) {
-        try {  visitor.visitFile(dir, null);
-        } catch (NullPointerException x3) {
-        try { visitor.visitFileFailed(null, new IOException());
-        } catch (NullPointerException x4) {
-        try { visitor.visitFileFailed(dir, null);
-        } catch (NullPointerException x5) {
-        try { visitor.postVisitDirectory(null, new IOException());
-        } catch (NullPointerException x6) {
-            // if we get here then all visit* methods threw NPE as expected
-            ranTheGauntlet = true;
-        }}}}}}}
-        if (!ranTheGauntlet)
-            throw new RuntimeException("A visit method did not throw NPE");
+        Path file = createFile(tmpdir.resolve("foo"));
+        try {
+            // files exist
+            assertTrue(isReadable(file));
+            assertTrue(isWritable(file));
+            assertTrue(exists(file));
+            assertTrue(!notExists(file));
+            assertTrue(isReadable(tmpdir));
+            assertTrue(isWritable(tmpdir));
+            assertTrue(exists(tmpdir));
+            assertTrue(!notExists(tmpdir));
+
+
+            // sym link exists
+            if (TestUtil.supportsLinks(tmpdir)) {
+                Path link = tmpdir.resolve("link");
+
+                createSymbolicLink(link, file);
+                try {
+                    assertTrue(isReadable(link));
+                    assertTrue(isWritable(link));
+                    assertTrue(exists(link));
+                    assertTrue(!notExists(link));
+                } finally {
+                    delete(link);
+                }
+
+                createSymbolicLink(link, doesNotExist);
+                try {
+                    assertTrue(!isReadable(link));
+                    assertTrue(!isWritable(link));
+                    assertTrue(!exists(link));
+                    assertTrue(exists(link, NOFOLLOW_LINKS));
+                    assertTrue(notExists(link));
+                    assertTrue(!notExists(link, NOFOLLOW_LINKS));
+                } finally {
+                    delete(link);
+                }
+            }
+
+            /**
+             * Test: Edit ACL to deny WRITE and EXECUTE
+             */
+            if (getFileStore(file).supportsFileAttributeView("acl")) {
+                AclFileAttributeView view =
+                    getFileAttributeView(file, AclFileAttributeView.class);
+                UserPrincipal owner = view.getOwner();
+                List<AclEntry> acl = view.getAcl();
+
+                // Insert entry to deny WRITE and EXECUTE
+                AclEntry entry = AclEntry.newBuilder()
+                    .setType(AclEntryType.DENY)
+                    .setPrincipal(owner)
+                    .setPermissions(AclEntryPermission.WRITE_DATA,
+                                    AclEntryPermission.EXECUTE)
+                    .build();
+                acl.add(0, entry);
+                view.setAcl(acl);
+                try {
+                    assertTrue(!isWritable(file));
+                    assertTrue(!isExecutable(file));
+                } finally {
+                    // Restore ACL
+                    acl.remove(0);
+                    view.setAcl(acl);
+                }
+            }
+
+            /**
+             * Test: Windows DOS read-only attribute
+             */
+            if (System.getProperty("os.name").startsWith("Windows")) {
+                setAttribute(file, "dos:readonly", true);
+                try {
+                    assertTrue(!isWritable(file));
+                } finally {
+                    setAttribute(file, "dos:readonly", false);
+                }
+
+                // Read-only attribute does not make direcory read-only
+                DosFileAttributeView view =
+                    getFileAttributeView(tmpdir, DosFileAttributeView.class);
+                boolean save = view.readAttributes().isReadOnly();
+                view.setReadOnly(true);
+                try {
+                    assertTrue(isWritable(file));
+                } finally {
+                    view.setReadOnly(save);
+                }
+            }
+        } finally {
+            delete(file);
+        }
+    }
+
+    static void assertTrue(boolean okay) {
+        if (!okay)
+            throw new RuntimeException("Assertion Failed");
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/PassThroughFileSystem.java	Fri Jan 28 09:28:43 2011 +0000
@@ -0,0 +1,537 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.nio.file.spi.FileSystemProvider;
+import java.nio.channels.SeekableByteChannel;
+import java.net.URI;
+import java.util.*;
+import java.io.*;
+
+/**
+ * A "pass through" file system implementation that passes through, or delegates,
+ * everything to the default file system.
+ */
+
+class PassThroughFileSystem extends FileSystem {
+    private final FileSystemProvider provider;
+    private final FileSystem delegate;
+
+    PassThroughFileSystem(FileSystemProvider provider, FileSystem delegate) {
+        this.provider = provider;
+        this.delegate = delegate;
+    }
+
+    /**
+     * Creates a new "pass through" file system. Useful for test environments
+     * where the provider might not be deployed.
+     */
+    static FileSystem create() throws IOException {
+        FileSystemProvider provider = new PassThroughProvider();
+        Map<String,?> env = Collections.emptyMap();
+        URI uri = URI.create("pass:///");
+        return provider.newFileSystem(uri, env);
+    }
+
+    static Path unwrap(Path wrapper) {
+        if (wrapper == null)
+            throw new NullPointerException();
+        if (!(wrapper instanceof PassThroughPath))
+            throw new ProviderMismatchException();
+        return ((PassThroughPath)wrapper).delegate;
+    }
+
+    @Override
+    public FileSystemProvider provider() {
+        return provider;
+    }
+
+    @Override
+    public void close() throws IOException {
+        delegate.close();
+    }
+
+    @Override
+    public boolean isOpen() {
+        return delegate.isOpen();
+    }
+
+    @Override
+    public boolean isReadOnly() {
+        return delegate.isReadOnly();
+    }
+
+    @Override
+    public String getSeparator() {
+        return delegate.getSeparator();
+    }
+
+    @Override
+    public Iterable<Path> getRootDirectories() {
+        final Iterable<Path> roots = delegate.getRootDirectories();
+        return new Iterable<Path>() {
+            @Override
+            public Iterator<Path> iterator() {
+                final Iterator<Path> itr = roots.iterator();
+                return new Iterator<Path>() {
+                    @Override
+                    public boolean hasNext() {
+                        return itr.hasNext();
+                    }
+                    @Override
+                    public Path next() {
+                        return new PassThroughPath(delegate, itr.next());
+                    }
+                    @Override
+                    public void remove() {
+                        itr.remove();
+                    }
+                };
+            }
+        };
+    }
+
+    @Override
+    public Iterable<FileStore> getFileStores() {
+        // assume that unwrapped objects aren't exposed
+        return delegate.getFileStores();
+    }
+
+    @Override
+    public Set<String> supportedFileAttributeViews() {
+        // assume that unwrapped objects aren't exposed
+        return delegate.supportedFileAttributeViews();
+    }
+
+    @Override
+    public Path getPath(String first, String... more) {
+        return new PassThroughPath(this, delegate.getPath(first, more));
+    }
+
+    @Override
+    public PathMatcher getPathMatcher(String syntaxAndPattern) {
+        final PathMatcher matcher = delegate.getPathMatcher(syntaxAndPattern);
+        return new PathMatcher() {
+            @Override
+            public boolean matches(Path path) {
+                return matcher.matches(unwrap(path));
+            }
+        };
+    }
+
+    @Override
+    public UserPrincipalLookupService getUserPrincipalLookupService() {
+        // assume that unwrapped objects aren't exposed
+        return delegate.getUserPrincipalLookupService();
+    }
+
+    @Override
+    public WatchService newWatchService() throws IOException {
+        // to keep it simple
+        throw new UnsupportedOperationException();
+    }
+
+    static class PassThroughProvider extends FileSystemProvider {
+        private static final String SCHEME = "pass";
+        private static volatile PassThroughFileSystem delegate;
+
+        public PassThroughProvider() { }
+
+        @Override
+        public String getScheme() {
+            return SCHEME;
+        }
+
+        private void checkScheme(URI uri) {
+            if (!uri.getScheme().equalsIgnoreCase(SCHEME))
+                throw new IllegalArgumentException();
+        }
+
+        private void checkUri(URI uri) {
+            checkScheme(uri);
+            if (!uri.getSchemeSpecificPart().equals("///"))
+                throw new IllegalArgumentException();
+        }
+
+        @Override
+        public FileSystem newFileSystem(URI uri, Map<String,?> env)
+            throws IOException
+        {
+            checkUri(uri);
+            synchronized (PassThroughProvider.class) {
+                if (delegate != null)
+                    throw new FileSystemAlreadyExistsException();
+                PassThroughFileSystem result =
+                    new PassThroughFileSystem(this, FileSystems.getDefault());
+                delegate = result;
+                return result;
+            }
+        }
+
+        @Override
+        public FileSystem getFileSystem(URI uri) {
+            checkUri(uri);
+            FileSystem result = delegate;
+            if (result == null)
+                throw new FileSystemNotFoundException();
+            return result;
+        }
+
+        @Override
+        public Path getPath(URI uri) {
+            checkScheme(uri);
+            if (delegate == null)
+                throw new FileSystemNotFoundException();
+            uri = URI.create(delegate.provider().getScheme() + ":" +
+                             uri.getSchemeSpecificPart());
+            return new PassThroughPath(delegate, delegate.provider().getPath(uri));
+        }
+
+        @Override
+        public void setAttribute(Path file, String attribute, Object value, LinkOption... options)
+            throws IOException
+        {
+            Files.setAttribute(unwrap(file), attribute, value, options);
+        }
+
+        @Override
+        public Map<String,Object> readAttributes(Path file, String attributes, LinkOption... options)
+            throws IOException
+        {
+            return Files.readAttributes(unwrap(file), attributes, options);
+        }
+
+        @Override
+        public <V extends FileAttributeView> V getFileAttributeView(Path file,
+                                                                    Class<V> type,
+                                                                    LinkOption... options)
+        {
+            return Files.getFileAttributeView(unwrap(file), type, options);
+        }
+
+        @Override
+        public <A extends BasicFileAttributes> A readAttributes(Path file,
+                                                                Class<A> type,
+                                                                LinkOption... options)
+            throws IOException
+        {
+            return Files.readAttributes(unwrap(file), type, options);
+        }
+
+        @Override
+        public void delete(Path file) throws IOException {
+            Files.delete(unwrap(file));
+        }
+
+        @Override
+        public void createSymbolicLink(Path link, Path target, FileAttribute<?>... attrs)
+            throws IOException
+        {
+            Files.createSymbolicLink(unwrap(link), unwrap(target), attrs);
+        }
+
+        @Override
+        public void createLink(Path link, Path existing) throws IOException {
+            Files.createLink(unwrap(link), unwrap(existing));
+        }
+
+        @Override
+        public Path readSymbolicLink(Path link) throws IOException {
+            Path target = Files.readSymbolicLink(unwrap(link));
+            return new PassThroughPath(delegate, target);
+        }
+
+
+        @Override
+        public void copy(Path source, Path target, CopyOption... options) throws IOException {
+            Files.copy(unwrap(source), unwrap(target), options);
+        }
+
+        @Override
+        public void move(Path source, Path target, CopyOption... options) throws IOException {
+            Files.move(unwrap(source), unwrap(target), options);
+        }
+
+        private DirectoryStream<Path> wrap(final DirectoryStream<Path> stream) {
+            return new DirectoryStream<Path>() {
+                @Override
+                public Iterator<Path> iterator() {
+                    final Iterator<Path> itr = stream.iterator();
+                    return new Iterator<Path>() {
+                        @Override
+                        public boolean hasNext() {
+                            return itr.hasNext();
+                        }
+                        @Override
+                        public Path next() {
+                            return new PassThroughPath(delegate, itr.next());
+                        }
+                        @Override
+                        public void remove() {
+                            itr.remove();
+                        }
+                    };
+                }
+                @Override
+                public void close() throws IOException {
+                    stream.close();
+                }
+            };
+        }
+
+        @Override
+        public DirectoryStream<Path> newDirectoryStream(Path dir, DirectoryStream.Filter<? super Path> filter)
+            throws IOException
+        {
+            return wrap(Files.newDirectoryStream(dir, filter));
+        }
+
+        @Override
+        public void createDirectory(Path dir, FileAttribute<?>... attrs)
+            throws IOException
+        {
+            Files.createDirectory(unwrap(dir), attrs);
+        }
+
+        @Override
+        public SeekableByteChannel newByteChannel(Path file,
+                                                  Set<? extends OpenOption> options,
+                                                  FileAttribute<?>... attrs)
+            throws IOException
+        {
+            return Files.newByteChannel(unwrap(file), options, attrs);
+        }
+
+
+        @Override
+        public boolean isHidden(Path file) throws IOException {
+            return Files.isHidden(unwrap(file));
+        }
+
+        @Override
+        public FileStore getFileStore(Path file) throws IOException {
+            return Files.getFileStore(unwrap(file));
+        }
+
+        @Override
+        public boolean isSameFile(Path file, Path other) throws IOException {
+            return Files.isSameFile(unwrap(file), unwrap(other));
+        }
+
+        @Override
+        public void checkAccess(Path file, AccessMode... modes)
+            throws IOException
+        {
+            // hack
+            if (modes.length == 0) {
+                if (Files.exists(unwrap(file)))
+                    return;
+                else
+                    throw new NoSuchFileException(file.toString());
+            }
+            throw new RuntimeException("not implemented yet");
+        }
+    }
+
+    static class PassThroughPath implements Path {
+        private final FileSystem fs;
+        private final Path delegate;
+
+        PassThroughPath(FileSystem fs, Path delegate) {
+            this.fs = fs;
+            this.delegate = delegate;
+        }
+
+        private Path wrap(Path path) {
+            return (path != null) ? new PassThroughPath(fs, path) : null;
+        }
+
+        @Override
+        public FileSystem getFileSystem() {
+            return fs;
+        }
+
+        @Override
+        public boolean isAbsolute() {
+            return delegate.isAbsolute();
+        }
+
+        @Override
+        public Path getRoot() {
+            return wrap(delegate.getRoot());
+        }
+
+        @Override
+        public Path getParent() {
+            return wrap(delegate.getParent());
+        }
+
+        @Override
+        public int getNameCount() {
+            return delegate.getNameCount();
+        }
+
+        @Override
+        public Path getFileName() {
+            return wrap(delegate.getFileName());
+        }
+
+        @Override
+        public Path getName(int index) {
+            return wrap(delegate.getName(index));
+        }
+
+        @Override
+        public Path subpath(int beginIndex, int endIndex) {
+            return wrap(delegate.subpath(beginIndex, endIndex));
+        }
+
+        @Override
+        public boolean startsWith(Path other) {
+            return delegate.startsWith(unwrap(other));
+        }
+
+        @Override
+        public boolean startsWith(String other) {
+            return delegate.startsWith(other);
+        }
+
+        @Override
+        public boolean endsWith(Path other) {
+            return delegate.endsWith(unwrap(other));
+        }
+
+        @Override
+        public boolean endsWith(String other) {
+            return delegate.endsWith(other);
+        }
+
+        @Override
+        public Path normalize() {
+            return wrap(delegate.normalize());
+        }
+
+        @Override
+        public Path resolve(Path other) {
+            return wrap(delegate.resolve(unwrap(other)));
+        }
+
+        @Override
+        public Path resolve(String other) {
+            return wrap(delegate.resolve(other));
+        }
+
+        @Override
+        public Path resolveSibling(Path other) {
+            return wrap(delegate.resolveSibling(unwrap(other)));
+        }
+
+        @Override
+        public Path resolveSibling(String other) {
+            return wrap(delegate.resolveSibling(other));
+        }
+
+        @Override
+        public Path relativize(Path other) {
+            return wrap(delegate.relativize(unwrap(other)));
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            if (!(other instanceof PassThroughPath))
+                return false;
+            return delegate.equals(unwrap((PassThroughPath)other));
+        }
+
+        @Override
+        public int hashCode() {
+            return delegate.hashCode();
+        }
+
+        @Override
+        public String toString() {
+            return delegate.toString();
+        }
+
+        @Override
+        public URI toUri() {
+            String ssp = delegate.toUri().getSchemeSpecificPart();
+            return URI.create(fs.provider().getScheme() + ":" + ssp);
+        }
+
+        @Override
+        public Path toAbsolutePath() {
+            return wrap(delegate.toAbsolutePath());
+        }
+
+        @Override
+        public Path toRealPath(boolean resolveLinks) throws IOException {
+            return wrap(delegate.toRealPath(resolveLinks));
+        }
+
+        @Override
+        public File toFile() {
+            return delegate.toFile();
+        }
+
+        @Override
+        public Iterator<Path> iterator() {
+            final Iterator<Path> itr = delegate.iterator();
+            return new Iterator<Path>() {
+                @Override
+                public boolean hasNext() {
+                    return itr.hasNext();
+                }
+                @Override
+                public Path next() {
+                    return wrap(itr.next());
+                }
+                @Override
+                public void remove() {
+                    itr.remove();
+                }
+            };
+        }
+
+        @Override
+        public int compareTo(Path other) {
+            return delegate.compareTo(unwrap(other));
+        }
+
+        @Override
+        public WatchKey register(WatchService watcher,
+                                      WatchEvent.Kind<?>[] events,
+                                      WatchEvent.Modifier... modifiers)
+        {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public  WatchKey register(WatchService watcher,
+                                      WatchEvent.Kind<?>... events)
+        {
+            throw new UnsupportedOperationException();
+        }
+    }
+}
--- a/jdk/test/java/nio/file/Files/PrintFileTree.java	Thu Jan 13 22:21:58 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.nio.file.*;
-import java.nio.file.attribute.*;
-import java.io.IOException;
-import java.util.*;
-
-/**
- * Invokes Files.walkFileTree to traverse a file tree and prints
- * each of the directories and files. The -follow option causes symbolic
- * links to be followed and the -printCycles option will print links
- * where the target of the link is an ancestor directory.
- */
-
-public class PrintFileTree {
-
-    public static void main(String[] args) throws Exception {
-        boolean followLinks = false;
-        boolean printCycles = false;
-        int i = 0;
-        while (i < (args.length-1)) {
-            switch (args[i]) {
-                case "-follow"      : followLinks = true; break;
-                case "-printCycles" : printCycles = true;  break;
-                default:
-                    throw new RuntimeException(args[i] + " not recognized");
-            }
-            i++;
-        }
-        Path dir = Paths.get(args[i]);
-
-        Set<FileVisitOption> options = new HashSet<FileVisitOption>();
-        if (followLinks)
-            options.add(FileVisitOption.FOLLOW_LINKS);
-
-        final boolean reportCycles = printCycles;
-        Files.walkFileTree(dir, options, Integer.MAX_VALUE, new FileVisitor<FileRef>() {
-            @Override
-            public FileVisitResult preVisitDirectory(FileRef dir, BasicFileAttributes attrs) {
-                System.out.println(dir);
-                return FileVisitResult.CONTINUE;
-            }
-            @Override
-            public FileVisitResult visitFile(FileRef file, BasicFileAttributes attrs) {
-                if (!attrs.isDirectory() || reportCycles)
-                    System.out.println(file);
-                return FileVisitResult.CONTINUE;
-            }
-            @Override
-            public FileVisitResult postVisitDirectory(FileRef dir, IOException exc)
-                throws IOException
-            {
-                if (exc != null)
-                    throw exc;
-                return FileVisitResult.CONTINUE;
-            }
-            @Override
-            public FileVisitResult visitFileFailed(FileRef file, IOException exc)
-                throws IOException
-            {
-                if (reportCycles && (exc instanceof FileSystemLoopException)) {
-                    System.out.println(file);
-                    return FileVisitResult.CONTINUE;
-                }
-                throw exc;
-            }
-        });
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/SBC.java	Fri Jan 28 09:28:43 2011 +0000
@@ -0,0 +1,431 @@
+/*
+ * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 4313887
+ * @summary Unit test for java.nio.file.Files.newByteChannel
+ * @library ..
+ */
+
+import java.nio.ByteBuffer;
+import java.nio.file.*;
+import static java.nio.file.StandardOpenOption.*;
+import static com.sun.nio.file.ExtendedOpenOption.*;
+import java.nio.file.attribute.FileAttribute;
+import java.nio.channels.*;
+import java.io.IOException;
+import java.util.*;
+
+public class SBC {
+
+    static boolean supportsLinks;
+
+    public static void main(String[] args) throws Exception {
+        Path dir = TestUtil.createTemporaryDirectory();
+        try {
+            supportsLinks = TestUtil.supportsLinks(dir);
+
+            // open options
+            createTests(dir);
+            appendTests(dir);
+            truncateExistingTests(dir);
+            noFollowLinksTests(dir);
+
+            // SeekableByteChannel methods
+            sizeTruncatePositionTests(dir);
+
+            // platform specific
+            if (System.getProperty("os.name").startsWith("Windows"))
+                dosSharingOptionTests(dir);
+
+            // misc. tests
+            badCombinations(dir);
+            unsupportedOptions(dir);
+            nullTests(dir);
+
+        } finally {
+            TestUtil.removeAll(dir);
+        }
+    }
+
+    // test CREATE and CREATE_NEW options
+    static void createTests(Path dir) throws Exception {
+        Path file = dir.resolve("foo");
+
+        // CREATE
+        try {
+            // create file (no existing file)
+            Files.newByteChannel(file, CREATE, WRITE).close();
+            if (Files.notExists(file))
+                throw new RuntimeException("File not created");
+
+            // create file (existing file)
+            Files.newByteChannel(file, CREATE, WRITE).close();
+
+            // create file where existing file is a sym link
+            if (supportsLinks) {
+                Path link = Files.createSymbolicLink(dir.resolve("link"), file);
+                try {
+                    // file already exists
+                    Files.newByteChannel(link, CREATE, WRITE).close();
+
+                    // file does not exist
+                    Files.delete(file);
+                    Files.newByteChannel(link, CREATE, WRITE).close();
+                    if (Files.notExists(file))
+                        throw new RuntimeException("File not created");
+
+                } finally {
+                    TestUtil.deleteUnchecked(link);
+                }
+            }
+
+        } finally {
+            TestUtil.deleteUnchecked(file);
+        }
+
+        // CREATE_NEW
+        try {
+            // create file
+            Files.newByteChannel(file, CREATE_NEW, WRITE).close();
+            if (Files.notExists(file))
+                throw new RuntimeException("File not created");
+
+            // create should fail
+            try {
+                SeekableByteChannel sbc =
+                    Files.newByteChannel(file, CREATE_NEW, WRITE);
+                sbc.close();
+                throw new RuntimeException("FileAlreadyExistsException not thrown");
+            } catch (FileAlreadyExistsException x) { }
+
+            // create should fail
+            if (supportsLinks) {
+                Path link = dir.resolve("link");
+                Path target = dir.resolve("thisDoesNotExist");
+                Files.createSymbolicLink(link, target);
+                try {
+
+                    try {
+                        SeekableByteChannel sbc =
+                            Files.newByteChannel(file, CREATE_NEW, WRITE);
+                        sbc.close();
+                        throw new RuntimeException("FileAlreadyExistsException not thrown");
+                    } catch (FileAlreadyExistsException x) { }
+
+                } finally {
+                    TestUtil.deleteUnchecked(link);
+                }
+            }
+
+
+        } finally {
+            TestUtil.deleteUnchecked(file);
+        }
+
+        // CREATE_NEW + SPARSE
+        try {
+            try (SeekableByteChannel sbc = Files.newByteChannel(file, CREATE_NEW, WRITE, SPARSE)) {
+                final long hole = 2L * 1024L * 1024L * 1024L;
+                sbc.position(hole);
+                write(sbc, "hello");
+                long size = sbc.size();
+                if (size != (hole + 5))
+                    throw new RuntimeException("Unexpected size");
+            }
+        } finally {
+            TestUtil.deleteUnchecked(file);
+        }
+    }
+
+    // test APPEND option
+    static void appendTests(Path dir) throws Exception {
+        Path file = dir.resolve("foo");
+        try {
+            // "hello there" should be written to file
+            try (SeekableByteChannel sbc = Files.newByteChannel(file, CREATE_NEW, WRITE, APPEND)) {
+                write(sbc, "hello ");
+                sbc.position(0L);
+                write(sbc, "there");
+            }
+
+            // check file
+            try (Scanner s = new Scanner(file)) {
+                String line = s.nextLine();
+                if (!line.equals("hello there"))
+                    throw new RuntimeException("Unexpected file contents");
+            }
+
+            // check that read is not allowed
+            try (SeekableByteChannel sbc = Files.newByteChannel(file, APPEND)) {
+                sbc.read(ByteBuffer.allocate(100));
+            } catch (NonReadableChannelException x) {
+            }
+        } finally {
+            // clean-up
+            TestUtil.deleteUnchecked(file);
+        }
+    }
+
+    // test TRUNCATE_EXISTING option
+    static void truncateExistingTests(Path dir) throws Exception {
+        Path file = dir.resolve("foo");
+        try {
+            try (SeekableByteChannel sbc = Files.newByteChannel(file, CREATE_NEW, WRITE)) {
+                write(sbc, "Have a nice day!");
+            }
+
+            // re-open with truncate option
+            // write short message and check
+            try (SeekableByteChannel sbc = Files.newByteChannel(file, WRITE, TRUNCATE_EXISTING)) {
+                write(sbc, "Hello there!");
+            }
+            try (Scanner s = new Scanner(file)) {
+                String line = s.nextLine();
+                if (!line.equals("Hello there!"))
+                    throw new RuntimeException("Unexpected file contents");
+            }
+
+            // re-open with create + truncate option
+            // check file is of size 0L
+            try (SeekableByteChannel sbc = Files.newByteChannel(file, WRITE, CREATE, TRUNCATE_EXISTING)) {
+                long size = ((FileChannel)sbc).size();
+                if (size != 0L)
+                    throw new RuntimeException("File not truncated");
+            }
+
+        } finally {
+            // clean-up
+            TestUtil.deleteUnchecked(file);
+        }
+
+    }
+
+    // test NOFOLLOW_LINKS option
+    static void noFollowLinksTests(Path dir) throws Exception {
+        if (!supportsLinks)
+            return;
+        Path file = Files.createFile(dir.resolve("foo"));
+        try {
+            // ln -s foo link
+            Path link = dir.resolve("link");
+            Files.createSymbolicLink(link, file);
+
+            // open with NOFOLLOW_LINKS option
+            try {
+                Files.newByteChannel(link, READ, LinkOption.NOFOLLOW_LINKS);
+                throw new RuntimeException();
+            } catch (IOException x) {
+            } finally {
+                TestUtil.deleteUnchecked(link);
+            }
+
+        } finally {
+            // clean-up
+            TestUtil.deleteUnchecked(file);
+        }
+    }
+
+    // test size/truncate/position methods
+    static void sizeTruncatePositionTests(Path dir) throws Exception {
+        Path file = dir.resolve("foo");
+        try {
+            try (SeekableByteChannel sbc = Files.newByteChannel(file, CREATE_NEW, READ, WRITE)) {
+                if (sbc.size() != 0L)
+                    throw new RuntimeException("Unexpected size");
+
+                // check size
+                write(sbc, "hello");
+                if (sbc.size() != 5L)
+                    throw new RuntimeException("Unexpected size");
+
+                // truncate (size and position should change)
+                sbc.truncate(4L);
+                if (sbc.size() != 4L)
+                    throw new RuntimeException("Unexpected size");
+                if (sbc.position() != 4L)
+                    throw new RuntimeException("Unexpected position");
+
+                // truncate (position should not change)
+                sbc.position(2L).truncate(3L);
+                if (sbc.size() != 3L)
+                    throw new RuntimeException("Unexpected size");
+                if (sbc.position() != 2L)
+                    throw new RuntimeException("Unexpected position");
+            }
+        } finally {
+            TestUtil.deleteUnchecked(file);
+        }
+    }
+
+    // Windows specific options for the use by applications that really want
+    // to use legacy DOS sharing options
+    static void dosSharingOptionTests(Path dir) throws Exception {
+        Path file = Files.createFile(dir.resolve("foo"));
+        try {
+            // no sharing
+            try (SeekableByteChannel ch = Files.newByteChannel(file, READ, NOSHARE_READ,
+                                                               NOSHARE_WRITE, NOSHARE_DELETE))
+            {
+                try {
+                    Files.newByteChannel(file, READ);
+                    throw new RuntimeException("Sharing violation expected");
+                } catch (IOException ignore) { }
+                try {
+                    Files.newByteChannel(file, WRITE);
+                    throw new RuntimeException("Sharing violation expected");
+                } catch (IOException ignore) { }
+                try {
+                    Files.delete(file);
+                    throw new RuntimeException("Sharing violation expected");
+                } catch (IOException ignore) { }
+            }
+
+            // read allowed
+            try (SeekableByteChannel ch = Files.newByteChannel(file, READ, NOSHARE_WRITE, NOSHARE_DELETE)) {
+                Files.newByteChannel(file, READ).close();
+                try {
+                    Files.newByteChannel(file, WRITE);
+                    throw new RuntimeException("Sharing violation expected");
+                } catch (IOException ignore) { }
+                try {
+                    Files.delete(file);
+                    throw new RuntimeException("Sharing violation expected");
+                } catch (IOException ignore) { }
+            }
+
+            // write allowed
+            try (SeekableByteChannel ch = Files.newByteChannel(file, READ, NOSHARE_READ, NOSHARE_DELETE)) {
+                try {
+                    Files.newByteChannel(file, READ);
+                    throw new RuntimeException("Sharing violation expected");
+                } catch (IOException ignore) { }
+                Files.newByteChannel(file, WRITE).close();
+                try {
+                    Files.delete(file);
+                    throw new RuntimeException("Sharing violation expected");
+                } catch (IOException ignore) { }
+            }
+
+            // delete allowed
+            try (SeekableByteChannel ch = Files.newByteChannel(file, READ, NOSHARE_READ, NOSHARE_WRITE)) {
+                try {
+                    Files.newByteChannel(file, READ);
+                    throw new RuntimeException("Sharing violation expected");
+                } catch (IOException ignore) { }
+                try {
+                    Files.newByteChannel(file, WRITE);
+                    throw new RuntimeException("Sharing violation expected");
+                } catch (IOException ignore) { }
+                Files.delete(file);
+            }
+
+        } finally {
+            TestUtil.deleteUnchecked(file);
+        }
+    }
+
+    // invalid combinations of options
+    static void badCombinations(Path dir) throws Exception {
+        Path file = dir.resolve("bad");
+
+        try {
+            Files.newByteChannel(file, READ, APPEND);
+            throw new RuntimeException("IllegalArgumentException expected");
+        } catch (IllegalArgumentException x) { }
+
+        try {
+            Files.newByteChannel(file, WRITE, APPEND, TRUNCATE_EXISTING);
+            throw new RuntimeException("IllegalArgumentException expected");
+        } catch (IllegalArgumentException x) { }
+    }
+
+    // unsupported operations
+    static void unsupportedOptions(Path dir) throws Exception {
+        Path file = dir.resolve("bad");
+
+        OpenOption badOption = new OpenOption() { };
+        try {
+            Files.newByteChannel(file, badOption);
+            throw new RuntimeException("UnsupportedOperationException expected");
+        } catch (UnsupportedOperationException e) { }
+        try {
+            Files.newByteChannel(file, READ, WRITE, badOption);
+            throw new RuntimeException("UnsupportedOperationException expected");
+        } catch (UnsupportedOperationException e) { }
+    }
+
+    // null handling
+    static void nullTests(Path dir) throws Exception {
+        Path file = dir.resolve("foo");
+
+        try {
+            OpenOption[] opts = { READ, null };
+            Files.newByteChannel((Path)null, opts);
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException x) { }
+
+        try {
+            Files.newByteChannel(file, (OpenOption[])null);
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException x) { }
+
+        try {
+            OpenOption[] opts = { READ, null };
+            Files.newByteChannel(file, opts);
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException x) { }
+
+        try {
+            Files.newByteChannel(file, (Set<OpenOption>)null);
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException x) { }
+
+        try {
+            Set<OpenOption> opts = new HashSet<>();
+            opts.add(READ);
+            opts.add(null);
+            Files.newByteChannel(file, opts);
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException x) { }
+
+        try {
+            EnumSet<StandardOpenOption> opts = EnumSet.of(READ);
+            Files.newByteChannel(file, opts, (FileAttribute[])null);
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException x) { }
+
+        try {
+            EnumSet<StandardOpenOption> opts = EnumSet.of(READ);
+            FileAttribute[] attrs = { null };
+            Files.newByteChannel(file, opts, attrs);
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException x) { }
+    }
+
+    static void write(WritableByteChannel wbc, String msg) throws IOException {
+        ByteBuffer buf = ByteBuffer.wrap(msg.getBytes());
+        while (buf.hasRemaining())
+            wbc.write(buf);
+    }
+}
--- a/jdk/test/java/nio/file/Files/SimpleFileTypeDetector.java	Thu Jan 13 22:21:58 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.nio.file.*;
-import java.nio.file.spi.FileTypeDetector;
-import java.io.*;
-
-
-public class SimpleFileTypeDetector extends FileTypeDetector {
-    public SimpleFileTypeDetector() {
-    }
-
-    public String probeContentType(FileRef file) throws IOException {
-
-        System.out.println("probe " + file + "...");
-
-        if (file instanceof Path) {
-            String name = ((Path)file).toString();
-            if (name.endsWith(".grape")) {
-                return "grape/unknown";
-            }
-        }
-
-        // unknown
-        return null;
-    }
-}
--- a/jdk/test/java/nio/file/Files/SkipSiblings.java	Thu Jan 13 22:21:58 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.nio.file.*;
-import java.nio.file.attribute.*;
-import java.io.IOException;
-import java.util.*;
-
-/**
- * Unit test for Files.walkFileTree to test SKIP_SIBLINGS return value.
- */
-
-public class SkipSiblings {
-
-    static final Random rand = new Random();
-    static final Set<Path> skipped = new HashSet<Path>();
-
-    // check if this path's directory has been skipped
-    static void check(Path path) {
-        if (skipped.contains(path.getParent()))
-            throw new RuntimeException(path + " should not have been visited");
-    }
-
-    // indicates if the siblings of this path should be skipped
-    static boolean skip(Path path) {
-        Path parent = path.getParent();
-        if (parent != null && rand.nextBoolean()) {
-            skipped.add(parent);
-            return true;
-        }
-        return false;
-    }
-
-    public static void main(String[] args) throws Exception {
-        Path dir = Paths.get(args[0]);
-
-        Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
-            @Override
-            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
-                check(dir);
-                if (skip(dir))
-                    return FileVisitResult.SKIP_SIBLINGS;
-                return FileVisitResult.CONTINUE;
-            }
-            @Override
-            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
-                check(file);
-                if (skip(file))
-                    return FileVisitResult.SKIP_SIBLINGS;
-                return FileVisitResult.CONTINUE;
-            }
-            @Override
-            public FileVisitResult postVisitDirectory(Path dir, IOException x) {
-                if (x != null)
-                    throw new RuntimeException(x);
-                check(dir);
-                return FileVisitResult.CONTINUE;
-            }
-        });
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/TemporaryFiles.java	Fri Jan 28 09:28:43 2011 +0000
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 4313887 6838333 7006126
+ * @summary Unit test for Files.createTempXXX
+ * @library ..
+ */
+
+import java.nio.file.*;
+import static java.nio.file.StandardOpenOption.*;
+import java.nio.file.attribute.*;
+import java.io.IOException;
+import java.util.Set;
+
+public class TemporaryFiles {
+
+    static void checkInDirectory(Path file, Path dir) {
+        if (dir == null)
+            dir = Paths.get(System.getProperty("java.io.tmpdir"));
+        if (!file.getParent().equals(dir))
+            throw new RuntimeException("Not in expected directory");
+    }
+
+    static void testTempFile(String prefix, String suffix, Path dir)
+        throws IOException
+    {
+        Path file = (dir == null) ?
+            Files.createTempFile(prefix, suffix) :
+            Files.createTempFile(dir, prefix, suffix);
+        try {
+            // check file name
+            String name = file.getFileName().toString();
+            if (prefix != null && !name.startsWith(prefix))
+                throw new RuntimeException("Should start with " + prefix);
+            if (suffix == null && !name.endsWith(".tmp"))
+                throw new RuntimeException("Should end with .tmp");
+            if (suffix != null && !name.endsWith(suffix))
+                throw new RuntimeException("Should end with " + suffix);
+
+            // check file is in expected directory
+            checkInDirectory(file, dir);
+
+            // check that file can be opened for reading and writing
+            Files.newByteChannel(file, READ).close();
+            Files.newByteChannel(file, WRITE).close();
+            Files.newByteChannel(file, READ,WRITE).close();
+
+            // check file permissions are 0600 or more secure
+            if (Files.getFileStore(file).supportsFileAttributeView("posix")) {
+                Set<PosixFilePermission> perms = Files.getPosixFilePermissions(file);
+                perms.remove(PosixFilePermission.OWNER_READ);
+                perms.remove(PosixFilePermission.OWNER_WRITE);
+                if (!perms.isEmpty())
+                    throw new RuntimeException("Temporary file is not secure");
+            }
+        } finally {
+            Files.delete(file);
+        }
+    }
+
+    static void testTempFile(String prefix, String suffix)
+        throws IOException
+    {
+        testTempFile(prefix, suffix, null);
+    }
+
+    static void testTempDirectory(String prefix, Path dir) throws IOException {
+        Path subdir = (dir == null) ?
+            Files.createTempDirectory(prefix) :
+            Files.createTempDirectory(dir, prefix);
+        try {
+            // check file name
+            String name = subdir.getFileName().toString();
+            if (prefix != null && !name.startsWith(prefix))
+                throw new RuntimeException("Should start with " + prefix);
+
+            // check directory is in expected directory
+            checkInDirectory(subdir, dir);
+
+            // check directory is empty
+            DirectoryStream<Path> stream = Files.newDirectoryStream(subdir);
+            try {
+                if (stream.iterator().hasNext())
+                    throw new RuntimeException("Tempory directory not empty");
+            } finally {
+                stream.close();
+            }
+
+            // check that we can create file in directory
+            Path file = Files.createFile(subdir.resolve("foo"));
+            try {
+                Files.newByteChannel(file, READ,WRITE).close();
+            } finally {
+                Files.delete(file);
+            }
+
+            // check file permissions are 0700 or more secure
+            if (Files.getFileStore(subdir).supportsFileAttributeView("posix")) {
+                Set<PosixFilePermission> perms = Files.getPosixFilePermissions(subdir);
+                perms.remove(PosixFilePermission.OWNER_READ);
+                perms.remove(PosixFilePermission.OWNER_WRITE);
+                perms.remove(PosixFilePermission.OWNER_EXECUTE);
+                if (!perms.isEmpty())
+                    throw new RuntimeException("Temporary directory is not secure");
+            }
+        } finally {
+            Files.delete(subdir);
+        }
+    }
+
+    static void testTempDirectory(String prefix) throws IOException {
+        testTempDirectory(prefix, null);
+    }
+
+    static void testInvalidFileTemp(String prefix, String suffix) throws IOException {
+        try {
+            Path file = Files.createTempFile(prefix, suffix);
+            Files.delete(file);
+            throw new RuntimeException("IllegalArgumentException expected");
+        } catch (IllegalArgumentException expected) { }
+    }
+
+    public static void main(String[] args) throws IOException {
+        // temporary-file directory
+        testTempFile("blah", ".dat");
+        testTempFile("blah", null);
+        testTempFile(null, ".dat");
+        testTempFile(null, null);
+        testTempDirectory("blah");
+        testTempDirectory(null);
+
+        // a given directory
+        Path dir = Files.createTempDirectory("tmpdir");
+        try {
+            testTempFile("blah", ".dat", dir);
+            testTempFile("blah", null, dir);
+            testTempFile(null, ".dat", dir);
+            testTempFile(null, null, dir);
+            testTempDirectory("blah", dir);
+            testTempDirectory(null, dir);
+        } finally {
+            Files.delete(dir);
+        }
+
+        // invalid prefix and suffix
+        testInvalidFileTemp("../blah", null);
+        testInvalidFileTemp("dir/blah", null);
+        testInvalidFileTemp("blah", ".dat/foo");
+    }
+}
--- a/jdk/test/java/nio/file/Files/TerminateWalk.java	Thu Jan 13 22:21:58 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.nio.file.*;
-import java.nio.file.attribute.*;
-import java.io.IOException;
-import java.util.*;
-
-/**
- * Unit test for Files.walkFileTree to test TERMINATE return value
- */
-
-public class TerminateWalk {
-
-    static final Random rand = new Random();
-    static boolean terminated;
-
-    static FileVisitResult maybeTerminate() {
-        if (terminated)
-            throw new RuntimeException("FileVisitor invoked after termination");
-        if (rand.nextInt(10) == 0) {
-            terminated = true;
-            return FileVisitResult.TERMINATE;
-        } else {
-            return FileVisitResult.CONTINUE;
-        }
-    }
-
-    public static void main(String[] args) throws Exception {
-        Path dir = Paths.get(args[0]);
-
-        Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
-            @Override
-            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
-                return maybeTerminate();
-            }
-            @Override
-            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
-                return maybeTerminate();
-            }
-            @Override
-            public FileVisitResult postVisitDirectory(Path dir, IOException x) {
-                return maybeTerminate();
-            }
-        });
-    }
-}
--- a/jdk/test/java/nio/file/Files/WalkWithSecurity.java	Thu Jan 13 22:21:58 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,132 +0,0 @@
-/*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/* @test
- * @bug 6876541
- * @summary Test Files.walkFileTree in the presence of a security manager
- * @build WalkWithSecurity
- * @run main/othervm WalkWithSecurity grantAll.policy pass
- * @run main/othervm WalkWithSecurity denyAll.policy fail
- * @run main/othervm WalkWithSecurity grantTopOnly.policy top_only
- */
-
-import java.nio.file.*;
-import java.nio.file.attribute.BasicFileAttributes;
-import java.io.IOException;
-
-public class WalkWithSecurity {
-
-    public static void main(String[] args) throws IOException {
-        String policyFile = args[0];
-        ExpectedResult expectedResult = ExpectedResult.valueOf(args[1].toUpperCase());
-
-        String here = System.getProperty("user.dir");
-        String testSrc = System.getProperty("test.src");
-        if (testSrc == null)
-            throw new RuntimeException("This test must be run by jtreg");
-        Path dir = Paths.get(testSrc);
-
-        // Sanity check the environment
-        if (Paths.get(here).isSameFile(dir))
-            throw new RuntimeException("Working directory cannot be " + dir);
-        DirectoryStream<Path> stream = dir.newDirectoryStream();
-        try {
-            if (!stream.iterator().hasNext())
-                throw new RuntimeException(testSrc + " is empty");
-        } finally {
-            stream.close();
-        }
-
-        // Install security manager with the given policy file
-        System.setProperty("java.security.policy",
-            dir.resolve(policyFile).toString());
-        System.setSecurityManager(new SecurityManager());
-
-        // Walk the source tree
-        CountingVisitor visitor = new CountingVisitor();
-        SecurityException exception = null;
-        try {
-            Files.walkFileTree(dir, visitor);
-        } catch (SecurityException se) {
-            exception = se;
-        }
-
-        // Check result
-        switch (expectedResult) {
-            case PASS:
-                if (exception != null) {
-                    exception.printStackTrace();
-                    throw new RuntimeException("SecurityException not expected");
-                }
-                if (visitor.count() == 0)
-                    throw new RuntimeException("No files visited");
-                break;
-            case FAIL:
-                if (exception == null)
-                    throw new RuntimeException("SecurityException expected");
-                if (visitor.count() > 0)
-                    throw new RuntimeException("Files were visited");
-                break;
-            case TOP_ONLY:
-                if (exception != null) {
-                    exception.printStackTrace();
-                    throw new RuntimeException("SecurityException not expected");
-                }
-                if (visitor.count() == 0)
-                    throw new RuntimeException("Starting file not visited");
-                if (visitor.count() > 1)
-                    throw new RuntimeException("More than starting file visited");
-                break;
-            default:
-                throw new RuntimeException("Should not get here");
-        }
-    }
-
-    static enum ExpectedResult {
-        PASS,
-        FAIL,
-        TOP_ONLY;
-    }
-
-    static class CountingVisitor extends SimpleFileVisitor<Path> {
-        private int count;
-
-        int count() {
-            return count;
-        }
-
-        @Override
-        public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
-            System.out.println(dir);
-            count++;
-            return FileVisitResult.CONTINUE;
-        }
-
-        @Override
-        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
-            System.out.println(file);
-            count++;
-            return FileVisitResult.CONTINUE;
-        }
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/delete_on_close.sh	Fri Jan 28 09:28:43 2011 +0000
@@ -0,0 +1,61 @@
+#
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+# @test
+# @bug 4313887
+# @summary Unit test for DELETE_ON_CLOSE open option
+# @library ..
+# @build DeleteOnClose
+# @run shell delete_on_close.sh
+
+# if TESTJAVA isn't set then we assume an interactive run.
+
+if [ -z "$TESTJAVA" ]; then
+    TESTSRC=.
+    TESTCLASSES=.
+    JAVA=java
+else
+    JAVA="${TESTJAVA}/bin/java"
+fi
+
+OS=`uname -s`
+case "$OS" in
+    Windows_* | CYGWIN* )
+        CLASSPATH="${TESTCLASSES};${TESTSRC}"
+        ;;
+    * )
+        CLASSPATH=${TESTCLASSES}:${TESTSRC}
+        ;;
+esac
+export CLASSPATH
+
+TMPFILE="$$.tmp"
+touch $TMPFILE
+$JAVA DeleteOnClose $TMPFILE 2>&1
+if [ $? != 0 ]; then exit 1; fi
+if [ -f $TMPFILE ]; then
+    echo "$TMPFILE was not deleted"
+    exit 1
+fi
+
+exit 0
--- a/jdk/test/java/nio/file/Files/denyAll.policy	Thu Jan 13 22:21:58 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-// policy file that does not grant any permissions
-grant {
-};
--- a/jdk/test/java/nio/file/Files/grantAll.policy	Thu Jan 13 22:21:58 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-// policy file that grants read access to source directory and all descendants
-grant {
-    permission java.io.FilePermission "${test.src}", "read";
-    permission java.io.FilePermission "${test.src}${file.separator}-", "read";
-};
--- a/jdk/test/java/nio/file/Files/grantTopOnly.policy	Thu Jan 13 22:21:58 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-// policy file that grants read access to source directory
-grant {
-    permission java.io.FilePermission "${test.src}", "read";
-};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/probeContentType/Basic.java	Fri Jan 28 09:28:43 2011 +0000
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 4313887
+ * @summary Unit test for probeContentType method
+ * @library ../..
+ * @build Basic SimpleFileTypeDetector
+ * @run main/othervm Basic
+ */
+
+import java.nio.file.*;
+import java.io.*;
+
+/**
+ * Uses Files.probeContentType to probe html file and custom file type.
+ */
+
+public class Basic {
+
+    static Path createHtmlFile() throws IOException {
+        Path file = Files.createTempFile("foo", ".html");
+        try (OutputStream out = Files.newOutputStream(file)) {
+            out.write("<html><body>foo</body></html>".getBytes());
+        }
+
+        return file;
+    }
+
+    static Path createGrapeFile() throws IOException {
+        return Files.createTempFile("red", ".grape");
+    }
+
+    public static void main(String[] args) throws IOException {
+
+        // exercise default file type detector
+        Path file = createHtmlFile();
+        try {
+            String type = Files.probeContentType(file);
+            if (type == null) {
+                System.err.println("Content type cannot be determined - test skipped");
+            } else {
+                if (!type.equals("text/html"))
+                    throw new RuntimeException("Unexpected type: " + type);
+            }
+        } finally {
+            Files.delete(file);
+        }
+
+        // exercise custom file type detector
+        file = createGrapeFile();
+        try {
+            String type = Files.probeContentType(file);
+            if (type == null)
+                throw new RuntimeException("Custom file type detector not installed?");
+            if (!type.equals("grape/unknown"))
+                throw new RuntimeException("Unexpected type: " + type);
+        } finally {
+            Files.delete(file);
+        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/probeContentType/ForceLoad.java	Fri Jan 28 09:28:43 2011 +0000
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 4313887
+ * @summary Test library dependencies by invoking Files.probeContentType
+ *     before other methods that would cause nio.dll to be loaded.
+ */
+
+import java.nio.file.*;
+import java.io.IOException;
+
+public class ForceLoad {
+
+    public static void main(String[] args) throws IOException {
+        Files.probeContentType(Paths.get("."));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/probeContentType/META-INF/services/java.nio.file.spi.FileTypeDetector	Fri Jan 28 09:28:43 2011 +0000
@@ -0,0 +1,1 @@
+SimpleFileTypeDetector
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/probeContentType/SimpleFileTypeDetector.java	Fri Jan 28 09:28:43 2011 +0000
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.nio.file.*;
+import java.nio.file.spi.FileTypeDetector;
+import java.io.*;
+
+
+public class SimpleFileTypeDetector extends FileTypeDetector {
+    public SimpleFileTypeDetector() {
+    }
+
+    public String probeContentType(Path file) throws IOException {
+        System.out.println("probe " + file + "...");
+        String name = file.toString();
+        return name.endsWith(".grape") ? "grape/unknown" : null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/walkFileTree/CreateFileTree.java	Fri Jan 28 09:28:43 2011 +0000
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.nio.file.*;
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * Creates a file tree with possible cycles caused by symbolic links
+ * to ancestor directories.
+ */
+
+public class CreateFileTree {
+
+    static final Random rand = new Random();
+
+    public static void main(String[] args) throws IOException {
+        Path top = Files.createTempDirectory("tree");
+        List<Path> dirs = new ArrayList<Path>();
+
+        // create tree
+        Queue<Path> queue = new ArrayDeque<Path>();
+        queue.add(top);
+        int total = 1 + rand.nextInt(20);
+        int n = 0;
+        Path dir;
+        while (((dir = queue.poll()) != null) && (n < total)) {
+            int r = Math.min((total-n), (1+rand.nextInt(3)));
+            for (int i=0; i<r; i++) {
+                String name = "dir" + (++n);
+                Path subdir = Files.createDirectory(dir.resolve(name));
+                queue.offer(subdir);
+                dirs.add(subdir);
+            }
+        }
+        assert dirs.size() >= 2;
+
+        // create a few regular files in the file tree
+        int files = dirs.size() * 3;
+        for (int i=0; i<files; i++) {
+            String name = "file" + (i+1);
+            int x = rand.nextInt(dirs.size());
+            Files.createFile(dirs.get(x).resolve(name));
+        }
+
+        // create a few sym links in the file tree so as to create cycles
+        int links = 1 + rand.nextInt(5);
+        for (int i=0; i<links; i++) {
+            int x = rand.nextInt(dirs.size());
+            int y;
+            do {
+                y = rand.nextInt(dirs.size());
+            } while (y != x);
+            String name = "link" + (i+1);
+            Path link = dirs.get(x).resolve(name);
+            Path target = dirs.get(y);
+            Files.createSymbolicLink(link, target);
+        }
+
+        // done
+        System.out.println(top);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/walkFileTree/MaxDepth.java	Fri Jan 28 09:28:43 2011 +0000
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * Unit test for Files.walkFileTree to test maxDepth parameter
+ */
+
+public class MaxDepth {
+    public static void main(String[] args) throws Exception {
+        final Path top = Paths.get(args[0]);
+
+        for (int i=0; i<5; i++) {
+            Set<FileVisitOption> opts = Collections.emptySet();
+            final int maxDepth = i;
+            Files.walkFileTree(top, opts, maxDepth, new SimpleFileVisitor<Path>() {
+                // compute depth based on relative path to top directory
+                private int depth(Path file) {
+                    Path rp = file.relativize(top);
+                    return (rp.getFileName().toString().equals("")) ? 0 : rp.getNameCount();
+                }
+
+                @Override
+                public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
+                    int d = depth(dir);
+                    if (d == maxDepth)
+                        throw new RuntimeException("Should not open directories at maxDepth");
+                    if (d > maxDepth)
+                        throw new RuntimeException("Too deep");
+                    return FileVisitResult.CONTINUE;
+                }
+
+                @Override
+                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
+                    int d = depth(file);
+                    if (d > maxDepth)
+                        throw new RuntimeException("Too deep");
+                    return FileVisitResult.CONTINUE;
+                }
+            });
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/walkFileTree/Nulls.java	Fri Jan 28 09:28:43 2011 +0000
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 4313887 6865748
+ * @summary Unit test for java.nio.file.Files.walkFileTree
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.io.IOException;
+import java.util.*;
+
+public class Nulls {
+
+    static void npeExpected() {
+        throw new RuntimeException("NullPointerException expected");
+    }
+
+    public static void main(String[] args) throws IOException {
+        try {
+            Files.walkFileTree(null, EnumSet.noneOf(FileVisitOption.class),
+                Integer.MAX_VALUE, new SimpleFileVisitor<Path>(){});
+            npeExpected();
+        } catch (NullPointerException e) {
+        }
+        try {
+            Files.walkFileTree(Paths.get("."), null, Integer.MAX_VALUE,
+                new SimpleFileVisitor<Path>(){});
+            npeExpected();
+        } catch (NullPointerException e) {
+        }
+        try {
+            Files.walkFileTree(Paths.get("."), EnumSet.noneOf(FileVisitOption.class),
+                -1, new SimpleFileVisitor<Path>(){});
+            throw new RuntimeException("IllegalArgumentExpected expected");
+        } catch (IllegalArgumentException e) {
+        }
+        try {
+            Set<FileVisitOption> opts = new HashSet<>(1);
+            opts.add(null);
+            Files.walkFileTree(Paths.get("."), opts, Integer.MAX_VALUE,
+                new SimpleFileVisitor<Path>(){});
+            npeExpected();
+        } catch (NullPointerException e) {
+        }
+        try {
+            Files.walkFileTree(Paths.get("."), EnumSet.noneOf(FileVisitOption.class),
+                Integer.MAX_VALUE, null);
+            npeExpected();
+        } catch (NullPointerException e) {
+        }
+
+        SimpleFileVisitor<Path> visitor = new SimpleFileVisitor<Path>() { };
+        boolean ranTheGauntlet = false;
+        Path dir = Paths.get(".");
+        BasicFileAttributes attrs = Files.readAttributes(dir, BasicFileAttributes.class);
+
+        try { visitor.preVisitDirectory(null, attrs);
+        } catch (NullPointerException x0) {
+        try { visitor.preVisitDirectory(dir, null);
+        } catch (NullPointerException x1) {
+        try { visitor.visitFile(null, attrs);
+        } catch (NullPointerException x2) {
+        try {  visitor.visitFile(dir, null);
+        } catch (NullPointerException x3) {
+        try { visitor.visitFileFailed(null, new IOException());
+        } catch (NullPointerException x4) {
+        try { visitor.visitFileFailed(dir, null);
+        } catch (NullPointerException x5) {
+        try { visitor.postVisitDirectory(null, new IOException());
+        } catch (NullPointerException x6) {
+            // if we get here then all visit* methods threw NPE as expected
+            ranTheGauntlet = true;
+        }}}}}}}
+        if (!ranTheGauntlet)
+            throw new RuntimeException("A visit method did not throw NPE");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/walkFileTree/PrintFileTree.java	Fri Jan 28 09:28:43 2011 +0000
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * Invokes Files.walkFileTree to traverse a file tree and prints
+ * each of the directories and files. The -follow option causes symbolic
+ * links to be followed and the -printCycles option will print links
+ * where the target of the link is an ancestor directory.
+ */
+
+public class PrintFileTree {
+
+    public static void main(String[] args) throws Exception {
+        boolean followLinks = false;
+        boolean printCycles = false;
+        int i = 0;
+        while (i < (args.length-1)) {
+            switch (args[i]) {
+                case "-follow"      : followLinks = true; break;
+                case "-printCycles" : printCycles = true;  break;
+                default:
+                    throw new RuntimeException(args[i] + " not recognized");
+            }
+            i++;
+        }
+        Path dir = Paths.get(args[i]);
+
+        Set<FileVisitOption> options = new HashSet<FileVisitOption>();
+        if (followLinks)
+            options.add(FileVisitOption.FOLLOW_LINKS);
+
+        final boolean reportCycles = printCycles;
+        Files.walkFileTree(dir, options, Integer.MAX_VALUE, new FileVisitor<Path>() {
+            @Override
+            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
+                System.out.println(dir);
+                return FileVisitResult.CONTINUE;
+            }
+            @Override
+            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
+                if (!attrs.isDirectory() || reportCycles)
+                    System.out.println(file);
+                return FileVisitResult.CONTINUE;
+            }
+            @Override
+            public FileVisitResult postVisitDirectory(Path dir, IOException exc)
+                throws IOException
+            {
+                if (exc != null)
+                    throw exc;
+                return FileVisitResult.CONTINUE;
+            }
+            @Override
+            public FileVisitResult visitFileFailed(Path file, IOException exc)
+                throws IOException
+            {
+                if (reportCycles && (exc instanceof FileSystemLoopException)) {
+                    System.out.println(file);
+                    return FileVisitResult.CONTINUE;
+                }
+                throw exc;
+            }
+        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/walkFileTree/SkipSiblings.java	Fri Jan 28 09:28:43 2011 +0000
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * Unit test for Files.walkFileTree to test SKIP_SIBLINGS return value.
+ */
+
+public class SkipSiblings {
+
+    static final Random rand = new Random();
+    static final Set<Path> skipped = new HashSet<Path>();
+
+    // check if this path's directory has been skipped
+    static void check(Path path) {
+        if (skipped.contains(path.getParent()))
+            throw new RuntimeException(path + " should not have been visited");
+    }
+
+    // indicates if the siblings of this path should be skipped
+    static boolean skip(Path path) {
+        Path parent = path.getParent();
+        if (parent != null && rand.nextBoolean()) {
+            skipped.add(parent);
+            return true;
+        }
+        return false;
+    }
+
+    public static void main(String[] args) throws Exception {
+        Path dir = Paths.get(args[0]);
+
+        Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
+            @Override
+            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
+                check(dir);
+                if (skip(dir))
+                    return FileVisitResult.SKIP_SIBLINGS;
+                return FileVisitResult.CONTINUE;
+            }
+            @Override
+            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
+                check(file);
+                if (skip(file))
+                    return FileVisitResult.SKIP_SIBLINGS;
+                return FileVisitResult.CONTINUE;
+            }
+            @Override
+            public FileVisitResult postVisitDirectory(Path dir, IOException x) {
+                if (x != null)
+                    throw new RuntimeException(x);
+                check(dir);
+                return FileVisitResult.CONTINUE;
+            }
+        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/walkFileTree/TerminateWalk.java	Fri Jan 28 09:28:43 2011 +0000
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * Unit test for Files.walkFileTree to test TERMINATE return value
+ */
+
+public class TerminateWalk {
+
+    static final Random rand = new Random();
+    static boolean terminated;
+
+    static FileVisitResult maybeTerminate() {
+        if (terminated)
+            throw new RuntimeException("FileVisitor invoked after termination");
+        if (rand.nextInt(10) == 0) {
+            terminated = true;
+            return FileVisitResult.TERMINATE;
+        } else {
+            return FileVisitResult.CONTINUE;
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        Path dir = Paths.get(args[0]);
+
+        Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
+            @Override
+            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
+                return maybeTerminate();
+            }
+            @Override
+            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
+                return maybeTerminate();
+            }
+            @Override
+            public FileVisitResult postVisitDirectory(Path dir, IOException x) {
+                return maybeTerminate();
+            }
+        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/walkFileTree/WalkWithSecurity.java	Fri Jan 28 09:28:43 2011 +0000
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 6876541
+ * @summary Test Files.walkFileTree in the presence of a security manager
+ * @build WalkWithSecurity
+ * @run main/othervm WalkWithSecurity grantAll.policy pass
+ * @run main/othervm WalkWithSecurity denyAll.policy fail
+ * @run main/othervm WalkWithSecurity grantTopOnly.policy top_only
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.io.IOException;
+
+public class WalkWithSecurity {
+
+    public static void main(String[] args) throws IOException {
+        String policyFile = args[0];
+        ExpectedResult expectedResult = ExpectedResult.valueOf(args[1].toUpperCase());
+
+        String here = System.getProperty("user.dir");
+        String testSrc = System.getProperty("test.src");
+        if (testSrc == null)
+            throw new RuntimeException("This test must be run by jtreg");
+        Path dir = Paths.get(testSrc);
+
+        // Sanity check the environment
+        if (Files.isSameFile(Paths.get(here), dir))
+            throw new RuntimeException("Working directory cannot be " + dir);
+        try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
+            if (!stream.iterator().hasNext())
+                throw new RuntimeException(testSrc + " is empty");
+        }
+
+        // Install security manager with the given policy file
+        System.setProperty("java.security.policy",
+            dir.resolve(policyFile).toString());
+        System.setSecurityManager(new SecurityManager());
+
+        // Walk the source tree
+        CountingVisitor visitor = new CountingVisitor();
+        SecurityException exception = null;
+        try {
+            Files.walkFileTree(dir, visitor);
+        } catch (SecurityException se) {
+            exception = se;
+        }
+
+        // Check result
+        switch (expectedResult) {
+            case PASS:
+                if (exception != null) {
+                    exception.printStackTrace();
+                    throw new RuntimeException("SecurityException not expected");
+                }
+                if (visitor.count() == 0)
+                    throw new RuntimeException("No files visited");
+                break;
+            case FAIL:
+                if (exception == null)
+                    throw new RuntimeException("SecurityException expected");
+                if (visitor.count() > 0)
+                    throw new RuntimeException("Files were visited");
+                break;
+            case TOP_ONLY:
+                if (exception != null) {
+                    exception.printStackTrace();
+                    throw new RuntimeException("SecurityException not expected");
+                }
+                if (visitor.count() == 0)
+                    throw new RuntimeException("Starting file not visited");
+                if (visitor.count() > 1)
+                    throw new RuntimeException("More than starting file visited");
+                break;
+            default:
+                throw new RuntimeException("Should not get here");
+        }
+    }
+
+    static enum ExpectedResult {
+        PASS,
+        FAIL,
+        TOP_ONLY;
+    }
+
+    static class CountingVisitor extends SimpleFileVisitor<Path> {
+        private int count;
+
+        int count() {
+            return count;
+        }
+
+        @Override
+        public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
+            System.out.println(dir);
+            count++;
+            return FileVisitResult.CONTINUE;
+        }
+
+        @Override
+        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
+            System.out.println(file);
+            count++;
+            return FileVisitResult.CONTINUE;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/walkFileTree/denyAll.policy	Fri Jan 28 09:28:43 2011 +0000
@@ -0,0 +1,3 @@
+// policy file that does not grant any permissions
+grant {
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/walkFileTree/grantAll.policy	Fri Jan 28 09:28:43 2011 +0000
@@ -0,0 +1,5 @@
+// policy file that grants read access to source directory and all descendants
+grant {
+    permission java.io.FilePermission "${test.src}", "read";
+    permission java.io.FilePermission "${test.src}${file.separator}-", "read";
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/walkFileTree/grantTopOnly.policy	Fri Jan 28 09:28:43 2011 +0000
@@ -0,0 +1,4 @@
+// policy file that grants read access to source directory
+grant {
+    permission java.io.FilePermission "${test.src}", "read";
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/walkFileTree/walk_file_tree.sh	Fri Jan 28 09:28:43 2011 +0000
@@ -0,0 +1,98 @@
+#
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+# @test
+# @bug 4313887 6907737
+# @summary Unit test for walkFileTree method
+# @build CreateFileTree PrintFileTree SkipSiblings TerminateWalk MaxDepth
+# @run shell walk_file_tree.sh
+
+# if TESTJAVA isn't set then we assume an interactive run.
+
+if [ -z "$TESTJAVA" ]; then
+    TESTSRC=.
+    TESTCLASSES=.
+    JAVA=java
+else
+    JAVA="${TESTJAVA}/bin/java"
+fi
+
+OS=`uname -s`
+case "$OS" in
+    Windows_* | CYGWIN* )
+        echo "This test does not run on Windows" 
+        exit 0
+        ;;
+    * )
+        CLASSPATH=${TESTCLASSES}:${TESTSRC}
+        ;;
+esac
+export CLASSPATH
+
+# create the file tree
+ROOT=`$JAVA CreateFileTree`
+if [ $? != 0 ]; then exit 1; fi
+
+failures=0
+
+# print the file tree and compare output with find(1)
+$JAVA PrintFileTree "$ROOT" > out1
+find "$ROOT" > out2
+diff out1 out2
+if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
+
+# repeat test following links. Some versions of find(1) output
+# cycles (sym links to ancestor directories), other versions do
+# not. For that reason we run PrintFileTree with the -printCycles
+# option when the output without this option differs to find(1).
+find "$ROOT" -follow > out1
+$JAVA PrintFileTree -follow "$ROOT" > out2
+diff out1 out2
+if [ $? != 0 ];
+  then 
+    # re-run printing cycles to stdout
+    $JAVA PrintFileTree -follow -printCycles "$ROOT" > out2
+    diff out1 out2
+    if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
+  fi
+
+# test SKIP_SIBLINGS
+$JAVA SkipSiblings "$ROOT"
+if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
+
+# test TERMINATE
+$JAVA TerminateWalk "$ROOT"
+if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
+
+# test maxDepth
+$JAVA MaxDepth "$ROOT"
+if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
+
+# clean-up
+rm -r "$ROOT"
+
+echo ''
+if [ $failures -gt 0 ];
+  then echo "$failures test(s) failed";
+  else echo "Test passed"; fi
+exit $failures
--- a/jdk/test/java/nio/file/Files/walk_file_tree.sh	Thu Jan 13 22:21:58 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-#
-# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-# @test
-# @bug 4313887 6907737
-# @summary Unit test for walkFileTree method
-# @build CreateFileTree PrintFileTree SkipSiblings TerminateWalk MaxDepth
-# @run shell walk_file_tree.sh
-
-# if TESTJAVA isn't set then we assume an interactive run.
-
-if [ -z "$TESTJAVA" ]; then
-    TESTSRC=.
-    TESTCLASSES=.
-    JAVA=java
-else
-    JAVA="${TESTJAVA}/bin/java"
-fi
-
-OS=`uname -s`
-case "$OS" in
-    Windows_* | CYGWIN* )
-        echo "This test does not run on Windows" 
-        exit 0
-        ;;
-    * )
-        CLASSPATH=${TESTCLASSES}:${TESTSRC}
-        ;;
-esac
-export CLASSPATH
-
-# create the file tree
-ROOT=`$JAVA CreateFileTree`
-if [ $? != 0 ]; then exit 1; fi
-
-failures=0
-
-# print the file tree and compare output with find(1)
-$JAVA PrintFileTree "$ROOT" > out1
-find "$ROOT" > out2
-diff out1 out2
-if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
-
-# repeat test following links. Some versions of find(1) output
-# cycles (sym links to ancestor directories), other versions do
-# not. For that reason we run PrintFileTree with the -printCycles
-# option when the output without this option differs to find(1).
-find "$ROOT" -follow > out1
-$JAVA PrintFileTree -follow "$ROOT" > out2
-diff out1 out2
-if [ $? != 0 ];
-  then 
-    # re-run printing cycles to stdout
-    $JAVA PrintFileTree -follow -printCycles "$ROOT" > out2
-    diff out1 out2
-    if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
-  fi
-
-# test SKIP_SIBLINGS
-$JAVA SkipSiblings "$ROOT"
-if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
-
-# test TERMINATE
-$JAVA TerminateWalk "$ROOT"
-if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
-
-# test maxDepth
-$JAVA MaxDepth "$ROOT"
-if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
-
-# clean-up
-rm -r "$ROOT"
-
-echo ''
-if [ $failures -gt 0 ];
-  then echo "$failures test(s) failed";
-  else echo "Test passed"; fi
-exit $failures
--- a/jdk/test/java/nio/file/Path/CheckPermissions.java	Thu Jan 13 22:21:58 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,697 +0,0 @@
-/*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/* @test
- * @bug 6866804
- * @summary Unit test for java.nio.file.Path
- * @library ..
- * @build CheckPermissions
- * @run main/othervm CheckPermissions
- */
-
-import java.nio.ByteBuffer;
-import java.nio.file.*;
-import java.nio.file.attribute.*;
-import java.nio.channels.SeekableByteChannel;
-import java.security.Permission;
-import java.io.*;
-import java.util.*;
-
-/**
- * Checks each method that accesses the file system does the right permission
- * check when there is a security manager set.
- */
-
-public class CheckPermissions {
-
-    static class Checks {
-        private List<Permission> permissionsChecked = new ArrayList<Permission>();
-        private Set<String>  propertiesChecked = new HashSet<String>();
-        private List<String> readsChecked   = new ArrayList<String>();
-        private List<String> writesChecked  = new ArrayList<String>();
-        private List<String> deletesChecked = new ArrayList<String>();
-        private List<String> execsChecked   = new ArrayList<String>();
-
-        List<Permission> permissionsChecked()  { return permissionsChecked; }
-        Set<String> propertiesChecked()        { return propertiesChecked; }
-        List<String> readsChecked()            { return readsChecked; }
-        List<String> writesChecked()           { return writesChecked; }
-        List<String> deletesChecked()          { return deletesChecked; }
-        List<String> execsChecked()            { return execsChecked; }
-    }
-
-    static ThreadLocal<Checks> myChecks =
-        new ThreadLocal<Checks>() {
-            @Override protected Checks initialValue() {
-                return null;
-            }
-        };
-
-    static void prepare() {
-        myChecks.set(new Checks());
-    }
-
-    static void assertCheckPermission(Class<? extends Permission> type,
-                                      String name)
-    {
-        for (Permission perm: myChecks.get().permissionsChecked()) {
-            if (type.isInstance(perm) && perm.getName().equals(name))
-                return;
-        }
-        throw new RuntimeException(type.getName() + "\"" + name + "\") not checked");
-    }
-
-    static void assertCheckPropertyAccess(String key) {
-        if (!myChecks.get().propertiesChecked().contains(key))
-            throw new RuntimeException("Property " + key + " not checked");
-    }
-
-    static void assertChecked(Path file, List<String> list) {
-        String s = file.toString();
-        for (String f: list) {
-            if (f.endsWith(s))
-                return;
-        }
-        throw new RuntimeException("Access not checked");
-    }
-
-    static void assertCheckRead(Path file) {
-        assertChecked(file, myChecks.get().readsChecked());
-    }
-
-    static void assertCheckWrite(Path file) {
-        assertChecked(file, myChecks.get().writesChecked());
-    }
-
-    static void assertCheckDelete(Path file) {
-        assertChecked(file, myChecks.get().deletesChecked());
-    }
-
-    static void assertCheckExec(Path file) {
-        assertChecked(file, myChecks.get().execsChecked());
-    }
-
-    static class LoggingSecurityManager extends SecurityManager {
-        static void install() {
-            System.setSecurityManager(new LoggingSecurityManager());
-        }
-
-        @Override
-        public void checkPermission(Permission perm) {
-            Checks checks = myChecks.get();
-            if (checks != null)
-                checks.permissionsChecked().add(perm);
-        }
-
-        @Override
-        public void checkPropertyAccess(String key) {
-            Checks checks = myChecks.get();
-            if (checks != null)
-                checks.propertiesChecked().add(key);
-        }
-
-        @Override
-        public void checkRead(String file) {
-            Checks checks = myChecks.get();
-            if (checks != null)
-                checks.readsChecked().add(file);
-        }
-
-        @Override
-        public void checkWrite(String file) {
-            Checks checks = myChecks.get();
-            if (checks != null)
-                checks.writesChecked().add(file);
-        }
-
-        @Override
-        public void checkDelete(String file) {
-            Checks checks = myChecks.get();
-            if (checks != null)
-                checks.deletesChecked().add(file);
-        }
-
-        @Override
-        public void checkExec(String file) {
-            Checks checks = myChecks.get();
-            if (checks != null)
-                checks.execsChecked().add(file);
-        }
-    }
-
-    static void testBasicFileAttributeView(BasicFileAttributeView view, Path file)
-        throws IOException
-    {
-        prepare();
-        view.readAttributes();
-        assertCheckRead(file);
-
-        prepare();
-        FileTime now = FileTime.fromMillis(System.currentTimeMillis());
-        view.setTimes(null, now, now);
-        assertCheckWrite(file);
-    }
-
-    static void testPosixFileAttributeView(PosixFileAttributeView view, Path file)
-        throws IOException
-    {
-        prepare();
-        PosixFileAttributes attrs = view.readAttributes();
-        assertCheckRead(file);
-        assertCheckPermission(RuntimePermission.class, "accessUserInformation");
-
-        prepare();
-        view.setPermissions(attrs.permissions());
-        assertCheckWrite(file);
-        assertCheckPermission(RuntimePermission.class, "accessUserInformation");
-
-        prepare();
-        view.setOwner(attrs.owner());
-        assertCheckWrite(file);
-        assertCheckPermission(RuntimePermission.class, "accessUserInformation");
-
-        prepare();
-        view.setOwner(attrs.owner());
-        assertCheckWrite(file);
-        assertCheckPermission(RuntimePermission.class, "accessUserInformation");
-    }
-
-    public static void main(String[] args) throws IOException {
-        Path dir = Paths.get(System.getProperty("test.dir", "."));
-        Path file = dir.resolve("file1234").createFile();
-        try {
-            LoggingSecurityManager.install();
-
-            // -- checkAccess --
-
-            prepare();
-            file.checkAccess();
-            assertCheckRead(file);
-
-            prepare();
-            file.checkAccess(AccessMode.READ);
-            assertCheckRead(file);
-
-            prepare();
-            file.checkAccess(AccessMode.WRITE);
-            assertCheckWrite(file);
-
-            prepare();
-            try {
-                file.checkAccess(AccessMode.EXECUTE);
-            } catch (AccessDeniedException x) { }
-            assertCheckExec(file);
-
-            prepare();
-            try {
-                file.checkAccess(AccessMode.READ, AccessMode.WRITE, AccessMode.EXECUTE);
-            } catch (AccessDeniedException x) { }
-            assertCheckRead(file);
-            assertCheckWrite(file);
-            assertCheckExec(file);
-
-            // -- copyTo --
-
-            Path target = dir.resolve("target1234");
-            prepare();
-            file.copyTo(target);
-            try {
-                assertCheckRead(file);
-                assertCheckWrite(target);
-            } finally {
-                target.delete();
-            }
-
-            if (TestUtil.supportsLinks(dir)) {
-                Path link = dir.resolve("link1234").createSymbolicLink(file);
-                try {
-                    prepare();
-                    link.copyTo(target, LinkOption.NOFOLLOW_LINKS);
-                    try {
-                        assertCheckRead(link);
-                        assertCheckWrite(target);
-                        assertCheckPermission(LinkPermission.class, "symbolic");
-                    } finally {
-                        target.delete();
-                    }
-                } finally {
-                    link.delete();
-                }
-            }
-
-            // -- createDirectory --
-
-            Path subdir = dir.resolve("subdir1234");
-            prepare();
-            subdir.createDirectory();
-            try {
-                assertCheckWrite(subdir);
-            } finally {
-                subdir.delete();
-            }
-
-            // -- createFile --
-
-            Path fileToCreate = dir.resolve("file7890");
-            prepare();
-            try {
-                fileToCreate.createFile();
-                assertCheckWrite(fileToCreate);
-            } finally {
-                fileToCreate.delete();
-            }
-
-            // -- createSymbolicLink --
-
-            if (TestUtil.supportsLinks(dir)) {
-                prepare();
-                Path link = dir.resolve("link1234").createSymbolicLink(file);
-                try {
-                    assertCheckWrite(link);
-                    assertCheckPermission(LinkPermission.class, "symbolic");
-                } finally {
-                    link.delete();
-                }
-            }
-
-            // -- delete/deleteIfExists --
-
-            Path fileToDelete = dir.resolve("file7890");
-
-            fileToDelete.createFile();
-            prepare();
-            fileToDelete.delete();
-            assertCheckDelete(fileToDelete);
-
-            fileToDelete.createFile();
-            prepare();
-            fileToDelete.deleteIfExists();
-            assertCheckDelete(fileToDelete);
-
-            // -- exists/notExists --
-
-            prepare();
-            file.exists();
-            assertCheckRead(file);
-
-            prepare();
-            file.notExists();
-            assertCheckRead(file);
-
-            // -- getFileStore --
-
-            prepare();
-            file.getFileStore();
-            assertCheckRead(file);
-            assertCheckPermission(RuntimePermission.class, "getFileStoreAttributes");
-
-            // -- isSameFile --
-
-            prepare();
-            file.isSameFile(dir);
-            assertCheckRead(file);
-            assertCheckRead(dir);
-
-            // -- moveTo --
-
-            Path target2 = dir.resolve("target1234");
-            prepare();
-            file.moveTo(target2);
-            try {
-                assertCheckWrite(file);
-                assertCheckWrite(target2);
-            } finally {
-                // restore file
-                target2.moveTo(file);
-            }
-
-            // -- newByteChannel --
-
-            SeekableByteChannel sbc;
-
-            prepare();
-            sbc = file.newByteChannel();
-            try {
-                assertCheckRead(file);
-            } finally {
-                sbc.close();
-            }
-            prepare();
-            sbc = file.newByteChannel(StandardOpenOption.WRITE);
-            try {
-                assertCheckWrite(file);
-            } finally {
-                sbc.close();
-            }
-            prepare();
-            sbc = file.newByteChannel(StandardOpenOption.READ, StandardOpenOption.WRITE);
-            try {
-                assertCheckRead(file);
-                assertCheckWrite(file);
-            } finally {
-                sbc.close();
-            }
-
-            prepare();
-            sbc = file.newByteChannel(StandardOpenOption.DELETE_ON_CLOSE);
-            try {
-                assertCheckRead(file);
-                assertCheckDelete(file);
-            } finally {
-                sbc.close();
-            }
-            file.createFile(); // restore file
-
-
-            // -- newInputStream/newOutptuStream --
-
-            prepare();
-            InputStream in = file.newInputStream();
-            try {
-                assertCheckRead(file);
-            } finally {
-                in.close();
-            }
-            prepare();
-            OutputStream out = file.newOutputStream();
-            try {
-                assertCheckWrite(file);
-            } finally {
-                out.close();
-            }
-
-            // -- newDirectoryStream --
-
-            prepare();
-            DirectoryStream<Path> stream = dir.newDirectoryStream();
-            try {
-                assertCheckRead(dir);
-
-                if (stream instanceof SecureDirectoryStream<?>) {
-                    Path entry;
-                    SecureDirectoryStream<Path> sds =
-                        (SecureDirectoryStream<Path>)stream;
-
-                    // newByteChannel
-                    entry = file.getName();
-                    prepare();
-                    sbc = sds.newByteChannel(entry, EnumSet.of(StandardOpenOption.READ));
-                    try {
-                        assertCheckRead(file);
-                    } finally {
-                        sbc.close();
-                    }
-                    prepare();
-                    sbc = sds.newByteChannel(entry, EnumSet.of(StandardOpenOption.WRITE));
-                    try {
-                        assertCheckWrite(file);
-                    } finally {
-                        sbc.close();
-                    }
-
-                    // deleteFile
-                    entry = file.getName();
-                    prepare();
-                    sds.deleteFile(entry);
-                    assertCheckDelete(file);
-                    dir.resolve(entry).createFile();  // restore file
-
-                    // deleteDirectory
-                    entry = Paths.get("subdir1234");
-                    dir.resolve(entry).createDirectory();
-                    prepare();
-                    sds.deleteDirectory(entry);
-                    assertCheckDelete(dir.resolve(entry));
-
-                    // move
-                    entry = Paths.get("tempname1234");
-                    prepare();
-                    sds.move(file.getName(), sds, entry);
-                    assertCheckWrite(file);
-                    assertCheckWrite(dir.resolve(entry));
-                    sds.move(entry, sds, file.getName());  // restore file
-
-                    // newDirectoryStream
-                    entry = Paths.get("subdir1234");
-                    dir.resolve(entry).createDirectory();
-                    try {
-                        prepare();
-                        sds.newDirectoryStream(entry).close();
-                        assertCheckRead(dir.resolve(entry));
-                    } finally {
-                        dir.resolve(entry).delete();
-                    }
-
-                    // getFileAttributeView to access attributes of directory
-                    testBasicFileAttributeView(sds
-                        .getFileAttributeView(BasicFileAttributeView.class), dir);
-                    testPosixFileAttributeView(sds
-                        .getFileAttributeView(PosixFileAttributeView.class), dir);
-
-                    // getFileAttributeView to access attributes of entry
-                    entry = file.getName();
-                    testBasicFileAttributeView(sds
-                        .getFileAttributeView(entry, BasicFileAttributeView.class), file);
-                    testPosixFileAttributeView(sds
-                        .getFileAttributeView(entry, PosixFileAttributeView.class), file);
-
-                } else {
-                    System.out.println("SecureDirectoryStream not tested");
-                }
-
-            } finally {
-                stream.close();
-            }
-
-            // -- toAbsolutePath --
-
-            prepare();
-            file.getName().toAbsolutePath();
-            assertCheckPropertyAccess("user.dir");
-
-            // -- toRealPath --
-
-            prepare();
-            file.toRealPath(true);
-            assertCheckRead(file);
-
-            prepare();
-            file.toRealPath(false);
-            assertCheckRead(file);
-
-            prepare();
-            Paths.get(".").toRealPath(true);
-            assertCheckPropertyAccess("user.dir");
-
-            prepare();
-            Paths.get(".").toRealPath(false);
-            assertCheckPropertyAccess("user.dir");
-
-            // -- register --
-
-            WatchService watcher = FileSystems.getDefault().newWatchService();
-            try {
-                prepare();
-                dir.register(watcher, StandardWatchEventKind.ENTRY_DELETE);
-                assertCheckRead(dir);
-            } finally {
-                watcher.close();
-            }
-
-            // -- getAttribute/setAttribute/readAttributes --
-
-            prepare();
-            file.getAttribute("size");
-            assertCheckRead(file);
-
-            prepare();
-            file.setAttribute("lastModifiedTime",
-                FileTime.fromMillis(System.currentTimeMillis()));
-            assertCheckWrite(file);
-
-            prepare();
-            file.readAttributes("*");
-            assertCheckRead(file);
-
-            // -- BasicFileAttributeView --
-            testBasicFileAttributeView(file
-                .getFileAttributeView(BasicFileAttributeView.class), file);
-
-            // -- PosixFileAttributeView --
-
-            {
-                PosixFileAttributeView view =
-                    file.getFileAttributeView(PosixFileAttributeView.class);
-                if (view != null &&
-                    file.getFileStore().supportsFileAttributeView(PosixFileAttributeView.class))
-                {
-                    testPosixFileAttributeView(view, file);
-                } else {
-                    System.out.println("PosixFileAttributeView not tested");
-                }
-            }
-
-            // -- DosFileAttributeView --
-
-            {
-                DosFileAttributeView view =
-                    file.getFileAttributeView(DosFileAttributeView.class);
-                if (view != null &&
-                    file.getFileStore().supportsFileAttributeView(DosFileAttributeView.class))
-                {
-                    prepare();
-                    view.readAttributes();
-                    assertCheckRead(file);
-
-                    prepare();
-                    view.setArchive(false);
-                    assertCheckWrite(file);
-
-                    prepare();
-                    view.setHidden(false);
-                    assertCheckWrite(file);
-
-                    prepare();
-                    view.setReadOnly(false);
-                    assertCheckWrite(file);
-
-                    prepare();
-                    view.setSystem(false);
-                    assertCheckWrite(file);
-                } else {
-                    System.out.println("DosFileAttributeView not tested");
-                }
-            }
-
-            // -- FileOwnerAttributeView --
-
-            {
-                FileOwnerAttributeView view =
-                    file.getFileAttributeView(FileOwnerAttributeView.class);
-                if (view != null &&
-                    file.getFileStore().supportsFileAttributeView(FileOwnerAttributeView.class))
-                {
-                    prepare();
-                    UserPrincipal owner = view.getOwner();
-                    assertCheckRead(file);
-                    assertCheckPermission(RuntimePermission.class, "accessUserInformation");
-
-                    prepare();
-                    view.setOwner(owner);
-                    assertCheckWrite(file);
-                    assertCheckPermission(RuntimePermission.class, "accessUserInformation");
-
-                } else {
-                    System.out.println("FileOwnerAttributeView not tested");
-                }
-            }
-
-            // -- UserDefinedFileAttributeView --
-
-            {
-                UserDefinedFileAttributeView view =
-                    file.getFileAttributeView(UserDefinedFileAttributeView.class);
-                if (view != null &&
-                    file.getFileStore().supportsFileAttributeView(UserDefinedFileAttributeView.class))
-                {
-                    prepare();
-                    view.write("test", ByteBuffer.wrap(new byte[100]));
-                    assertCheckWrite(file);
-                    assertCheckPermission(RuntimePermission.class,
-                                               "accessUserDefinedAttributes");
-
-                    prepare();
-                    view.read("test", ByteBuffer.allocate(100));
-                    assertCheckRead(file);
-                    assertCheckPermission(RuntimePermission.class,
-                                               "accessUserDefinedAttributes");
-
-                    prepare();
-                    view.size("test");
-                    assertCheckRead(file);
-                    assertCheckPermission(RuntimePermission.class,
-                                               "accessUserDefinedAttributes");
-
-                    prepare();
-                    view.list();
-                    assertCheckRead(file);
-                    assertCheckPermission(RuntimePermission.class,
-                                               "accessUserDefinedAttributes");
-
-                    prepare();
-                    view.delete("test");
-                    assertCheckWrite(file);
-                    assertCheckPermission(RuntimePermission.class,
-                                               "accessUserDefinedAttributes");
-                } else {
-                    System.out.println("UserDefinedFileAttributeView not tested");
-                }
-            }
-
-            // -- AclFileAttributeView --
-            {
-                AclFileAttributeView view =
-                    file.getFileAttributeView(AclFileAttributeView.class);
-                if (view != null &&
-                    file.getFileStore().supportsFileAttributeView(AclFileAttributeView.class))
-                {
-                    prepare();
-                    List<AclEntry> acl = view.getAcl();
-                    assertCheckRead(file);
-                    assertCheckPermission(RuntimePermission.class, "accessUserInformation");
-                    prepare();
-                    view.setAcl(acl);
-                    assertCheckWrite(file);
-                    assertCheckPermission(RuntimePermission.class, "accessUserInformation");
-                } else {
-                    System.out.println("AclFileAttributeView not tested");
-                }
-            }
-
-            // -- UserPrincipalLookupService
-
-            UserPrincipalLookupService lookupService =
-                FileSystems.getDefault().getUserPrincipalLookupService();
-            UserPrincipal owner = Attributes.getOwner(file);
-
-            prepare();
-            lookupService.lookupPrincipalByName(owner.getName());
-            assertCheckPermission(RuntimePermission.class,
-                                       "lookupUserInformation");
-
-            try {
-                UserPrincipal group = Attributes.readPosixFileAttributes(file).group();
-                prepare();
-                lookupService.lookupPrincipalByGroupName(group.getName());
-                assertCheckPermission(RuntimePermission.class,
-                                           "lookupUserInformation");
-            } catch (UnsupportedOperationException ignore) {
-                System.out.println("lookupPrincipalByGroupName not tested");
-            }
-
-
-        } finally {
-            file.deleteIfExists();
-        }
-    }
-}
--- a/jdk/test/java/nio/file/Path/CopyAndMove.java	Thu Jan 13 22:21:58 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1006 +0,0 @@
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/* @test
- * @bug 4313887 6838333 6917021
- * @summary Unit test for java.nio.file.Path copyTo/moveTo methods
- * @library ..
- * @build CopyAndMove PassThroughFileSystem
- * @run main/othervm CopyAndMove
- */
-
-import java.nio.ByteBuffer;
-import java.nio.file.*;
-import static java.nio.file.StandardCopyOption.*;
-import static java.nio.file.LinkOption.*;
-import java.nio.file.attribute.*;
-import java.io.*;
-import java.util.*;
-
-public class CopyAndMove {
-    static final Random rand = new Random();
-    static boolean heads() { return rand.nextBoolean(); }
-
-    public static void main(String[] args) throws Exception {
-        Path dir1 = TestUtil.createTemporaryDirectory();
-        try {
-            // Same directory
-            doCopyTests(dir1, dir1, TestUtil.supportsLinks(dir1));
-            doMoveTests(dir1, dir1, TestUtil.supportsLinks(dir1));
-
-            // Different directories. Use test.dir if possible as it might be
-            // a different volume/file system and so improve test coverage.
-            String testDir = System.getProperty("test.dir", ".");
-            Path dir2 = TestUtil.createTemporaryDirectory(testDir);
-            try {
-                boolean testSymbolicLinks =
-                    TestUtil.supportsLinks(dir1) && TestUtil.supportsLinks(dir2);
-                doCopyTests(dir1, dir2, testSymbolicLinks);
-                doMoveTests(dir1, dir2, testSymbolicLinks);
-            } finally {
-                TestUtil.removeAll(dir2);
-            }
-
-            // Target is location associated with custom provider
-            Path dir3 = PassThroughFileSystem.create().getPath(dir1.toString());
-            doCopyTests(dir1, dir3, false);
-            doMoveTests(dir1, dir3, false);
-
-        } finally {
-            TestUtil.removeAll(dir1);
-        }
-    }
-
-    static void checkBasicAttributes(BasicFileAttributes attrs1,
-                                     BasicFileAttributes attrs2)
-    {
-        // check file type
-        assertTrue(attrs1.isRegularFile() == attrs2.isRegularFile());
-        assertTrue(attrs1.isDirectory() == attrs2.isDirectory());
-        assertTrue(attrs1.isSymbolicLink() == attrs2.isSymbolicLink());
-        assertTrue(attrs1.isOther() == attrs2.isOther());
-
-        // check last modified time
-        long time1 = attrs1.lastModifiedTime().toMillis();
-        long time2 = attrs2.lastModifiedTime().toMillis();
-        assertTrue(time1 == time2);
-
-        // check size
-        if (attrs1.isRegularFile())
-            assertTrue(attrs1.size() == attrs2.size());
-    }
-
-    static void checkPosixAttributes(PosixFileAttributes attrs1,
-                                     PosixFileAttributes attrs2)
-    {
-        assertTrue(attrs1.permissions().equals(attrs2.permissions()));
-        assertTrue(attrs1.owner().equals(attrs2.owner()));
-        assertTrue(attrs1.group().equals(attrs2.group()));
-    }
-
-    static void checkDosAttributes(DosFileAttributes attrs1,
-                                   DosFileAttributes attrs2)
-    {
-        assertTrue(attrs1.isReadOnly() == attrs2.isReadOnly());
-        assertTrue(attrs1.isHidden() == attrs2.isHidden());
-        assertTrue(attrs1.isSystem() == attrs2.isSystem());
-    }
-
-    static void checkUserDefinedFileAttributes(Map<String,ByteBuffer> attrs1,
-                                     Map<String,ByteBuffer> attrs2)
-    {
-        assert attrs1.size() == attrs2.size();
-        for (String name: attrs1.keySet()) {
-            ByteBuffer bb1 = attrs1.get(name);
-            ByteBuffer bb2 = attrs2.get(name);
-            assertTrue(bb2 != null);
-            assertTrue(bb1.equals(bb2));
-        }
-    }
-
-    static Map<String,ByteBuffer> readUserDefinedFileAttributes(Path file)
-        throws IOException
-    {
-        UserDefinedFileAttributeView view = file
-            .getFileAttributeView(UserDefinedFileAttributeView.class);
-        Map<String,ByteBuffer> result = new HashMap<String,ByteBuffer>();
-        for (String name: view.list()) {
-            int size = view.size(name);
-            ByteBuffer bb = ByteBuffer.allocate(size);
-            int n = view.read(name, bb);
-            assertTrue(n == size);
-            bb.flip();
-            result.put(name, bb);
-        }
-        return result;
-    }
-
-    // move source to target with verification
-    static void moveAndVerify(Path source, Path target, CopyOption... options)
-        throws IOException
-    {
-        // read attributes before file is moved
-        BasicFileAttributes basicAttributes = null;
-        PosixFileAttributes posixAttributes = null;
-        DosFileAttributes dosAttributes = null;
-        Map<String,ByteBuffer> namedAttributes = null;
-
-        // get file attributes of source file
-        String os = System.getProperty("os.name");
-        if (os.equals("SunOS") || os.equals("Linux")) {
-            posixAttributes = Attributes.readPosixFileAttributes(source, NOFOLLOW_LINKS);
-            basicAttributes = posixAttributes;
-        }
-        if (os.startsWith("Windows")) {
-            dosAttributes = Attributes.readDosFileAttributes(source, NOFOLLOW_LINKS);
-            basicAttributes = dosAttributes;
-        }
-        if (basicAttributes == null)
-            basicAttributes = Attributes.readBasicFileAttributes(source, NOFOLLOW_LINKS);
-
-        // hash file contents if regular file
-        int hash = (basicAttributes.isRegularFile()) ? computeHash(source) : 0;
-
-        // record link target if symbolic link
-        Path linkTarget = null;
-        if (basicAttributes.isSymbolicLink())
-            linkTarget = source.readSymbolicLink();
-
-        // read named attributes if available (and file is not a sym link)
-        if (!basicAttributes.isSymbolicLink() &&
-            source.getFileStore().supportsFileAttributeView("xattr"))
-        {
-            namedAttributes = readUserDefinedFileAttributes(source);
-        }
-
-        // move file
-        source.moveTo(target, options);
-
-        // verify source does not exist
-        assertTrue(source.notExists());
-
-        // verify file contents
-        if (basicAttributes.isRegularFile()) {
-            if (computeHash(target) != hash)
-                throw new RuntimeException("Failed to verify move of regular file");
-        }
-
-        // verify link target
-        if (basicAttributes.isSymbolicLink()) {
-            if (!target.readSymbolicLink().equals(linkTarget))
-                throw new RuntimeException("Failed to verify move of symbolic link");
-        }
-
-        // verify basic attributes
-        checkBasicAttributes(basicAttributes,
-            Attributes.readBasicFileAttributes(target, NOFOLLOW_LINKS));
-
-        // verify other attributes when same provider
-        if (source.getFileSystem().provider() == target.getFileSystem().provider()) {
-
-            // verify POSIX attributes
-            if (posixAttributes != null && !basicAttributes.isSymbolicLink()) {
-                checkPosixAttributes(posixAttributes,
-                    Attributes.readPosixFileAttributes(target, NOFOLLOW_LINKS));
-            }
-
-            // verify DOS attributes
-            if (dosAttributes != null && !basicAttributes.isSymbolicLink()) {
-                checkDosAttributes(dosAttributes,
-                    Attributes.readDosFileAttributes(target, NOFOLLOW_LINKS));
-            }
-
-            // verify named attributes
-            if (namedAttributes != null &&
-                target.getFileStore().supportsFileAttributeView("xattr"))
-            {
-                checkUserDefinedFileAttributes(namedAttributes,
-                                               readUserDefinedFileAttributes(target));
-            }
-        }
-    }
-
-    /**
-     * Tests all possible ways to invoke moveTo
-     */
-    static void doMoveTests(Path dir1, Path dir2, boolean supportsLinks)
-        throws IOException
-    {
-        Path source, target, entry;
-
-        boolean sameDevice = dir1.getFileStore().equals(dir2.getFileStore());
-
-        // -- regular file --
-
-        /**
-         * Test: move regular file, target does not exist
-         */
-        source = createSourceFile(dir1);
-        target = getTargetFile(dir2);
-        moveAndVerify(source, target);
-        target.delete();
-
-        /**
-         * Test: move regular file, target exists
-         */
-        source = createSourceFile(dir1);
-        target = getTargetFile(dir2).createFile();
-        try {
-            moveAndVerify(source, target);
-            throw new RuntimeException("FileAlreadyExistsException expected");
-        } catch (FileAlreadyExistsException x) {
-        }
-        target.delete();
-        target.createDirectory();
-        try {
-            moveAndVerify(source, target);
-            throw new RuntimeException("FileAlreadyExistsException expected");
-        } catch (FileAlreadyExistsException x) {
-        }
-        source.delete();
-        target.delete();
-
-        /**
-         * Test: move regular file, target does not exist
-         */
-        source = createSourceFile(dir1);
-        target = getTargetFile(dir2);
-        moveAndVerify(source, target, REPLACE_EXISTING);
-        target.delete();
-
-        /**
-         * Test: move regular file, target exists
-         */
-        source = createSourceFile(dir1);
-        target = getTargetFile(dir2).createFile();
-        moveAndVerify(source, target, REPLACE_EXISTING);
-        target.delete();
-
-        /**
-         * Test: move regular file, target exists and is empty directory
-         */
-        source = createSourceFile(dir1);
-        target = getTargetFile(dir2).createDirectory();
-        moveAndVerify(source, target, REPLACE_EXISTING);
-        target.delete();
-
-        /**
-         * Test: move regular file, target exists and is non-empty directory
-         */
-        source = createSourceFile(dir1);
-        target = getTargetFile(dir2).createDirectory();
-        entry = target.resolve("foo").createFile();
-        try {
-            moveAndVerify(source, target);
-            throw new RuntimeException("FileAlreadyExistsException expected");
-        } catch (FileAlreadyExistsException x) {
-        }
-        entry.delete();
-        source.delete();
-        target.delete();
-
-        /**
-         * Test atomic move of regular file (same file store)
-         */
-        source = createSourceFile(dir1);
-        target = getTargetFile(dir1);
-        moveAndVerify(source, target, ATOMIC_MOVE);
-        target.delete();
-
-        /**
-         * Test atomic move of regular file (different file store)
-         */
-        if (!sameDevice) {
-            source = createSourceFile(dir1);
-            target = getTargetFile(dir2);
-            try {
-                moveAndVerify(source, target, ATOMIC_MOVE);
-                throw new RuntimeException("AtomicMoveNotSupportedException expected");
-            } catch (AtomicMoveNotSupportedException x) {
-            }
-            source.delete();
-        }
-
-        // -- directories --
-
-        /*
-         * Test: move empty directory, target does not exist
-         */
-        source = createSourceDirectory(dir1);
-        target = getTargetFile(dir2);
-        moveAndVerify(source, target);
-        target.delete();
-
-        /**
-         * Test: move empty directory, target exists
-         */
-        source = createSourceDirectory(dir1);
-        target = getTargetFile(dir2).createFile();
-        try {
-            moveAndVerify(source, target);
-            throw new RuntimeException("FileAlreadyExistsException expected");
-        } catch (FileAlreadyExistsException x) {
-        }
-        target.delete();
-        target.createDirectory();
-        try {
-            moveAndVerify(source, target);
-            throw new RuntimeException("FileAlreadyExistsException expected");
-        } catch (FileAlreadyExistsException x) {
-        }
-        source.delete();
-        target.delete();
-
-        /**
-         * Test: move empty directory, target does not exist
-         */
-        source = createSourceDirectory(dir1);
-        target = getTargetFile(dir2);
-        moveAndVerify(source, target, REPLACE_EXISTING);
-        target.delete();
-
-        /**
-         * Test: move empty directory, target exists
-         */
-        source = createSourceDirectory(dir1);
-        target = getTargetFile(dir2).createFile();
-        moveAndVerify(source, target, REPLACE_EXISTING);
-        target.delete();
-
-        /**
-         * Test: move empty, target exists and is empty directory
-         */
-        source = createSourceDirectory(dir1);
-        target = getTargetFile(dir2).createDirectory();
-        moveAndVerify(source, target, REPLACE_EXISTING);
-        target.delete();
-
-        /**
-         * Test: move empty directory, target exists and is non-empty directory
-         */
-        source = createSourceDirectory(dir1);
-        target = getTargetFile(dir2).createDirectory();
-        entry = target.resolve("foo").createFile();
-        try {
-            moveAndVerify(source, target, REPLACE_EXISTING);
-            throw new RuntimeException("FileAlreadyExistsException expected");
-        } catch (FileAlreadyExistsException x) {
-        }
-        entry.delete();
-        source.delete();
-        target.delete();
-
-        /**
-         * Test: move non-empty directory (same file system)
-         */
-        source = createSourceDirectory(dir1);
-        source.resolve("foo").createFile();
-        target = getTargetFile(dir1);
-        moveAndVerify(source, target);
-        target.resolve("foo").delete();
-        target.delete();
-
-        /**
-         * Test: move non-empty directory (different file store)
-         */
-        if (!sameDevice) {
-            source = createSourceDirectory(dir1);
-            source.resolve("foo").createFile();
-            target = getTargetFile(dir2);
-            try {
-                moveAndVerify(source, target);
-                throw new RuntimeException("IOException expected");
-            } catch (IOException x) {
-            }
-            source.resolve("foo").delete();
-            source.delete();
-        }
-
-        /**
-         * Test atomic move of directory (same file store)
-         */
-        source = createSourceDirectory(dir1);
-        source.resolve("foo").createFile();
-        target = getTargetFile(dir1);
-        moveAndVerify(source, target, ATOMIC_MOVE);
-        target.resolve("foo").delete();
-        target.delete();
-
-        // -- symbolic links --
-
-        /**
-         * Test: Move symbolic link to file, target does not exist
-         */
-        if (supportsLinks) {
-            Path tmp = createSourceFile(dir1);
-            source = dir1.resolve("link").createSymbolicLink(tmp);
-            target = getTargetFile(dir2);
-            moveAndVerify(source, target);
-            target.delete();
-            tmp.delete();
-        }
-
-        /**
-         * Test: Move symbolic link to directory, target does not exist
-         */
-        if (supportsLinks) {
-            source = dir1.resolve("link").createSymbolicLink(dir2);
-            target = getTargetFile(dir2);
-            moveAndVerify(source, target);
-            target.delete();
-        }
-
-        /**
-         * Test: Move broken symbolic link, target does not exists
-         */
-        if (supportsLinks) {
-            Path tmp = Paths.get("doesnotexist");
-            source = dir1.resolve("link").createSymbolicLink(tmp);
-            target = getTargetFile(dir2);
-            moveAndVerify(source, target);
-            target.delete();
-        }
-
-        /**
-         * Test: Move symbolic link, target exists
-         */
-        if (supportsLinks) {
-            source = dir1.resolve("link").createSymbolicLink(dir2);
-            target = getTargetFile(dir2).createFile();
-            try {
-                moveAndVerify(source, target);
-                throw new RuntimeException("FileAlreadyExistsException expected");
-            } catch (FileAlreadyExistsException x) {
-            }
-            source.delete();
-            target.delete();
-        }
-
-        /**
-         * Test: Move regular file, target exists
-         */
-        if (supportsLinks) {
-            source = dir1.resolve("link").createSymbolicLink(dir2);
-            target = getTargetFile(dir2).createFile();
-            moveAndVerify(source, target, REPLACE_EXISTING);
-            target.delete();
-        }
-
-        /**
-         * Test: move symbolic link, target exists and is empty directory
-         */
-        if (supportsLinks) {
-            source = dir1.resolve("link").createSymbolicLink(dir2);
-            target = getTargetFile(dir2).createDirectory();
-            moveAndVerify(source, target, REPLACE_EXISTING);
-            target.delete();
-        }
-
-        /**
-         * Test: symbolic link, target exists and is non-empty directory
-         */
-        if (supportsLinks) {
-            source = dir1.resolve("link").createSymbolicLink(dir2);
-            target = getTargetFile(dir2).createDirectory();
-            entry = target.resolve("foo").createFile();
-            try {
-                moveAndVerify(source, target);
-                throw new RuntimeException("FileAlreadyExistsException expected");
-            } catch (FileAlreadyExistsException x) {
-            }
-            entry.delete();
-            source.delete();
-            target.delete();
-        }
-
-        /**
-         * Test atomic move of symbolic link (same file store)
-         */
-        if (supportsLinks) {
-            source = dir1.resolve("link").createSymbolicLink(dir1);
-            target = getTargetFile(dir2).createFile();
-            moveAndVerify(source, target, REPLACE_EXISTING);
-            target.delete();
-        }
-
-        // -- misc. tests --
-
-        /**
-         * Test nulls
-         */
-        source = createSourceFile(dir1);
-        target = getTargetFile(dir2);
-        try {
-            source.moveTo(null);
-            throw new RuntimeException("NullPointerException expected");
-        } catch (NullPointerException x) { }
-        try {
-            source.moveTo(target, (CopyOption[])null);
-            throw new RuntimeException("NullPointerException expected");
-        } catch (NullPointerException x) { }
-        try {
-            CopyOption[] opts = { REPLACE_EXISTING, null };
-            source.moveTo(target, opts);
-            throw new RuntimeException("NullPointerException expected");
-        } catch (NullPointerException x) { }
-        source.delete();
-
-        /**
-         * Test UOE
-         */
-        source = createSourceFile(dir1);
-        target = getTargetFile(dir2);
-        try {
-            source.moveTo(target, new CopyOption() { });
-        } catch (UnsupportedOperationException x) { }
-        try {
-            source.moveTo(target, REPLACE_EXISTING,  new CopyOption() { });
-        } catch (UnsupportedOperationException x) { }
-        source.delete();
-    }
-
-    // copy source to target with verification
-    static void copyAndVerify(Path source, Path target, CopyOption... options)
-        throws IOException
-    {
-        source.copyTo(target, options);
-
-        // get attributes of source and target file to verify copy
-        boolean followLinks = true;
-        LinkOption[] linkOptions = new LinkOption[0];
-        boolean copyAttributes = false;
-        for (CopyOption opt : options) {
-            if (opt == NOFOLLOW_LINKS) {
-                followLinks = false;
-                linkOptions = new LinkOption[] { NOFOLLOW_LINKS };
-            }
-            if (opt == COPY_ATTRIBUTES)
-                copyAttributes = true;
-        }
-        BasicFileAttributes basicAttributes = Attributes
-            .readBasicFileAttributes(source, linkOptions);
-
-        // check hash if regular file
-        if (basicAttributes.isRegularFile())
-            assertTrue(computeHash(source) == computeHash(target));
-
-        // check link target if symbolic link
-        if (basicAttributes.isSymbolicLink())
-            assert( source.readSymbolicLink().equals(target.readSymbolicLink()));
-
-        // check that attributes are copied
-        if (copyAttributes && followLinks) {
-            checkBasicAttributes(basicAttributes,
-                Attributes.readBasicFileAttributes(source, linkOptions));
-
-            // verify other attributes when same provider
-            if (source.getFileSystem().provider() == target.getFileSystem().provider()) {
-
-                // check POSIX attributes are copied
-                String os = System.getProperty("os.name");
-                if (os.equals("SunOS") || os.equals("Linux")) {
-                    checkPosixAttributes(
-                        Attributes.readPosixFileAttributes(source, linkOptions),
-                        Attributes.readPosixFileAttributes(target, linkOptions));
-                }
-
-                // check DOS attributes are copied
-                if (os.startsWith("Windows")) {
-                    checkDosAttributes(
-                        Attributes.readDosFileAttributes(source, linkOptions),
-                        Attributes.readDosFileAttributes(target, linkOptions));
-                }
-
-                // check named attributes are copied
-                if (followLinks &&
-                    source.getFileStore().supportsFileAttributeView("xattr") &&
-                    target.getFileStore().supportsFileAttributeView("xattr"))
-                {
-                    checkUserDefinedFileAttributes(readUserDefinedFileAttributes(source),
-                                                   readUserDefinedFileAttributes(target));
-                }
-            }
-        }
-    }
-
-    /**
-     * Tests all possible ways to invoke copyTo
-     */
-    static void doCopyTests(Path dir1, Path dir2, boolean supportsLinks)
-        throws IOException
-    {
-        Path source, target, link, entry;
-
-        // -- regular file --
-
-        /**
-         * Test: move regular file, target does not exist
-         */
-        source = createSourceFile(dir1);
-        target = getTargetFile(dir2);
-        copyAndVerify(source, target);
-        source.delete();
-        target.delete();
-
-        /**
-         * Test: copy regular file, target exists
-         */
-        source = createSourceFile(dir1);
-        target = getTargetFile(dir2).createFile();
-        try {
-            copyAndVerify(source, target);
-            throw new RuntimeException("FileAlreadyExistsException expected");
-        } catch (FileAlreadyExistsException x) {
-        }
-        target.delete();
-        target.createDirectory();
-        try {
-            copyAndVerify(source, target);
-            throw new RuntimeException("FileAlreadyExistsException expected");
-        } catch (FileAlreadyExistsException x) {
-        }
-        source.delete();
-        target.delete();
-
-        /**
-         * Test: copy regular file, target does not exist
-         */
-        source = createSourceFile(dir1);
-        target = getTargetFile(dir2);
-        copyAndVerify(source, target, REPLACE_EXISTING);
-        source.delete();
-        target.delete();
-
-        /**
-         * Test: copy regular file, target exists
-         */
-        source = createSourceFile(dir1);
-        target = getTargetFile(dir2).createFile();
-        copyAndVerify(source, target, REPLACE_EXISTING);
-        source.delete();
-        target.delete();
-
-        /**
-         * Test: copy regular file, target exists and is empty directory
-         */
-        source = createSourceFile(dir1);
-        target = getTargetFile(dir2).createDirectory();
-        copyAndVerify(source, target, REPLACE_EXISTING);
-        source.delete();
-        target.delete();
-
-        /**
-         * Test: copy regular file, target exists and is non-empty directory
-         */
-        source = createSourceFile(dir1);
-        target = getTargetFile(dir2).createDirectory();
-        entry = target.resolve("foo").createFile();
-        try {
-            copyAndVerify(source, target);
-            throw new RuntimeException("FileAlreadyExistsException expected");
-        } catch (FileAlreadyExistsException x) {
-        }
-        entry.delete();
-        source.delete();
-        target.delete();
-
-        /**
-         * Test: copy regular file + attributes
-         */
-        source = createSourceFile(dir1);
-        target = getTargetFile(dir2);
-        copyAndVerify(source, target, COPY_ATTRIBUTES);
-        source.delete();
-        target.delete();
-
-
-        // -- directory --
-
-        /*
-         * Test: copy directory, target does not exist
-         */
-        source = createSourceDirectory(dir1);
-        target = getTargetFile(dir2);
-        copyAndVerify(source, target);
-        source.delete();
-        target.delete();
-
-        /**
-         * Test: copy directory, target exists
-         */
-        source = createSourceDirectory(dir1);
-        target = getTargetFile(dir2).createFile();
-        try {
-            copyAndVerify(source, target);
-            throw new RuntimeException("FileAlreadyExistsException expected");
-        } catch (FileAlreadyExistsException x) {
-        }
-        target.delete();
-        target.createDirectory();
-        try {
-            copyAndVerify(source, target);
-            throw new RuntimeException("FileAlreadyExistsException expected");
-        } catch (FileAlreadyExistsException x) {
-        }
-        source.delete();
-        target.delete();
-
-        /**
-         * Test: copy directory, target does not exist
-         */
-        source = createSourceDirectory(dir1);
-        target = getTargetFile(dir2);
-        copyAndVerify(source, target, REPLACE_EXISTING);
-        source.delete();
-        target.delete();
-
-        /**
-         * Test: copy directory, target exists
-         */
-        source = createSourceDirectory(dir1);
-        target = getTargetFile(dir2).createFile();
-        copyAndVerify(source, target, REPLACE_EXISTING);
-        source.delete();
-        target.delete();
-
-        /**
-         * Test: copy directory, target exists and is empty directory
-         */
-        source = createSourceDirectory(dir1);
-        target = getTargetFile(dir2).createDirectory();
-        copyAndVerify(source, target, REPLACE_EXISTING);
-        source.delete();
-        target.delete();
-
-        /**
-         * Test: copy directory, target exists and is non-empty directory
-         */
-        source = createSourceDirectory(dir1);
-        target = getTargetFile(dir2).createDirectory();
-        entry = target.resolve("foo").createFile();
-        try {
-            copyAndVerify(source, target, REPLACE_EXISTING);
-            throw new RuntimeException("FileAlreadyExistsException expected");
-        } catch (FileAlreadyExistsException x) {
-        }
-        entry.delete();
-        source.delete();
-        target.delete();
-
-        /*
-         * Test: copy directory + attributes
-         */
-        source = createSourceDirectory(dir1);
-        target = getTargetFile(dir2);
-        copyAndVerify(source, target, COPY_ATTRIBUTES);
-        source.delete();
-        target.delete();
-
-        // -- symbolic links --
-
-        /**
-         * Test: Follow link
-         */
-        if (supportsLinks) {
-            source = createSourceFile(dir1);
-            link = dir1.resolve("link").createSymbolicLink(source);
-            target = getTargetFile(dir2);
-            copyAndVerify(link, target);
-            link.delete();
-            source.delete();
-        }
-
-        /**
-         * Test: Copy link (to file)
-         */
-        if (supportsLinks) {
-            source = createSourceFile(dir1);
-            link = dir1.resolve("link").createSymbolicLink(source);
-            target = getTargetFile(dir2);
-            copyAndVerify(link, target, NOFOLLOW_LINKS);
-            link.delete();
-            source.delete();
-        }
-
-        /**
-         * Test: Copy link (to directory)
-         */
-        if (supportsLinks) {
-            source = dir1.resolve("mydir").createDirectory();
-            link = dir1.resolve("link").createSymbolicLink(source);
-            target = getTargetFile(dir2);
-            copyAndVerify(link, target, NOFOLLOW_LINKS);
-            link.delete();
-            source.delete();
-        }
-
-        /**
-         * Test: Copy broken link
-         */
-        if (supportsLinks) {
-            assertTrue(source.notExists());
-            link = dir1.resolve("link").createSymbolicLink(source);
-            target = getTargetFile(dir2);
-            copyAndVerify(link, target, NOFOLLOW_LINKS);
-            link.delete();
-        }
-
-        /**
-         * Test: Copy link to UNC (Windows only)
-         */
-        if (supportsLinks &&
-            System.getProperty("os.name").startsWith("Windows"))
-        {
-            Path unc = Paths.get("\\\\rialto\\share\\file");
-            link = dir1.resolve("link").createSymbolicLink(unc);
-            target = getTargetFile(dir2);
-            copyAndVerify(link, target, NOFOLLOW_LINKS);
-            link.delete();
-        }
-
-        // -- misc. tests --
-
-        /**
-         * Test nulls
-         */
-        source = createSourceFile(dir1);
-        target = getTargetFile(dir2);
-        try {
-            source.copyTo(null);
-            throw new RuntimeException("NullPointerException expected");
-        } catch (NullPointerException x) { }
-        try {
-            source.copyTo(target, (CopyOption[])null);
-            throw new RuntimeException("NullPointerException expected");
-        } catch (NullPointerException x) { }
-        try {
-            CopyOption[] opts = { REPLACE_EXISTING, null };
-            source.copyTo(target, opts);
-            throw new RuntimeException("NullPointerException expected");
-        } catch (NullPointerException x) { }
-        source.delete();
-
-        /**
-         * Test UOE
-         */
-        source = createSourceFile(dir1);
-        target = getTargetFile(dir2);
-        try {
-            source.copyTo(target, new CopyOption() { });
-        } catch (UnsupportedOperationException x) { }
-        try {
-            source.copyTo(target, REPLACE_EXISTING,  new CopyOption() { });
-        } catch (UnsupportedOperationException x) { }
-        source.delete();
-    }
-
-
-    static void assertTrue(boolean value) {
-        if (!value)
-            throw new RuntimeException("Assertion failed");
-    }
-
-    // computes simple hash of the given file
-    static int computeHash(Path file) throws IOException {
-        int h = 0;
-
-        InputStream in = file.newInputStream();
-        try {
-            byte[] buf = new byte[1024];
-            int n;
-            do {
-                n = in.read(buf);
-                for (int i=0; i<n; i++) {
-                    h = 31*h + (buf[i] & 0xff);
-                }
-            } while (n > 0);
-        } finally {
-            in.close();
-        }
-        return h;
-    }
-
-    // create file of random size in given directory
-    static Path createSourceFile(Path dir) throws IOException {
-        String name = "source" + Integer.toString(rand.nextInt());
-        Path file = dir.resolve(name).createFile();
-        byte[] bytes = new byte[rand.nextInt(128*1024)];
-        rand.nextBytes(bytes);
-        OutputStream out = file.newOutputStream();
-        try {
-            out.write(bytes);
-        } finally {
-            out.close();
-        }
-        randomizeAttributes(file);
-        return file;
-    }
-
-    // create directory in the given directory
-    static Path createSourceDirectory(Path dir) throws IOException {
-        String name = "sourcedir" + Integer.toString(rand.nextInt());
-        Path subdir = dir.resolve(name).createDirectory();
-        randomizeAttributes(subdir);
-        return subdir;
-    }
-
-    // "randomize" the file attributes of the given file.
-    static void randomizeAttributes(Path file) throws IOException {
-        String os = System.getProperty("os.name");
-        boolean isWindows = os.startsWith("Windows");
-        boolean isUnix = os.equals("SunOS") || os.equals("Linux");
-        boolean isDirectory = Attributes.readBasicFileAttributes(file, NOFOLLOW_LINKS)
-            .isDirectory();
-
-        if (isUnix) {
-            Set<PosixFilePermission> perms = Attributes
-                .readPosixFileAttributes(file, NOFOLLOW_LINKS).permissions();
-            PosixFilePermission[] toChange = {
-                PosixFilePermission.GROUP_READ,
-                PosixFilePermission.GROUP_WRITE,
-                PosixFilePermission.GROUP_EXECUTE,
-                PosixFilePermission.OTHERS_READ,
-                PosixFilePermission.OTHERS_WRITE,
-                PosixFilePermission.OTHERS_EXECUTE
-            };
-            for (PosixFilePermission perm: toChange) {
-                if (heads()) {
-                    perms.add(perm);
-                } else {
-                    perms.remove(perm);
-                }
-            }
-            Attributes.setPosixFilePermissions(file, perms);
-        }
-
-        if (isWindows) {
-            DosFileAttributeView view = file
-                .getFileAttributeView(DosFileAttributeView.class, NOFOLLOW_LINKS);
-            // only set or unset the hidden attribute
-            view.setHidden(heads());
-        }
-
-        boolean addUserDefinedFileAttributes = heads() &&
-            file.getFileStore().supportsFileAttributeView("xattr");
-
-        // remove this when copying a direcory copies its named streams
-        if (isWindows && isDirectory) addUserDefinedFileAttributes = false;
-
-        if (addUserDefinedFileAttributes) {
-            UserDefinedFileAttributeView view = file
-                .getFileAttributeView(UserDefinedFileAttributeView.class);
-            int n = rand.nextInt(16);
-            while (n > 0) {
-                byte[] value = new byte[1 + rand.nextInt(100)];
-                view.write("user." + Integer.toString(n), ByteBuffer.wrap(value));
-                n--;
-            }
-        }
-    }
-
-    // create name for file in given directory
-    static Path getTargetFile(Path dir) throws IOException {
-        String name = "target" + Integer.toString(rand.nextInt());
-        return dir.resolve(name);
-    }
- }
--- a/jdk/test/java/nio/file/Path/DeleteOnClose.java	Thu Jan 13 22:21:58 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.nio.file.*;
-import static java.nio.file.StandardOpenOption.*;
-import java.io.*;
-import java.util.*;
-
-public class DeleteOnClose {
-
-    public static void main(String[] args) throws IOException {
-        // open file but do not close it. Its existance will be checked by
-        // the calling script.
-        Paths.get(args[0]).newByteChannel(READ, WRITE, DELETE_ON_CLOSE);
-
-        // check temporary file has been deleted after closing it
-        Path file = File.createTempFile("blah", "tmp").toPath();
-        file.newByteChannel(READ, WRITE, DELETE_ON_CLOSE).close();
-        if (file.exists())
-            throw new RuntimeException("Temporary file was not deleted");
-
-        Path dir = TestUtil.createTemporaryDirectory();
-        try {
-            // check that DELETE_ON_CLOSE fails when file is a sym link
-            if (TestUtil.supportsLinks(dir)) {
-                file = dir.resolve("foo").createFile();
-                Path link = dir.resolve("link").createSymbolicLink(file);
-                try {
-                    link.newByteChannel(READ, WRITE, DELETE_ON_CLOSE);
-                    throw new RuntimeException("IOException expected");
-                } catch (IOException ignore) { }
-            }
-
-            // check that DELETE_ON_CLOSE works with files created via open
-            // directories
-            DirectoryStream stream = dir.newDirectoryStream();
-            try {
-                if (stream instanceof SecureDirectoryStream) {
-                    SecureDirectoryStream secure = (SecureDirectoryStream)stream;
-                    file = Paths.get("foo");
-
-                    Set<OpenOption> opts = new HashSet<OpenOption>();
-                    opts.add(WRITE);
-                    opts.add(DELETE_ON_CLOSE);
-                    secure.newByteChannel(file, opts).close();
-
-                    if (dir.resolve(file).exists())
-                        throw new RuntimeException("File not deleted");
-                }
-            } finally {
-                stream.close();
-            }
-        } finally {
-            TestUtil.removeAll(dir);
-        }
-    }
-}
--- a/jdk/test/java/nio/file/Path/FileAttributes.java	Thu Jan 13 22:21:58 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,264 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/* @test
- * @bug 4313887 6838333
- * @summary Unit test for java.nio.file.Path
- * @library ..
- */
-
-import java.nio.file.*;
-import java.nio.file.attribute.*;
-import java.io.IOException;
-import java.util.*;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Exercises getAttribute/setAttribute/readAttributes methods.
- */
-
-public class FileAttributes {
-
-    static void assertTrue(boolean okay) {
-        if (!okay)
-            throw new RuntimeException("Assertion Failed");
-    }
-
-    static void checkEqual(Object o1, Object o2) {
-        if (o1 == null) {
-            assertTrue(o2 == null);
-        } else {
-            assertTrue (o1.equals(o2));
-        }
-    }
-
-    // checks that two time values are within 1s of each other
-    static void checkNearEqual(FileTime t1, FileTime t2) {
-        long diff = Math.abs(t1.toMillis() - t2.toMillis());
-        assertTrue(diff <= 1000);
-    }
-
-    // Exercise getAttribute/setAttribute/readAttributes on basic attributes
-    static void checkBasicAttributes(FileRef file, BasicFileAttributes attrs)
-        throws IOException
-    {
-        // getAttribute
-        checkEqual(attrs.size(), file.getAttribute("size"));
-        checkEqual(attrs.lastModifiedTime(), file.getAttribute("basic:lastModifiedTime"));
-        checkEqual(attrs.lastAccessTime(), file.getAttribute("lastAccessTime"));
-        checkEqual(attrs.creationTime(), file.getAttribute("basic:creationTime"));
-        assertTrue((Boolean)file.getAttribute("isRegularFile"));
-        assertTrue(!(Boolean)file.getAttribute("basic:isDirectory"));
-        assertTrue(!(Boolean)file.getAttribute("isSymbolicLink"));
-        assertTrue(!(Boolean)file.getAttribute("basic:isOther"));
-        checkEqual(attrs.fileKey(), file.getAttribute("basic:fileKey"));
-
-        // setAttribute
-        FileTime modTime = attrs.lastModifiedTime();
-        file.setAttribute("basic:lastModifiedTime", FileTime.fromMillis(0L));
-        checkEqual(Attributes.readBasicFileAttributes(file).lastModifiedTime(),
-                   FileTime.fromMillis(0L));
-        file.setAttribute("lastModifiedTime", modTime);
-        checkEqual(Attributes.readBasicFileAttributes(file).lastModifiedTime(), modTime);
-
-        Map<String,?> map;
-        map = file.readAttributes("*");
-        assertTrue(map.size() >= 9);
-        checkEqual(attrs.isRegularFile(), map.get("isRegularFile")); // check one
-
-        map = file.readAttributes("basic:*");
-        assertTrue(map.size() >= 9);
-        checkEqual(attrs.lastAccessTime(), map.get("lastAccessTime")); // check one
-
-        map = file.readAttributes("size,lastModifiedTime");
-        assertTrue(map.size() == 2);
-        checkEqual(attrs.size(), map.get("size"));
-        checkEqual(attrs.lastModifiedTime(), map.get("lastModifiedTime"));
-
-        map = file.readAttributes(
-            "basic:lastModifiedTime,lastAccessTime,ShouldNotExist");
-        assertTrue(map.size() == 2);
-        checkEqual(attrs.lastModifiedTime(), map.get("lastModifiedTime"));
-        checkEqual(attrs.lastAccessTime(), map.get("lastAccessTime"));
-    }
-
-    // Exercise getAttribute/setAttribute/readAttributes on posix attributes
-    static void checkPosixAttributes(FileRef file, PosixFileAttributes attrs)
-        throws IOException
-    {
-        checkBasicAttributes(file, attrs);
-
-        // getAttribute
-        checkEqual(attrs.permissions(), file.getAttribute("posix:permissions"));
-        checkEqual(attrs.owner(), file.getAttribute("posix:owner"));
-        checkEqual(attrs.group(), file.getAttribute("posix:group"));
-
-        // setAttribute
-        Set<PosixFilePermission> orig = attrs.permissions();
-        Set<PosixFilePermission> newPerms = new HashSet<PosixFilePermission>(orig);
-        newPerms.remove(PosixFilePermission.OTHERS_READ);
-        newPerms.remove(PosixFilePermission.OTHERS_WRITE);
-        newPerms.remove(PosixFilePermission.OTHERS_EXECUTE);
-        file.setAttribute("posix:permissions", newPerms);
-        checkEqual(Attributes.readPosixFileAttributes(file).permissions(), newPerms);
-        file.setAttribute("posix:permissions", orig);
-        checkEqual(Attributes.readPosixFileAttributes(file).permissions(), orig);
-        file.setAttribute("posix:owner", attrs.owner());
-        file.setAttribute("posix:group", attrs.group());
-
-        // readAttributes
-        Map<String,?> map;
-        map = file.readAttributes("posix:*");
-        assertTrue(map.size() >= 12);
-        checkEqual(attrs.permissions(), map.get("permissions")); // check one
-
-        map = file.readAttributes("posix:size,owner,ShouldNotExist");
-        assertTrue(map.size() == 2);
-        checkEqual(attrs.size(), map.get("size"));
-        checkEqual(attrs.owner(), map.get("owner"));
-    }
-
-    // Exercise getAttribute/readAttributes on unix attributes
-    static void checkUnixAttributes(FileRef file) throws IOException {
-        // getAttribute
-        int mode = (Integer)file.getAttribute("unix:mode");
-        long ino = (Long)file.getAttribute("unix:ino");
-        long dev = (Long)file.getAttribute("unix:dev");
-        long rdev = (Long)file.getAttribute("unix:rdev");
-        int nlink = (Integer)file.getAttribute("unix:nlink");
-        int uid = (Integer)file.getAttribute("unix:uid");
-        int gid = (Integer)file.getAttribute("unix:gid");
-        FileTime ctime = (FileTime)file.getAttribute("unix:ctime");
-
-        // readAttributes
-        Map<String,?> map;
-        map = file.readAttributes("unix:*");
-        assertTrue(map.size() >= 20);
-
-        map = file.readAttributes("unix:size,uid,gid,ShouldNotExist");
-        assertTrue(map.size() == 3);
-        checkEqual(map.get("size"),
-                   Attributes.readBasicFileAttributes(file).size());
-    }
-
-    // Exercise getAttribute/setAttribute on dos attributes
-    static void checkDosAttributes(FileRef file, DosFileAttributes attrs)
-        throws IOException
-    {
-        checkBasicAttributes(file, attrs);
-
-        // getAttribute
-        checkEqual(attrs.isReadOnly(), file.getAttribute("dos:readonly"));
-        checkEqual(attrs.isHidden(), file.getAttribute("dos:hidden"));
-        checkEqual(attrs.isSystem(), file.getAttribute("dos:system"));
-        checkEqual(attrs.isArchive(), file.getAttribute("dos:archive"));
-
-        // setAttribute
-        boolean value;
-
-        value = attrs.isReadOnly();
-        file.setAttribute("dos:readonly", !value);
-        checkEqual(Attributes.readDosFileAttributes(file).isReadOnly(), !value);
-        file.setAttribute("dos:readonly", value);
-        checkEqual(Attributes.readDosFileAttributes(file).isReadOnly(), value);
-
-        value = attrs.isHidden();
-        file.setAttribute("dos:hidden", !value);
-        checkEqual(Attributes.readDosFileAttributes(file).isHidden(), !value);
-        file.setAttribute("dos:hidden", value);
-        checkEqual(Attributes.readDosFileAttributes(file).isHidden(), value);
-
-        value = attrs.isSystem();
-        file.setAttribute("dos:system", !value);
-        checkEqual(Attributes.readDosFileAttributes(file).isSystem(), !value);
-        file.setAttribute("dos:system", value);
-        checkEqual(Attributes.readDosFileAttributes(file).isSystem(), value);
-
-        value = attrs.isArchive();
-        file.setAttribute("dos:archive", !value);
-        checkEqual(Attributes.readDosFileAttributes(file).isArchive(), !value);
-        file.setAttribute("dos:archive", value);
-        checkEqual(Attributes.readDosFileAttributes(file).isArchive(), value);
-
-        // readAttributes
-        Map<String,?> map;
-        map = file.readAttributes("dos:*");
-        assertTrue(map.size() >= 13);
-        checkEqual(attrs.isReadOnly(), map.get("readonly")); // check one
-
-        map = file.readAttributes("dos:size,hidden,ShouldNotExist");
-        assertTrue(map.size() == 2);
-        checkEqual(attrs.size(), map.get("size"));
-        checkEqual(attrs.isHidden(), map.get("hidden"));
-    }
-
-    static void miscTests(Path file) throws IOException {
-        // NPE tests
-        try {
-            file.getAttribute(null);
-            throw new RuntimeException("NullPointerException expected");
-        } catch (NullPointerException npe) { }
-        try {
-            file.getAttribute("isRegularFile", (LinkOption[])null);
-            throw new RuntimeException("NullPointerException expected");
-        } catch (NullPointerException npe) { }
-        try {
-            file.setAttribute(null, 0L);
-            throw new RuntimeException("NullPointerException expected");
-        } catch (NullPointerException npe) { }
-    }
-
-    static void doTests(Path dir) throws IOException {
-        Path file = dir.resolve("foo").createFile();
-        FileStore store = file.getFileStore();
-        try {
-            checkBasicAttributes(file,
-                Attributes.readBasicFileAttributes(file));
-
-            if (store.supportsFileAttributeView("posix"))
-                checkPosixAttributes(file,
-                    Attributes.readPosixFileAttributes(file));
-
-            if (store.supportsFileAttributeView("unix"))
-                checkUnixAttributes(file);
-
-            if (store.supportsFileAttributeView("dos"))
-                checkDosAttributes(file,
-                    Attributes.readDosFileAttributes(file));
-
-            miscTests(file);
-        } finally {
-            file.delete();
-        }
-    }
-
-
-    public static void main(String[] args) throws IOException {
-        Path dir = TestUtil.createTemporaryDirectory();
-        try {
-            doTests(dir);
-        } finally {
-            TestUtil.removeAll(dir);
-        }
-    }
-}
--- a/jdk/test/java/nio/file/Path/InterruptCopy.java	Thu Jan 13 22:21:58 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,126 +0,0 @@
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/* @test
- * @bug 4313887 6993267
- * @summary Unit test for Sun-specific ExtendedCopyOption.INTERRUPTIBLE option
- * @library ..
- * @run main/othervm -XX:-UseVMInterruptibleIO InterruptCopy
- */
-
-import java.nio.file.*;
-import java.nio.file.attribute.Attributes;
-import java.io.*;
-import java.util.concurrent.*;
-import com.sun.nio.file.ExtendedCopyOption;
-
-public class InterruptCopy {
-
-    private static final long FILE_SIZE_TO_COPY = 512L * 1024L * 1024L;
-    private static final int DELAY_IN_MS = 500;
-    private static final int DURATION_MAX_IN_MS = 5000;
-
-    public static void main(String[] args) throws Exception {
-        Path dir = TestUtil.createTemporaryDirectory();
-        try {
-            FileStore store = dir.getFileStore();
-            System.out.format("Checking space (%s)\n", store);
-            long usableSpace = Attributes
-                .readFileStoreSpaceAttributes(store).usableSpace();
-            if (usableSpace < 2*FILE_SIZE_TO_COPY) {
-                System.out.println("Insufficient disk space to run test.");
-                return;
-            }
-            doTest(dir);
-        } finally {
-            TestUtil.removeAll(dir);
-        }
-    }
-
-    static void doTest(Path dir) throws Exception {
-        final Path source = dir.resolve("foo");
-        final Path target = dir.resolve("bar");
-
-        // create source file (don't create it as sparse file because we
-        // require the copy to take a long time)
-        System.out.println("Creating source file...");
-        byte[] buf = new byte[32*1024];
-        long total = 0;
-        OutputStream out = source.newOutputStream();
-        try {
-            do {
-                out.write(buf);
-                total += buf.length;
-            } while (total < FILE_SIZE_TO_COPY);
-        } finally {
-            out.close();
-        }
-        System.out.println("Source file created.");
-
-        ScheduledExecutorService pool =
-            Executors.newSingleThreadScheduledExecutor();
-        try {
-            // copy source to target in main thread, interrupting it after a delay
-            final Thread me = Thread.currentThread();
-            Future<?> wakeup = pool.schedule(new Runnable() {
-                public void run() {
-                    me.interrupt();
-                }}, DELAY_IN_MS, TimeUnit.MILLISECONDS);
-            System.out.println("Copying file...");
-            try {
-                long start = System.currentTimeMillis();
-                source.copyTo(target, ExtendedCopyOption.INTERRUPTIBLE);
-                long duration = System.currentTimeMillis() - start;
-                if (duration > DURATION_MAX_IN_MS)
-                    throw new RuntimeException("Copy was not interrupted");
-            } catch (IOException e) {
-                boolean interrupted = Thread.interrupted();
-                if (!interrupted)
-                    throw new RuntimeException("Interrupt status was not set");
-                System.out.println("Copy failed (this is expected)");
-            }
-            try {
-                wakeup.get();
-            } catch (InterruptedException ignore) { }
-            Thread.interrupted();
-
-            // copy source to target via task in thread pool, interrupting it after
-            // a delay using cancel(true)
-            Future<Void> result = pool.submit(new Callable<Void>() {
-                public Void call() throws IOException {
-                    System.out.println("Copying file...");
-                    source.copyTo(target, ExtendedCopyOption.INTERRUPTIBLE,
-                        StandardCopyOption.REPLACE_EXISTING);
-                    return null;
-                }
-            });
-            Thread.sleep(DELAY_IN_MS);
-            boolean cancelled = result.cancel(true);
-            if (!cancelled)
-                result.get();
-            System.out.println("Copy cancelled.");
-        } finally {
-            pool.shutdown();
-        }
-    }
-}
--- a/jdk/test/java/nio/file/Path/Links.java	Thu Jan 13 22:21:58 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,195 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/* @test
- * @bug 4313887 6838333 6863864
- * @summary Unit test for java.nio.file.Path createSymbolicLink,
- *     readSymbolicLink, and createLink methods
- * @library ..
- * @build Links
- * @run main/othervm Links
- */
-
-import java.nio.file.*;
-import java.nio.file.attribute.*;
-import java.io.*;
-
-public class Links {
-
-    static final boolean isWindows =
-        System.getProperty("os.name").startsWith("Windows");
-
-    static void assertTrue(boolean okay) {
-        if (!okay)
-            throw new RuntimeException("Assertion failed");
-    }
-
-    /**
-     * Exercise createSymbolicLink and readLink methods
-     */
-    static void testSymLinks(Path dir) throws IOException {
-        final Path link = dir.resolve("link");
-
-        // Check if sym links are supported
-        try {
-            link.createSymbolicLink(Paths.get("foo"));
-            link.delete();
-        } catch (UnsupportedOperationException x) {
-            // sym links not supported
-            return;
-        } catch (IOException x) {
-            // probably insufficient privileges to create sym links (Windows)
-            return;
-        }
-
-        // Test links to various targets
-        String[] windowsTargets =
-            { "foo", "C:\\foo", "\\foo", "\\\\server\\share\\foo" };
-        String[] otherTargets = { "relative", "/absolute" };
-
-        String[] targets = (isWindows) ? windowsTargets : otherTargets;
-        for (String s: targets) {
-            Path target = Paths.get(s);
-            link.createSymbolicLink(target);
-            try {
-                assertTrue(link.readSymbolicLink().equals(target));
-            } finally {
-                link.delete();
-            }
-        }
-
-        // Test links to directory
-        Path mydir = dir.resolve("mydir");
-        Path myfile = mydir.resolve("myfile");
-        try {
-            mydir.createDirectory();
-            myfile.createFile();
-
-            // link -> "mydir"
-            link.createSymbolicLink(mydir.getName());
-            assertTrue(link.readSymbolicLink().equals(mydir.getName()));
-
-            // Test access to directory via link
-            DirectoryStream<Path> stream = link.newDirectoryStream();
-            try {
-                boolean found = false;
-                for (Path entry: stream) {
-                    if (entry.getName().equals(myfile.getName())) {
-                        found = true;
-                        break;
-                    }
-                }
-                assertTrue(found);
-            } finally {
-                stream.close();
-            }
-
-            // Test link2 -> link -> mydir
-            final Path link2 = dir.resolve("link2");
-            Path target2 = link.getName();
-            link2.createSymbolicLink(target2);
-            try {
-                assertTrue(link2.readSymbolicLink().equals(target2));
-                link2.newDirectoryStream().close();
-            } finally {
-                link2.delete();
-            }
-
-            // Remove mydir and re-create link2 before re-creating mydir
-            // (This is a useful test on Windows to ensure that creating a
-            // sym link to a directory sym link creates the right type of link).
-            myfile.delete();
-            mydir.delete();
-            link2.createSymbolicLink(target2);
-            try {
-                assertTrue(link2.readSymbolicLink().equals(target2));
-                mydir.createDirectory();
-                link2.newDirectoryStream().close();
-            } finally {
-                link2.delete();
-            }
-
-        } finally {
-            myfile.deleteIfExists();
-            mydir.deleteIfExists();
-            link.deleteIfExists();
-        }
-    }
-
-    /**
-     * Exercise createLink method
-     */
-    static void testHardLinks(Path dir) throws IOException {
-        Path foo = dir.resolve("foo").createFile();
-        try {
-            Path bar;
-            try {
-                bar = dir.resolve("bar").createLink(foo);
-            } catch (UnsupportedOperationException x) {
-                return;
-            } catch (IOException x) {
-                // probably insufficient privileges (Windows)
-                return;
-            }
-            try {
-                Object key1 = Attributes
-                    .readBasicFileAttributes(foo).fileKey();
-                Object key2 = Attributes
-                    .readBasicFileAttributes(bar).fileKey();
-                assertTrue((key1 == null) || (key1.equals(key2)));
-            } finally {
-                bar.delete();
-            }
-
-
-        } finally {
-            foo.delete();
-        }
-    }
-
-    public static void main(String[] args) throws IOException {
-        Path dir = TestUtil.createTemporaryDirectory();
-        try {
-            testSymLinks(dir);
-            testHardLinks(dir);
-
-            // repeat tests on Windows with long path
-            if (isWindows) {
-                Path dirWithLongPath = null;
-                try {
-                    dirWithLongPath = TestUtil.createDirectoryWithLongPath(dir);
-                } catch (IOException x) {
-                    System.out.println("Unable to create long path: " + x);
-                }
-                if (dirWithLongPath != null) {
-                    System.out.println("");
-                    System.out.println("** REPEAT TESTS WITH LONG PATH **");
-                    testSymLinks(dirWithLongPath);
-                    testHardLinks(dirWithLongPath);
-                }
-            }
-        } finally {
-            TestUtil.removeAll(dir);
-        }
-    }
-}
--- a/jdk/test/java/nio/file/Path/Misc.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/test/java/nio/file/Path/Misc.java	Fri Jan 28 09:28:43 2011 +0000
@@ -22,17 +22,13 @@
  */
 
 /* @test
- * @bug 4313887 6838333 6867101
- * @summary Unit test for java.nio.file.Path for miscellenous methods not
- *   covered by other tests
+ * @bug 4313887 6838333
+ * @summary Unit test for miscellenous java.nio.file.Path methods
  * @library ..
  */
 
 import java.nio.file.*;
-import static java.nio.file.LinkOption.*;
-import java.nio.file.attribute.*;
 import java.io.*;
-import java.util.*;
 
 public class Misc {
     static final boolean isWindows =
@@ -45,22 +41,14 @@
             supportsLinks = TestUtil.supportsLinks(dir);
 
             // equals and hashCode methods
-            equalsAndHashCode();
+            testEqualsAndHashCode();
 
-            // checkAccess method
-            checkAccessTests(dir);
-
-            // getFileAttributeView methods
-            getFileAttributeViewTests(dir);
+            // toFile method
+            testToFile(dir);
 
             // toRealPath method
-            toRealPathTests(dir);
+            testToRealPath(dir);
 
-            // isSameFile method
-            isSameFileTests(dir);
-
-            // isHidden method
-            isHiddenTests(dir);
 
         } finally {
             TestUtil.removeAll(dir);
@@ -70,8 +58,7 @@
     /**
      * Exercise equals and hashCode methods
      */
-    static void equalsAndHashCode() {
-
+    static void testEqualsAndHashCode() {
         Path thisFile = Paths.get("this");
         Path thatFile = Paths.get("that");
 
@@ -93,172 +80,25 @@
     }
 
     /**
-     * Exercise checkAccess method
+     * Exercise toFile method
      */
-    static void checkAccessTests(Path dir) throws IOException {
-        final Path file = dir.resolve("foo").createFile();
-
-        /**
-         * Test: This directory should readable and writable
-         */
-        dir.checkAccess();
-        dir.checkAccess(AccessMode.READ);
-        dir.checkAccess(AccessMode.WRITE);
-        dir.checkAccess(AccessMode.READ, AccessMode.WRITE);
-
-        /**
-         * Test: Check access to all files in all root directories.
-         * (A useful test on Windows for special files such as pagefile.sys)
-         */
-        for (Path root: FileSystems.getDefault().getRootDirectories()) {
-            DirectoryStream<Path> stream;
-            try {
-                stream = root.newDirectoryStream();
-            } catch (IOException x) {
-                continue; // skip root directories that aren't accessible
-            }
-            try {
-                for (Path entry: stream) {
-                    try {
-                        entry.checkAccess();
-                    } catch (AccessDeniedException ignore) { }
-                }
-            } finally {
-                stream.close();
-            }
-        }
-
-        /**
-         * Test: File does not exist
-         */
-        Path doesNotExist = dir.resolve("thisDoesNotExists");
-        try {
-            doesNotExist.checkAccess();
-            throw new RuntimeException("NoSuchFileException expected");
-        } catch (NoSuchFileException x) {
-        }
-        try {
-            doesNotExist.checkAccess(AccessMode.READ);
-            throw new RuntimeException("NoSuchFileException expected");
-        } catch (NoSuchFileException x) {
-        }
-        try {
-            doesNotExist.checkAccess(AccessMode.WRITE);
-            throw new RuntimeException("NoSuchFileException expected");
-        } catch (NoSuchFileException x) {
-        }
-        try {
-            doesNotExist.checkAccess(AccessMode.EXECUTE);
-            throw new RuntimeException("NoSuchFileException expected");
-        } catch (NoSuchFileException x) {
-        }
-
-        /**
-         * Test: Edit ACL to deny WRITE and EXECUTE
-         */
-        AclFileAttributeView view = file
-            .getFileAttributeView(AclFileAttributeView.class);
-        if (view != null &&
-            file.getFileStore().supportsFileAttributeView("acl"))
-        {
-            UserPrincipal owner = view.getOwner();
-            List<AclEntry> acl = view.getAcl();
-
-            // Insert entry to deny WRITE and EXECUTE
-            AclEntry entry = AclEntry.newBuilder()
-                .setType(AclEntryType.DENY)
-                .setPrincipal(owner)
-                .setPermissions(AclEntryPermission.WRITE_DATA,
-                    AclEntryPermission.EXECUTE)
-                .build();
-            acl.add(0, entry);
-            view.setAcl(acl);
-
-            try {
-                file.checkAccess(AccessMode.WRITE);
-                throw new RuntimeException("AccessDeniedException expected");
-            } catch (AccessDeniedException x) {
-            }
-
-            try {
-                file.checkAccess(AccessMode.EXECUTE);
-                throw new RuntimeException("AccessDeniedException expected");
-            } catch (AccessDeniedException x) {
-            }
-
-
-            // Restore ACL
-            acl.remove(0);
-            view.setAcl(acl);
-        }
-
-        /**
-         * Test: Windows DOS read-only attribute
-         */
-        if (isWindows) {
-            DosFileAttributeView dview =
-                file.getFileAttributeView(DosFileAttributeView.class);
-            dview.setReadOnly(true);
-            try {
-                file.checkAccess(AccessMode.WRITE);
-                throw new RuntimeException("AccessDeniedException expected");
-            } catch (AccessDeniedException x) {
-            }
-            dview.setReadOnly(false);
-
-            // Read-only attribute does not make direcory read-only
-            dview = dir.getFileAttributeView(DosFileAttributeView.class);
-            boolean save = dview.readAttributes().isReadOnly();
-            dview.setReadOnly(true);
-            dir.checkAccess(AccessMode.WRITE);
-            dview.setReadOnly(save);
-        }
-
-        /**
-         * Test: null
-         */
-        try {
-            file.checkAccess((AccessMode)null);
-            throw new RuntimeException("NullPointerException expected");
-        } catch (NullPointerException ignore) { }
-
-        // clean-up
-        file.delete();
+    static void testToFile(Path dir) throws IOException {
+        File d = dir.toFile();
+        assertTrue(d.toString().equals(dir.toString()));
+        assertTrue(d.toPath().equals(dir));
     }
 
     /**
-     * Exercise getFileAttributeFile methods
-     */
-    static void getFileAttributeViewTests(Path dir) {
-        assertTrue(dir.getFileAttributeView(BasicFileAttributeView.class)
-            instanceof BasicFileAttributeView);
-        assertTrue(dir.getFileAttributeView(BasicFileAttributeView.class, NOFOLLOW_LINKS)
-            instanceof BasicFileAttributeView);
-        assertTrue(dir.getFileAttributeView(BogusFileAttributeView.class) == null);
-        try {
-            dir.getFileAttributeView((Class<FileAttributeView>)null);
-        } catch (NullPointerException ignore) { }
-        try {
-            dir.getFileAttributeView(BasicFileAttributeView.class, (LinkOption[])null);
-        } catch (NullPointerException ignore) { }
-        try {
-            dir.getFileAttributeView(BasicFileAttributeView.class, (LinkOption)null);
-        } catch (NullPointerException ignore) { }
-
-    }
-    interface BogusFileAttributeView extends FileAttributeView { }
-
-    /**
      * Exercise toRealPath method
      */
-    static void toRealPathTests(Path dir) throws IOException {
-        final Path file = dir.resolve("foo").createFile();
+    static void testToRealPath(Path dir) throws IOException {
+        final Path file = Files.createFile(dir.resolve("foo"));
         final Path link = dir.resolve("link");
 
         /**
-         * Test: toRealPath(true) will access same file as toRealPath(false)
+         * Test: totRealPath(true) will access same file as toRealPath(false)
          */
-        assertTrue(file.toRealPath(true).isSameFile(file.toRealPath(false)));
+        assertTrue(Files.isSameFile(file.toRealPath(true), file.toRealPath(false)));
 
         /**
          * Test: toRealPath should fail if file does not exist
@@ -279,29 +119,27 @@
          * Test: toRealPath(true) should resolve links
          */
         if (supportsLinks) {
-            link.createSymbolicLink(file.toAbsolutePath());
+            Files.createSymbolicLink(link, file.toAbsolutePath());
             assertTrue(link.toRealPath(true).equals(file.toRealPath(true)));
-            link.delete();
+            Files.delete(link);
         }
 
-
         /**
          * Test: toRealPath(false) should not resolve links
          */
         if (supportsLinks) {
-            link.createSymbolicLink(file.toAbsolutePath());
-            assertTrue(link.toRealPath(false).getName().equals(link.getName()));
-            link.delete();
+            Files.createSymbolicLink(link, file.toAbsolutePath());
+            assertTrue(link.toRealPath(false).getFileName().equals(link.getFileName()));
+            Files.delete(link);
         }
 
         /**
          * Test: toRealPath(false) with broken link
          */
         if (supportsLinks) {
-            Path broken = dir.resolve("doesNotExist");
-            link.createSymbolicLink(broken);
-            assertTrue(link.toRealPath(false).getName().equals(link.getName()));
-            link.delete();
+            Path broken = Files.createSymbolicLink(link, doesNotExist);
+            assertTrue(link.toRealPath(false).getFileName().equals(link.getFileName()));
+            Files.delete(link);
         }
 
         /**
@@ -314,105 +152,13 @@
          * Test: toRealPath should eliminate ".." when it doesn't follow a
          *       symbolic link
          */
-        Path subdir = dir.resolve("subdir").createDirectory();
+        Path subdir = Files.createDirectory(dir.resolve("subdir"));
         assertTrue(subdir.resolve("..").toRealPath(true).equals(dir.toRealPath(true)));
         assertTrue(subdir.resolve("..").toRealPath(false).equals(dir.toRealPath(false)));
-        subdir.delete();
+        Files.delete(subdir);
 
         // clean-up
-        file.delete();
-    }
-
-    /**
-     * Exercise isSameFile method
-     */
-    static void isSameFileTests(Path dir) throws IOException {
-        Path thisFile = dir.resolve("thisFile");
-        Path thatFile = dir.resolve("thatFile");
-
-        /**
-         * Test: isSameFile for self and null
-         */
-        assertTrue(thisFile.isSameFile(thisFile));
-        assertTrue(!thisFile.isSameFile(null));
-
-        /**
-         * Test: Neither files exist
-         */
-        try {
-            thisFile.isSameFile(thatFile);
-            throw new RuntimeException("IOException not thrown");
-        } catch (IOException x) {
-        }
-        try {
-            thatFile.isSameFile(thisFile);
-            throw new RuntimeException("IOException not thrown");
-        } catch (IOException x) {
-        }
-
-        thisFile.createFile();
-        try {
-            /**
-             * Test: One file exists
-             */
-            try {
-                thisFile.isSameFile(thatFile);
-                throw new RuntimeException("IOException not thrown");
-            } catch (IOException x) {
-            }
-            try {
-                thatFile.isSameFile(thisFile);
-                throw new RuntimeException("IOException not thrown");
-            } catch (IOException x) {
-            }
-
-            thatFile.createFile();
-
-            /**
-             * Test: Both file exists
-             */
-            try {
-                assertTrue(!thisFile.isSameFile(thatFile));
-                assertTrue(!thatFile.isSameFile(thisFile));
-            } finally {
-                TestUtil.deleteUnchecked(thatFile);
-            }
-
-            /**
-             * Test: Symbolic links
-             */
-            if (supportsLinks) {
-                thatFile.createSymbolicLink(thisFile);
-                try {
-                    assertTrue(thisFile.isSameFile(thatFile));
-                    assertTrue(thatFile.isSameFile(thisFile));
-                } finally {
-                    TestUtil.deleteUnchecked(thatFile);
-                }
-            }
-        } finally {
-            thisFile.delete();
-        }
-    }
-
-    /**
-     * Exercise isHidden method
-     */
-    static void isHiddenTests(Path dir) throws IOException {
-        assertTrue(!dir.isHidden());
-
-        Path file = dir.resolve(".foo");
-        if (isWindows) {
-            file.createFile();
-            try {
-                file.setAttribute("dos:hidden", true);
-                assertTrue(file.isHidden());
-            } finally {
-                file.delete();
-            }
-        } else {
-            assertTrue(file.isHidden());
-        }
+        Files.delete(file);
     }
 
     static void assertTrue(boolean okay) {
--- a/jdk/test/java/nio/file/Path/PassThroughFileSystem.java	Thu Jan 13 22:21:58 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,554 +0,0 @@
-/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.nio.file.*;
-import java.nio.file.attribute.*;
-import java.nio.file.spi.FileSystemProvider;
-import java.nio.channels.SeekableByteChannel;
-import java.net.URI;
-import java.util.*;
-import java.io.*;
-
-/**
- * A "pass through" file system implementation that passes through, or delegates,
- * everything to the default file system.
- */
-
-class PassThroughFileSystem extends FileSystem {
-    private final FileSystemProvider provider;
-    private final FileSystem delegate;
-
-    PassThroughFileSystem(FileSystemProvider provider, FileSystem delegate) {
-        this.provider = provider;
-        this.delegate = delegate;
-    }
-
-    /**
-     * Creates a new "pass through" file system. Useful for test environments
-     * where the provider might not be deployed.
-     */
-    static FileSystem create() throws IOException {
-        FileSystemProvider provider = new PassThroughProvider();
-        Map<String,?> env = Collections.emptyMap();
-        URI uri = URI.create("pass:///");
-        return provider.newFileSystem(uri, env);
-    }
-
-    @Override
-    public FileSystemProvider provider() {
-        return provider;
-    }
-
-    @Override
-    public void close() throws IOException {
-        delegate.close();
-    }
-
-    @Override
-    public boolean isOpen() {
-        return delegate.isOpen();
-    }
-
-    @Override
-    public boolean isReadOnly() {
-        return delegate.isReadOnly();
-    }
-
-    @Override
-    public String getSeparator() {
-        return delegate.getSeparator();
-    }
-
-    @Override
-    public Iterable<Path> getRootDirectories() {
-        final Iterable<Path> roots = delegate.getRootDirectories();
-        return new Iterable<Path>() {
-            @Override
-            public Iterator<Path> iterator() {
-                final Iterator<Path> itr = roots.iterator();
-                return new Iterator<Path>() {
-                    @Override
-                    public boolean hasNext() {
-                        return itr.hasNext();
-                    }
-                    @Override
-                    public Path next() {
-                        return new PassThroughPath(delegate, itr.next());
-                    }
-                    @Override
-                    public void remove() {
-                        itr.remove();
-                    }
-                };
-            }
-        };
-    }
-
-    @Override
-    public Iterable<FileStore> getFileStores() {
-        // assume that unwrapped objects aren't exposed
-        return delegate.getFileStores();
-    }
-
-    @Override
-    public Set<String> supportedFileAttributeViews() {
-        // assume that unwrapped objects aren't exposed
-        return delegate.supportedFileAttributeViews();
-    }
-
-    @Override
-    public Path getPath(String path) {
-        return new PassThroughPath(this, delegate.getPath(path));
-    }
-
-    @Override
-    public PathMatcher getPathMatcher(String syntaxAndPattern) {
-        final PathMatcher matcher = delegate.getPathMatcher(syntaxAndPattern);
-        return new PathMatcher() {
-            @Override
-            public boolean matches(Path path) {
-                return matcher.matches(PassThroughPath.unwrap(path));
-            }
-        };
-    }
-
-    @Override
-    public UserPrincipalLookupService getUserPrincipalLookupService() {
-        // assume that unwrapped objects aren't exposed
-        return delegate.getUserPrincipalLookupService();
-    }
-
-    @Override
-    public WatchService newWatchService() throws IOException {
-        // to keep it simple
-        throw new UnsupportedOperationException();
-    }
-
-    static class PassThroughProvider extends FileSystemProvider {
-        private static final String SCHEME = "pass";
-        private static volatile PassThroughFileSystem delegate;
-
-        public PassThroughProvider() { }
-
-        @Override
-        public String getScheme() {
-            return SCHEME;
-        }
-
-        private void checkScheme(URI uri) {
-            if (!uri.getScheme().equalsIgnoreCase(SCHEME))
-                throw new IllegalArgumentException();
-        }
-
-        private void checkUri(URI uri) {
-            checkScheme(uri);
-            if (!uri.getSchemeSpecificPart().equals("///"))
-                throw new IllegalArgumentException();
-        }
-
-        @Override
-        public FileSystem newFileSystem(URI uri, Map<String,?> env)
-            throws IOException
-        {
-            checkUri(uri);
-            synchronized (PassThroughProvider.class) {
-                if (delegate != null)
-                    throw new FileSystemAlreadyExistsException();
-                PassThroughFileSystem result =
-                    new PassThroughFileSystem(this, FileSystems.getDefault());
-                delegate = result;
-                return result;
-            }
-        }
-
-        @Override
-        public FileSystem getFileSystem(URI uri) {
-            checkUri(uri);
-            FileSystem result = delegate;
-            if (result == null)
-                throw new FileSystemNotFoundException();
-            return result;
-        }
-
-        @Override
-        public Path getPath(URI uri) {
-            checkScheme(uri);
-            if (delegate == null)
-                throw new FileSystemNotFoundException();
-            uri = URI.create(delegate.provider().getScheme() + ":" +
-                             uri.getSchemeSpecificPart());
-            return new PassThroughPath(delegate, delegate.provider().getPath(uri));
-        }
-    }
-
-    static class PassThroughPath extends Path {
-        private final FileSystem fs;
-        private final Path delegate;
-
-        PassThroughPath(FileSystem fs, Path delegate) {
-            this.fs = fs;
-            this.delegate = delegate;
-        }
-
-        private Path wrap(Path path) {
-            return (path != null) ? new PassThroughPath(fs, path) : null;
-        }
-
-        static Path unwrap(Path wrapper) {
-            if (!(wrapper instanceof PassThroughPath))
-                throw new ProviderMismatchException();
-            return ((PassThroughPath)wrapper).delegate;
-        }
-
-        @Override
-        public FileSystem getFileSystem() {
-            return fs;
-        }
-
-        @Override
-        public boolean isAbsolute() {
-            return delegate.isAbsolute();
-        }
-
-        @Override
-        public Path getRoot() {
-            return wrap(delegate.getRoot());
-        }
-
-
-        @Override
-        public Path getName() {
-            return wrap(delegate.getName());
-        }
-
-        @Override
-        public Path getParent() {
-            return wrap(delegate.getParent());
-        }
-
-        @Override
-        public int getNameCount() {
-            return delegate.getNameCount();
-        }
-
-        @Override
-        public Path getName(int index) {
-            return wrap(delegate.getName(index));
-        }
-
-        @Override
-        public Path subpath(int beginIndex, int endIndex) {
-            return wrap(delegate.subpath(beginIndex, endIndex));
-        }
-
-        @Override
-        public boolean startsWith(Path other) {
-            return delegate.startsWith(unwrap(other));
-        }
-
-        @Override
-        public boolean endsWith(Path other) {
-            return delegate.endsWith(unwrap(other));
-        }
-
-        @Override
-        public Path normalize() {
-            return wrap(delegate.normalize());
-        }
-
-        @Override
-        public Path resolve(Path other) {
-            return wrap(delegate.resolve(unwrap(other)));
-        }
-
-        @Override
-        public Path resolve(String other) {
-            return wrap(delegate.resolve(other));
-        }
-
-        @Override
-        public Path relativize(Path other) {
-            return wrap(delegate.relativize(unwrap(other)));
-        }
-
-        @Override
-        public void setAttribute(String attribute, Object value, LinkOption... options)
-            throws IOException
-        {
-            delegate.setAttribute(attribute, value, options);
-        }
-
-        @Override
-        public Object getAttribute(String attribute, LinkOption... options)
-            throws IOException
-        {
-            // assume that unwrapped objects aren't exposed
-            return delegate.getAttribute(attribute, options);
-        }
-
-        @Override
-        public Map<String,?> readAttributes(String attributes, LinkOption... options)
-            throws IOException
-        {
-            // assume that unwrapped objects aren't exposed
-            return delegate.readAttributes(attributes, options);
-        }
-
-        @Override
-        public <V extends FileAttributeView> V getFileAttributeView(Class<V> type,
-                                                                    LinkOption... options)
-        {
-            return delegate.getFileAttributeView(type, options);
-        }
-
-        @Override
-        public void delete() throws IOException {
-            delegate.delete();
-        }
-
-        @Override
-        public void deleteIfExists() throws IOException {
-            delegate.deleteIfExists();
-        }
-
-        @Override
-        public Path createSymbolicLink(Path target, FileAttribute<?>... attrs)
-            throws IOException
-        {
-            delegate.createSymbolicLink(unwrap(target), attrs);
-            return this;
-        }
-
-        @Override
-        public Path createLink(Path existing) throws IOException {
-            delegate.createLink(unwrap(existing));
-            return this;
-        }
-
-        @Override
-        public Path readSymbolicLink() throws IOException {
-            return wrap(delegate.readSymbolicLink());
-        }
-
-        @Override
-        public URI toUri() {
-            String ssp = delegate.toUri().getSchemeSpecificPart();
-            return URI.create(fs.provider().getScheme() + ":" + ssp);
-        }
-
-        @Override
-        public Path toAbsolutePath() {
-            return wrap(delegate.toAbsolutePath());
-        }
-
-        @Override
-        public Path toRealPath(boolean resolveLinks) throws IOException {
-            return wrap(delegate.toRealPath(resolveLinks));
-        }
-
-        @Override
-        public Path copyTo(Path target, CopyOption... options) throws IOException {
-            return wrap(delegate.copyTo(unwrap(target), options));
-        }
-
-        @Override
-        public Path moveTo(Path target, CopyOption... options) throws IOException {
-            return wrap(delegate.copyTo(unwrap(target), options));
-        }
-
-        private DirectoryStream<Path> wrap(final DirectoryStream<Path> stream) {
-            return new DirectoryStream<Path>() {
-                @Override
-                public Iterator<Path> iterator() {
-                    final Iterator<Path> itr = stream.iterator();
-                    return new Iterator<Path>() {
-                        @Override
-                        public boolean hasNext() {
-                            return itr.hasNext();
-                        }
-                        @Override
-                        public Path next() {
-                            return wrap(itr.next());
-                        }
-                        @Override
-                        public void remove() {
-                            itr.remove();
-                        }
-                    };
-                }
-                @Override
-                public void close() throws IOException {
-                    stream.close();
-                }
-            };
-        }
-
-        @Override
-        public DirectoryStream<Path> newDirectoryStream() throws IOException {
-            return wrap(delegate.newDirectoryStream());
-        }
-
-        @Override
-        public DirectoryStream<Path> newDirectoryStream(String glob)
-            throws IOException
-        {
-            return wrap(delegate.newDirectoryStream(glob));
-        }
-
-        @Override
-        public DirectoryStream<Path> newDirectoryStream(DirectoryStream.Filter<? super Path> filter)
-            throws IOException
-        {
-            return wrap(delegate.newDirectoryStream(filter));
-        }
-
-        @Override
-        public Path createFile(FileAttribute<?>... attrs) throws IOException {
-            delegate.createFile(attrs);
-            return this;
-        }
-
-        @Override
-        public Path createDirectory(FileAttribute<?>... attrs)
-            throws IOException
-        {
-            delegate.createDirectory(attrs);
-            return this;
-        }
-
-        @Override
-        public SeekableByteChannel newByteChannel(Set<? extends OpenOption> options,
-                                                       FileAttribute<?>... attrs)
-            throws IOException
-        {
-            return delegate.newByteChannel(options, attrs);
-        }
-
-        @Override
-        public SeekableByteChannel newByteChannel(OpenOption... options)
-            throws IOException
-        {
-            return delegate.newByteChannel(options);
-        }
-
-        @Override
-        public InputStream newInputStream(OpenOption... options) throws IOException {
-            return delegate.newInputStream();
-        }
-
-        @Override
-        public OutputStream newOutputStream(OpenOption... options)
-            throws IOException
-        {
-            return delegate.newOutputStream(options);
-        }
-
-        @Override
-        public boolean isHidden() throws IOException {
-            return delegate.isHidden();
-        }
-
-        @Override
-        public void checkAccess(AccessMode... modes) throws IOException {
-            delegate.checkAccess(modes);
-        }
-
-        @Override
-        public boolean exists() {
-            return delegate.exists();
-        }
-
-        @Override
-        public boolean notExists() {
-            return delegate.notExists();
-        }
-
-        @Override
-        public FileStore getFileStore() throws IOException {
-            return delegate.getFileStore();
-        }
-
-        @Override
-        public WatchKey register(WatchService watcher,
-                                      WatchEvent.Kind<?>[] events,
-                                      WatchEvent.Modifier... modifiers)
-        {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public  WatchKey register(WatchService watcher,
-                                      WatchEvent.Kind<?>... events)
-        {
-            throw new UnsupportedOperationException();
-        }
-
-
-        @Override
-        public Iterator<Path> iterator() {
-            final Iterator<Path> itr = delegate.iterator();
-            return new Iterator<Path>() {
-                @Override
-                public boolean hasNext() {
-                    return itr.hasNext();
-                }
-                @Override
-                public Path next() {
-                    return wrap(itr.next());
-                }
-                @Override
-                public void remove() {
-                    itr.remove();
-                }
-            };
-        }
-
-        @Override
-        public int compareTo(Path other) {
-            return delegate.compareTo(unwrap(other));
-        }
-
-        @Override
-        public boolean isSameFile(Path other) throws IOException {
-            return delegate.isSameFile(unwrap(other));
-        }
-
-
-        @Override
-        public boolean equals(Object other) {
-            if (!(other instanceof PassThroughPath))
-                return false;
-            return delegate.equals(unwrap((PassThroughPath)other));
-        }
-
-        @Override
-        public int hashCode() {
-            return delegate.hashCode();
-        }
-
-        @Override
-        public String toString() {
-            return delegate.toString();
-        }
-    }
-}
--- a/jdk/test/java/nio/file/Path/PathOps.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/test/java/nio/file/Path/PathOps.java	Fri Jan 28 09:28:43 2011 +0000
@@ -22,7 +22,7 @@
  */
 
 /* @test
- * @bug 4313887 6838333 6925932
+ * @bug 4313887 6838333 6925932 7006126
  * @summary Unit test for java.nio.file.Path path operations
  */
 
@@ -36,15 +36,15 @@
     private Path path;
     private Exception exc;
 
-    private PathOps(String s) {
+    private PathOps(String first, String... more) {
         out.println();
-        input = s;
+        input = first;
         try {
-            path = FileSystems.getDefault().getPath(s);
-            out.format("%s -> %s", s, path);
+            path = FileSystems.getDefault().getPath(first, more);
+            out.format("%s -> %s", first, path);
         } catch (Exception x) {
             exc = x;
-            out.format("%s -> %s", s, x);
+            out.format("%s -> %s", first, x);
         }
         out.println();
     }
@@ -97,7 +97,7 @@
     PathOps name(String expected) {
         out.println("check name");
         checkPath();
-        check(path.getName(), expected);
+        check(path.getFileName(), expected);
         return this;
     }
 
@@ -168,6 +168,13 @@
         return this;
     }
 
+    PathOps resolveSibling(String other, String expected) {
+        out.format("test resolveSibling %s\n", other);
+        checkPath();
+        check(path.resolveSibling(other), expected);
+        return this;
+    }
+
     PathOps relativize(String other, String expected) {
         out.format("test relativize %s\n", other);
         checkPath();
@@ -198,8 +205,8 @@
         return this;
     }
 
-    static PathOps test(String s) {
-        return new PathOps(s);
+    static PathOps test(String first, String... more) {
+        return new PathOps(first, more);
     }
 
     // -- PathOpss --
@@ -213,6 +220,26 @@
     static void doWindowsTests() {
         header("Windows specific tests");
 
+        // construction
+        test("C:\\")
+            .string("C:\\");
+        test("C:\\", "")
+            .string("C:\\");
+        test("C:\\", "foo")
+            .string("C:\\foo");
+        test("C:\\", "\\foo")
+            .string("C:\\foo");
+        test("C:\\", "foo\\")
+            .string("C:\\foo");
+        test("foo", "bar", "gus")
+            .string("foo\\bar\\gus");
+        test("")
+            .string("");
+        test("", "C:\\")
+            .string("C:\\");
+        test("", "foo", "", "bar", "", "\\gus")
+            .string("foo\\bar\\gus");
+
         // all components present
         test("C:\\a\\b\\c")
             .root("C:\\")
@@ -252,17 +279,23 @@
             .root(null)
             .parent(null)
             .name("foo");
+        test("")
+            .root(null)
+            .parent(null)
+            .name("");
 
         // startsWith
         test("C:\\")
             .starts("C:\\")
             .starts("c:\\")
             .notStarts("C")
-            .notStarts("C:");
+            .notStarts("C:")
+            .notStarts("");
         test("C:")
             .starts("C:")
             .starts("c:")
-            .notStarts("C");
+            .notStarts("C")
+            .notStarts("");
         test("\\")
             .starts("\\");
         test("C:\\foo\\bar")
@@ -273,7 +306,8 @@
             .starts("C:\\Foo\\Bar")
             .notStarts("C:")
             .notStarts("C")
-            .notStarts("C:foo");
+            .notStarts("C:foo")
+            .notStarts("");
         test("\\foo\\bar")
             .starts("\\")
             .starts("\\foo")
@@ -281,26 +315,35 @@
             .starts("\\foo\\bar")
             .starts("\\fOo\\BaR")
             .notStarts("foo")
-            .notStarts("foo\\bar");
+            .notStarts("foo\\bar")
+            .notStarts("");
         test("foo\\bar")
             .starts("foo")
             .starts("foo\\bar")
-            .notStarts("\\");
+            .notStarts("\\")
+            .notStarts("");
         test("\\\\server\\share")
             .starts("\\\\server\\share")
             .starts("\\\\server\\share\\")
+            .notStarts("\\")
+            .notStarts("");
+        test("")
+            .starts("")
             .notStarts("\\");
 
         // endsWith
         test("C:\\")
             .ends("C:\\")
             .ends("c:\\")
-            .notEnds("\\");
+            .notEnds("\\")
+            .notEnds("");
         test("C:")
             .ends("C:")
-            .ends("c:");
+            .ends("c:")
+            .notEnds("");
         test("\\")
-            .ends("\\");
+            .ends("\\")
+            .notEnds("");
         test("C:\\foo\\bar")
             .ends("bar")
             .ends("BAR")
@@ -309,7 +352,8 @@
             .ends("C:\\foo\\bar")
             .ends("c:\\foO\\baR")
             .notEnds("r")
-            .notEnds("\\foo\\bar");
+            .notEnds("\\foo\\bar")
+            .notEnds("");
         test("\\foo\\bar")
             .ends("bar")
             .ends("BaR")
@@ -317,17 +361,23 @@
             .ends("foO\\baR")
             .ends("\\foo\\bar")
             .ends("\\Foo\\Bar")
-            .notEnds("oo\\bar");
+            .notEnds("oo\\bar")
+            .notEnds("");
         test("foo\\bar")
             .ends("bar")
             .ends("BAR")
             .ends("foo\\bar")
             .ends("Foo\\Bar")
-            .notEnds("ar");
+            .notEnds("ar")
+            .notEnds("");
         test("\\\\server\\share")
             .ends("\\\\server\\share")
             .ends("\\\\server\\share\\")
             .notEnds("shared")
+            .notEnds("\\")
+            .notEnds("");
+        test("")
+            .ends("")
             .notEnds("\\");
 
         // elements
@@ -338,6 +388,8 @@
         test("foo.bar\\gus.alice")
             .element(0, "foo.bar")
             .element(1, "gus.alice");
+        test("")
+            .element(0, "");
 
         // subpath
         test("C:\\foo")
@@ -355,6 +407,8 @@
             .subpath(2, 3, "gus");
         test("\\\\server\\share\\foo")
             .subpath(0, 1, "foo");
+        test("")
+            .subpath(0, 1, "");
 
         // isAbsolute
         test("foo").notAbsolute();
@@ -362,6 +416,7 @@
         test("C:\\").absolute();
         test("C:\\abc").absolute();
         test("\\\\server\\share\\").absolute();
+        test("").notAbsolute();
 
         // resolve
         test("C:\\")
@@ -369,42 +424,99 @@
             .resolve("D:\\bar", "D:\\bar")
             .resolve("\\\\server\\share\\bar", "\\\\server\\share\\bar")
             .resolve("C:foo", "C:\\foo")
-            .resolve("D:foo", "D:foo");
+            .resolve("D:foo", "D:foo")
+            .resolve("", "C:\\");
         test("\\")
             .resolve("foo", "\\foo")
             .resolve("D:bar", "D:bar")
             .resolve("C:\\bar", "C:\\bar")
             .resolve("\\\\server\\share\\bar", "\\\\server\\share\\bar")
-            .resolve("\\foo", "\\foo");
+            .resolve("\\foo", "\\foo")
+            .resolve("", "\\");
         test("\\foo")
             .resolve("bar", "\\foo\\bar")
             .resolve("D:bar", "D:bar")
             .resolve("C:\\bar", "C:\\bar")
             .resolve("\\\\server\\share\\bar", "\\\\server\\share\\bar")
-            .resolve("\\bar", "\\bar");
+            .resolve("\\bar", "\\bar")
+            .resolve("", "\\foo");
         test("foo")
             .resolve("bar", "foo\\bar")
             .resolve("D:\\bar", "D:\\bar")
             .resolve("\\\\server\\share\\bar", "\\\\server\\share\\bar")
             .resolve("C:bar", "C:bar")
-            .resolve("D:foo", "D:foo");
+            .resolve("D:foo", "D:foo")
+            .resolve("", "foo");
         test("C:")
-            .resolve("foo", "C:foo");
+            .resolve("foo", "C:foo")
+            .resolve("", "C:");
         test("\\\\server\\share\\foo")
             .resolve("bar", "\\\\server\\share\\foo\\bar")
             .resolve("\\bar", "\\\\server\\share\\bar")
             .resolve("D:\\bar", "D:\\bar")
             .resolve("\\\\other\\share\\bar", "\\\\other\\share\\bar")
-            .resolve("D:bar", "D:bar");
+            .resolve("D:bar", "D:bar")
+            .resolve("", "\\\\server\\share\\foo");
+        test("")
+            .resolve("", "")
+            .resolve("foo", "foo")
+            .resolve("C:\\", "C:\\")
+            .resolve("C:foo", "C:foo")
+            .resolve("\\\\server\\share\\bar", "\\\\server\\share\\bar");
+
+        // resolveSibling
+        test("foo")
+            .resolveSibling("bar", "bar")
+            .resolveSibling("D:\\bar", "D:\\bar")
+            .resolveSibling("\\\\server\\share\\bar", "\\\\server\\share\\bar")
+            .resolveSibling("C:bar", "C:bar")
+            .resolveSibling("D:foo", "D:foo")
+            .resolveSibling("", "");
+        test("foo\\bar")
+            .resolveSibling("gus", "foo\\gus")
+            .resolveSibling("D:\\bar", "D:\\bar")
+            .resolveSibling("\\\\server\\share\\bar", "\\\\server\\share\\bar")
+            .resolveSibling("C:bar", "C:bar")
+            .resolveSibling("D:foo", "D:foo")
+            .resolveSibling("", "foo");
+        test("C:\\foo")
+            .resolveSibling("gus", "C:\\gus")
+            .resolveSibling("D:\\bar", "D:\\bar")
+            .resolveSibling("\\\\server\\share\\bar", "\\\\server\\share\\bar")
+            .resolveSibling("C:bar", "C:\\bar")
+            .resolveSibling("D:foo", "D:foo")
+            .resolveSibling("", "C:\\");
+        test("C:\\foo\\bar")
+            .resolveSibling("gus", "C:\\foo\\gus")
+            .resolveSibling("D:\\bar", "D:\\bar")
+            .resolveSibling("\\\\server\\share\\bar", "\\\\server\\share\\bar")
+            .resolveSibling("C:bar", "C:\\foo\\bar")
+            .resolveSibling("D:foo", "D:foo")
+            .resolveSibling("", "C:\\foo");
+        test("\\\\server\\share\\foo")
+            .resolveSibling("bar", "\\\\server\\share\\bar")
+            .resolveSibling("\\bar", "\\\\server\\share\\bar")
+            .resolveSibling("D:\\bar", "D:\\bar")
+            .resolveSibling("\\\\other\\share\\bar", "\\\\other\\share\\bar")
+            .resolveSibling("D:bar", "D:bar")
+            .resolveSibling("", "\\\\server\\share\\");
+        test("")
+            .resolveSibling("", "")
+            .resolveSibling("foo", "foo")
+            .resolveSibling("C:\\", "C:\\");
 
         // relativize
         test("foo\\bar")
-            .relativize("foo\\bar", null)
+            .relativize("foo\\bar", "")
             .relativize("foo", "..");
         test("C:\\a\\b\\c")
-            .relativize("C:\\a", "..\\..");
+            .relativize("C:\\a", "..\\..")
+            .relativize("C:\\a\\b\\c", "");
         test("\\\\server\\share\\foo")
-            .relativize("\\\\server\\share\\bar", "..\\bar");
+            .relativize("\\\\server\\share\\bar", "..\\bar")
+            .relativize("\\\\server\\share\\foo", "");
+        test("")
+            .relativize("", "");
 
         // normalize
         test("C:\\")
@@ -436,7 +548,7 @@
         test("foo\\.")
             .normalize("foo");
         test("foo\\..")
-            .normalize(null);
+            .normalize("");
         test("C:\\foo")
             .normalize("C:\\foo");
         test("C:\\foo\\.")
@@ -478,7 +590,7 @@
         test("\\..\\foo")
             .normalize("\\foo");
         test(".")
-            .normalize(null);
+            .normalize("");
         test("..")
             .normalize("..");
         test("\\..\\..")
@@ -493,6 +605,8 @@
             .normalize("foo");
         test(".\\foo\\.\\bar\\.\\gus\\..\\.\\..")
             .normalize("foo");
+        test("")
+            .normalize("");
 
         // UNC corner cases
         test("\\\\server\\share\\")
@@ -557,6 +671,26 @@
     static void doUnixTests() {
         header("Unix specific tests");
 
+        // construction
+        test("/")
+            .string("/");
+        test("/", "")
+            .string("/");
+        test("/", "foo")
+            .string("/foo");
+        test("/", "/foo")
+            .string("/foo");
+        test("/", "foo/")
+            .string("/foo");
+        test("foo", "bar", "gus")
+            .string("foo/bar/gus");
+        test("")
+            .string("");
+        test("", "/")
+            .string("/");
+        test("", "foo", "", "bar", "", "/gus")
+            .string("foo/bar/gus");
+
         // all components
         test("/a/b/c")
             .root("/")
@@ -580,10 +714,15 @@
             .root(null)
             .parent(null)
             .name("foo");
+        test("")
+             .root(null)
+             .parent(null)
+             .name("");
 
         // startsWith
         test("/")
             .starts("/")
+            .notStarts("")
             .notStarts("/foo");
         test("/foo")
             .starts("/")
@@ -598,6 +737,7 @@
             .notStarts("foo/bar");
         test("foo")
             .starts("foo")
+            .notStarts("")
             .notStarts("f");
         test("foo/bar")
             .starts("foo")
@@ -605,10 +745,14 @@
             .notStarts("f")
             .notStarts("/foo")
             .notStarts("/foo/bar");
+        test("")
+             .starts("")
+             .notStarts("/");
 
         // endsWith
         test("/")
             .ends("/")
+            .notEnds("")
             .notEnds("foo")
             .notEnds("/foo");
         test("/foo")
@@ -625,6 +769,7 @@
             .notEnds("o/bar");
         test("foo")
             .ends("foo")
+            .notEnds("")
             .notEnds("oo")
             .notEnds("oola");
         test("foo/bar")
@@ -642,12 +787,47 @@
             .notEnds("r/gus")
             .notEnds("barack/gus")
             .notEnds("bar/gust");
+        test("")
+            .ends("")
+            .notEnds("/");
 
         // elements
         test("a/b/c")
-            .element(0,"a")
-            .element(1,"b")
-            .element(2,"c");
+            .element(0, "a")
+            .element(1, "b")
+            .element(2, "c");
+        test("")
+            .element(0, "");
+
+        // subpath
+        test("/foo")
+            .subpath(0, 1, "foo");
+        test("foo")
+            .subpath(0, 1, "foo");
+        test("/foo/bar")
+            .subpath(0, 1, "foo")
+            .subpath(1, 2, "bar")
+            .subpath(0, 2, "foo/bar");
+        test("foo/bar")
+            .subpath(0, 1, "foo")
+            .subpath(1, 2, "bar")
+            .subpath(0, 2, "foo/bar");
+        test("/foo/bar/gus")
+            .subpath(0, 1, "foo")
+            .subpath(1, 2, "bar")
+            .subpath(2, 3, "gus")
+            .subpath(0, 2, "foo/bar")
+            .subpath(1, 3, "bar/gus")
+            .subpath(0, 3, "foo/bar/gus");
+        test("foo/bar/gus")
+            .subpath(0, 1, "foo")
+            .subpath(1, 2, "bar")
+            .subpath(2, 3, "gus")
+            .subpath(0, 2, "foo/bar")
+            .subpath(1, 3, "bar/gus")
+            .subpath(0, 3, "foo/bar/gus");
+        test("")
+            .subpath(0, 1, "");
 
         // isAbsolute
         test("/")
@@ -656,20 +836,61 @@
             .absolute();
         test("tmp")
             .notAbsolute();
+        test("")
+            .notAbsolute();
+
 
         // resolve
         test("/tmp")
             .resolve("foo", "/tmp/foo")
-            .resolve("/foo", "/foo");
+            .resolve("/foo", "/foo")
+            .resolve("", "/tmp");
         test("tmp")
             .resolve("foo", "tmp/foo")
+            .resolve("/foo", "/foo")
+            .resolve("", "tmp");
+        test("")
+            .resolve("", "")
+            .resolve("foo", "foo")
             .resolve("/foo", "/foo");
 
+        // resolveSibling
+        test("foo")
+            .resolveSibling("bar", "bar")
+            .resolveSibling("/bar", "/bar")
+            .resolveSibling("", "");
+        test("foo/bar")
+            .resolveSibling("gus", "foo/gus")
+            .resolveSibling("/gus", "/gus")
+            .resolveSibling("", "foo");
+        test("/foo")
+            .resolveSibling("gus", "/gus")
+            .resolveSibling("/gus", "/gus")
+            .resolveSibling("", "/");
+        test("/foo/bar")
+            .resolveSibling("gus", "/foo/gus")
+            .resolveSibling("/gus", "/gus")
+            .resolveSibling("", "/foo");
+        test("")
+            .resolveSibling("foo", "foo")
+            .resolveSibling("/foo", "/foo")
+            .resolve("", "");
+
         // relativize
         test("/a/b/c")
-            .relativize("/a/b/c", null)
+            .relativize("/a/b/c", "")
             .relativize("/a/b/c/d/e", "d/e")
-            .relativize("/a/x", "../../x");
+            .relativize("/a/x", "../../x")
+            .relativize("/x", "../../../x");
+        test("a/b/c")
+            .relativize("a/b/c/d", "d")
+            .relativize("a/x", "../../x")
+            .relativize("x", "../../../x")
+            .relativize("", "../../..");
+        test("")
+            .relativize("a", "a")
+            .relativize("a/b/c", "a/b/c")
+            .relativize("", "");
 
         // normalize
         test("/")
@@ -679,7 +900,7 @@
         test("/foo")
             .normalize("/foo");
         test(".")
-            .normalize(null);
+            .normalize("");
         test("..")
             .normalize("..");
         test("/..")
@@ -691,7 +912,7 @@
         test("./foo")
             .normalize("foo");
         test("foo/..")
-            .normalize(null);
+            .normalize("");
         test("../foo")
             .normalize("../foo");
         test("../../foo")
@@ -717,7 +938,7 @@
         test("//bar\u0000")
             .invalid();
 
-        // normalization
+        // normalization of input
         test("//foo//bar")
             .string("/foo/bar")
             .root("/")
@@ -749,13 +970,13 @@
         }
 
         try {
-            path.startsWith(null);
+            path.startsWith((Path)null);
             throw new RuntimeException("NullPointerException not thrown");
         } catch (NullPointerException npe) {
         }
 
         try {
-            path.endsWith(null);
+            path.endsWith((Path)null);
             throw new RuntimeException("NullPointerException not thrown");
         } catch (NullPointerException npe) {
         }
--- a/jdk/test/java/nio/file/Path/SBC.java	Thu Jan 13 22:21:58 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,468 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/* @test
- * @bug 4313887
- * @summary Unit test for java.nio.file.Path.newByteChannel
- * @library ..
- */
-
-import java.nio.ByteBuffer;
-import java.nio.file.*;
-import static java.nio.file.StandardOpenOption.*;
-import static com.sun.nio.file.ExtendedOpenOption.*;
-import java.nio.file.attribute.FileAttribute;
-import java.nio.channels.*;
-import java.io.IOException;
-import java.util.*;
-
-public class SBC {
-
-    static boolean supportsLinks;
-
-    public static void main(String[] args) throws Exception {
-        Path dir = TestUtil.createTemporaryDirectory();
-        try {
-            supportsLinks = TestUtil.supportsLinks(dir);
-
-            // open options
-            createTests(dir);
-            appendTests(dir);
-            truncateExistingTests(dir);
-            noFollowLinksTests(dir);
-
-            // SeekableByteChannel methods
-            sizeTruncatePositionTests(dir);
-
-            // platform specific
-            if (System.getProperty("os.name").startsWith("Windows"))
-                dosSharingOptionTests(dir);
-
-            // misc. tests
-            badCombinations(dir);
-            unsupportedOptions(dir);
-            nullTests(dir);
-
-        } finally {
-            TestUtil.removeAll(dir);
-        }
-    }
-
-    // test CREATE and CREATE_NEW options
-    static void createTests(Path dir) throws Exception {
-        Path file = dir.resolve("foo");
-
-        // CREATE
-        try {
-            // create file (no existing file)
-            file.newByteChannel(CREATE, WRITE).close();
-            if (file.notExists())
-                throw new RuntimeException("File not created");
-
-            // create file (existing file)
-            file.newByteChannel(CREATE, WRITE).close();
-
-            // create file where existing file is a sym link
-            if (supportsLinks) {
-                Path link = dir.resolve("link").createSymbolicLink(file);
-                try {
-                    // file already exists
-                    link.newByteChannel(CREATE, WRITE).close();
-
-                    // file does not exist
-                    file.delete();
-                    link.newByteChannel(CREATE, WRITE).close();
-                    if (file.notExists())
-                        throw new RuntimeException("File not created");
-
-                } finally {
-                    TestUtil.deleteUnchecked(link);
-                }
-            }
-
-        } finally {
-            TestUtil.deleteUnchecked(file);
-        }
-
-        // CREATE_NEW
-        try {
-            // create file
-            file.newByteChannel(CREATE_NEW, WRITE).close();
-            if (file.notExists())
-                throw new RuntimeException("File not created");
-
-            // create should fail
-            try {
-                SeekableByteChannel sbc =
-                    file.newByteChannel(CREATE_NEW, WRITE);
-                sbc.close();
-                throw new RuntimeException("FileAlreadyExistsException not thrown");
-            } catch (FileAlreadyExistsException x) { }
-
-            // create should fail
-            if (supportsLinks) {
-                Path link = dir.resolve("link");
-                Path target = dir.resolve("thisDoesNotExist");
-                link.createSymbolicLink(target);
-                try {
-
-                    try {
-                        SeekableByteChannel sbc =
-                            file.newByteChannel(CREATE_NEW, WRITE);
-                        sbc.close();
-                        throw new RuntimeException("FileAlreadyExistsException not thrown");
-                    } catch (FileAlreadyExistsException x) { }
-
-                } finally {
-                    TestUtil.deleteUnchecked(link);
-                }
-            }
-
-
-        } finally {
-            TestUtil.deleteUnchecked(file);
-        }
-
-        // CREATE_NEW + SPARSE
-        try {
-            SeekableByteChannel sbc = file
-                .newByteChannel(CREATE_NEW, WRITE, SPARSE);
-            try {
-                final long hole = 2L * 1024L * 1024L * 1024L;
-                sbc.position(hole);
-                write(sbc, "hello");
-                long size = sbc.size();
-                if (size != (hole + 5))
-                    throw new RuntimeException("Unexpected size");
-            } finally {
-                sbc.close();
-            }
-        } finally {
-            TestUtil.deleteUnchecked(file);
-        }
-    }
-
-    // test APPEND option
-    static void appendTests(Path dir) throws Exception {
-        Path file = dir.resolve("foo");
-        try {
-            // "hello there" should be written to file
-            SeekableByteChannel sbc = file
-                .newByteChannel(CREATE_NEW, WRITE, APPEND);
-            try {
-                write(sbc, "hello ");
-                sbc.position(0L);
-                write(sbc, "there");
-            } finally {
-                sbc.close();
-            }
-
-            // check file
-            Scanner s = new Scanner(file);
-            try {
-                String line = s.nextLine();
-                if (!line.equals("hello there"))
-                    throw new RuntimeException("Unexpected file contents");
-            } finally {
-                s.close();
-            }
-
-            // check that read is not allowed
-            sbc = file.newByteChannel(APPEND);
-            try {
-                sbc.read(ByteBuffer.allocate(100));
-            } catch (NonReadableChannelException x) {
-            } finally {
-                sbc.close();
-            }
-        } finally {
-            // clean-up
-            TestUtil.deleteUnchecked(file);
-        }
-    }
-
-    // test TRUNCATE_EXISTING option
-    static void truncateExistingTests(Path dir) throws Exception {
-        Path file = dir.resolve("foo");
-        try {
-            SeekableByteChannel sbc =
-                file.newByteChannel(CREATE_NEW, WRITE);
-            try {
-                write(sbc, "Have a nice day!");
-            } finally {
-                sbc.close();
-            }
-
-            // re-open with truncate option
-            // write short message and check
-            sbc = file.newByteChannel(WRITE, TRUNCATE_EXISTING);
-            try {
-                write(sbc, "Hello there!");
-            } finally {
-                sbc.close();
-            }
-            Scanner s = new Scanner(file);
-            try {
-                String line = s.nextLine();
-                if (!line.equals("Hello there!"))
-                    throw new RuntimeException("Unexpected file contents");
-            } finally {
-                s.close();
-            }
-
-            // re-open with create + truncate option
-            // check file is of size 0L
-            sbc = file.newByteChannel(WRITE, CREATE, TRUNCATE_EXISTING);
-            try {
-                long size = ((FileChannel)sbc).size();
-                if (size != 0L)
-                    throw new RuntimeException("File not truncated");
-            } finally {
-                sbc.close();
-            }
-
-        } finally {
-            // clean-up
-            TestUtil.deleteUnchecked(file);
-        }
-
-    }
-
-    // test NOFOLLOW_LINKS option
-    static void noFollowLinksTests(Path dir) throws Exception {
-        if (!supportsLinks)
-            return;
-        Path file = dir.resolve("foo").createFile();
-        try {
-            // ln -s foo link
-            Path link = dir.resolve("link").createSymbolicLink(file);
-
-            // open with NOFOLLOW_LINKS option
-            try {
-                link.newByteChannel(READ, LinkOption.NOFOLLOW_LINKS);
-                throw new RuntimeException();
-            } catch (IOException x) {
-            } finally {
-                TestUtil.deleteUnchecked(link);
-            }
-
-        } finally {
-            // clean-up
-            TestUtil.deleteUnchecked(file);
-        }
-    }
-
-    // test size/truncate/position methods
-    static void sizeTruncatePositionTests(Path dir) throws Exception {
-        Path file = dir.resolve("foo");
-        try {
-            SeekableByteChannel sbc = file
-                .newByteChannel(CREATE_NEW, READ, WRITE);
-            try {
-                if (sbc.size() != 0L)
-                    throw new RuntimeException("Unexpected size");
-
-                // check size
-                write(sbc, "hello");
-                if (sbc.size() != 5L)
-                    throw new RuntimeException("Unexpected size");
-
-                // truncate (size and position should change)
-                sbc.truncate(4L);
-                if (sbc.size() != 4L)
-                    throw new RuntimeException("Unexpected size");
-                if (sbc.position() != 4L)
-                    throw new RuntimeException("Unexpected position");
-
-                // truncate (position should not change)
-                sbc.position(2L).truncate(3L);
-                if (sbc.size() != 3L)
-                    throw new RuntimeException("Unexpected size");
-                if (sbc.position() != 2L)
-                    throw new RuntimeException("Unexpected position");
-            } finally {
-                sbc.close();
-            }
-        } finally {
-            TestUtil.deleteUnchecked(file);
-        }
-    }
-
-    // Windows specific options for the use by applications that really want
-    // to use legacy DOS sharing options
-    static void dosSharingOptionTests(Path dir) throws Exception {
-        Path file = dir.resolve("foo").createFile();
-        try {
-            SeekableByteChannel ch;
-
-            // no sharing
-            ch = file.newByteChannel(READ,
-                NOSHARE_READ, NOSHARE_WRITE, NOSHARE_DELETE);
-            try {
-                try {
-                    file.newByteChannel(READ);
-                    throw new RuntimeException("Sharing violation expected");
-                } catch (IOException ignore) { }
-                try {
-                    file.newByteChannel(WRITE);
-                    throw new RuntimeException("Sharing violation expected");
-                } catch (IOException ignore) { }
-                try {
-                    file.delete();
-                    throw new RuntimeException("Sharing violation expected");
-                } catch (IOException ignore) { }
-            } finally {
-                ch.close();
-            }
-
-            // read allowed
-            ch = file.newByteChannel(READ, NOSHARE_WRITE, NOSHARE_DELETE);
-            try {
-                file.newByteChannel(READ).close();
-                try {
-                    file.newByteChannel(WRITE);
-                    throw new RuntimeException("Sharing violation expected");
-                } catch (IOException ignore) { }
-                try {
-                    file.delete();
-                    throw new RuntimeException("Sharing violation expected");
-                } catch (IOException ignore) { }
-            } finally {
-                ch.close();
-            }
-
-            // write allowed
-            ch = file.newByteChannel(READ, NOSHARE_READ, NOSHARE_DELETE);
-            try {
-                try {
-                    file.newByteChannel(READ);
-                    throw new RuntimeException("Sharing violation expected");
-                } catch (IOException ignore) { }
-                file.newByteChannel(WRITE).close();
-                try {
-                    file.delete();
-                    throw new RuntimeException("Sharing violation expected");
-                } catch (IOException ignore) { }
-            } finally {
-                ch.close();
-            }
-
-            // delete allowed
-            ch = file.newByteChannel(READ, NOSHARE_READ, NOSHARE_WRITE);
-            try {
-                try {
-                    file.newByteChannel(READ);
-                    throw new RuntimeException("Sharing violation expected");
-                } catch (IOException ignore) { }
-                try {
-                    file.newByteChannel(WRITE);
-                    throw new RuntimeException("Sharing violation expected");
-                } catch (IOException ignore) { }
-                file.delete();
-            } finally {
-                ch.close();
-            }
-
-        } finally {
-            TestUtil.deleteUnchecked(file);
-        }
-    }
-
-    // invalid combinations of options
-    static void badCombinations(Path dir) throws Exception {
-        Path file = dir.resolve("bad");
-
-        try {
-            file.newByteChannel(READ, APPEND);
-            throw new RuntimeException("IllegalArgumentException expected");
-        } catch (IllegalArgumentException x) { }
-
-        try {
-            file.newByteChannel(WRITE, APPEND, TRUNCATE_EXISTING);
-            throw new RuntimeException("IllegalArgumentException expected");
-        } catch (IllegalArgumentException x) { }
-    }
-
-    // unsupported operations
-    static void unsupportedOptions(Path dir) throws Exception {
-        Path file = dir.resolve("bad");
-
-        OpenOption badOption = new OpenOption() { };
-        try {
-            file.newByteChannel(badOption);
-            throw new RuntimeException("UnsupportedOperationException expected");
-        } catch (UnsupportedOperationException e) { }
-        try {
-            file.newByteChannel(READ, WRITE, badOption);
-            throw new RuntimeException("UnsupportedOperationException expected");
-        } catch (UnsupportedOperationException e) { }
-    }
-
-    // null handling
-    static void nullTests(Path dir) throws Exception {
-        Path file = dir.resolve("foo");
-
-        try {
-            file.newByteChannel((OpenOption[])null);
-            throw new RuntimeException("NullPointerException expected");
-        } catch (NullPointerException x) { }
-
-        try {
-            OpenOption[] opts = { READ, null };
-            file.newByteChannel(opts);
-            throw new RuntimeException("NullPointerException expected");
-        } catch (NullPointerException x) { }
-
-        try {
-            file.newByteChannel((Set<OpenOption>)null);
-            throw new RuntimeException("NullPointerException expected");
-        } catch (NullPointerException x) { }
-
-        try {
-            Set<OpenOption> opts = new HashSet<OpenOption>();
-            opts.add(READ);
-            opts.add(null);
-            file.newByteChannel(opts);
-            throw new RuntimeException("NullPointerException expected");
-        } catch (NullPointerException x) { }
-
-        try {
-            EnumSet<StandardOpenOption> opts = EnumSet.of(READ);
-            file.newByteChannel(opts, (FileAttribute[])null);
-            throw new RuntimeException("NullPointerException expected");
-        } catch (NullPointerException x) { }
-
-        try {
-            EnumSet<StandardOpenOption> opts = EnumSet.of(READ);
-            FileAttribute[] attrs = { null };
-            file.newByteChannel(opts, attrs);
-            throw new RuntimeException("NullPointerException expected");
-        } catch (NullPointerException x) { }
-    }
-
-    static void write(WritableByteChannel wbc, String msg) throws IOException {
-        ByteBuffer buf = ByteBuffer.wrap(msg.getBytes());
-        while (buf.hasRemaining())
-            wbc.write(buf);
-    }
-}
--- a/jdk/test/java/nio/file/Path/TemporaryFiles.java	Thu Jan 13 22:21:58 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/* @test
- * @bug 4313887 6838333
- * @summary Unit test for File.createTemporaryXXX (to be be moved to test/java/io/File)
- * @library ..
- */
-
-import java.nio.file.*;
-import static java.nio.file.StandardOpenOption.*;
-import java.nio.file.attribute.*;
-import java.io.File;
-import java.io.IOException;
-import java.util.Set;
-
-public class TemporaryFiles {
-
-    static void checkInTempDirectory(Path file) {
-        Path tmpdir = Paths.get(System.getProperty("java.io.tmpdir"));
-        if (!file.getParent().equals(tmpdir))
-            throw new RuntimeException("Not in temporary directory");
-    }
-
-    static void checkFile(Path file) throws IOException {
-        // check file is in temporary directory
-        checkInTempDirectory(file);
-
-        // check that file can be opened for reading and writing
-        file.newByteChannel(READ).close();
-        file.newByteChannel(WRITE).close();
-        file.newByteChannel(READ,WRITE).close();
-
-        // check file permissions are 0600 or more secure
-        if (file.getFileStore().supportsFileAttributeView("posix")) {
-            Set<PosixFilePermission> perms = Attributes
-                .readPosixFileAttributes(file).permissions();
-            perms.remove(PosixFilePermission.OWNER_READ);
-            perms.remove(PosixFilePermission.OWNER_WRITE);
-            if (!perms.isEmpty())
-                throw new RuntimeException("Temporary file is not secure");
-        }
-    }
-
-    static void checkDirectory(Path dir) throws IOException {
-        // check directory is in temporary directory
-        checkInTempDirectory(dir);
-
-        // check directory is empty
-        DirectoryStream<Path> stream = dir.newDirectoryStream();
-        try {
-            if (stream.iterator().hasNext())
-                throw new RuntimeException("Tempory directory not empty");
-        } finally {
-            stream.close();
-        }
-
-        // check file permissions are 0700 or more secure
-        if (dir.getFileStore().supportsFileAttributeView("posix")) {
-            Set<PosixFilePermission> perms = Attributes
-                .readPosixFileAttributes(dir).permissions();
-            perms.remove(PosixFilePermission.OWNER_READ);
-            perms.remove(PosixFilePermission.OWNER_WRITE);
-            perms.remove(PosixFilePermission.OWNER_EXECUTE);
-            if (!perms.isEmpty())
-                throw new RuntimeException("Temporary directory is not secure");
-        }
-    }
-
-    public static void main(String[] args) throws IOException {
-        Path file = File.createTemporaryFile("blah", null).toPath();
-        try {
-            checkFile(file);
-        } finally {
-            TestUtil.deleteUnchecked(file);
-        }
-    }
-}
--- a/jdk/test/java/nio/file/Path/delete_on_close.sh	Thu Jan 13 22:21:58 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-#
-# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-# @test
-# @bug 4313887
-# @summary Unit test for DELETE_ON_CLOSE open option
-# @library ..
-# @build DeleteOnClose
-# @run shell delete_on_close.sh
-
-# if TESTJAVA isn't set then we assume an interactive run.
-
-if [ -z "$TESTJAVA" ]; then
-    TESTSRC=.
-    TESTCLASSES=.
-    JAVA=java
-else
-    JAVA="${TESTJAVA}/bin/java"
-fi
-
-OS=`uname -s`
-case "$OS" in
-    Windows_* | CYGWIN* )
-        CLASSPATH="${TESTCLASSES};${TESTSRC}"
-        ;;
-    * )
-        CLASSPATH=${TESTCLASSES}:${TESTSRC}
-        ;;
-esac
-export CLASSPATH
-
-TMPFILE="$$.tmp"
-touch $TMPFILE
-$JAVA DeleteOnClose $TMPFILE 2>&1
-if [ $? != 0 ]; then exit 1; fi
-if [ -f $TMPFILE ]; then
-    echo "$TMPFILE was not deleted"
-    exit 1
-fi
-
-exit 0
--- a/jdk/test/java/nio/file/TestUtil.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/test/java/nio/file/TestUtil.java	Fri Jan 28 09:28:43 2011 +0000
@@ -31,17 +31,12 @@
     }
 
     static Path createTemporaryDirectory(String where) throws IOException {
-        Path top = FileSystems.getDefault().getPath(where);
-        Random r = new Random();
-        Path dir;
-        do {
-            dir = top.resolve("name" + r.nextInt());
-        } while (dir.exists());
-        return dir.createDirectory();
+        Path dir = FileSystems.getDefault().getPath(where);
+        return Files.createTempDirectory(dir, "name");
     }
 
     static Path createTemporaryDirectory() throws IOException {
-        return createTemporaryDirectory(System.getProperty("java.io.tmpdir"));
+        return Files.createTempDirectory("name");
     }
 
     static void removeAll(Path dir) throws IOException {
@@ -53,7 +48,7 @@
             @Override
             public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
                 try {
-                    file.delete();
+                    Files.delete(file);
                 } catch (IOException x) {
                     System.err.format("Unable to delete %s: %s\n", file, x);
                 }
@@ -62,7 +57,7 @@
             @Override
             public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
                 try {
-                    dir.delete();
+                    Files.delete(dir);
                 } catch (IOException x) {
                     System.err.format("Unable to delete %s: %s\n", dir, x);
                 }
@@ -78,7 +73,7 @@
 
     static void deleteUnchecked(Path file) {
         try {
-            file.delete();
+            Files.delete(file);
         } catch (IOException exc) {
             System.err.format("Unable to delete %s: %s\n", file, exc);
         }
@@ -99,7 +94,7 @@
         String name = sb.toString();
         do {
             dir = dir.resolve(name).resolve(".");
-            dir.createDirectory();
+            Files.createDirectory(dir);
         } while (dir.toString().length() < 2048);
         return dir;
     }
@@ -111,8 +106,8 @@
         Path link = dir.resolve("testlink");
         Path target = dir.resolve("testtarget");
         try {
-            link.createSymbolicLink(target);
-            link.delete();
+            Files.createSymbolicLink(link, target);
+            Files.delete(link);
             return true;
         } catch (UnsupportedOperationException x) {
             return false;
--- a/jdk/test/java/nio/file/WatchService/Basic.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/test/java/nio/file/WatchService/Basic.java	Fri Jan 28 09:28:43 2011 +0000
@@ -41,8 +41,9 @@
 
 public class Basic {
 
-    static void createFile(Path file) throws IOException {
-        file.newOutputStream().close();
+    static void checkKey(WatchKey key, Path dir) {
+        if (!key.isValid())
+            throw new RuntimeException("Key is not valid");
     }
 
     static void takeExpectedKey(WatchService watcher, WatchKey expected) {
@@ -80,19 +81,19 @@
         FileSystem fs = FileSystems.getDefault();
         Path name = fs.getPath("foo");
 
-        WatchService watcher = fs.newWatchService();
-        try {
+        try (WatchService watcher = fs.newWatchService()) {
             // --- ENTRY_CREATE ---
 
             // register for event
             System.out.format("register %s for ENTRY_CREATE\n", dir);
             WatchKey myKey = dir.register(watcher,
                 new WatchEvent.Kind<?>[]{ ENTRY_CREATE });
+            checkKey(myKey, dir);
 
             // create file
             Path file = dir.resolve("foo");
             System.out.format("create %s\n", file);
-            createFile(file);
+            Files.createFile(file);
 
             // remove key and check that we got the ENTRY_CREATE event
             takeExpectedKey(watcher, myKey);
@@ -112,9 +113,10 @@
                 new WatchEvent.Kind<?>[]{ ENTRY_DELETE });
             if (deleteKey != myKey)
                 throw new RuntimeException("register did not return existing key");
+            checkKey(deleteKey, dir);
 
             System.out.format("delete %s\n", file);
-            file.delete();
+            Files.delete(file);
             takeExpectedKey(watcher, myKey);
             checkExpectedEvent(myKey.pollEvents(),
                 StandardWatchEventKind.ENTRY_DELETE, name);
@@ -126,7 +128,7 @@
             System.out.println("OKAY");
 
             // create the file for the next test
-            createFile(file);
+            Files.createFile(file);
 
             // --- ENTRY_MODIFY ---
 
@@ -135,13 +137,11 @@
                 new WatchEvent.Kind<?>[]{ ENTRY_MODIFY });
             if (newKey != myKey)
                 throw new RuntimeException("register did not return existing key");
+            checkKey(newKey, dir);
 
             System.out.format("update: %s\n", file);
-            OutputStream out = file.newOutputStream(StandardOpenOption.APPEND);
-            try {
+            try (OutputStream out = Files.newOutputStream(file, StandardOpenOption.APPEND)) {
                 out.write("I am a small file".getBytes("UTF-8"));
-            } finally {
-                out.close();
             }
 
             // remove key and check that we got the ENTRY_MODIFY event
@@ -151,10 +151,7 @@
             System.out.println("OKAY");
 
             // done
-            file.delete();
-
-        } finally {
-            watcher.close();
+            Files.delete(file);
         }
     }
 
@@ -164,12 +161,12 @@
     static void testCancel(Path dir) throws IOException {
         System.out.println("-- Cancel --");
 
-        WatchService watcher = FileSystems.getDefault().newWatchService();
-        try {
+        try (WatchService watcher = FileSystems.getDefault().newWatchService()) {
 
             System.out.format("register %s for events\n", dir);
             WatchKey myKey = dir.register(watcher,
                 new WatchEvent.Kind<?>[]{ ENTRY_CREATE });
+            checkKey(myKey, dir);
 
             System.out.println("cancel key");
             myKey.cancel();
@@ -177,7 +174,7 @@
             // create a file in the directory
             Path file = dir.resolve("mars");
             System.out.format("create: %s\n", file);
-            createFile(file);
+            Files.createFile(file);
 
             // poll for keys - there will be none
             System.out.println("poll...");
@@ -190,12 +187,9 @@
             }
 
             // done
-            file.delete();
+            Files.delete(file);
 
             System.out.println("OKAY");
-
-        } finally {
-            watcher.close();
         }
     }
 
@@ -206,17 +200,16 @@
     static void testAutomaticCancel(Path dir) throws IOException {
         System.out.println("-- Automatic Cancel --");
 
-        Path subdir = dir.resolve("bar").createDirectory();
+        Path subdir = Files.createDirectory(dir.resolve("bar"));
 
-        WatchService watcher = FileSystems.getDefault().newWatchService();
-        try {
+        try (WatchService watcher = FileSystems.getDefault().newWatchService()) {
 
             System.out.format("register %s for events\n", subdir);
             WatchKey myKey = subdir.register(watcher,
                 new WatchEvent.Kind<?>[]{ ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY });
 
             System.out.format("delete: %s\n", subdir);
-            subdir.delete();
+            Files.delete(subdir);
             takeExpectedKey(watcher, myKey);
 
             System.out.println("reset key");
@@ -227,8 +220,6 @@
 
             System.out.println("OKAY");
 
-        } finally {
-            watcher.close();
         }
     }
 
@@ -411,7 +402,7 @@
             // create gus1
             Path file1 = dir.resolve(name1);
             System.out.format("create %s\n", file1);
-            createFile(file1);
+            Files.createFile(file1);
 
             // register with both watch services (different events)
             System.out.println("register for different events");
@@ -426,7 +417,7 @@
             // create gus2
             Path file2 = dir.resolve(name2);
             System.out.format("create %s\n", file2);
-            createFile(file2);
+            Files.createFile(file2);
 
             // check that key1 got ENTRY_CREATE
             takeExpectedKey(watcher1, key1);
@@ -439,7 +430,7 @@
                 throw new RuntimeException("key not expected");
 
             // delete gus1
-            file1.delete();
+            Files.delete(file1);
 
             // check that key2 got ENTRY_DELETE
             takeExpectedKey(watcher2, key2);
@@ -462,7 +453,7 @@
 
             // create file and key2 should be queued
             System.out.format("create %s\n", file1);
-            createFile(file1);
+            Files.createFile(file1);
             takeExpectedKey(watcher2, key2);
             checkExpectedEvent(key2.pollEvents(),
                 StandardWatchEventKind.ENTRY_CREATE, name1);
--- a/jdk/test/java/nio/file/WatchService/FileTreeModifier.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/test/java/nio/file/WatchService/FileTreeModifier.java	Fri Jan 28 09:28:43 2011 +0000
@@ -62,10 +62,7 @@
         WatchService watcher = fs.newWatchService();
 
         // create directories
-        Path subdir = top
-           .resolve("a").createDirectory()
-           .resolve("b").createDirectory()
-           .resolve("c").createDirectory();
+        Path subdir = Files.createDirectories(top.resolve("a").resolve("b").resolve("c"));
 
         // Test ENTRY_CREATE with FILE_TREE modifier.
 
@@ -73,7 +70,7 @@
             new WatchEvent.Kind<?>[]{ ENTRY_CREATE }, FILE_TREE);
 
         // create file in a/b/c and check we get create event
-        Path file = subdir.resolve("foo").createFile();
+        Path file = Files.createFile(subdir.resolve("foo"));
         checkExpectedEvent(watcher, ENTRY_CREATE, top.relativize(file));
         key.reset();
 
@@ -85,7 +82,7 @@
             throw new RuntimeException("Existing key not returned");
 
         // delete a/b/c/foo and check we get delete event
-        file.delete();
+        Files.delete(file);
         checkExpectedEvent(watcher, ENTRY_DELETE, top.relativize(file));
         key.reset();
 
@@ -96,19 +93,20 @@
             throw new RuntimeException("Existing key not returned");
 
         // create a/b/c/foo
-        file.createFile();
+        Files.createFile(file);
 
         // check that key is not queued
+        WatchKey nextKey;
         try {
-            k = watcher.poll(3, TimeUnit.SECONDS);
+            nextKey = watcher.poll(3, TimeUnit.SECONDS);
         } catch (InterruptedException e) {
             throw new RuntimeException();
         }
-        if (k != null)
+        if (nextKey != null)
             throw new RuntimeException("WatchKey not expected to be polled");
 
         // create bar and check we get create event
-        file = top.resolve("bar").createFile();
+        file = Files.createFile(top.resolve("bar"));
         checkExpectedEvent(watcher, ENTRY_CREATE, top.relativize(file));
         key.reset();
 
@@ -121,11 +119,8 @@
             throw new RuntimeException("Existing key not returned");
 
         // modify bar and check we get modify event
-        OutputStream out = file.newOutputStream();
-        try {
+        try (OutputStream out = Files.newOutputStream(file)) {
             out.write("Double shot expresso please".getBytes("UTF-8"));
-        } finally {
-            out.close();
         }
         checkExpectedEvent(watcher, ENTRY_MODIFY, top.relativize(file));
         key.reset();
--- a/jdk/test/java/nio/file/WatchService/LotsOfEvents.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/test/java/nio/file/WatchService/LotsOfEvents.java	Fri Jan 28 09:28:43 2011 +0000
@@ -55,15 +55,14 @@
     static void testOverflowEvent(Path dir)
         throws IOException, InterruptedException
     {
-        WatchService watcher = dir.getFileSystem().newWatchService();
-        try {
+        try (WatchService watcher = dir.getFileSystem().newWatchService()) {
             dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE);
 
             // create a lot of files
             int n = 1024;
             Path[] files = new Path[n];
             for (int i=0; i<n; i++) {
-                files[i] = dir.resolve("foo" + i).createFile();
+                files[i] = Files.createFile(dir.resolve("foo" + i));
             }
 
             // give time for events to accumulate (improve chance of overflow)
@@ -74,7 +73,7 @@
 
             // delete the files
             for (int i=0; i<n; i++) {
-                files[i].delete();
+                Files.delete(files[i]);
             }
 
             // give time for events to accumulate (improve chance of overflow)
@@ -82,8 +81,6 @@
 
             // check that we see the delete events (or overflow)
             drainAndCheckOverflowEvents(watcher, ENTRY_DELETE, n);
-        } finally {
-            watcher.close();
         }
     }
 
@@ -147,8 +144,7 @@
                 entries[i].create();
         }
 
-        WatchService watcher = dir.getFileSystem().newWatchService();
-        try {
+        try (WatchService watcher = dir.getFileSystem().newWatchService()) {
             dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
 
             // do several rounds of noise and test
@@ -169,7 +165,7 @@
                 // events for the same file.
                 WatchKey key = watcher.poll(15, TimeUnit.SECONDS);
                 while (key != null) {
-                    Set<Path> modified = new HashSet<Path>();
+                    Set<Path> modified = new HashSet<>();
                     for (WatchEvent<?> event: key.pollEvents()) {
                         WatchEvent.Kind<?> kind = event.kind();
                         Path file = (kind == OVERFLOW) ? null : (Path)event.context();
@@ -188,9 +184,6 @@
                     key = watcher.poll(2, TimeUnit.SECONDS);
                 }
             }
-
-        } finally {
-            watcher.close();
         }
     }
 
@@ -200,20 +193,17 @@
             this.file = file;
         }
         void create() throws IOException {
-            if (file.notExists())
-                file.createFile();
+            if (Files.notExists(file))
+                Files.createFile(file);
 
         }
         void deleteIfExists() throws IOException {
-            file.deleteIfExists();
+            Files.deleteIfExists(file);
         }
         void modifyIfExists() throws IOException {
-            if (file.exists()) {
-                OutputStream out = file.newOutputStream(StandardOpenOption.APPEND);
-                try {
+            if (Files.exists(file)) {
+                try (OutputStream out = Files.newOutputStream(file, StandardOpenOption.APPEND)) {
                     out.write("message".getBytes());
-                } finally {
-                    out.close();
                 }
             }
         }
--- a/jdk/test/java/nio/file/WatchService/SensitivityModifier.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/test/java/nio/file/WatchService/SensitivityModifier.java	Fri Jan 28 09:28:43 2011 +0000
@@ -51,6 +51,7 @@
         }
     }
 
+    @SuppressWarnings("unchecked")
     static void doTest(Path top) throws Exception {
         FileSystem fs = top.getFileSystem();
         WatchService watcher = fs.newWatchService();
@@ -61,11 +62,11 @@
         Path[] dirs = new Path[nDirs];
         Path[] files = new Path[nFiles];
         for (int i=0; i<nDirs; i++) {
-            dirs[i] = top.resolve("dir" + i).createDirectory();
+            dirs[i] = Files.createDirectory(top.resolve("dir" + i));
         }
         for (int i=0; i<nFiles; i++) {
             Path dir = dirs[rand.nextInt(nDirs)];
-            files[i] = dir.resolve("file" + i).createFile();
+            files[i] = Files.createFile(dir.resolve("file" + i));
         }
 
         // register the directories (random sensitivity)
@@ -80,11 +81,8 @@
         for (int i=0; i<10; i++) {
             Path file = files[rand.nextInt(nFiles)];
             System.out.println("Modify: " + file);
-            OutputStream out = file.newOutputStream();
-            try {
+            try (OutputStream out = Files.newOutputStream(file)) {
                 out.write(new byte[100]);
-            } finally {
-                out.close();
             }
             System.out.println("Waiting for event...");
             WatchKey key = watcher.take();
@@ -92,7 +90,7 @@
             if (event.kind() != ENTRY_MODIFY)
                 throw new RuntimeException("Unexpected event: " + event);
             Path name = ((WatchEvent<Path>)event).context();
-            if (!name.equals(file.getName()))
+            if (!name.equals(file.getFileName()))
                 throw new RuntimeException("Unexpected context: " + name);
             System.out.println("Event OK");
 
--- a/jdk/test/java/nio/file/attribute/AclFileAttributeView/Basic.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/test/java/nio/file/attribute/AclFileAttributeView/Basic.java	Fri Jan 28 09:28:43 2011 +0000
@@ -47,11 +47,11 @@
     // sanity check read and writing ACL
     static void testReadWrite(Path dir) throws IOException {
         Path file = dir.resolve("foo");
-        if (file.notExists())
-            file.createFile();
+        if (Files.notExists(file))
+            Files.createFile(file);
 
-        AclFileAttributeView view = file
-            .getFileAttributeView(AclFileAttributeView.class);
+        AclFileAttributeView view =
+            Files.getFileAttributeView(file, AclFileAttributeView.class);
 
         // print existing ACL
         List<AclEntry> acl = view.getAcl();
@@ -79,7 +79,7 @@
         }
 
         // if PosixFileAttributeView then repeat test with OWNER@
-        if (file.getFileStore().supportsFileAttributeView("posix")) {
+        if (Files.getFileStore(file).supportsFileAttributeView("posix")) {
             owner = file.getFileSystem().getUserPrincipalLookupService()
                 .lookupPrincipalByName("OWNER@");
             entry = AclEntry.newBuilder(entry).setPrincipal(owner).build();
@@ -115,7 +115,8 @@
 
     // sanity check create a file or directory with initial ACL
     static void testCreateFile(Path dir) throws IOException {
-        UserPrincipal user = Attributes.getOwner(dir);
+        UserPrincipal user = Files.getOwner(dir);
+        AclFileAttributeView view;
 
         // create file with initial ACL
         System.out.println("-- create file with initial ACL --");
@@ -127,8 +128,9 @@
                 .setPermissions(SYNCHRONIZE, READ_DATA, WRITE_DATA,
                     READ_ATTRIBUTES, READ_ACL, WRITE_ATTRIBUTES, DELETE)
                 .build());
-        file.createFile(asAclAttribute(fileAcl));
-        assertEquals(Attributes.getAcl(file), fileAcl);
+        Files.createFile(file, asAclAttribute(fileAcl));
+        view = Files.getFileAttributeView(file, AclFileAttributeView.class);
+        assertEquals(view.getAcl(), fileAcl);
 
         // create directory with initial ACL
         System.out.println("-- create directory with initial ACL --");
@@ -142,17 +144,18 @@
             AclEntry.newBuilder(fileAcl.get(0))
                 .setFlags(FILE_INHERIT)
                 .build());
-        subdir.createDirectory(asAclAttribute(dirAcl));
-        assertEquals(Attributes.getAcl(subdir), dirAcl);
+        Files.createDirectory(subdir, asAclAttribute(dirAcl));
+        view = Files.getFileAttributeView(subdir, AclFileAttributeView.class);
+        assertEquals(view.getAcl(), dirAcl);
     }
 
     public static void main(String[] args) throws IOException {
         // use work directory rather than system temporary directory to
         // improve chances that ACLs are supported
-        Path dir = Paths.get("./work" + new Random().nextInt())
-            .createDirectory();
+        Path dir = Paths.get("./work" + new Random().nextInt());
+        Files.createDirectory(dir);
         try {
-            if (!dir.getFileStore().supportsFileAttributeView("acl")) {
+            if (!Files.getFileStore(dir).supportsFileAttributeView("acl")) {
                 System.out.println("ACLs not supported - test skipped!");
                 return;
             }
--- a/jdk/test/java/nio/file/attribute/BasicFileAttributeView/Basic.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/test/java/nio/file/attribute/BasicFileAttributeView/Basic.java	Fri Jan 28 09:28:43 2011 +0000
@@ -43,7 +43,7 @@
     static void checkAttributesOfDirectory(Path dir)
         throws IOException
     {
-        BasicFileAttributes attrs = Attributes.readBasicFileAttributes(dir);
+        BasicFileAttributes attrs = Files.readAttributes(dir, BasicFileAttributes.class);
         check(attrs.isDirectory(), "is a directory");
         check(!attrs.isRegularFile(), "is not a regular file");
         check(!attrs.isSymbolicLink(), "is not a link");
@@ -58,7 +58,7 @@
     static void checkAttributesOfFile(Path dir, Path file)
         throws IOException
     {
-        BasicFileAttributes attrs = Attributes.readBasicFileAttributes(file);
+        BasicFileAttributes attrs = Files.readAttributes(file, BasicFileAttributes.class);
         check(attrs.isRegularFile(), "is a regular file");
         check(!attrs.isDirectory(), "is not a directory");
         check(!attrs.isSymbolicLink(), "is not a link");
@@ -73,8 +73,8 @@
         // copy last-modified time and file create time from directory to file,
         // re-read attribtues, and check they match
         BasicFileAttributeView view =
-            file.getFileAttributeView(BasicFileAttributeView.class);
-        BasicFileAttributes dirAttrs = Attributes.readBasicFileAttributes(dir);
+            Files.getFileAttributeView(file, BasicFileAttributeView.class);
+        BasicFileAttributes dirAttrs = Files.readAttributes(dir, BasicFileAttributes.class);
         view.setTimes(dirAttrs.lastModifiedTime(), null, null);
         if (dirAttrs.creationTime() != null) {
             view.setTimes(null, null, dirAttrs.creationTime());
@@ -95,8 +95,8 @@
     static void checkAttributesOfLink(Path link)
         throws IOException
     {
-        BasicFileAttributes attrs = Attributes
-            .readBasicFileAttributes(link, LinkOption.NOFOLLOW_LINKS);
+        BasicFileAttributes attrs =
+            Files.readAttributes(link, BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS);
         check(attrs.isSymbolicLink(), "is a link");
         check(!attrs.isDirectory(), "is a directory");
         check(!attrs.isRegularFile(), "is not a regular file");
@@ -108,11 +108,8 @@
     {
         // create file
         Path file = dir.resolve("foo");
-        OutputStream out = file.newOutputStream();
-        try {
+        try (OutputStream out = Files.newOutputStream(file)) {
             out.write("this is not an empty file".getBytes("UTF-8"));
-        } finally {
-            out.close();
         }
 
         // check attributes of directory and file
@@ -122,7 +119,7 @@
         // symbolic links may be supported
         Path link = dir.resolve("link");
         try {
-            link.createSymbolicLink( file );
+            Files.createSymbolicLink(link, file);
         } catch (UnsupportedOperationException x) {
             return;
         } catch (IOException x) {
--- a/jdk/test/java/nio/file/attribute/DosFileAttributeView/Basic.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/test/java/nio/file/attribute/DosFileAttributeView/Basic.java	Fri Jan 28 09:28:43 2011 +0000
@@ -74,27 +74,25 @@
     static void readWriteTests(Path dir) throws IOException {
 
         // create "foo" and test that we can read/write each FAT attribute
-        Path file = dir.resolve("foo");
-        file.createFile();
+        Path file = Files.createFile(dir.resolve("foo"));
         try {
-            testAttributes(file
-                .getFileAttributeView(DosFileAttributeView.class));
+            testAttributes(Files.getFileAttributeView(file, DosFileAttributeView.class));
 
             // Following tests use a symbolic link so skip if not supported
             if (!TestUtil.supportsLinks(dir))
                 return;
 
-            Path link = dir.resolve("link").createSymbolicLink(file);
+            Path link = dir.resolve("link");
+            Files.createSymbolicLink(link, file);
 
             // test following links
-            testAttributes(link
-                .getFileAttributeView(DosFileAttributeView.class));
+            testAttributes(Files.getFileAttributeView(link, DosFileAttributeView.class));
 
             // test not following links
             try {
                 try {
-                    testAttributes(link
-                        .getFileAttributeView(DosFileAttributeView.class, NOFOLLOW_LINKS));
+                    testAttributes(Files
+                        .getFileAttributeView(link, DosFileAttributeView.class, NOFOLLOW_LINKS));
                 } catch (IOException x) {
                     // access to link attributes not supported
                     return;
@@ -103,32 +101,32 @@
                 // set all attributes on link
                 // run test on target of link (which leaves them all un-set)
                 // check that attributes of link remain all set
-                setAll(link
-                    .getFileAttributeView(DosFileAttributeView.class, NOFOLLOW_LINKS), true);
-                testAttributes(link
-                    .getFileAttributeView(DosFileAttributeView.class));
-                DosFileAttributes attrs = Attributes.readDosFileAttributes(link, NOFOLLOW_LINKS);
+                setAll(Files
+                    .getFileAttributeView(link, DosFileAttributeView.class, NOFOLLOW_LINKS), true);
+                testAttributes(Files
+                    .getFileAttributeView(link, DosFileAttributeView.class));
+                DosFileAttributes attrs =
+                    Files.getFileAttributeView(link, DosFileAttributeView.class, NOFOLLOW_LINKS)
+                         .readAttributes();
                 check(attrs.isReadOnly());
                 check(attrs.isHidden());
                 check(attrs.isArchive());
                 check(attrs.isSystem());
-                setAll(link
-                    .getFileAttributeView(DosFileAttributeView.class, NOFOLLOW_LINKS), false);
+                setAll(Files
+                    .getFileAttributeView(link, DosFileAttributeView.class, NOFOLLOW_LINKS), false);
 
                 // set all attributes on target
                 // run test on link (which leaves them all un-set)
                 // check that attributes of target remain all set
-                setAll(link
-                    .getFileAttributeView(DosFileAttributeView.class), true);
-                testAttributes(link
-                    .getFileAttributeView(DosFileAttributeView.class, NOFOLLOW_LINKS));
-                attrs = Attributes.readDosFileAttributes(link);
+                setAll(Files.getFileAttributeView(link, DosFileAttributeView.class), true);
+                testAttributes(Files
+                    .getFileAttributeView(link, DosFileAttributeView.class, NOFOLLOW_LINKS));
+                attrs = Files.getFileAttributeView(link, DosFileAttributeView.class).readAttributes();
                 check(attrs.isReadOnly());
                 check(attrs.isHidden());
                 check(attrs.isArchive());
                 check(attrs.isSystem());
-                setAll(link
-                    .getFileAttributeView(DosFileAttributeView.class), false);
+                setAll(Files.getFileAttributeView(link, DosFileAttributeView.class), false);
             } finally {
                 TestUtil.deleteUnchecked(link);
             }
@@ -143,7 +141,7 @@
 
         try {
             // skip test if DOS file attributes not supported
-            if (!dir.getFileStore().supportsFileAttributeView("dos")) {
+            if (!Files.getFileStore(dir).supportsFileAttributeView("dos")) {
                 System.out.println("DOS file attribute not supported.");
                 return;
             }
--- a/jdk/test/java/nio/file/attribute/FileStoreAttributeView/Basic.java	Thu Jan 13 22:21:58 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,135 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/* @test
- * @bug 4313887 6838333
- * @summary Unit test for java.nio.file.attribute.FileStoreAttributeView
- * @library ../..
- */
-
-import java.nio.file.*;
-import java.nio.file.attribute.*;
-import java.io.File;
-import java.io.IOException;
-import java.util.*;
-
-/**
- * Simple unit test for FileStoreAttributeView that checks that the disk space
- * attribtues are "close" to the equivalent values reported by java.io.File.
- */
-
-public class Basic {
-
-    static final long K = 1024L;
-    static final long G = 1024L * 1024L * 1024L;
-
-    /**
-     * Print out the disk space information for the given file system
-     */
-    static void printFileStore(FileStore fs) throws IOException {
-        FileStoreSpaceAttributeView view =
-            fs.getFileStoreAttributeView(FileStoreSpaceAttributeView.class);
-        FileStoreSpaceAttributes attrs = view.readAttributes();
-
-        long total = attrs.totalSpace() / K;
-        long used = (attrs.totalSpace() - attrs.unallocatedSpace()) / K;
-        long avail = attrs.usableSpace() / K;
-
-        String s = fs.toString();
-        if (s.length() > 20) {
-            System.out.println(s);
-            s = "";
-        }
-        System.out.format("%-20s %12d %12d %12d\n", s, total, used, avail);
-    }
-
-    /**
-     * Check that two values are within 1GB of each other
-     */
-    static void checkWithin1GB(long value1, long value2) {
-        long diff = Math.abs(value1 - value2);
-        if (diff > G)
-            throw new RuntimeException("values differ by more than 1GB");
-    }
-
-    /**
-     * Check disk space on the file system of the given file
-     */
-    static void checkSpace(Path file) throws IOException {
-        System.out.println(" -- check space -- ");
-        System.out.println(file);
-
-        FileStore fs = file.getFileStore();
-        System.out.format("Filesystem: %s\n", fs);
-
-        // get values reported by java.io.File
-        File f = new File(file.toString());
-        long total = f.getTotalSpace();
-        long free = f.getFreeSpace();
-        long usable = f.getUsableSpace();
-        System.out.println("java.io.File");
-        System.out.format("    Total: %d\n", total);
-        System.out.format("     Free: %d\n", free);
-        System.out.format("   Usable: %d\n", usable);
-
-        // get values reported by the FileStoreSpaceAttributeView
-        FileStoreSpaceAttributes attrs = fs
-            .getFileStoreAttributeView(FileStoreSpaceAttributeView.class)
-            .readAttributes();
-        System.out.println("java.nio.file.FileStoreSpaceAttributeView:");
-        System.out.format("    Total: %d\n", attrs.totalSpace());
-        System.out.format("     Free: %d\n", attrs.unallocatedSpace());
-        System.out.format("   Usable: %d\n", attrs.usableSpace());
-
-        // check values are "close"
-        checkWithin1GB(total, attrs.totalSpace());
-        checkWithin1GB(free, attrs.unallocatedSpace());
-        checkWithin1GB(usable, attrs.usableSpace());
-
-        // get values by name
-        checkWithin1GB(total, (Long)fs.getAttribute("space:totalSpace"));
-        checkWithin1GB(free, (Long)fs.getAttribute("space:unallocatedSpace"));
-        checkWithin1GB(usable, (Long)fs.getAttribute("space:usableSpace"));
-    }
-
-    public static void main(String[] args) throws IOException {
-        // print out the disk space information for all file systems
-        FileSystem fs = FileSystems.getDefault();
-        for (FileStore store: fs.getFileStores()) {
-            printFileStore(store);
-        }
-
-        Path dir = TestUtil.createTemporaryDirectory();
-        try {
-            // check space using directory
-            checkSpace(dir);
-
-            // check space using file
-            Path file = dir.resolve("foo").createFile();
-            checkSpace(file);
-
-        } finally {
-            TestUtil.removeAll(dir);
-        }
-    }
-}
--- a/jdk/test/java/nio/file/attribute/FileTime/Basic.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/test/java/nio/file/attribute/FileTime/Basic.java	Fri Jan 28 09:28:43 2011 +0000
@@ -29,13 +29,16 @@
 import java.nio.file.attribute.FileTime;
 import java.util.concurrent.TimeUnit;
 import static java.util.concurrent.TimeUnit.*;
-import java.io.IOException;
+import java.util.Random;
 
 public class Basic {
 
-    public static void main(String[] args) throws IOException {
+    static final Random rand = new Random();
+
+    public static void main(String[] args) {
         long now = System.currentTimeMillis();
         long tomorrowInDays = TimeUnit.DAYS.convert(now, MILLISECONDS) + 1;
+        long yesterdayInDays = TimeUnit.DAYS.convert(now, MILLISECONDS) - 1;
 
         // equals
         eq(now, MILLISECONDS, now, MILLISECONDS);
@@ -50,6 +53,29 @@
         cmp(now, MILLISECONDS, now+1234, MILLISECONDS, -1);
         cmp(tomorrowInDays, DAYS, now, MILLISECONDS, 1);
         cmp(now, MILLISECONDS, tomorrowInDays, DAYS, -1);
+        cmp(yesterdayInDays, DAYS, now, MILLISECONDS, -1);
+        cmp(now, MILLISECONDS, yesterdayInDays, DAYS, 1);
+        cmp(yesterdayInDays, DAYS, now, MILLISECONDS, -1);
+        cmp(Long.MAX_VALUE, DAYS, Long.MAX_VALUE, NANOSECONDS, 1);
+        cmp(Long.MAX_VALUE, DAYS, Long.MIN_VALUE, NANOSECONDS, 1);
+        cmp(Long.MIN_VALUE, DAYS, Long.MIN_VALUE, NANOSECONDS, -1);
+        cmp(Long.MIN_VALUE, DAYS, Long.MAX_VALUE, NANOSECONDS, -1);
+
+        // to(TimeUnit)
+        to(MILLISECONDS.convert(1, DAYS) - 1, MILLISECONDS);
+        to(MILLISECONDS.convert(1, DAYS) + 0, MILLISECONDS);
+        to(MILLISECONDS.convert(1, DAYS) + 1, MILLISECONDS);
+        to(1, MILLISECONDS);
+        to(0, MILLISECONDS);
+        to(1, MILLISECONDS);
+        to(MILLISECONDS.convert(-1, DAYS) - 1, MILLISECONDS);
+        to(MILLISECONDS.convert(-1, DAYS) + 0, MILLISECONDS);
+        to(MILLISECONDS.convert(-1, DAYS) + 1, MILLISECONDS);
+        for (TimeUnit unit: TimeUnit.values()) {
+            for (int i=0; i<100; i++) { to(rand.nextLong(), unit); }
+            to(Long.MIN_VALUE, unit);
+            to(Long.MAX_VALUE, unit);
+        }
 
         // toString
         ts(1L, DAYS, "1970-01-02T00:00:00Z");
@@ -59,6 +85,8 @@
         ts(1L, MILLISECONDS, "1970-01-01T00:00:00.001Z");
         ts(1L, MICROSECONDS, "1970-01-01T00:00:00.000001Z");
         ts(1L, NANOSECONDS, "1970-01-01T00:00:00.000000001Z");
+        ts(999999999L, NANOSECONDS, "1970-01-01T00:00:00.999999999Z");
+        ts(9999999999L, NANOSECONDS, "1970-01-01T00:00:09.999999999Z");
 
         ts(-1L, DAYS, "1969-12-31T00:00:00Z");
         ts(-1L, HOURS, "1969-12-31T23:00:00Z");
@@ -67,6 +95,8 @@
         ts(-1L, MILLISECONDS, "1969-12-31T23:59:59.999Z");
         ts(-1L, MICROSECONDS, "1969-12-31T23:59:59.999999Z");
         ts(-1L, NANOSECONDS, "1969-12-31T23:59:59.999999999Z");
+        ts(-999999999L, NANOSECONDS, "1969-12-31T23:59:59.000000001Z");
+        ts(-9999999999L, NANOSECONDS, "1969-12-31T23:59:50.000000001Z");
 
         ts(-62135596799999L, MILLISECONDS, "0001-01-01T00:00:00.001Z");
         ts(-62135596800000L, MILLISECONDS, "0001-01-01T00:00:00Z");
@@ -114,9 +144,24 @@
             throw new RuntimeException("should not be equal");
     }
 
-    static void ts(long v, TimeUnit y, String expected) {
-        String s = FileTime.from(v, y).toString();
-        if (!s.equals(expected))
-            throw new RuntimeException("unexpected format");
+    static void to(long v, TimeUnit unit) {
+        FileTime t = FileTime.from(v, unit);
+        for (TimeUnit u: TimeUnit.values()) {
+            long result = t.to(u);
+            long expected = u.convert(v, unit);
+            if (result != expected) {
+                throw new RuntimeException("unexpected result");
+            }
+        }
+    }
+
+    static void ts(long v, TimeUnit unit, String expected) {
+        String result = FileTime.from(v, unit).toString();
+        if (!result.equals(expected)) {
+            System.err.format("FileTime.from(%d, %s).toString() failed\n", v, unit);
+            System.err.format("Expected: %s\n", expected);
+            System.err.format("     Got: %s\n", result);
+            throw new RuntimeException();
+        }
     }
 }
--- a/jdk/test/java/nio/file/attribute/PosixFileAttributeView/Basic.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/test/java/nio/file/attribute/PosixFileAttributeView/Basic.java	Fri Jan 28 09:28:43 2011 +0000
@@ -49,9 +49,8 @@
         Set<PosixFilePermission> perms = PosixFilePermissions.fromString(mode);
 
         // change permissions and re-read them.
-        Attributes.setPosixFilePermissions(file, perms);
-        Set<PosixFilePermission> current = Attributes
-            .readPosixFileAttributes(file).permissions();
+        Files.setPosixFilePermissions(file, perms);
+        Set<PosixFilePermission> current = Files.getPosixFilePermissions(file);
         if (!current.equals(perms)) {
             throw new RuntimeException("Actual permissions: " +
                 PosixFilePermissions.toString(current) + ", expected: " +
@@ -59,8 +58,8 @@
         }
 
         // repeat test using setAttribute/getAttribute
-        file.setAttribute("posix:permissions", perms);
-        current = (Set<PosixFilePermission>)file.getAttribute("posix:permissions");
+        Files.setAttribute(file, "posix:permissions", perms);
+        current = (Set<PosixFilePermission>)Files.getAttribute(file, "posix:permissions");
         if (!current.equals(perms)) {
             throw new RuntimeException("Actual permissions: " +
                 PosixFilePermissions.toString(current) + ", expected: " +
@@ -97,25 +96,25 @@
         FileAttribute<Set<PosixFilePermission>> attr =
             PosixFilePermissions.asFileAttribute(requested);
         System.out.format("create file with mode: %s\n", mode);
-        file.createFile(attr);
+        Files.createFile(file, attr);
         try {
-            checkSecure(requested,  file
-                .getFileAttributeView(PosixFileAttributeView.class)
-                .readAttributes()
-                .permissions());
+            checkSecure(requested,
+                Files.getFileAttributeView(file, PosixFileAttributeView.class)
+                     .readAttributes()
+                     .permissions());
         } finally {
-            file.delete();
+            Files.delete(file);
         }
 
         System.out.format("create directory with mode: %s\n", mode);
-        file.createDirectory(attr);
+        Files.createDirectory(file, attr);
         try {
-            checkSecure(requested,  file
-                .getFileAttributeView(PosixFileAttributeView.class)
-                .readAttributes()
-                .permissions());
+            checkSecure(requested,
+                Files.getFileAttributeView(file, PosixFileAttributeView.class)
+                     .readAttributes()
+                     .permissions());
         } finally {
-            file.delete();
+            Files.delete(file);
         }
     }
 
@@ -130,11 +129,11 @@
         // create file and test updating and reading its permissions
         Path file = dir.resolve("foo");
         System.out.format("create %s\n", file);
-        file.createFile();
+        Files.createFile(file);
         try {
             // get initial permissions so that we can restore them later
-            PosixFileAttributeView view = file
-                .getFileAttributeView(PosixFileAttributeView.class);
+            PosixFileAttributeView view =
+                Files.getFileAttributeView(file, PosixFileAttributeView.class);
             Set<PosixFilePermission> save = view.readAttributes()
                 .permissions();
 
@@ -165,7 +164,7 @@
                 view.setPermissions(save);
             }
         } finally {
-            file.delete();
+            Files.delete(file);
         }
 
         // create link (to file that doesn't exist) and test reading of
@@ -173,15 +172,18 @@
         if (TestUtil.supportsLinks(dir)) {
             Path link = dir.resolve("link");
             System.out.format("create link %s\n", link);
-            link.createSymbolicLink(file);
+            Files.createSymbolicLink(link, file);
             try {
-                PosixFileAttributes attrs = Attributes
-                    .readPosixFileAttributes(link, NOFOLLOW_LINKS);
+                PosixFileAttributes attrs =
+                    Files.getFileAttributeView(link,
+                                               PosixFileAttributeView.class,
+                                               NOFOLLOW_LINKS)
+                         .readAttributes();
                 if (!attrs.isSymbolicLink()) {
                     throw new RuntimeException("not a link");
                 }
             } finally {
-                link.delete();
+                Files.delete(link);
             }
         }
 
@@ -235,12 +237,12 @@
         Path file = dir.resolve("gus");
         System.out.format("create %s\n", file);
 
-        file.createFile();
+        Files.createFile(file);
         try {
 
             // read attributes of directory to get owner/group
-            PosixFileAttributeView view = file
-                .getFileAttributeView(PosixFileAttributeView.class);
+            PosixFileAttributeView view =
+                Files.getFileAttributeView(file, PosixFileAttributeView.class);
             PosixFileAttributes attrs = view.readAttributes();
 
             // set to existing owner/group
@@ -248,13 +250,13 @@
             view.setGroup(attrs.group());
 
             // repeat test using set/getAttribute
-            UserPrincipal owner = (UserPrincipal)file.getAttribute("posix:owner");
-            file.setAttribute("posix:owner", owner);
-            UserPrincipal group = (UserPrincipal)file.getAttribute("posix:group");
-            file.setAttribute("posix:group", group);
+            UserPrincipal owner = (UserPrincipal)Files.getAttribute(file, "posix:owner");
+            Files.setAttribute(file, "posix:owner", owner);
+            UserPrincipal group = (UserPrincipal)Files.getAttribute(file, "posix:group");
+            Files.setAttribute(file, "posix:group", group);
 
         } finally {
-            file.delete();
+            Files.delete(file);
         }
 
         System.out.println("OKAY");
@@ -272,7 +274,7 @@
             .getUserPrincipalLookupService();
 
         // read attributes of directory to get owner/group
-        PosixFileAttributes attrs = Attributes.readPosixFileAttributes(dir);
+        PosixFileAttributes attrs = Files.readAttributes(dir, PosixFileAttributes.class);
 
         // lookup owner and check it matches file's owner
         System.out.format("lookup: %s\n", attrs.owner().getName());
@@ -322,8 +324,8 @@
     {
         System.out.println("-- Exceptions --");
 
-        PosixFileAttributeView view = dir
-            .getFileAttributeView(PosixFileAttributeView.class);
+        PosixFileAttributeView view =
+            Files.getFileAttributeView(dir,PosixFileAttributeView.class);
 
         // NullPointerException
         try {
@@ -355,7 +357,7 @@
         } catch (NullPointerException x) {
         }
         try {
-            Set<PosixFilePermission> perms = new HashSet<PosixFilePermission>();
+            Set<PosixFilePermission> perms = new HashSet<>();
             perms.add(null);
             view.setPermissions(perms);
             throw new RuntimeException("NullPointerException not thrown");
@@ -377,7 +379,7 @@
     public static void main(String[] args) throws IOException {
         Path dir = TestUtil.createTemporaryDirectory();
         try {
-            if (!dir.getFileStore().supportsFileAttributeView("posix")) {
+            if (!Files.getFileStore(dir).supportsFileAttributeView("posix")) {
                 System.out.println("PosixFileAttributeView not supported");
                 return;
             }
--- a/jdk/test/java/nio/file/attribute/UserDefinedFileAttributeView/Basic.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/test/java/nio/file/attribute/UserDefinedFileAttributeView/Basic.java	Fri Jan 28 09:28:43 2011 +0000
@@ -79,8 +79,8 @@
     }
 
     static void test(Path file, LinkOption... options) throws IOException {
-        final UserDefinedFileAttributeView view = file
-            .getFileAttributeView(UserDefinedFileAttributeView.class, options);
+        final UserDefinedFileAttributeView view =
+            Files.getFileAttributeView(file, UserDefinedFileAttributeView.class, options);
         ByteBuffer buf = rand.nextBoolean() ?
             ByteBuffer.allocate(100) : ByteBuffer.allocateDirect(100);
 
@@ -131,24 +131,24 @@
         // Test: dynamic access
         String name = "user:" + ATTR_NAME;
         byte[] valueAsBytes = ATTR_VALUE.getBytes();
-        file.setAttribute(name, valueAsBytes);
-        byte[] actualAsBytes = (byte[])file.getAttribute(name);
+        Files.setAttribute(file, name, valueAsBytes);
+        byte[] actualAsBytes = (byte[])Files.getAttribute(file, name);
         if (!Arrays.equals(valueAsBytes, actualAsBytes))
             throw new RuntimeException("Unexpected attribute value");
-        Map<String,?> map = file.readAttributes(name);
+        Map<String,?> map = Files.readAttributes(file, name);
         if (!Arrays.equals(valueAsBytes, (byte[])map.get(ATTR_NAME)))
             throw new RuntimeException("Unexpected attribute value");
-        map = file.readAttributes("user:*");
+        map = Files.readAttributes(file, "user:*");
         if (!Arrays.equals(valueAsBytes, (byte[])map.get(ATTR_NAME)))
             throw new RuntimeException("Unexpected attribute value");
-        map = file.readAttributes("user:DoesNotExist");
+        map = Files.readAttributes(file, "user:DoesNotExist");
         if (!map.isEmpty())
             throw new RuntimeException("Map expected to be empty");
     }
 
     static void miscTests(final Path file) throws IOException {
-        final UserDefinedFileAttributeView view = file
-            .getFileAttributeView(UserDefinedFileAttributeView.class);
+        final UserDefinedFileAttributeView view =
+            Files.getFileAttributeView(file, UserDefinedFileAttributeView.class);
         view.write(ATTR_NAME, ByteBuffer.wrap(ATTR_VALUE.getBytes()));
 
         // NullPointerException
@@ -180,31 +180,31 @@
             }});
         expectNullPointerException(new Task() {
             public void run() throws IOException {
-                file.getAttribute(null);
+                Files.getAttribute(file, null);
             }});
         expectNullPointerException(new Task() {
             public void run() throws IOException {
-                file.getAttribute("user:" + ATTR_NAME, (LinkOption[])null);
+                Files.getAttribute(file, "user:" + ATTR_NAME, (LinkOption[])null);
             }});
         expectNullPointerException(new Task() {
             public void run() throws IOException {
-                file.setAttribute("user:" + ATTR_NAME, null);
+                Files.setAttribute(file, "user:" + ATTR_NAME, null);
             }});
         expectNullPointerException(new Task() {
             public void run() throws IOException {
-                file.setAttribute(null, new byte[0]);
+                Files.setAttribute(file, null, new byte[0]);
             }});
         expectNullPointerException(new Task() {
             public void run() throws IOException {
-                file.setAttribute("user: " + ATTR_NAME, new byte[0], (LinkOption[])null);
+                Files.setAttribute(file, "user: " + ATTR_NAME, new byte[0], (LinkOption[])null);
             }});
         expectNullPointerException(new Task() {
             public void run() throws IOException {
-                file.readAttributes((String)null);
+                Files.readAttributes(file, (String)null);
             }});
         expectNullPointerException(new Task() {
             public void run() throws IOException {
-                file.readAttributes("*", (LinkOption[])null);
+                Files.readAttributes(file, "*", (LinkOption[])null);
             }});
 
         // Read-only buffer
@@ -229,46 +229,50 @@
         // create temporary directory to run tests
         Path dir = TestUtil.createTemporaryDirectory();
         try {
-            if (!dir.getFileStore().supportsFileAttributeView("user")) {
+            if (!Files.getFileStore(dir).supportsFileAttributeView("user")) {
                 System.out.println("UserDefinedFileAttributeView not supported - skip test");
                 return;
             }
 
             // test access to user defined attributes of regular file
-            Path file = dir.resolve("foo.html").createFile();
+            Path file = dir.resolve("foo.html");
+            Files.createFile(file);
             try {
                 test(file);
             } finally {
-                file.delete();
+                Files.delete(file);
             }
 
-            // test access to user define attributes of directory
-            file = dir.resolve("foo").createDirectory();
+            // test access to user defined attributes of directory
+            Path subdir = dir.resolve("foo");
+            Files.createDirectory(subdir);
             try {
-                test(file);
+                test(subdir);
             } finally {
-                file.delete();
+                Files.delete(subdir);
             }
 
             // test access to user defined attributes of sym link
             if (TestUtil.supportsLinks(dir)) {
                 Path target = dir.resolve("doesnotexist");
-                Path link = dir.resolve("link").createSymbolicLink(target);
+                Path link = dir.resolve("link");
+                Files.createSymbolicLink(link, target);
                 try {
                     test(link, NOFOLLOW_LINKS);
                 } catch (IOException x) {
                     // access to attributes of sym link may not be supported
                 } finally {
-                    link.delete();
+                    Files.delete(link);
                 }
             }
 
             // misc. tests
             try {
-                file = dir.resolve("foo.txt").createFile();
+                file = dir.resolve("foo.txt");
+                Files.createFile(file);
                 miscTests(dir);
             } finally {
-                file.delete();
+                Files.delete(file);
             }
 
         } finally {
--- a/jdk/test/java/nio/file/spi/SetDefaultProvider.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/test/java/nio/file/spi/SetDefaultProvider.java	Fri Jan 28 09:28:43 2011 +0000
@@ -22,14 +22,13 @@
  */
 
 /* @test
- * @bug 4313887
+ * @bug 4313887 7006126
  * @summary Unit test for java.nio.file.spi.FileSystemProvider
  * @build TestProvider SetDefaultProvider
  * @run main/othervm -Djava.nio.file.spi.DefaultFileSystemProvider=TestProvider SetDefaultProvider
  */
 
 import java.nio.file.*;
-import java.nio.file.spi.*;
 
 public class SetDefaultProvider {
     public static void main(String[] args) throws Exception {
--- a/jdk/test/java/nio/file/spi/TestProvider.java	Thu Jan 13 22:21:58 2011 -0800
+++ b/jdk/test/java/nio/file/spi/TestProvider.java	Fri Jan 28 09:28:43 2011 +0000
@@ -24,6 +24,7 @@
 import java.nio.file.spi.FileSystemProvider;
 import java.nio.file.*;
 import java.nio.file.attribute.*;
+import java.nio.channels.SeekableByteChannel;
 import java.net.URI;
 import java.util.*;
 import java.io.IOException;
@@ -34,7 +35,6 @@
 
     public TestProvider(FileSystemProvider defaultProvider) {
         theFileSystem = new TestFileSystem(this);
-
     }
 
     @Override
@@ -57,6 +57,124 @@
         throw new RuntimeException("not implemented");
     }
 
+    @Override
+    public void setAttribute(Path file, String attribute, Object value,
+                             LinkOption... options)
+        throws IOException
+    {
+        throw new RuntimeException("not implemented");
+    }
+
+    @Override
+    public Map<String,Object> readAttributes(Path file, String attributes,
+                                             LinkOption... options)
+        throws IOException
+    {
+        throw new RuntimeException("not implemented");
+    }
+
+    @Override
+    public <A extends BasicFileAttributes> A readAttributes(Path file,
+                                                            Class<A> type,
+                                                            LinkOption... options)
+        throws IOException
+    {
+        throw new RuntimeException("not implemented");
+    }
+
+    @Override
+    public <V extends FileAttributeView> V getFileAttributeView(Path file,
+                                                                Class<V> type,
+                                                                LinkOption... options)
+    {
+        throw new RuntimeException("not implemented");
+    }
+
+
+    @Override
+    public void delete(Path file) throws IOException {
+        throw new RuntimeException("not implemented");
+    }
+
+    @Override
+    public void createSymbolicLink(Path link, Path target, FileAttribute<?>... attrs)
+        throws IOException
+    {
+        throw new RuntimeException("not implemented");
+    }
+
+    @Override
+    public void createLink(Path link, Path existing) throws IOException {
+        throw new RuntimeException("not implemented");
+    }
+
+    @Override
+    public Path readSymbolicLink(Path link) throws IOException {
+        throw new RuntimeException("not implemented");
+    }
+
+
+    @Override
+    public void copy(Path source, Path target, CopyOption... options)
+        throws IOException
+    {
+        throw new RuntimeException("not implemented");
+    }
+
+    @Override
+    public void move(Path source, Path target, CopyOption... options)
+        throws IOException
+    {
+        throw new RuntimeException("not implemented");
+    }
+
+    @Override
+    public DirectoryStream<Path> newDirectoryStream(Path dir,
+                                                    DirectoryStream.Filter<? super Path> filter)
+        throws IOException
+    {
+        throw new RuntimeException("not implemented");
+    }
+
+    @Override
+    public void createDirectory(Path dir, FileAttribute<?>... attrs)
+        throws IOException
+    {
+        throw new RuntimeException("not implemented");
+    }
+
+    @Override
+    public SeekableByteChannel newByteChannel(Path file,
+                                              Set<? extends OpenOption> options,
+                                              FileAttribute<?>... attrs)
+        throws IOException
+    {
+        throw new RuntimeException("not implemented");
+    }
+
+
+    @Override
+    public boolean isHidden(Path file) throws IOException {
+        throw new RuntimeException("not implemented");
+    }
+
+    @Override
+    public FileStore getFileStore(Path file) throws IOException {
+        throw new RuntimeException("not implemented");
+    }
+
+    @Override
+    public boolean isSameFile(Path file, Path other) throws IOException {
+        throw new RuntimeException("not implemented");
+    }
+
+    @Override
+    public void checkAccess(Path file, AccessMode... modes)
+        throws IOException
+    {
+        throw new RuntimeException("not implemented");
+    }
+
     static class TestFileSystem extends FileSystem {
         private final TestProvider provider;
 
@@ -105,7 +223,7 @@
         }
 
         @Override
-        public Path getPath(String path) {
+        public Path getPath(String first, String... more) {
             throw new RuntimeException("not implemented");
         }
 
@@ -124,5 +242,4 @@
             throw new RuntimeException("not implemented");
         }
     }
-
 }