changeset 3669:802c085308bf

Merge
author igor
date Tue, 15 Feb 2011 19:16:39 -0800
parents 4f84cda2a7d5 9d141e45ee4b
children bdc069d3f910
files src/share/classes/java/io/TempFileHelper.java src/share/classes/java/nio/file/FileRef.java src/share/classes/java/nio/file/attribute/Attributes.java src/share/classes/java/nio/file/attribute/FileStoreSpaceAttributeView.java src/share/classes/java/nio/file/attribute/FileStoreSpaceAttributes.java src/share/demo/zipfs test/java/nio/file/Files/ContentType.java test/java/nio/file/Files/CreateFileTree.java test/java/nio/file/Files/ForceLoad.java test/java/nio/file/Files/META-INF/services/java.nio.file.spi.FileTypeDetector test/java/nio/file/Files/MaxDepth.java test/java/nio/file/Files/PrintFileTree.java test/java/nio/file/Files/SimpleFileTypeDetector.java test/java/nio/file/Files/SkipSiblings.java test/java/nio/file/Files/TerminateWalk.java test/java/nio/file/Files/WalkWithSecurity.java test/java/nio/file/Files/denyAll.policy test/java/nio/file/Files/grantAll.policy test/java/nio/file/Files/grantTopOnly.policy test/java/nio/file/Files/walk_file_tree.sh test/java/nio/file/Path/CheckPermissions.java test/java/nio/file/Path/CopyAndMove.java test/java/nio/file/Path/DeleteOnClose.java test/java/nio/file/Path/FileAttributes.java test/java/nio/file/Path/InterruptCopy.java test/java/nio/file/Path/Links.java test/java/nio/file/Path/PassThroughFileSystem.java test/java/nio/file/Path/SBC.java test/java/nio/file/Path/TemporaryFiles.java test/java/nio/file/Path/delete_on_close.sh test/java/nio/file/attribute/FileStoreAttributeView/Basic.java
diffstat 401 files changed, 19177 insertions(+), 13997 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Wed Feb 09 21:20:41 2011 -0800
+++ b/.hgtags	Tue Feb 15 19:16:39 2011 -0800
@@ -103,3 +103,4 @@
 8361ef97a0f90086c9048beaf7cea1a37216c4cd jdk7-b126
 29e09de1d0b4f84faea114cf10b3ec08b59acc4e jdk7-b127
 f08682e23279d6cccbdcafda1eb0647ba4900874 jdk7-b128
+14cd5d54a8d0b9c368d60ea83a066735b9931015 jdk7-b129
--- a/make/java/java/FILES_java.gmk	Wed Feb 09 21:20:41 2011 -0800
+++ b/make/java/java/FILES_java.gmk	Tue Feb 15 19:16:39 2011 -0800
@@ -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/make/java/nio/FILES_java.gmk	Wed Feb 09 21:20:41 2011 -0800
+++ b/make/java/nio/FILES_java.gmk	Tue Feb 15 19:16:39 2011 -0800
@@ -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/make/netbeans/common/java-data-native.ent	Wed Feb 09 21:20:41 2011 -0800
+++ b/make/netbeans/common/java-data-native.ent	Tue Feb 15 19:16:39 2011 -0800
@@ -31,7 +31,7 @@
  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 -->
 
-<java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/2">
+<java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/3">
     <compilation-unit>
         <package-root>${root}/src/share/classes</package-root>
         <package-root>${root}/src/windows/classes</package-root>
@@ -39,6 +39,6 @@
         <classpath mode="boot">${bootstrap.jdk}/jre/lib/rt.jar</classpath>
         <built-to>${root}/build/${platform}-${arch}/classes</built-to>
         <javadoc-built-to>${root}/build/javadoc/${name}</javadoc-built-to>
-        <source-level>1.5</source-level>
+        <source-level>1.7</source-level>
     </compilation-unit>
 </java-data>
--- a/make/netbeans/common/java-data-no-native.ent	Wed Feb 09 21:20:41 2011 -0800
+++ b/make/netbeans/common/java-data-no-native.ent	Tue Feb 15 19:16:39 2011 -0800
@@ -31,12 +31,12 @@
  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 -->
 
-<java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/2">
+<java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/3">
     <compilation-unit>
         <package-root>${root}/src/share/classes</package-root>
         <classpath mode="boot">${bootstrap.jdk}/jre/lib/rt.jar</classpath>
         <built-to>${root}/build/${platform}-${arch}/classes</built-to>
         <javadoc-built-to>${root}/build/javadoc/${name}</javadoc-built-to>
-        <source-level>1.5</source-level>
+        <source-level>1.7</source-level>
     </compilation-unit>
 </java-data>
--- a/src/share/bin/java.c	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/bin/java.c	Tue Feb 15 19:16:39 2011 -0800
@@ -244,6 +244,7 @@
         for (i = 0; i < argc ; i++) {
             printf("argv[%d] = %s\n", i, argv[i]);
         }
+        AddOption("-Dsun.java.launcher.diag=true", NULL);
     }
 
     CreateExecutionEnvironment(&argc, &argv,
@@ -1009,6 +1010,8 @@
         } else if (JLI_StrCmp(arg, "-XshowSettings") == 0 ||
                 JLI_StrCCmp(arg, "-XshowSettings:") == 0) {
             showSettings = arg;
+        } else if (JLI_StrCmp(arg, "-Xdiag") == 0) {
+            AddOption("-Dsun.java.launcher.diag=true", NULL);
 /*
  * The following case provide backward compatibility with old-style
  * command line options.
--- a/src/share/classes/com/sun/jndi/ldap/Connection.java	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/com/sun/jndi/ldap/Connection.java	Tue Feb 15 19:16:39 2011 -0800
@@ -656,14 +656,17 @@
                 }
                 nparent = notifyParent;
             }
-        }
-        if (nparent) {
-            LdapRequest ldr = pendingRequests;
-            while (ldr != null) {
-                ldr.notify();
-                ldr = ldr.next;
+            if (nparent) {
+                LdapRequest ldr = pendingRequests;
+                while (ldr != null) {
+
+                    synchronized (ldr) {
+                        ldr.notify();
+                        ldr = ldr.next;
+                    }
+                }
+                parent.processConnectionClosure();
             }
-            parent.processConnectionClosure();
         }
     }
 
--- a/src/share/classes/com/sun/jndi/toolkit/ctx/Continuation.java	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/com/sun/jndi/toolkit/ctx/Continuation.java	Tue Feb 15 19:16:39 2011 -0800
@@ -143,7 +143,7 @@
         e.setRemainingName(remainingName);
         e.setResolvedObj(resolvedObj);
 
-        if (starter == null)
+        if (starter == null || starter.isEmpty())
             e.setResolvedName(null);
         else if (remainingName == null)
             e.setResolvedName(starter);
--- a/src/share/classes/java/awt/Window.java	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/java/awt/Window.java	Tue Feb 15 19:16:39 2011 -0800
@@ -504,6 +504,8 @@
         }
 
         modalExclusionType = Dialog.ModalExclusionType.NO_EXCLUDE;
+
+        SunToolkit.checkAndSetPolicy(this, false);
     }
 
     /**
--- a/src/share/classes/java/awt/doc-files/FocusSpec.html	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/java/awt/doc-files/FocusSpec.html	Tue Feb 15 19:16:39 2011 -0800
@@ -894,8 +894,7 @@
 focus across Windows. If the request is denied for this reason, the
 request is remembered and will be granted when the Window is later
 focused by the user. Otherwise, the focus change request changes the
-focused Window as well. Currently, Microsoft Windows supports cross-Window 
-focus transfers while Solaris does not.
+focused Window as well.
 <p>
 There is no way to determine synchronously whether a focus change
 request has been granted. Instead, client code must install a
--- a/src/share/classes/java/awt/geom/CubicCurve2D.java	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/java/awt/geom/CubicCurve2D.java	Tue Feb 15 19:16:39 2011 -0800
@@ -31,6 +31,10 @@
 import java.io.Serializable;
 import sun.awt.geom.Curve;
 
+import static java.lang.Math.abs;
+import static java.lang.Math.max;
+import static java.lang.Math.ulp;
+
 /**
  * The <code>CubicCurve2D</code> class defines a cubic parametric curve
  * segment in {@code (x,y)} coordinate space.
@@ -1083,95 +1087,286 @@
      * @since 1.3
      */
     public static int solveCubic(double eqn[], double res[]) {
-        // From Numerical Recipes, 5.6, Quadratic and Cubic Equations
-        double d = eqn[3];
-        if (d == 0.0) {
-            // The cubic has degenerated to quadratic (or line or ...).
+        // From Graphics Gems:
+        // http://tog.acm.org/resources/GraphicsGems/gems/Roots3And4.c
+        final double d = eqn[3];
+        if (d == 0) {
             return QuadCurve2D.solveQuadratic(eqn, res);
         }
-        double a = eqn[2] / d;
-        double b = eqn[1] / d;
-        double c = eqn[0] / d;
-        int roots = 0;
-        double Q = (a * a - 3.0 * b) / 9.0;
-        double R = (2.0 * a * a * a - 9.0 * a * b + 27.0 * c) / 54.0;
-        double R2 = R * R;
-        double Q3 = Q * Q * Q;
-        a = a / 3.0;
-        if (R2 < Q3) {
-            double theta = Math.acos(R / Math.sqrt(Q3));
-            Q = -2.0 * Math.sqrt(Q);
+
+        /* normal form: x^3 + Ax^2 + Bx + C = 0 */
+        final double A = eqn[2] / d;
+        final double B = eqn[1] / d;
+        final double C = eqn[0] / d;
+
+
+        //  substitute x = y - A/3 to eliminate quadratic term:
+        //     x^3 +Px + Q = 0
+        //
+        // Since we actually need P/3 and Q/2 for all of the
+        // calculations that follow, we will calculate
+        // p = P/3
+        // q = Q/2
+        // instead and use those values for simplicity of the code.
+        double sq_A = A * A;
+        double p = 1.0/3 * (-1.0/3 * sq_A + B);
+        double q = 1.0/2 * (2.0/27 * A * sq_A - 1.0/3 * A * B + C);
+
+        /* use Cardano's formula */
+
+        double cb_p = p * p * p;
+        double D = q * q + cb_p;
+
+        final double sub = 1.0/3 * A;
+
+        int num;
+        if (D < 0) { /* Casus irreducibilis: three real solutions */
+            // see: http://en.wikipedia.org/wiki/Cubic_function#Trigonometric_.28and_hyperbolic.29_method
+            double phi = 1.0/3 * Math.acos(-q / Math.sqrt(-cb_p));
+            double t = 2 * Math.sqrt(-p);
+
             if (res == eqn) {
-                // Copy the eqn so that we don't clobber it with the
-                // roots.  This is needed so that fixRoots can do its
-                // work with the original equation.
-                eqn = new double[4];
-                System.arraycopy(res, 0, eqn, 0, 4);
+                eqn = Arrays.copyOf(eqn, 4);
             }
-            res[roots++] = Q * Math.cos(theta / 3.0) - a;
-            res[roots++] = Q * Math.cos((theta + Math.PI * 2.0)/ 3.0) - a;
-            res[roots++] = Q * Math.cos((theta - Math.PI * 2.0)/ 3.0) - a;
-            fixRoots(res, eqn);
+
+            res[ 0 ] =  ( t * Math.cos(phi));
+            res[ 1 ] =  (-t * Math.cos(phi + Math.PI / 3));
+            res[ 2 ] =  (-t * Math.cos(phi - Math.PI / 3));
+            num = 3;
+
+            for (int i = 0; i < num; ++i) {
+                res[ i ] -= sub;
+            }
+
         } else {
-            boolean neg = (R < 0.0);
-            double S = Math.sqrt(R2 - Q3);
-            if (neg) {
-                R = -R;
+            // Please see the comment in fixRoots marked 'XXX' before changing
+            // any of the code in this case.
+            double sqrt_D = Math.sqrt(D);
+            double u = Math.cbrt(sqrt_D - q);
+            double v = - Math.cbrt(sqrt_D + q);
+            double uv = u+v;
+
+            num = 1;
+
+            double err = 1200000000*ulp(abs(uv) + abs(sub));
+            if (iszero(D, err) || within(u, v, err)) {
+                if (res == eqn) {
+                    eqn = Arrays.copyOf(eqn, 4);
+                }
+                res[1] = -(uv / 2) - sub;
+                num = 2;
             }
-            double A = Math.pow(R + S, 1.0 / 3.0);
-            if (!neg) {
-                A = -A;
-            }
-            double B = (A == 0.0) ? 0.0 : (Q / A);
-            res[roots++] = (A + B) - a;
+            // this must be done after the potential Arrays.copyOf
+            res[ 0 ] =  uv - sub;
         }
-        return roots;
+
+        if (num > 1) { // num == 3 || num == 2
+            num = fixRoots(eqn, res, num);
+        }
+        if (num > 2 && (res[2] == res[1] || res[2] == res[0])) {
+            num--;
+        }
+        if (num > 1 && res[1] == res[0]) {
+            res[1] = res[--num]; // Copies res[2] to res[1] if needed
+        }
+        return num;
     }
 
-    /*
-     * This pruning step is necessary since solveCubic uses the
-     * cosine function to calculate the roots when there are 3
-     * of them.  Since the cosine method can have an error of
-     * +/- 1E-14 we need to make sure that we don't make any
-     * bad decisions due to an error.
-     *
-     * If the root is not near one of the endpoints, then we will
-     * only have a slight inaccuracy in calculating the x intercept
-     * which will only cause a slightly wrong answer for some
-     * points very close to the curve.  While the results in that
-     * case are not as accurate as they could be, they are not
-     * disastrously inaccurate either.
-     *
-     * On the other hand, if the error happens near one end of
-     * the curve, then our processing to reject values outside
-     * of the t=[0,1] range will fail and the results of that
-     * failure will be disastrous since for an entire horizontal
-     * range of test points, we will either overcount or undercount
-     * the crossings and get a wrong answer for all of them, even
-     * when they are clearly and obviously inside or outside the
-     * curve.
-     *
-     * To work around this problem, we try a couple of Newton-Raphson
-     * iterations to see if the true root is closer to the endpoint
-     * or further away.  If it is further away, then we can stop
-     * since we know we are on the right side of the endpoint.  If
-     * we change direction, then either we are now being dragged away
-     * from the endpoint in which case the first condition will cause
-     * us to stop, or we have passed the endpoint and are headed back.
-     * In the second case, we simply evaluate the slope at the
-     * endpoint itself and place ourselves on the appropriate side
-     * of it or on it depending on that result.
-     */
-    private static void fixRoots(double res[], double eqn[]) {
-        final double EPSILON = 1E-5;
+    // preconditions: eqn != res && eqn[3] != 0 && num > 1
+    // This method tries to improve the accuracy of the roots of eqn (which
+    // should be in res). It also might eliminate roots in res if it decideds
+    // that they're not real roots. It will not check for roots that the
+    // computation of res might have missed, so this method should only be
+    // used when the roots in res have been computed using an algorithm
+    // that never underestimates the number of roots (such as solveCubic above)
+    private static int fixRoots(double[] eqn, double[] res, int num) {
+        double[] intervals = {eqn[1], 2*eqn[2], 3*eqn[3]};
+        int critCount = QuadCurve2D.solveQuadratic(intervals, intervals);
+        if (critCount == 2 && intervals[0] == intervals[1]) {
+            critCount--;
+        }
+        if (critCount == 2 && intervals[0] > intervals[1]) {
+            double tmp = intervals[0];
+            intervals[0] = intervals[1];
+            intervals[1] = tmp;
+        }
+
+        // below we use critCount to possibly filter out roots that shouldn't
+        // have been computed. We require that eqn[3] != 0, so eqn is a proper
+        // cubic, which means that its limits at -/+inf are -/+inf or +/-inf.
+        // Therefore, if critCount==2, the curve is shaped like a sideways S,
+        // and it could have 1-3 roots. If critCount==0 it is monotonic, and
+        // if critCount==1 it is monotonic with a single point where it is
+        // flat. In the last 2 cases there can only be 1 root. So in cases
+        // where num > 1 but critCount < 2, we eliminate all roots in res
+        // except one.
+
+        if (num == 3) {
+            double xe = getRootUpperBound(eqn);
+            double x0 = -xe;
+
+            Arrays.sort(res, 0, num);
+            if (critCount == 2) {
+                // this just tries to improve the accuracy of the computed
+                // roots using Newton's method.
+                res[0] = refineRootWithHint(eqn, x0, intervals[0], res[0]);
+                res[1] = refineRootWithHint(eqn, intervals[0], intervals[1], res[1]);
+                res[2] = refineRootWithHint(eqn, intervals[1], xe, res[2]);
+                return 3;
+            } else if (critCount == 1) {
+                // we only need fx0 and fxe for the sign of the polynomial
+                // at -inf and +inf respectively, so we don't need to do
+                // fx0 = solveEqn(eqn, 3, x0); fxe = solveEqn(eqn, 3, xe)
+                double fxe = eqn[3];
+                double fx0 = -fxe;
+
+                double x1 = intervals[0];
+                double fx1 = solveEqn(eqn, 3, x1);
+
+                // if critCount == 1 or critCount == 0, but num == 3 then
+                // something has gone wrong. This branch and the one below
+                // would ideally never execute, but if they do we can't know
+                // which of the computed roots is closest to the real root;
+                // therefore, we can't use refineRootWithHint. But even if
+                // we did know, being here most likely means that the
+                // curve is very flat close to two of the computed roots
+                // (or maybe even all three). This might make Newton's method
+                // fail altogether, which would be a pain to detect and fix.
+                // This is why we use a very stable bisection method.
+                if (oppositeSigns(fx0, fx1)) {
+                    res[0] = bisectRootWithHint(eqn, x0, x1, res[0]);
+                } else if (oppositeSigns(fx1, fxe)) {
+                    res[0] = bisectRootWithHint(eqn, x1, xe, res[2]);
+                } else /* fx1 must be 0 */ {
+                    res[0] = x1;
+                }
+                // return 1
+            } else if (critCount == 0) {
+                res[0] = bisectRootWithHint(eqn, x0, xe, res[1]);
+                // return 1
+            }
+        } else if (num == 2 && critCount == 2) {
+            // XXX: here we assume that res[0] has better accuracy than res[1].
+            // This is true because this method is only used from solveCubic
+            // which puts in res[0] the root that it would compute anyway even
+            // if num==1. If this method is ever used from any other method, or
+            // if the solveCubic implementation changes, this assumption should
+            // be reevaluated, and the choice of goodRoot might have to become
+            // goodRoot = (abs(eqn'(res[0])) > abs(eqn'(res[1]))) ? res[0] : res[1]
+            // where eqn' is the derivative of eqn.
+            double goodRoot = res[0];
+            double badRoot = res[1];
+            double x1 = intervals[0];
+            double x2 = intervals[1];
+            // If a cubic curve really has 2 roots, one of those roots must be
+            // at a critical point. That can't be goodRoot, so we compute x to
+            // be the farthest critical point from goodRoot. If there are two
+            // roots, x must be the second one, so we evaluate eqn at x, and if
+            // it is zero (or close enough) we put x in res[1] (or badRoot, if
+            // |solveEqn(eqn, 3, badRoot)| < |solveEqn(eqn, 3, x)| but this
+            // shouldn't happen often).
+            double x = abs(x1 - goodRoot) > abs(x2 - goodRoot) ? x1 : x2;
+            double fx = solveEqn(eqn, 3, x);
+
+            if (iszero(fx, 10000000*ulp(x))) {
+                double badRootVal = solveEqn(eqn, 3, badRoot);
+                res[1] = abs(badRootVal) < abs(fx) ? badRoot : x;
+                return 2;
+            }
+        } // else there can only be one root - goodRoot, and it is already in res[0]
+
+        return 1;
+    }
+
+    // use newton's method.
+    private static double refineRootWithHint(double[] eqn, double min, double max, double t) {
+        if (!inInterval(t, min, max)) {
+            return t;
+        }
+        double[] deriv = {eqn[1], 2*eqn[2], 3*eqn[3]};
+        double origt = t;
         for (int i = 0; i < 3; i++) {
-            double t = res[i];
-            if (Math.abs(t) < EPSILON) {
-                res[i] = findZero(t, 0, eqn);
-            } else if (Math.abs(t - 1) < EPSILON) {
-                res[i] = findZero(t, 1, eqn);
+            double slope = solveEqn(deriv, 2, t);
+            double y = solveEqn(eqn, 3, t);
+            double delta = - (y / slope);
+            double newt = t + delta;
+
+            if (slope == 0 || y == 0 || t == newt) {
+                break;
             }
+
+            t = newt;
         }
+        if (within(t, origt, 1000*ulp(origt)) && inInterval(t, min, max)) {
+            return t;
+        }
+        return origt;
+    }
+
+    private static double bisectRootWithHint(double[] eqn, double x0, double xe, double hint) {
+        double delta1 = Math.min(abs(hint - x0) / 64, 0.0625);
+        double delta2 = Math.min(abs(hint - xe) / 64, 0.0625);
+        double x02 = hint - delta1;
+        double xe2 = hint + delta2;
+        double fx02 = solveEqn(eqn, 3, x02);
+        double fxe2 = solveEqn(eqn, 3, xe2);
+        while (oppositeSigns(fx02, fxe2)) {
+            if (x02 >= xe2) {
+                return x02;
+            }
+            x0 = x02;
+            xe = xe2;
+            delta1 /= 64;
+            delta2 /= 64;
+            x02 = hint - delta1;
+            xe2 = hint + delta2;
+            fx02 = solveEqn(eqn, 3, x02);
+            fxe2 = solveEqn(eqn, 3, xe2);
+        }
+        if (fx02 == 0) {
+            return x02;
+        }
+        if (fxe2 == 0) {
+            return xe2;
+        }
+
+        return bisectRoot(eqn, x0, xe);
+    }
+
+    private static double bisectRoot(double[] eqn, double x0, double xe) {
+        double fx0 = solveEqn(eqn, 3, x0);
+        double m = x0 + (xe - x0) / 2;
+        while (m != x0 && m != xe) {
+            double fm = solveEqn(eqn, 3, m);
+            if (fm == 0) {
+                return m;
+            }
+            if (oppositeSigns(fx0, fm)) {
+                xe = m;
+            } else {
+                fx0 = fm;
+                x0 = m;
+            }
+            m = x0 + (xe-x0)/2;
+        }
+        return m;
+    }
+
+    private static boolean inInterval(double t, double min, double max) {
+        return min <= t && t <= max;
+    }
+
+    private static boolean within(double x, double y, double err) {
+        double d = y - x;
+        return (d <= err && d >= -err);
+    }
+
+    private static boolean iszero(double x, double err) {
+        return within(x, 0, err);
+    }
+
+    private static boolean oppositeSigns(double x1, double x2) {
+        return (x1 < 0 && x2 > 0) || (x1 > 0 && x2 < 0);
     }
 
     private static double solveEqn(double eqn[], int order, double t) {
@@ -1182,60 +1377,26 @@
         return v;
     }
 
-    private static double findZero(double t, double target, double eqn[]) {
-        double slopeqn[] = {eqn[1], 2*eqn[2], 3*eqn[3]};
-        double slope;
-        double origdelta = 0;
-        double origt = t;
-        while (true) {
-            slope = solveEqn(slopeqn, 2, t);
-            if (slope == 0) {
-                // At a local minima - must return
-                return t;
-            }
-            double y = solveEqn(eqn, 3, t);
-            if (y == 0) {
-                // Found it! - return it
-                return t;
-            }
-            // assert(slope != 0 && y != 0);
-            double delta = - (y / slope);
-            // assert(delta != 0);
-            if (origdelta == 0) {
-                origdelta = delta;
-            }
-            if (t < target) {
-                if (delta < 0) return t;
-            } else if (t > target) {
-                if (delta > 0) return t;
-            } else { /* t == target */
-                return (delta > 0
-                        ? (target + java.lang.Double.MIN_VALUE)
-                        : (target - java.lang.Double.MIN_VALUE));
-            }
-            double newt = t + delta;
-            if (t == newt) {
-                // The deltas are so small that we aren't moving...
-                return t;
-            }
-            if (delta * origdelta < 0) {
-                // We have reversed our path.
-                int tag = (origt < t
-                           ? getTag(target, origt, t)
-                           : getTag(target, t, origt));
-                if (tag != INSIDE) {
-                    // Local minima found away from target - return the middle
-                    return (origt + t) / 2;
-                }
-                // Local minima somewhere near target - move to target
-                // and let the slope determine the resulting t.
-                t = target;
-            } else {
-                t = newt;
-            }
-        }
+    /*
+     * Computes M+1 where M is an upper bound for all the roots in of eqn.
+     * See: http://en.wikipedia.org/wiki/Sturm%27s_theorem#Applications.
+     * The above link doesn't contain a proof, but I [dlila] proved it myself
+     * so the result is reliable. The proof isn't difficult, but it's a bit
+     * long to include here.
+     * Precondition: eqn must represent a cubic polynomial
+     */
+    private static double getRootUpperBound(double[] eqn) {
+        double d = eqn[3];
+        double a = eqn[2];
+        double b = eqn[1];
+        double c = eqn[0];
+
+        double M = 1 + max(max(abs(a), abs(b)), abs(c)) / abs(d);
+        M += ulp(M) + 1;
+        return M;
     }
 
+
     /**
      * {@inheritDoc}
      * @since 1.2
@@ -1273,110 +1434,6 @@
         return contains(p.getX(), p.getY());
     }
 
-    /*
-     * Fill an array with the coefficients of the parametric equation
-     * in t, ready for solving against val with solveCubic.
-     * We currently have:
-     * <pre>
-     *   val = P(t) = C1(1-t)^3 + 3CP1 t(1-t)^2 + 3CP2 t^2(1-t) + C2 t^3
-     *              = C1 - 3C1t + 3C1t^2 - C1t^3 +
-     *                3CP1t - 6CP1t^2 + 3CP1t^3 +
-     *                3CP2t^2 - 3CP2t^3 +
-     *                C2t^3
-     *            0 = (C1 - val) +
-     *                (3CP1 - 3C1) t +
-     *                (3C1 - 6CP1 + 3CP2) t^2 +
-     *                (C2 - 3CP2 + 3CP1 - C1) t^3
-     *            0 = C + Bt + At^2 + Dt^3
-     *     C = C1 - val
-     *     B = 3*CP1 - 3*C1
-     *     A = 3*CP2 - 6*CP1 + 3*C1
-     *     D = C2 - 3*CP2 + 3*CP1 - C1
-     * </pre>
-     */
-    private static void fillEqn(double eqn[], double val,
-                                double c1, double cp1, double cp2, double c2) {
-        eqn[0] = c1 - val;
-        eqn[1] = (cp1 - c1) * 3.0;
-        eqn[2] = (cp2 - cp1 - cp1 + c1) * 3.0;
-        eqn[3] = c2 + (cp1 - cp2) * 3.0 - c1;
-        return;
-    }
-
-    /*
-     * Evaluate the t values in the first num slots of the vals[] array
-     * and place the evaluated values back into the same array.  Only
-     * evaluate t values that are within the range <0, 1>, including
-     * the 0 and 1 ends of the range iff the include0 or include1
-     * booleans are true.  If an "inflection" equation is handed in,
-     * then any points which represent a point of inflection for that
-     * cubic equation are also ignored.
-     */
-    private static int evalCubic(double vals[], int num,
-                                 boolean include0,
-                                 boolean include1,
-                                 double inflect[],
-                                 double c1, double cp1,
-                                 double cp2, double c2) {
-        int j = 0;
-        for (int i = 0; i < num; i++) {
-            double t = vals[i];
-            if ((include0 ? t >= 0 : t > 0) &&
-                (include1 ? t <= 1 : t < 1) &&
-                (inflect == null ||
-                 inflect[1] + (2*inflect[2] + 3*inflect[3]*t)*t != 0))
-            {
-                double u = 1 - t;
-                vals[j++] = c1*u*u*u + 3*cp1*t*u*u + 3*cp2*t*t*u + c2*t*t*t;
-            }
-        }
-        return j;
-    }
-
-    private static final int BELOW = -2;
-    private static final int LOWEDGE = -1;
-    private static final int INSIDE = 0;
-    private static final int HIGHEDGE = 1;
-    private static final int ABOVE = 2;
-
-    /*
-     * Determine where coord lies with respect to the range from
-     * low to high.  It is assumed that low <= high.  The return
-     * value is one of the 5 values BELOW, LOWEDGE, INSIDE, HIGHEDGE,
-     * or ABOVE.
-     */
-    private static int getTag(double coord, double low, double high) {
-        if (coord <= low) {
-            return (coord < low ? BELOW : LOWEDGE);
-        }
-        if (coord >= high) {
-            return (coord > high ? ABOVE : HIGHEDGE);
-        }
-        return INSIDE;
-    }
-
-    /*
-     * Determine if the pttag represents a coordinate that is already
-     * in its test range, or is on the border with either of the two
-     * opttags representing another coordinate that is "towards the
-     * inside" of that test range.  In other words, are either of the
-     * two "opt" points "drawing the pt inward"?
-     */
-    private static boolean inwards(int pttag, int opt1tag, int opt2tag) {
-        switch (pttag) {
-        case BELOW:
-        case ABOVE:
-        default:
-            return false;
-        case LOWEDGE:
-            return (opt1tag >= INSIDE || opt2tag >= INSIDE);
-        case INSIDE:
-            return true;
-        case HIGHEDGE:
-            return (opt1tag <= INSIDE || opt2tag <= INSIDE);
-        }
-    }
-
     /**
      * {@inheritDoc}
      * @since 1.2
--- a/src/share/classes/java/io/BufferedReader.java	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/java/io/BufferedReader.java	Tue Feb 15 19:16:39 2011 -0800
@@ -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/src/share/classes/java/io/BufferedWriter.java	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/java/io/BufferedWriter.java	Tue Feb 15 19:16:39 2011 -0800
@@ -57,6 +57,7 @@
  * @see PrintWriter
  * @see FileWriter
  * @see OutputStreamWriter
+ * @see java.nio.file.Files#newBufferedWriter
  *
  * @author      Mark Reinhold
  * @since       JDK1.1
--- a/src/share/classes/java/io/File.java	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/java/io/File.java	Tue Feb 15 19:16:39 2011 -0800
@@ -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/src/share/classes/java/io/FileInputStream.java	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/java/io/FileInputStream.java	Tue Feb 15 19:16:39 2011 -0800
@@ -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/src/share/classes/java/io/FileOutputStream.java	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/java/io/FileOutputStream.java	Tue Feb 15 19:16:39 2011 -0800
@@ -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/src/share/classes/java/io/FilePermission.java	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/java/io/FilePermission.java	Tue Feb 15 19:16:39 2011 -0800
@@ -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/src/share/classes/java/io/PrintStream.java	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/java/io/PrintStream.java	Tue Feb 15 19:16:39 2011 -0800
@@ -70,11 +70,11 @@
     private OutputStreamWriter charOut;
 
     /**
-     * nonNull is explicitly declared here so as not to create an extra
-     * dependency on java.util.Objects.nonNull. PrintStream is loaded
+     * requireNonNull is explicitly declared here so as not to create an extra
+     * dependency on java.util.Objects.requireNonNull. PrintStream is loaded
      * early during system initialization.
      */
-    private static <T> T nonNull(T obj, String message) {
+    private static <T> T requireNonNull(T obj, String message) {
         if (obj == null)
             throw new NullPointerException(message);
         return obj;
@@ -88,7 +88,7 @@
     private static Charset toCharset(String csn)
         throws UnsupportedEncodingException
     {
-        nonNull(csn, "charsetName");
+        requireNonNull(csn, "charsetName");
         try {
             return Charset.forName(csn);
         } catch (IllegalCharsetNameException|UnsupportedCharsetException unused) {
@@ -148,7 +148,7 @@
      * @see java.io.PrintWriter#PrintWriter(java.io.OutputStream, boolean)
      */
     public PrintStream(OutputStream out, boolean autoFlush) {
-        this(autoFlush, nonNull(out, "Null output stream"));
+        this(autoFlush, requireNonNull(out, "Null output stream"));
     }
 
     /**
@@ -173,7 +173,7 @@
         throws UnsupportedEncodingException
     {
         this(autoFlush,
-             nonNull(out, "Null output stream"),
+             requireNonNull(out, "Null output stream"),
              toCharset(encoding));
     }
 
--- a/src/share/classes/java/io/PrintWriter.java	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/java/io/PrintWriter.java	Tue Feb 15 19:16:39 2011 -0800
@@ -82,7 +82,7 @@
     private static Charset toCharset(String csn)
         throws UnsupportedEncodingException
     {
-        Objects.nonNull(csn, "charsetName");
+        Objects.requireNonNull(csn, "charsetName");
         try {
             return Charset.forName(csn);
         } catch (IllegalCharsetNameException|UnsupportedCharsetException unused) {
--- a/src/share/classes/java/io/SerialCallbackContext.java	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/java/io/SerialCallbackContext.java	Tue Feb 15 19:16:39 2011 -0800
@@ -54,5 +54,3 @@
           thread = null;
       }
   }
-
-
--- a/src/share/classes/java/io/TempFileHelper.java	Wed Feb 09 21:20:41 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/src/share/classes/java/lang/StackTraceElement.java	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/java/lang/StackTraceElement.java	Tue Feb 15 19:16:39 2011 -0800
@@ -68,8 +68,8 @@
      */
     public StackTraceElement(String declaringClass, String methodName,
                              String fileName, int lineNumber) {
-        this.declaringClass = Objects.nonNull(declaringClass, "Declaring class is null");
-        this.methodName     = Objects.nonNull(methodName, "Method name is null");
+        this.declaringClass = Objects.requireNonNull(declaringClass, "Declaring class is null");
+        this.methodName     = Objects.requireNonNull(methodName, "Method name is null");
         this.fileName       = fileName;
         this.lineNumber     = lineNumber;
     }
--- a/src/share/classes/java/lang/SuppressWarnings.java	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/java/lang/SuppressWarnings.java	Tue Feb 15 19:16:39 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 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
@@ -44,7 +44,7 @@
  * @since 1.5
  * @author Josh Bloch
  */
-@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, TYPE_PARAMETER})
+@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
 @Retention(RetentionPolicy.SOURCE)
 public @interface SuppressWarnings {
     /**
--- a/src/share/classes/java/lang/Thread.java	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/java/lang/Thread.java	Tue Feb 15 19:16:39 2011 -0800
@@ -690,7 +690,7 @@
         /* Notify the group that this thread is about to be started
          * so that it can be added to the group's list of threads
          * and the group's unstarted count can be decremented. */
-        group.threadStarting(this);
+        group.add(this);
 
         boolean started = false;
         try {
--- a/src/share/classes/java/lang/ThreadGroup.java	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/java/lang/ThreadGroup.java	Tue Feb 15 19:16:39 2011 -0800
@@ -868,21 +868,6 @@
     }
 
     /**
-     * Notifies the group that the thread {@code t} is about to be
-     * started and adds the thread to this thread group.
-     *
-     * The thread is now a fully fledged member of the group, even though
-     * it hasn't been started yet. It will prevent the group from being
-     * destroyed so the unstarted Threads count is decremented.
-     */
-    void threadStarting(Thread t) {
-        synchronized (this) {
-            add(t);
-            nUnstartedThreads--;
-        }
-    }
-
-    /**
      * Adds the specified thread to this thread group.
      *
      * <p> Note: This method is called from both library code
@@ -910,6 +895,12 @@
             // This is done last so it doesn't matter in case the
             // thread is killed
             nthreads++;
+
+            // The thread is now a fully fledged member of the group, even
+            // though it may, or may not, have been started yet. It will prevent
+            // the group from being destroyed so the unstarted Threads count is
+            // decremented.
+            nUnstartedThreads--;
         }
     }
 
--- a/src/share/classes/java/lang/annotation/ElementType.java	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/java/lang/annotation/ElementType.java	Tue Feb 15 19:16:39 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -40,12 +40,6 @@
     /** Class, interface (including annotation type), or enum declaration */
     TYPE,
 
-    /** Uses of a type */
-    TYPE_USE,
-
-    /** type parameters */
-    TYPE_PARAMETER,
-
     /** Field declaration (includes enum constants) */
     FIELD,
 
--- a/src/share/classes/java/math/BigDecimal.java	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/java/math/BigDecimal.java	Tue Feb 15 19:16:39 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -121,8 +121,8 @@
  * scale for each operation is listed in the table below.
  *
  * <table border>
- * <caption top><h3>Preferred Scales for Results of Arithmetic Operations
- * </h3></caption>
+ * <caption><b>Preferred Scales for Results of Arithmetic Operations
+ * </b></caption>
  * <tr><th>Operation</th><th>Preferred Scale of Result</th></tr>
  * <tr><td>Add</td><td>max(addend.scale(), augend.scale())</td>
  * <tr><td>Subtract</td><td>max(minuend.scale(), subtrahend.scale())</td>
@@ -661,25 +661,25 @@
      * <dd>{@code .} <i>FractionPart</i>
      * <dd><i>IntegerPart</i>
      * <p>
-     * <dt><i>IntegerPart:
-     * <dd>Digits</i>
+     * <dt><i>IntegerPart:</i>
+     * <dd><i>Digits</i>
      * <p>
-     * <dt><i>FractionPart:
-     * <dd>Digits</i>
+     * <dt><i>FractionPart:</i>
+     * <dd><i>Digits</i>
      * <p>
-     * <dt><i>Exponent:
-     * <dd>ExponentIndicator SignedInteger</i>
+     * <dt><i>Exponent:</i>
+     * <dd><i>ExponentIndicator SignedInteger</i>
      * <p>
      * <dt><i>ExponentIndicator:</i>
      * <dd>{@code e}
      * <dd>{@code E}
      * <p>
-     * <dt><i>SignedInteger:
-     * <dd>Sign<sub>opt</sub> Digits</i>
+     * <dt><i>SignedInteger:</i>
+     * <dd><i>Sign<sub>opt</sub> Digits</i>
      * <p>
-     * <dt><i>Digits:
-     * <dd>Digit
-     * <dd>Digits Digit</i>
+     * <dt><i>Digits:</i>
+     * <dd><i>Digit</i>
+     * <dd><i>Digits Digit</i>
      * <p>
      * <dt><i>Digit:</i>
      * <dd>any character for which {@link Character#isDigit}
--- a/src/share/classes/java/math/RoundingMode.java	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/java/math/RoundingMode.java	Tue Feb 15 19:16:39 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -53,7 +53,7 @@
  *
  *<p>
  *<table border>
- * <caption top><h3>Summary of Rounding Operations Under Different Rounding Modes</h3></caption>
+ * <caption><b>Summary of Rounding Operations Under Different Rounding Modes</b></caption>
  * <tr><th></th><th colspan=8>Result of rounding input to one digit with the given
  *                           rounding mode</th>
  * <tr valign=top>
--- a/src/share/classes/java/nio/channels/FileChannel.java	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/java/nio/channels/FileChannel.java	Tue Feb 15 19:16:39 2011 -0800
@@ -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/src/share/classes/java/nio/channels/SeekableByteChannel.java	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/java/nio/channels/SeekableByteChannel.java	Tue Feb 15 19:16:39 2011 -0800
@@ -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/src/share/classes/java/nio/file/AccessMode.java	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/java/nio/file/AccessMode.java	Tue Feb 15 19:16:39 2011 -0800
@@ -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/src/share/classes/java/nio/file/CopyMoveHelper.java	Tue Feb 15 19:16:39 2011 -0800
@@ -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/src/share/classes/java/nio/file/CopyOption.java	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/java/nio/file/CopyOption.java	Tue Feb 15 19:16:39 2011 -0800
@@ -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/src/share/classes/java/nio/file/DirectoryIteratorException.java	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/java/nio/file/DirectoryIteratorException.java	Tue Feb 15 19:16:39 2011 -0800
@@ -56,7 +56,7 @@
      *          if the cause is {@code null}
      */
     public DirectoryIteratorException(IOException cause) {
-        super(Objects.nonNull(cause));
+        super(Objects.requireNonNull(cause));
     }
 
     /**
--- a/src/share/classes/java/nio/file/DirectoryStream.java	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/java/nio/file/DirectoryStream.java	Tue Feb 15 19:16:39 2011 -0800
@@ -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/src/share/classes/java/nio/file/FileRef.java	Wed Feb 09 21:20:41 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/src/share/classes/java/nio/file/FileStore.java	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/java/nio/file/FileStore.java	Tue Feb 15 19:16:39 2011 -0800
@@ -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/src/share/classes/java/nio/file/FileSystem.java	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/java/nio/file/FileSystem.java	Tue Feb 15 19:16:39 2011 -0800
@@ -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/src/share/classes/java/nio/file/FileSystems.java	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/java/nio/file/FileSystems.java	Tue Feb 15 19:16:39 2011 -0800
@@ -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/src/share/classes/java/nio/file/FileTreeWalker.java	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/java/nio/file/FileTreeWalker.java	Tue Feb 15 19:16:39 2011 -0800
@@ -69,7 +69,7 @@
         FileVisitResult result = walk(start,
                                       0,
                                       new ArrayList<AncestorDirectory>());
-        Objects.nonNull(result, "FileVisitor returned null");
+        Objects.requireNonNull(result, "FileVisitor returned null");
     }
 
     /**
@@ -102,12 +102,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 +152,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 +176,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 +213,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/src/share/classes/java/nio/file/FileVisitor.java	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/java/nio/file/FileVisitor.java	Tue Feb 15 19:16:39 2011 -0800
@@ -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/src/share/classes/java/nio/file/Files.java	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/java/nio/file/Files.java	Tue Feb 15 19:16:39 2011 -0800
@@ -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,33 +1530,948 @@
      * 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.
      *
@@ -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
     {
-        walkFileTree(start,
-                     EnumSet.noneOf(FileVisitOption.class),
-                     Integer.MAX_VALUE,
-                     visitor);
+        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
+    {
+        CharsetDecoder decoder = cs.newDecoder();
+        Reader reader = new InputStreamReader(newInputStream(path), decoder);
+        return new BufferedReader(reader);
     }
 
     /**
-     * Creates a directory by creating all nonexistent parent directories first.
+     * 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 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> The {@code Writer} methods to write text throw {@code IOException}
+     * if the text cannot be encoded using the specified charset.
      *
-     * <p> If this method fails, then it may do so after creating some, but not
-     * all, of the parent directories.
+     * @param   path
+     *          the path to the file
+     * @param   cs
+     *          the charset to use for encoding
+     * @param   options
+     *          options specifying how the file is opened
      *
-     * @param   dir
-     *          the directory to create
+     * @return  a new buffered writer, with default buffer size, to write text
+     *          to the file
      *
-     * @param   attrs
-     *          an optional list of file attributes to set atomically when
-     *          creating the directory
+     * @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.
      *
-     * @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}
-     *
+     * @see #write(Path,Iterable,Charset,OpenOption[])
      */
-    public static void createDirectories(Path dir, FileAttribute<?>... attrs)
+    public static BufferedWriter newBufferedWriter(Path path, Charset cs,
+                                                   OpenOption... 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
+        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;
+    }
+
+    /**
+     * 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>  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> <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   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
+     *
+     * @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 {@code options} contains a copy option that is not supported
+     * @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. 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 long copy(InputStream in, Path target, CopyOption... options)
+        throws IOException
+    {
+        // ensure not null before opening file
+        Objects.requireNonNull(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;
+        if (replaceExisting) {
+            try {
+                deleteIfExists(target);
+            } catch (SecurityException x) {
+                se = x;
+            }
+        }
+
+        // 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 {
-            dir = dir.toAbsolutePath();
-        } catch (SecurityException x) {
-            // don't have permission to get absolute path
-            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
+            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.requireNonNull(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.requireNonNull(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.requireNonNull(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/src/share/classes/java/nio/file/LinkOption.java	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/java/nio/file/LinkOption.java	Tue Feb 15 19:16:39 2011 -0800
@@ -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/src/share/classes/java/nio/file/LinkPermission.java	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/java/nio/file/LinkPermission.java	Tue Feb 15 19:16:39 2011 -0800
@@ -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/src/share/classes/java/nio/file/OpenOption.java	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/java/nio/file/OpenOption.java	Tue Feb 15 19:16:39 2011 -0800
@@ -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/src/share/classes/java/nio/file/Path.java	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/java/nio/file/Path.java	Tue Feb 15 19:16:39 2011 -0800
@@ -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.
+ * An object that may be used to locate a file in a file system. It will
+ * typically represent a system dependent file path.
  *
- * <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>
- *
- * <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.
+ * 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.
  *
- * <h4>File operations</h4>
+ * <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>
  *
- * <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> <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> In addition to the operations defined by the {@link FileRef} interface,
- * this class defines the following operations:
- *
- * <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> 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;
+    Path toRealPath(boolean resolveLinks) throws IOException;
 
     /**
-     * Copy the file located by this path to a target location.
+     * 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> 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> 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> 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
+     * @return  a {@code File} object representing this path
      *
      * @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")}.
+     *          if this {@code Path} is not associated with the default provider
      */
-    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;
-
-    /**
-     * 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.
-     *
-     * <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> 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
-     *
-     * @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.
-     */
-    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/src/share/classes/java/nio/file/PathMatcher.java	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/java/nio/file/PathMatcher.java	Tue Feb 15 19:16:39 2011 -0800
@@ -32,7 +32,7 @@
  * @since 1.7
  *
  * @see FileSystem#getPathMatcher
- * @see Path#newDirectoryStream(String)
+ * @see Files#newDirectoryStream(Path,String)
  */
 
 public interface PathMatcher {
--- a/src/share/classes/java/nio/file/Paths.java	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/java/nio/file/Paths.java	Tue Feb 15 19:16:39 2011 -0800
@@ -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/src/share/classes/java/nio/file/SecureDirectoryStream.java	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/java/nio/file/SecureDirectoryStream.java	Tue Feb 15 19:16:39 2011 -0800
@@ -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);
 }
--- a/src/share/classes/java/nio/file/SimpleFileVisitor.java	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/java/nio/file/SimpleFileVisitor.java	Tue Feb 15 19:16:39 2011 -0800
@@ -57,8 +57,8 @@
     public FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs)
         throws IOException
     {
-        Objects.nonNull(dir);
-        Objects.nonNull(attrs);
+        Objects.requireNonNull(dir);
+        Objects.requireNonNull(attrs);
         return FileVisitResult.CONTINUE;
     }
 
@@ -72,8 +72,8 @@
     public FileVisitResult visitFile(T file, BasicFileAttributes attrs)
         throws IOException
     {
-        Objects.nonNull(file);
-        Objects.nonNull(attrs);
+        Objects.requireNonNull(file);
+        Objects.requireNonNull(attrs);
         return FileVisitResult.CONTINUE;
     }
 
@@ -87,7 +87,7 @@
     public FileVisitResult visitFileFailed(T file, IOException exc)
         throws IOException
     {
-        Objects.nonNull(file);
+        Objects.requireNonNull(file);
         throw exc;
     }
 
@@ -104,7 +104,7 @@
     public FileVisitResult postVisitDirectory(T dir, IOException exc)
         throws IOException
     {
-        Objects.nonNull(dir);
+        Objects.requireNonNull(dir);
         if (exc != null)
             throw exc;
         return FileVisitResult.CONTINUE;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/nio/file/TempFileHelper.java	Tue Feb 15 19:16:39 2011 -0800
@@ -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/src/share/classes/java/nio/file/WatchEvent.java	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/java/nio/file/WatchEvent.java	Tue Feb 15 19:16:39 2011 -0800
@@ -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/src/share/classes/java/nio/file/WatchKey.java	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/java/nio/file/WatchKey.java	Tue Feb 15 19:16:39 2011 -0800
@@ -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/src/share/classes/java/nio/file/WatchService.java	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/java/nio/file/WatchService.java	Tue Feb 15 19:16:39 2011 -0800
@@ -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/src/share/classes/java/nio/file/attribute/AclEntry.java	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/java/nio/file/attribute/AclEntry.java	Tue Feb 15 19:16:39 2011 -0800
@@ -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/src/share/classes/java/nio/file/attribute/AclFileAttributeView.java	Wed Feb 09 21:20:41 2011 -0800
+++ b/src/share/classes/java/nio/file/attribute/AclFileAttributeView.java	Tue Feb 15 19:16:39 2011 -0800
@@ -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/src/share/classes/java/nio/file/attribute/Attributes.java	Wed Feb 09 21:20:41 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;
-