diff --git a/.hgtags-top-repo b/.hgtags-top-repo
index 7e83ea7..241e1cd 100644
--- a/.hgtags-top-repo
+++ b/.hgtags-top-repo
@@ -23,3 +23,4 @@
 e8a2a4d187773a62f3309b0fa265c13425bc2258 jdk7-b46
 d7744e86dedc21a8ecf6bdb73eb191b8eaf5b0da jdk7-b47
 4ae9f4bfdb98f65bd957e3fe72471b320150b38e jdk7-b48
+aee93a8992d2389121eb610c00a86196f3e2b9b0 jdk7-b49
diff --git a/corba/.hgtags b/corba/.hgtags
index c1c59cf..434fb01 100644
--- a/corba/.hgtags
+++ b/corba/.hgtags
@@ -23,3 +23,4 @@
 1691dbfc08f8ee3f4e23a1ff30cdff920718696c jdk7-b46
 167ad0164301f318b069a947e1c9c07ed667748a jdk7-b47
 0be222241fd405e48915647facfaa176621b39b9 jdk7-b48
+d70978bc64bc7a04be7797ab0dcd9b7b1b3a6bff jdk7-b49
diff --git a/hotspot/.hgtags b/hotspot/.hgtags
index 95ce2df..c1cb5d2 100644
--- a/hotspot/.hgtags
+++ b/hotspot/.hgtags
@@ -23,3 +23,4 @@
 16bb38eeda35b46268eefa4c1f829eb086e0ca46 jdk7-b46
 fcb923bad68e2b10380a030ea83a723f4dc3d4d6 jdk7-b47
 bcb33806d186561c781992e5f4d8a90bb033f9f0 jdk7-b48
+8b22ccb5aba2c6c11bddf6488a7bb7ef5b4bf2be jdk7-b49
diff --git a/jaxp/.hgtags b/jaxp/.hgtags
index a5c20cf..d760b86 100644
--- a/jaxp/.hgtags
+++ b/jaxp/.hgtags
@@ -23,3 +23,4 @@
 b2271877894af809b7703767fe8d4e38591a02a2 jdk7-b46
 d711ad1954b294957737ea386cfd4d3c05028a36 jdk7-b47
 39de90eb4822cafaacc69edd67ab5547e55ae920 jdk7-b48
+5c1f24531903573c1830775432276da567243f9c jdk7-b49
diff --git a/jaxws/.hgtags b/jaxws/.hgtags
index 0229b71..0912b5f 100644
--- a/jaxws/.hgtags
+++ b/jaxws/.hgtags
@@ -23,3 +23,4 @@
 af4a3eeb7812a5d09a241c50b51b3c648a9d45c1 jdk7-b46
 223011570edbd49bb0fe51cdeb2089f95d305267 jdk7-b47
 01e5dd31d0c10a2db3d50db346905d2d3db45e88 jdk7-b48
+18ca864890f3d4ed942ecbffb78c936a57759921 jdk7-b49
diff --git a/jdk/.hgtags b/jdk/.hgtags
index 95051d6..6a5bcb2 100644
--- a/jdk/.hgtags
+++ b/jdk/.hgtags
@@ -23,3 +23,4 @@
 4b03e27a44090d1f646af28dc58f9ead827e24c7 jdk7-b46
 b4ac413b1f129eeef0acab3f31081c1b7dfe3b27 jdk7-b47
 5fbd9ea7def17186693b6f7099b5d0dc73903eee jdk7-b48
+8311105ea7a3db7bcbcb2b696459127c7f2297a4 jdk7-b49
diff --git a/jdk/make/common/Defs-windows.gmk b/jdk/make/common/Defs-windows.gmk
index 7b17849..75da038 100644
--- a/jdk/make/common/Defs-windows.gmk
+++ b/jdk/make/common/Defs-windows.gmk
@@ -398,16 +398,7 @@
   # SA will never be supported here.
   INCLUDE_SA = false
 else
-  # Hopefully, SA will be supported here one of these days,
-  # and these will be changed to true.  Until then,
-  # to build SA on windows, do a control build with
-  #    BUILD_WIN_SA=1
-  # on the make command.
-  ifdef BUILD_WIN_SA
-    INCLUDE_SA = true
-  else
-    INCLUDE_SA = false
-  endif
+  INCLUDE_SA = true
 endif
 
 # Settings for the VERSIONINFO tap on windows. 
diff --git a/jdk/make/docs/CORE_PKGS.gmk b/jdk/make/docs/CORE_PKGS.gmk
index 4a41a20..f9b9ee5 100644
--- a/jdk/make/docs/CORE_PKGS.gmk
+++ b/jdk/make/docs/CORE_PKGS.gmk
@@ -1,5 +1,5 @@
 #
-# Copyright 2001-2008 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2001-2009 Sun Microsystems, Inc.  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
@@ -110,6 +110,9 @@
   java.nio.channels.spi                          \
   java.nio.charset                               \
   java.nio.charset.spi                           \
+  java.nio.file					 \
+  java.nio.file.attribute			 \
+  java.nio.file.spi				 \
   java.rmi                                       \
   java.rmi.activation                            \
   java.rmi.dgc                                   \
diff --git a/jdk/make/docs/NON_CORE_PKGS.gmk b/jdk/make/docs/NON_CORE_PKGS.gmk
index ccf7a0f..6028a85 100644
--- a/jdk/make/docs/NON_CORE_PKGS.gmk
+++ b/jdk/make/docs/NON_CORE_PKGS.gmk
@@ -1,5 +1,5 @@
 #
-# Copyright 2002-2008 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2002-2009 Sun Microsystems, Inc.  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
@@ -65,6 +65,8 @@
 HTTPSERVER_PKGS  = com.sun.net.httpserver       \
                    com.sun.net.httpserver.spi 
 
+NIO_PKGS         = com.sun.nio.file
+
 DOCLETAPI_PKGS   = com.sun.javadoc
 
 TAGLETAPI_FILE   = com/sun/tools/doclets/Taglet.java
@@ -92,6 +94,7 @@
                    $(MGMT_PKGS) \
                    $(JAAS_PKGS) \
                    $(JGSS_PKGS) \
+                   $(NIO_PKGS) \
                    $(OLD_JSSE_PKGS) \
                    $(HTTPSERVER_PKGS) \
                    $(SMARTCARDIO_PKGS) \
diff --git a/jdk/make/java/nio/Exportedfiles.gmk b/jdk/make/java/nio/Exportedfiles.gmk
index 49c4e24..fd8b73f 100644
--- a/jdk/make/java/nio/Exportedfiles.gmk
+++ b/jdk/make/java/nio/Exportedfiles.gmk
@@ -1,5 +1,5 @@
 #
-# Copyright 2000-2005 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2000-2009 Sun Microsystems, Inc.  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
@@ -33,7 +33,7 @@
     sun/nio/ch/DatagramChannelImpl.java \
     sun/nio/ch/DatagramDispatcher.java \
     sun/nio/ch/FileChannelImpl.java \
-    sun/nio/ch/FileDispatcher.java \
+    sun/nio/ch/FileDispatcherImpl.java \
     sun/nio/ch/FileKey.java \
     sun/nio/ch/FileLockImpl.java \
     sun/nio/ch/IOStatus.java \
diff --git a/jdk/make/java/nio/FILES_c.gmk b/jdk/make/java/nio/FILES_c.gmk
index 6f7c3ff..b1670c2 100644
--- a/jdk/make/java/nio/FILES_c.gmk
+++ b/jdk/make/java/nio/FILES_c.gmk
@@ -1,5 +1,5 @@
 #
-# Copyright 2000-2005 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2000-2009 Sun Microsystems, Inc.  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
@@ -27,7 +27,7 @@
         DatagramChannelImpl.c \
         DatagramDispatcher.c \
 	FileChannelImpl.c \
-	FileDispatcher.c \
+	FileDispatcherImpl.c \
 	FileKey.c \
 	IOUtil.c \
         MappedByteBuffer.c \
diff --git a/jdk/make/java/nio/FILES_java.gmk b/jdk/make/java/nio/FILES_java.gmk
index 29f1f8f..5027274 100644
--- a/jdk/make/java/nio/FILES_java.gmk
+++ b/jdk/make/java/nio/FILES_java.gmk
@@ -1,5 +1,5 @@
 #
-# Copyright 2000-2008 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2000-2009 Sun Microsystems, Inc.  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
@@ -31,19 +31,29 @@
 	java/nio/MappedByteBuffer.java \
 	java/nio/StringCharBuffer.java \
 	\
+	java/nio/channels/AsynchronousByteChannel.java \
+	java/nio/channels/AsynchronousChannel.java \
+	java/nio/channels/AsynchronousChannelGroup.java \
+	java/nio/channels/AsynchronousDatagramChannel.java \
+	java/nio/channels/AsynchronousFileChannel.java \
+	java/nio/channels/AsynchronousServerSocketChannel.java \
+	java/nio/channels/AsynchronousSocketChannel.java \
 	java/nio/channels/ByteChannel.java \
 	java/nio/channels/Channel.java \
 	java/nio/channels/Channels.java \
+	java/nio/channels/CompletionHandler.java \
 	java/nio/channels/DatagramChannel.java \
 	java/nio/channels/FileChannel.java \
 	java/nio/channels/FileLock.java \
 	java/nio/channels/GatheringByteChannel.java \
 	java/nio/channels/InterruptibleChannel.java \
+	java/nio/channels/Pipe.java \
 	java/nio/channels/MembershipKey.java \
 	java/nio/channels/MulticastChannel.java \
 	java/nio/channels/NetworkChannel.java \
 	java/nio/channels/ReadableByteChannel.java \
 	java/nio/channels/ScatteringByteChannel.java \
+	java/nio/channels/SeekableByteChannel.java \
 	java/nio/channels/SelectableChannel.java \
 	java/nio/channels/Selector.java \
 	java/nio/channels/SelectionKey.java \
@@ -55,6 +65,7 @@
 	java/nio/channels/spi/AbstractSelectableChannel.java \
 	java/nio/channels/spi/AbstractSelectionKey.java \
 	java/nio/channels/spi/AbstractSelector.java \
+	java/nio/channels/spi/AsynchronousChannelProvider.java \
 	java/nio/channels/spi/SelectorProvider.java \
 	\
 	java/nio/charset/Charset.java \
@@ -66,21 +77,117 @@
 	\
 	java/nio/charset/spi/CharsetProvider.java \
 	\
+	java/nio/file/AccessDeniedException.java \
+	java/nio/file/AccessMode.java \
+	java/nio/file/AtomicMoveNotSupportedException.java \
+	java/nio/file/ClosedDirectoryStreamException.java \
+	java/nio/file/ClosedFileSystemException.java \
+	java/nio/file/ClosedWatchServiceException.java \
+	java/nio/file/CopyOption.java \
+	java/nio/file/DirectoryNotEmptyException.java \
+	java/nio/file/DirectoryStream.java \
+	java/nio/file/DirectoryStreamFilters.java \
+	java/nio/file/FileAction.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 \
+	java/nio/file/FileSystemException.java \
+	java/nio/file/FileSystemNotFoundException.java \
+	java/nio/file/FileSystems.java \
+	java/nio/file/FileTreeWalker.java \
+	java/nio/file/FileVisitOption.java \
+	java/nio/file/FileVisitResult.java \
+	java/nio/file/FileVisitor.java \
+	java/nio/file/Files.java \
+	java/nio/file/InvalidPathException.java \
+	java/nio/file/LinkOption.java \
+	java/nio/file/LinkPermission.java \
+	java/nio/file/NoSuchFileException.java \
+	java/nio/file/NotDirectoryException.java \
+	java/nio/file/NotLinkException.java \
+	java/nio/file/OpenOption.java \
+	java/nio/file/Path.java \
+	java/nio/file/PathMatcher.java \
+	java/nio/file/Paths.java \
+	java/nio/file/ProviderMismatchException.java \
+	java/nio/file/ProviderNotFoundException.java \
+	java/nio/file/ReadOnlyFileSystemException.java \
+	java/nio/file/SecureDirectoryStream.java \
+	java/nio/file/SimpleFileVisitor.java \
+	java/nio/file/StandardCopyOption.java \
+	java/nio/file/StandardOpenOption.java \
+	java/nio/file/StandardWatchEventKind.java \
+	java/nio/file/WatchEvent.java \
+	java/nio/file/WatchKey.java \
+	java/nio/file/WatchService.java \
+	java/nio/file/Watchable.java \
+	\
+	java/nio/file/attribute/AclEntry.java \
+	java/nio/file/attribute/AclEntryFlag.java \
+	java/nio/file/attribute/AclEntryPermission.java \
+	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 \
+	java/nio/file/attribute/DosFileAttributes.java \
+	java/nio/file/attribute/FileAttribute.java \
+	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/GroupPrincipal.java \
+	java/nio/file/attribute/UserDefinedFileAttributeView.java \
+	java/nio/file/attribute/PosixFileAttributeView.java \
+	java/nio/file/attribute/PosixFileAttributes.java \
+	java/nio/file/attribute/PosixFilePermission.java \
+	java/nio/file/attribute/PosixFilePermissions.java \
+	java/nio/file/attribute/UserPrincipal.java \
+	java/nio/file/attribute/UserPrincipalLookupService.java \
+	java/nio/file/attribute/UserPrincipalNotFoundException.java \
+	\
+	java/nio/file/spi/AbstractPath.java \
+	java/nio/file/spi/FileSystemProvider.java \
+	java/nio/file/spi/FileTypeDetector.java \
+	\
+	com/sun/nio/file/ExtendedCopyOption.java \
+	com/sun/nio/file/ExtendedOpenOption.java \
+	com/sun/nio/file/ExtendedWatchEventModifier.java \
+	com/sun/nio/file/SensitivityWatchEventModifier.java \
+	\
 	sun/nio/ByteBuffered.java \
 	\
+	sun/nio/ch/AbstractFuture.java \
         sun/nio/ch/AbstractPollArrayWrapper.java \
 	sun/nio/ch/AllocatedNativeObject.java \
+	sun/nio/ch/AsynchronousChannelGroupImpl.java \
+	sun/nio/ch/AsynchronousFileChannelImpl.java \
+	sun/nio/ch/AsynchronousServerSocketChannelImpl.java \
+	sun/nio/ch/AsynchronousSocketChannelImpl.java \
+	sun/nio/ch/Cancellable.java \
 	sun/nio/ch/ChannelInputStream.java \
+	sun/nio/ch/CompletedFuture.java \
         sun/nio/ch/DatagramChannelImpl.java \
         sun/nio/ch/DatagramDispatcher.java \
 	sun/nio/ch/DatagramSocketAdaptor.java \
+	sun/nio/ch/DefaultAsynchronousChannelProvider.java \
         sun/nio/ch/DefaultSelectorProvider.java \
 	sun/nio/ch/DirectBuffer.java \
 	sun/nio/ch/ExtendedSocketOption.java \
 	sun/nio/ch/FileChannelImpl.java \
 	sun/nio/ch/FileDispatcher.java \
+	sun/nio/ch/FileDispatcherImpl.java \
 	sun/nio/ch/FileKey.java \
+	sun/nio/ch/FileLockImpl.java \
+	sun/nio/ch/FileLockTable.java \
+	sun/nio/ch/Groupable.java \
 	sun/nio/ch/Interruptible.java \
+	sun/nio/ch/Invoker.java \
 	sun/nio/ch/IOUtil.java \
 	sun/nio/ch/IOStatus.java \
 	sun/nio/ch/IOVecWrapper.java \
@@ -92,6 +199,7 @@
 	sun/nio/ch/NativeThreadSet.java \
 	sun/nio/ch/Net.java \
 	sun/nio/ch/OptionKey.java \
+	sun/nio/ch/PendingFuture.java \
 	sun/nio/ch/PipeImpl.java \
 	sun/nio/ch/PollArrayWrapper.java \
 	sun/nio/ch/Reflect.java \
@@ -101,12 +209,14 @@
 	sun/nio/ch/SelChImpl.java \
 	sun/nio/ch/ServerSocketAdaptor.java \
 	sun/nio/ch/ServerSocketChannelImpl.java \
+	sun/nio/ch/SimpleAsynchronousDatagramChannelImpl.java \
         sun/nio/ch/SinkChannelImpl.java \
 	sun/nio/ch/SocketAdaptor.java \
 	sun/nio/ch/SocketChannelImpl.java \
 	sun/nio/ch/SocketDispatcher.java \
 	sun/nio/ch/SocketOptionRegistry.java \
         sun/nio/ch/SourceChannelImpl.java \
+	sun/nio/ch/ThreadPool.java \
 	sun/nio/ch/Util.java \
 	\
 	sun/nio/cs/AbstractCharsetProvider.java \
@@ -134,6 +244,25 @@
 	sun/nio/cs/UTF_32LE_BOM.java \
 	sun/nio/cs/UTF_32Coder.java \
 	\
+	sun/nio/fs/AbstractAclFileAttributeView.java \
+	sun/nio/fs/AbstractBasicFileAttributeView.java \
+	sun/nio/fs/AbstractFileStoreSpaceAttributeView.java \
+	sun/nio/fs/AbstractFileTypeDetector.java \
+	sun/nio/fs/AbstractPoller.java \
+	sun/nio/fs/AbstractUserDefinedFileAttributeView.java \
+	sun/nio/fs/AbstractWatchKey.java \
+	sun/nio/fs/AbstractWatchService.java \
+	sun/nio/fs/BasicFileAttributesHolder.java \
+	sun/nio/fs/Cancellable.java \
+	sun/nio/fs/DefaultFileSystemProvider.java \
+	sun/nio/fs/DefaultFileTypeDetector.java \
+	sun/nio/fs/FileOwnerAttributeViewImpl.java \
+	sun/nio/fs/Globs.java \
+	sun/nio/fs/MimeType.java \
+	sun/nio/fs/NativeBuffer.java \
+	sun/nio/fs/NativeBuffers.java \
+	sun/nio/fs/Reflect.java \
+	\
 	java/net/DatagramSocket.java \
 	java/net/DatagramSocketImpl.java \
 	java/net/PlainSocketImpl.java \
@@ -244,24 +373,31 @@
 	java/nio/InvalidMarkException.java \
 	java/nio/ReadOnlyBufferException.java \
 	\
+	java/nio/channels/AcceptPendingException.java \
 	java/nio/channels/AlreadyBoundException.java \
 	java/nio/channels/AlreadyConnectedException.java \
 	java/nio/channels/AsynchronousCloseException.java \
+	java/nio/channels/CancelledKeyException.java \
 	java/nio/channels/ClosedByInterruptException.java \
 	java/nio/channels/ClosedChannelException.java \
 	java/nio/channels/ClosedSelectorException.java \
 	java/nio/channels/ConnectionPendingException.java \
 	java/nio/channels/FileLockInterruptionException.java \
 	java/nio/channels/IllegalBlockingModeException.java \
+	java/nio/channels/IllegalChannelGroupException.java \
 	java/nio/channels/IllegalSelectorException.java \
+	java/nio/channels/InterruptedByTimeoutException.java \
 	java/nio/channels/NoConnectionPendingException.java \
 	java/nio/channels/NonReadableChannelException.java \
 	java/nio/channels/NonWritableChannelException.java \
 	java/nio/channels/NotYetBoundException.java \
 	java/nio/channels/NotYetConnectedException.java \
 	java/nio/channels/OverlappingFileLockException.java \
+	java/nio/channels/ReadPendingException.java \
+	java/nio/channels/ShutdownChannelGroupException.java \
 	java/nio/channels/UnresolvedAddressException.java \
 	java/nio/channels/UnsupportedAddressTypeException.java \
+	java/nio/channels/WritePendingException.java \
 	\
 	java/nio/charset/CharacterCodingException.java \
 	java/nio/charset/IllegalCharsetNameException.java \
diff --git a/jdk/make/java/nio/Makefile b/jdk/make/java/nio/Makefile
index bf7bc2e..f85cc69 100644
--- a/jdk/make/java/nio/Makefile
+++ b/jdk/make/java/nio/Makefile
@@ -1,5 +1,5 @@
 #
-# Copyright 2000-2008 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2000-2009 Sun Microsystems, Inc.  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
@@ -56,56 +56,214 @@
         sun/nio/ch/DevPollSelectorProvider.java \
 	sun/nio/ch/InheritedChannel.java \
         sun/nio/ch/PollSelectorProvider.java \
-        sun/nio/ch/PollSelectorImpl.java
+        sun/nio/ch/PollSelectorImpl.java \
+	sun/nio/ch/Port.java \
+	sun/nio/ch/SimpleAsynchronousFileChannelImpl.java \
+	sun/nio/ch/SolarisAsynchronousChannelProvider.java \
+	sun/nio/ch/SolarisEventPort.java \
+	sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.java \
+	sun/nio/ch/UnixAsynchronousSocketChannelImpl.java \
+	\
+	sun/nio/fs/GnomeFileTypeDetector.java \
+	sun/nio/fs/PollingWatchService.java \
+	sun/nio/fs/SolarisAclFileAttributeView.java \
+	sun/nio/fs/SolarisFileStore.java \
+	sun/nio/fs/SolarisFileSystem.java \
+	sun/nio/fs/SolarisFileSystemProvider.java \
+	sun/nio/fs/SolarisUserDefinedFileAttributeView.java \
+	sun/nio/fs/SolarisNativeDispatcher.java \
+	sun/nio/fs/SolarisWatchService.java \
+	sun/nio/fs/UnixChannelFactory.java \
+	sun/nio/fs/UnixCopyFile.java \
+	sun/nio/fs/UnixDirectoryStream.java \
+	sun/nio/fs/UnixException.java \
+	sun/nio/fs/UnixFileAttributeViews.java \
+	sun/nio/fs/UnixFileAttributes.java \
+	sun/nio/fs/UnixFileKey.java \
+	sun/nio/fs/UnixFileModeAttribute.java \
+	sun/nio/fs/UnixFileStore.java \
+	sun/nio/fs/UnixFileStoreAttributes.java \
+	sun/nio/fs/UnixFileSystem.java \
+	sun/nio/fs/UnixFileSystemProvider.java \
+	sun/nio/fs/UnixMountEntry.java \
+	sun/nio/fs/UnixNativeDispatcher.java \
+	sun/nio/fs/UnixPath.java \
+	sun/nio/fs/UnixSecureDirectoryStream.java \
+	sun/nio/fs/UnixUriUtils.java \
+	sun/nio/fs/UnixUserPrincipals.java
 
 FILES_c += \
         DevPollArrayWrapper.c \
 	InheritedChannel.c \
 	NativeThread.c \
-        PollArrayWrapper.c
+        PollArrayWrapper.c \
+	SolarisEventPort.c \
+	UnixAsynchronousServerSocketChannelImpl.c \
+	UnixAsynchronousSocketChannelImpl.c \
+	\
+	GnomeFileTypeDetector.c \
+	SolarisNativeDispatcher.c \
+	SolarisWatchService.c \
+	UnixCopyFile.c \
+	UnixNativeDispatcher.c
 
 FILES_export += \
 	sun/nio/ch/DevPollArrayWrapper.java \
 	sun/nio/ch/InheritedChannel.java \
-	sun/nio/ch/NativeThread.java
+	sun/nio/ch/NativeThread.java \
+	sun/nio/ch/SolarisEventPort.java \
+	sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.java \
+	sun/nio/ch/UnixAsynchronousSocketChannelImpl.java \
+	\
+	sun/nio/fs/GnomeFileTypeDetector.java \
+	sun/nio/fs/SolarisNativeDispatcher.java \
+	sun/nio/fs/SolarisWatchService.java \
+	sun/nio/fs/UnixCopyFile.java \
+	sun/nio/fs/UnixNativeDispatcher.java
+
+FILES_gen += \
+	sun/nio/fs/SolarisConstants.java \
+	sun/nio/fs/UnixConstants.java
 endif # PLATFORM = solaris
 
 ifeq ($(PLATFORM), windows)
 FILES_java += \
+	sun/nio/ch/Iocp.java \
+	sun/nio/ch/PendingIoCache.java \
+	sun/nio/ch/WindowsAsynchronousChannelProvider.java \
+	sun/nio/ch/WindowsAsynchronousFileChannelImpl.java \
+	sun/nio/ch/WindowsAsynchronousServerSocketChannelImpl.java \
+	sun/nio/ch/WindowsAsynchronousSocketChannelImpl.java \
         sun/nio/ch/WindowsSelectorImpl.java \
-        sun/nio/ch/WindowsSelectorProvider.java
+        sun/nio/ch/WindowsSelectorProvider.java \
+	\
+	sun/nio/fs/RegistryFileTypeDetector.java \
+	sun/nio/fs/WindowsAclFileAttributeView.java \
+	sun/nio/fs/WindowsChannelFactory.java \
+	sun/nio/fs/WindowsConstants.java \
+	sun/nio/fs/WindowsDirectoryStream.java \
+	sun/nio/fs/WindowsException.java \
+	sun/nio/fs/WindowsFileAttributeViews.java \
+	sun/nio/fs/WindowsFileAttributes.java \
+	sun/nio/fs/WindowsFileCopy.java \
+	sun/nio/fs/WindowsFileStore.java \
+	sun/nio/fs/WindowsFileSystem.java \
+	sun/nio/fs/WindowsFileSystemProvider.java \
+	sun/nio/fs/WindowsLinkSupport.java \
+	sun/nio/fs/WindowsUserDefinedFileAttributeView.java \
+	sun/nio/fs/WindowsNativeDispatcher.java \
+	sun/nio/fs/WindowsPath.java \
+	sun/nio/fs/WindowsPathParser.java \
+	sun/nio/fs/WindowsPathType.java \
+	sun/nio/fs/WindowsSecurity.java \
+	sun/nio/fs/WindowsSecurityDescriptor.java \
+	sun/nio/fs/WindowsUriSupport.java \
+	sun/nio/fs/WindowsUserPrincipals.java \
+	sun/nio/fs/WindowsWatchService.java
 
 FILES_c += \
+	Iocp.c \
+	RegistryFileTypeDetector.c \
+	WindowsAsynchronousFileChannelImpl.c \
+	WindowsAsynchronousServerSocketChannelImpl.c \
+	WindowsAsynchronousSocketChannelImpl.c \
+	WindowsNativeDispatcher.c \
         WindowsSelectorImpl.c
 
 FILES_export += \
-	sun/nio/ch/WindowsSelectorImpl.java
+	sun/nio/ch/Iocp.java \
+	sun/nio/ch/WindowsAsynchronousFileChannelImpl.java \
+	sun/nio/ch/WindowsAsynchronousServerSocketChannelImpl.java \
+	sun/nio/ch/WindowsAsynchronousSocketChannelImpl.java \
+	sun/nio/ch/WindowsSelectorImpl.java \
+	sun/nio/fs/WindowsNativeDispatcher.java \
+	sun/nio/fs/RegistryFileTypeDetector.java
 endif # PLATFORM = windows
 
 ifeq ($(PLATFORM), linux)
 FILES_java += \
         sun/nio/ch/AbstractPollSelectorImpl.java \
+	sun/nio/ch/EPoll.java \
 	sun/nio/ch/EPollArrayWrapper.java \
+	sun/nio/ch/EPollPort.java \
 	sun/nio/ch/EPollSelectorProvider.java \
 	sun/nio/ch/EPollSelectorImpl.java \
 	sun/nio/ch/InheritedChannel.java \
+	sun/nio/ch/LinuxAsynchronousChannelProvider.java \
         sun/nio/ch/PollSelectorProvider.java \
-        sun/nio/ch/PollSelectorImpl.java
+        sun/nio/ch/PollSelectorImpl.java \
+	sun/nio/ch/Port.java \
+	sun/nio/ch/SimpleAsynchronousFileChannelImpl.java \
+	sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.java \
+	sun/nio/ch/UnixAsynchronousSocketChannelImpl.java \
+	\
+	sun/nio/fs/GnomeFileTypeDetector.java \
+	sun/nio/fs/LinuxDosFileAttributeView.java \
+	sun/nio/fs/LinuxFileStore.java \
+	sun/nio/fs/LinuxFileSystem.java \
+	sun/nio/fs/LinuxFileSystemProvider.java \
+	sun/nio/fs/LinuxUserDefinedFileAttributeView.java \
+	sun/nio/fs/LinuxNativeDispatcher.java \
+	sun/nio/fs/LinuxWatchService.java \
+	sun/nio/fs/PollingWatchService.java \
+	sun/nio/fs/UnixChannelFactory.java \
+	sun/nio/fs/UnixCopyFile.java \
+	sun/nio/fs/UnixDirectoryStream.java \
+	sun/nio/fs/UnixException.java \
+	sun/nio/fs/UnixFileAttributeViews.java \
+	sun/nio/fs/UnixFileAttributes.java \
+	sun/nio/fs/UnixFileKey.java \
+	sun/nio/fs/UnixFileModeAttribute.java \
+	sun/nio/fs/UnixFileStore.java \
+	sun/nio/fs/UnixFileStoreAttributes.java \
+	sun/nio/fs/UnixFileSystem.java \
+	sun/nio/fs/UnixFileSystemProvider.java \
+	sun/nio/fs/UnixMountEntry.java \
+	sun/nio/fs/UnixNativeDispatcher.java \
+	sun/nio/fs/UnixPath.java \
+	sun/nio/fs/UnixSecureDirectoryStream.java \
+	sun/nio/fs/UnixUriUtils.java \
+	sun/nio/fs/UnixUserPrincipals.java
 
 FILES_c += \
+	EPoll.c \
 	EPollArrayWrapper.c \
+	EPollPort.c \
 	InheritedChannel.c \
 	NativeThread.c \
-        PollArrayWrapper.c
+        PollArrayWrapper.c \
+	UnixAsynchronousServerSocketChannelImpl.c \
+	UnixAsynchronousSocketChannelImpl.c \
+	\
+	GnomeFileTypeDetector.c \
+	LinuxNativeDispatcher.c \
+	LinuxWatchService.c \
+	UnixCopyFile.c \
+	UnixNativeDispatcher.c
 
 FILES_export += \
+	sun/nio/ch/EPoll.java \
         sun/nio/ch/EPollArrayWrapper.java \
+	sun/nio/ch/EPollPort.java \
 	sun/nio/ch/InheritedChannel.java \
-	sun/nio/ch/NativeThread.java
+	sun/nio/ch/NativeThread.java \
+	sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.java \
+	sun/nio/ch/UnixAsynchronousSocketChannelImpl.java \
+	\
+	sun/nio/fs/GnomeFileTypeDetector.java \
+	sun/nio/fs/LinuxNativeDispatcher.java \
+	sun/nio/fs/LinuxWatchService.java \
+	sun/nio/fs/UnixCopyFile.java \
+	sun/nio/fs/UnixNativeDispatcher.java
+	
+FILES_gen += \
+	sun/nio/fs/UnixConstants.java
 endif # PLATFORM = linux
 
+#
 # Find platform-specific C source files
 #
+vpath %.c $(PLATFORM_SRC)/native/sun/nio/fs
 vpath %.c $(PLATFORM_SRC)/native/sun/nio/ch
 vpath %.c $(SHARE_SRC)/native/sun/nio/ch
 
@@ -175,12 +333,14 @@
 CS_SRC=$(NIO_SRC)/charset
 SCH_SRC=$(SNIO_SRC)/ch
 SCS_SRC=$(SNIO_SRC)/cs
+SFS_SRC=$(SNIO_SRC)/fs
 
 BUF_GEN=$(NIO_GEN)
 CH_GEN=$(NIO_GEN)/channels
 CS_GEN=$(NIO_GEN)/charset
 SCH_GEN=$(SNIO_GEN)/ch
 SCS_GEN=$(SNIO_GEN)/cs
+SFS_GEN=$(SNIO_GEN)/fs
 
 FILES_gensbcs_out = $(FILES_gen_sbcs:%.java=$(GENSRCDIR)/%.java)
 
@@ -670,4 +830,40 @@
 	$(BOOT_JAVA_CMD) -cp $(CHARSETMAPPING_JARFILE) build.tools.charsetmapping.GenerateSBCS \
 		$(GENCSSRC) $(SCS_GEN) sbcs
 
+# 
+# Generated file system implementation classes (Unix only)
+#
+
+GENUC_SRC = $(PLATFORM_SRC)/native/sun/nio/fs/genUnixConstants.c
+
+GENUC_EXE = $(TEMPDIR)/genUnixConstants
+
+GENUC_COPYRIGHT_YEARS = $(shell $(CAT) $(GENUC_SRC) | \
+	$(NAWK) '/^.*Copyright.*Sun/ { print $$3 }')
+
+$(GENUC_EXE) : $(GENUC_SRC)
+	$(prep-target)
+	$(CC) $(CPPFLAGS) -o $@ $(GENUC_SRC)
+
+$(SFS_GEN)/UnixConstants.java: $(GENUC_EXE)
+	$(prep-target)
+	NAWK="$(NAWK)" SH="$(SH)" $(SH) -e addNotices.sh $(GENUC_COPYRIGHT_YEARS) > $@
+	$(GENUC_EXE) >> $@
+
+GENSC_SRC = $(PLATFORM_SRC)/native/sun/nio/fs/genSolarisConstants.c
+
+GENSC_EXE = $(TEMPDIR)/genSolarisConstants
+
+GENSC_COPYRIGHT_YEARS = $(shell $(CAT) $(GENSC_SRC) | \
+	$(NAWK) '/^.*Copyright.*Sun/ { print $$3 }')
+
+$(GENSC_EXE) : $(GENSC_SRC)
+	$(prep-target)
+	$(CC) $(CPPFLAGS) -o $@ $(GENSC_SRC)
+
+$(SFS_GEN)/SolarisConstants.java: $(GENSC_EXE)
+	$(prep-target)
+	NAWK="$(NAWK)" SH="$(SH)" $(SH) -e addNotices.sh $(GENSC_COPYRIGHT_YEARS) > $@
+	$(GENSC_EXE) >> $@
+
 .PHONY: sources 
diff --git a/jdk/make/java/nio/mapfile-linux b/jdk/make/java/nio/mapfile-linux
index 3fb47b0..0bd2408 100644
--- a/jdk/make/java/nio/mapfile-linux
+++ b/jdk/make/java/nio/mapfile-linux
@@ -1,5 +1,5 @@
 #
-# Copyright 2001-2008 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2001-2009 Sun Microsystems, Inc.  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,27 +44,38 @@
 		Java_sun_nio_ch_EPollArrayWrapper_interrupt;
 		Java_sun_nio_ch_EPollArrayWrapper_offsetofData;
 		Java_sun_nio_ch_EPollArrayWrapper_sizeofEPollEvent;
+		Java_sun_nio_ch_EPoll_init;
+		Java_sun_nio_ch_EPoll_eventSize;
+		Java_sun_nio_ch_EPoll_eventsOffset;
+		Java_sun_nio_ch_EPoll_dataOffset;
+		Java_sun_nio_ch_EPoll_epollCreate;
+		Java_sun_nio_ch_EPoll_epollCtl;
+		Java_sun_nio_ch_EPoll_epollWait;
+		Java_sun_nio_ch_EPollPort_close0;
+		Java_sun_nio_ch_EPollPort_drain1;
+		Java_sun_nio_ch_EPollPort_interrupt;
+		Java_sun_nio_ch_EPollPort_socketpair;
                 Java_sun_nio_ch_FileChannelImpl_close0;
-                Java_sun_nio_ch_FileChannelImpl_force0;
                 Java_sun_nio_ch_FileChannelImpl_initIDs;
-                Java_sun_nio_ch_FileChannelImpl_lock0;
                 Java_sun_nio_ch_FileChannelImpl_map0;
                 Java_sun_nio_ch_FileChannelImpl_position0;
-                Java_sun_nio_ch_FileChannelImpl_release0;
-                Java_sun_nio_ch_FileChannelImpl_size0;
                 Java_sun_nio_ch_FileChannelImpl_transferTo0;
-                Java_sun_nio_ch_FileChannelImpl_truncate0;
                 Java_sun_nio_ch_FileChannelImpl_unmap0;
-                Java_sun_nio_ch_FileDispatcher_close0;
-                Java_sun_nio_ch_FileDispatcher_closeIntFD;
-                Java_sun_nio_ch_FileDispatcher_init;
-                Java_sun_nio_ch_FileDispatcher_preClose0;
-                Java_sun_nio_ch_FileDispatcher_pread0;
-                Java_sun_nio_ch_FileDispatcher_pwrite0;
-                Java_sun_nio_ch_FileDispatcher_read0;
-                Java_sun_nio_ch_FileDispatcher_readv0;
-                Java_sun_nio_ch_FileDispatcher_write0;
-                Java_sun_nio_ch_FileDispatcher_writev0;
+                Java_sun_nio_ch_FileDispatcherImpl_close0;
+                Java_sun_nio_ch_FileDispatcherImpl_closeIntFD;
+		Java_sun_nio_ch_FileDispatcherImpl_force0;
+                Java_sun_nio_ch_FileDispatcherImpl_init;
+		Java_sun_nio_ch_FileDispatcherImpl_lock0;
+                Java_sun_nio_ch_FileDispatcherImpl_preClose0;
+                Java_sun_nio_ch_FileDispatcherImpl_pread0;
+                Java_sun_nio_ch_FileDispatcherImpl_pwrite0;
+                Java_sun_nio_ch_FileDispatcherImpl_read0;
+                Java_sun_nio_ch_FileDispatcherImpl_readv0;
+		Java_sun_nio_ch_FileDispatcherImpl_release0;
+		Java_sun_nio_ch_FileDispatcherImpl_size0;
+		Java_sun_nio_ch_FileDispatcherImpl_truncate0;
+                Java_sun_nio_ch_FileDispatcherImpl_write0;
+                Java_sun_nio_ch_FileDispatcherImpl_writev0;
                 Java_sun_nio_ch_FileKey_init;
                 Java_sun_nio_ch_FileKey_initIDs;
 		Java_sun_nio_ch_InheritedChannel_close0;
@@ -108,6 +119,76 @@
                 Java_sun_nio_ch_ServerSocketChannelImpl_accept0;
                 Java_sun_nio_ch_ServerSocketChannelImpl_initIDs;
                 Java_sun_nio_ch_SocketChannelImpl_checkConnect;
+		Java_sun_nio_ch_UnixAsynchronousServerSocketChannelImpl_accept0;
+		Java_sun_nio_ch_UnixAsynchronousServerSocketChannelImpl_initIDs;
+		Java_sun_nio_ch_UnixAsynchronousSocketChannelImpl_checkConnect;
+		Java_sun_nio_fs_GnomeFileTypeDetector_initializeGio;
+		Java_sun_nio_fs_GnomeFileTypeDetector_probeUsingGio;
+		Java_sun_nio_fs_GnomeFileTypeDetector_initializeGnomeVfs;
+		Java_sun_nio_fs_GnomeFileTypeDetector_probeUsingGnomeVfs;
+		Java_sun_nio_fs_LinuxWatchService_init;
+		Java_sun_nio_fs_LinuxWatchService_eventSize;
+		Java_sun_nio_fs_LinuxWatchService_eventOffsets;
+		Java_sun_nio_fs_LinuxWatchService_inotifyInit;
+		Java_sun_nio_fs_LinuxWatchService_inotifyAddWatch;
+		Java_sun_nio_fs_LinuxWatchService_inotifyRmWatch;
+		Java_sun_nio_fs_LinuxWatchService_configureBlocking;
+		Java_sun_nio_fs_LinuxWatchService_socketpair;
+		Java_sun_nio_fs_LinuxWatchService_poll;
+		Java_sun_nio_fs_LinuxNativeDispatcher_init;
+		Java_sun_nio_fs_LinuxNativeDispatcher_fgetxattr0;
+		Java_sun_nio_fs_LinuxNativeDispatcher_flistxattr;
+		Java_sun_nio_fs_LinuxNativeDispatcher_fsetxattr0;
+		Java_sun_nio_fs_LinuxNativeDispatcher_fremovexattr0;
+		Java_sun_nio_fs_LinuxNativeDispatcher_setmntent0;
+		Java_sun_nio_fs_LinuxNativeDispatcher_endmntent;
+		Java_sun_nio_fs_UnixNativeDispatcher_initIDs;
+		Java_sun_nio_fs_UnixNativeDispatcher_getcwd;
+		Java_sun_nio_fs_UnixNativeDispatcher_strerror;
+		Java_sun_nio_fs_UnixNativeDispatcher_dup;
+		Java_sun_nio_fs_UnixNativeDispatcher_access0;
+		Java_sun_nio_fs_UnixNativeDispatcher_stat0;
+		Java_sun_nio_fs_UnixNativeDispatcher_lstat0;
+		Java_sun_nio_fs_UnixNativeDispatcher_fstat;
+		Java_sun_nio_fs_UnixNativeDispatcher_fstatat0;
+		Java_sun_nio_fs_UnixNativeDispatcher_chmod0;
+		Java_sun_nio_fs_UnixNativeDispatcher_fchmod;
+		Java_sun_nio_fs_UnixNativeDispatcher_chown0;
+		Java_sun_nio_fs_UnixNativeDispatcher_lchown0;
+		Java_sun_nio_fs_UnixNativeDispatcher_fchown;
+		Java_sun_nio_fs_UnixNativeDispatcher_utimes0;
+		Java_sun_nio_fs_UnixNativeDispatcher_futimes;
+		Java_sun_nio_fs_UnixNativeDispatcher_open0;
+		Java_sun_nio_fs_UnixNativeDispatcher_openat0;
+		Java_sun_nio_fs_UnixNativeDispatcher_close;
+		Java_sun_nio_fs_UnixNativeDispatcher_read;
+		Java_sun_nio_fs_UnixNativeDispatcher_write;
+		Java_sun_nio_fs_UnixNativeDispatcher_fopen0;
+		Java_sun_nio_fs_UnixNativeDispatcher_fclose;
+		Java_sun_nio_fs_UnixNativeDispatcher_opendir0;
+		Java_sun_nio_fs_UnixNativeDispatcher_fdopendir;
+		Java_sun_nio_fs_UnixNativeDispatcher_readdir;
+		Java_sun_nio_fs_UnixNativeDispatcher_closedir;
+		Java_sun_nio_fs_UnixNativeDispatcher_link0;
+		Java_sun_nio_fs_UnixNativeDispatcher_unlink0;
+		Java_sun_nio_fs_UnixNativeDispatcher_unlinkat0;
+		Java_sun_nio_fs_UnixNativeDispatcher_rename0;
+		Java_sun_nio_fs_UnixNativeDispatcher_renameat0;
+		Java_sun_nio_fs_UnixNativeDispatcher_mkdir0;
+		Java_sun_nio_fs_UnixNativeDispatcher_rmdir0;
+		Java_sun_nio_fs_UnixNativeDispatcher_symlink0;
+		Java_sun_nio_fs_UnixNativeDispatcher_readlink0;
+		Java_sun_nio_fs_UnixNativeDispatcher_realpath0;
+		Java_sun_nio_fs_UnixNativeDispatcher_statvfs0;
+		Java_sun_nio_fs_UnixNativeDispatcher_pathconf0;
+		Java_sun_nio_fs_UnixNativeDispatcher_fpathconf;
+		Java_sun_nio_fs_UnixNativeDispatcher_mknod0;
+		Java_sun_nio_fs_UnixNativeDispatcher_getpwuid;
+		Java_sun_nio_fs_UnixNativeDispatcher_getgrgid;
+		Java_sun_nio_fs_UnixNativeDispatcher_getpwnam0;
+		Java_sun_nio_fs_UnixNativeDispatcher_getgrnam0;
+		Java_sun_nio_fs_UnixNativeDispatcher_getextmntent;
+		Java_sun_nio_fs_UnixCopyFile_transfer;
 
 	local:
 		*;
diff --git a/jdk/make/java/nio/mapfile-solaris b/jdk/make/java/nio/mapfile-solaris
index 6e109e2..2192a5a 100644
--- a/jdk/make/java/nio/mapfile-solaris
+++ b/jdk/make/java/nio/mapfile-solaris
@@ -1,5 +1,5 @@
 #
-# Copyright 2001-2008 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2001-2009 Sun Microsystems, Inc.  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
@@ -43,26 +43,26 @@
                 Java_sun_nio_ch_DevPollArrayWrapper_register;
                 Java_sun_nio_ch_DevPollArrayWrapper_registerMultiple;
                 Java_sun_nio_ch_FileChannelImpl_close0;
-                Java_sun_nio_ch_FileChannelImpl_force0;
                 Java_sun_nio_ch_FileChannelImpl_initIDs;
-                Java_sun_nio_ch_FileChannelImpl_lock0;
                 Java_sun_nio_ch_FileChannelImpl_map0;
                 Java_sun_nio_ch_FileChannelImpl_position0;
-                Java_sun_nio_ch_FileChannelImpl_release0;
-                Java_sun_nio_ch_FileChannelImpl_size0;
                 Java_sun_nio_ch_FileChannelImpl_transferTo0;
-                Java_sun_nio_ch_FileChannelImpl_truncate0;
                 Java_sun_nio_ch_FileChannelImpl_unmap0;
-                Java_sun_nio_ch_FileDispatcher_close0;
-                Java_sun_nio_ch_FileDispatcher_closeIntFD;
-                Java_sun_nio_ch_FileDispatcher_init;
-                Java_sun_nio_ch_FileDispatcher_preClose0;
-                Java_sun_nio_ch_FileDispatcher_pread0;
-                Java_sun_nio_ch_FileDispatcher_pwrite0;
-                Java_sun_nio_ch_FileDispatcher_read0;
-                Java_sun_nio_ch_FileDispatcher_readv0;
-                Java_sun_nio_ch_FileDispatcher_write0;
-                Java_sun_nio_ch_FileDispatcher_writev0;
+                Java_sun_nio_ch_FileDispatcherImpl_close0;
+                Java_sun_nio_ch_FileDispatcherImpl_closeIntFD;
+		Java_sun_nio_ch_FileDispatcherImpl_force0;
+                Java_sun_nio_ch_FileDispatcherImpl_init;
+		Java_sun_nio_ch_FileDispatcherImpl_lock0;
+                Java_sun_nio_ch_FileDispatcherImpl_preClose0;
+                Java_sun_nio_ch_FileDispatcherImpl_pread0;
+                Java_sun_nio_ch_FileDispatcherImpl_pwrite0;
+                Java_sun_nio_ch_FileDispatcherImpl_read0;
+                Java_sun_nio_ch_FileDispatcherImpl_readv0;
+		Java_sun_nio_ch_FileDispatcherImpl_release0;
+		Java_sun_nio_ch_FileDispatcherImpl_size0;
+		Java_sun_nio_ch_FileDispatcherImpl_truncate0;
+                Java_sun_nio_ch_FileDispatcherImpl_write0;
+                Java_sun_nio_ch_FileDispatcherImpl_writev0;
                 Java_sun_nio_ch_FileKey_init;
                 Java_sun_nio_ch_FileKey_initIDs;
 		Java_sun_nio_ch_InheritedChannel_close0;
@@ -106,6 +106,75 @@
                 Java_sun_nio_ch_ServerSocketChannelImpl_accept0;
                 Java_sun_nio_ch_ServerSocketChannelImpl_initIDs;
                 Java_sun_nio_ch_SocketChannelImpl_checkConnect;
+		Java_sun_nio_ch_UnixAsynchronousServerSocketChannelImpl_accept0;
+		Java_sun_nio_ch_UnixAsynchronousServerSocketChannelImpl_initIDs;
+		Java_sun_nio_ch_UnixAsynchronousSocketChannelImpl_checkConnect;
+		Java_sun_nio_ch_SolarisEventPort_init;
+		Java_sun_nio_ch_SolarisEventPort_portCreate;
+		Java_sun_nio_ch_SolarisEventPort_portClose;
+		Java_sun_nio_ch_SolarisEventPort_portAssociate;
+		Java_sun_nio_ch_SolarisEventPort_portGet;
+		Java_sun_nio_ch_SolarisEventPort_portGetn;
+		Java_sun_nio_ch_SolarisEventPort_portSend;
+		Java_sun_nio_fs_GnomeFileTypeDetector_initializeGio;
+		Java_sun_nio_fs_GnomeFileTypeDetector_probeUsingGio;
+		Java_sun_nio_fs_GnomeFileTypeDetector_initializeGnomeVfs;
+		Java_sun_nio_fs_GnomeFileTypeDetector_probeUsingGnomeVfs;
+		Java_sun_nio_fs_UnixNativeDispatcher_initIDs;
+		Java_sun_nio_fs_UnixNativeDispatcher_getcwd;
+		Java_sun_nio_fs_UnixNativeDispatcher_strerror;
+		Java_sun_nio_fs_UnixNativeDispatcher_dup;
+		Java_sun_nio_fs_UnixNativeDispatcher_access0;
+		Java_sun_nio_fs_UnixNativeDispatcher_stat0;
+		Java_sun_nio_fs_UnixNativeDispatcher_lstat0;
+		Java_sun_nio_fs_UnixNativeDispatcher_fstat;
+		Java_sun_nio_fs_UnixNativeDispatcher_fstatat0;
+		Java_sun_nio_fs_UnixNativeDispatcher_chmod0;
+		Java_sun_nio_fs_UnixNativeDispatcher_fchmod;
+		Java_sun_nio_fs_UnixNativeDispatcher_chown0;
+		Java_sun_nio_fs_UnixNativeDispatcher_lchown0;
+		Java_sun_nio_fs_UnixNativeDispatcher_fchown;
+		Java_sun_nio_fs_UnixNativeDispatcher_utimes0;
+		Java_sun_nio_fs_UnixNativeDispatcher_futimes;
+		Java_sun_nio_fs_UnixNativeDispatcher_open0;
+		Java_sun_nio_fs_UnixNativeDispatcher_openat0;
+		Java_sun_nio_fs_UnixNativeDispatcher_close;
+		Java_sun_nio_fs_UnixNativeDispatcher_read;
+		Java_sun_nio_fs_UnixNativeDispatcher_write;
+		Java_sun_nio_fs_UnixNativeDispatcher_fopen0;
+		Java_sun_nio_fs_UnixNativeDispatcher_fclose;
+		Java_sun_nio_fs_UnixNativeDispatcher_opendir0;
+		Java_sun_nio_fs_UnixNativeDispatcher_fdopendir;
+		Java_sun_nio_fs_UnixNativeDispatcher_readdir;
+		Java_sun_nio_fs_UnixNativeDispatcher_closedir;
+		Java_sun_nio_fs_UnixNativeDispatcher_link0;
+		Java_sun_nio_fs_UnixNativeDispatcher_unlink0;
+		Java_sun_nio_fs_UnixNativeDispatcher_unlinkat0;
+		Java_sun_nio_fs_UnixNativeDispatcher_rename0;
+		Java_sun_nio_fs_UnixNativeDispatcher_renameat0;
+		Java_sun_nio_fs_UnixNativeDispatcher_mkdir0;
+		Java_sun_nio_fs_UnixNativeDispatcher_rmdir0;
+		Java_sun_nio_fs_UnixNativeDispatcher_symlink0;
+		Java_sun_nio_fs_UnixNativeDispatcher_readlink0;
+		Java_sun_nio_fs_UnixNativeDispatcher_realpath0;
+		Java_sun_nio_fs_UnixNativeDispatcher_statvfs0;
+		Java_sun_nio_fs_UnixNativeDispatcher_pathconf0;
+		Java_sun_nio_fs_UnixNativeDispatcher_fpathconf;
+		Java_sun_nio_fs_UnixNativeDispatcher_mknod0;
+		Java_sun_nio_fs_UnixNativeDispatcher_getpwuid;
+		Java_sun_nio_fs_UnixNativeDispatcher_getgrgid;
+		Java_sun_nio_fs_UnixNativeDispatcher_getpwnam0;
+		Java_sun_nio_fs_UnixNativeDispatcher_getgrnam0;
+		Java_sun_nio_fs_UnixNativeDispatcher_getextmntent;
+		Java_sun_nio_fs_UnixCopyFile_transfer;
+		Java_sun_nio_fs_SolarisNativeDispatcher_init;
+		Java_sun_nio_fs_SolarisNativeDispatcher_facl;
+		Java_sun_nio_fs_SolarisWatchService_init;
+		Java_sun_nio_fs_SolarisWatchService_portCreate;
+		Java_sun_nio_fs_SolarisWatchService_portAssociate;
+		Java_sun_nio_fs_SolarisWatchService_portDissociate;
+		Java_sun_nio_fs_SolarisWatchService_portSend;
+		Java_sun_nio_fs_SolarisWatchService_portGetn;
 
 	local:
 		*;
diff --git a/jdk/make/mksample/nio/Makefile b/jdk/make/mksample/nio/Makefile
index e051062..5fcfd03 100644
--- a/jdk/make/mksample/nio/Makefile
+++ b/jdk/make/mksample/nio/Makefile
@@ -1,5 +1,5 @@
 #
-# Copyright 2004-2008 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2004-2009 Sun Microsystems, Inc.  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
@@ -31,7 +31,7 @@
 PRODUCT = java
 include $(BUILDDIR)/common/Defs.gmk
 
-SUBDIRS = multicast server
+SUBDIRS = file multicast server
 all build clean clobber::
 	$(SUBDIRS-loop)
 
diff --git a/jdk/make/mksample/nio/file/Makefile b/jdk/make/mksample/nio/file/Makefile
new file mode 100644
index 0000000..f7159de
--- /dev/null
+++ b/jdk/make/mksample/nio/file/Makefile
@@ -0,0 +1,56 @@
+#
+# Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
+#
+# Makefile for the nio/file sample code
+#
+
+BUILDDIR = ../../..
+
+PRODUCT = java
+
+include $(BUILDDIR)/common/Defs.gmk
+
+SAMPLE_SRC_DIR = $(SHARE_SRC)/sample/nio/file
+SAMPLE_DST_DIR = $(SAMPLEDIR)/nio/file
+
+SAMPLE_FILES =							\
+	$(SAMPLE_DST_DIR)/AclEdit.java				\
+	$(SAMPLE_DST_DIR)/Chmod.java				\
+	$(SAMPLE_DST_DIR)/Copy.java				\
+	$(SAMPLE_DST_DIR)/DiskUsage.java			\
+	$(SAMPLE_DST_DIR)/FileType.java				\
+	$(SAMPLE_DST_DIR)/WatchDir.java				\
+	$(SAMPLE_DST_DIR)/Xdd.java
+
+all build: $(SAMPLE_FILES)
+
+$(SAMPLE_DST_DIR)/%: $(SAMPLE_SRC_DIR)/%
+	$(install-file)
+
+clean clobber:
+	$(RM) -r $(SAMPLE_DST_DIR)
+
+.PHONY: all build clean clobber
diff --git a/jdk/src/share/classes/com/sun/nio/file/ExtendedCopyOption.java b/jdk/src/share/classes/com/sun/nio/file/ExtendedCopyOption.java
new file mode 100644
index 0000000..b612c0e
--- /dev/null
+++ b/jdk/src/share/classes/com/sun/nio/file/ExtendedCopyOption.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package com.sun.nio.file;
+
+import java.nio.file.CopyOption;
+
+/**
+ * Defines <em>extended</em> copy options supported on some platforms
+ * by Sun's provider implementation.
+ *
+ * @since 1.7
+ */
+
+public enum ExtendedCopyOption implements CopyOption {
+    /**
+     * The copy may be interrupted by the {@link Thread#interrupt interrupt}
+     * method.
+     */
+    INTERRUPTIBLE,
+}
diff --git a/jdk/src/share/classes/com/sun/nio/file/ExtendedOpenOption.java b/jdk/src/share/classes/com/sun/nio/file/ExtendedOpenOption.java
new file mode 100644
index 0000000..25208d8
--- /dev/null
+++ b/jdk/src/share/classes/com/sun/nio/file/ExtendedOpenOption.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package com.sun.nio.file;
+
+import java.nio.file.OpenOption;
+
+/**
+ * Defines <em>extended</em> open options supported on some platforms
+ * by Sun's provider implementation.
+ *
+ * @since 1.7
+ */
+
+public enum ExtendedOpenOption implements OpenOption {
+    /**
+     * Prevent operations on the file that request read access.
+     */
+    NOSHARE_READ,
+    /**
+     * Prevent operations on the file that request write access.
+     */
+    NOSHARE_WRITE,
+    /**
+     * Prevent operations on the file that request delete access.
+     */
+    NOSHARE_DELETE;
+}
diff --git a/jdk/src/share/classes/com/sun/nio/file/ExtendedWatchEventModifier.java b/jdk/src/share/classes/com/sun/nio/file/ExtendedWatchEventModifier.java
new file mode 100644
index 0000000..0f6ddc3
--- /dev/null
+++ b/jdk/src/share/classes/com/sun/nio/file/ExtendedWatchEventModifier.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package com.sun.nio.file;
+
+import java.nio.file.WatchEvent.Modifier;
+
+/**
+ * Defines <em>extended</em> watch event modifiers supported on some platforms
+ * by Sun's provider implementation.
+ *
+ * @since 1.7
+ */
+
+public enum ExtendedWatchEventModifier implements Modifier {
+
+    /**
+     * Register a file tree instead of a single directory.
+     */
+    FILE_TREE,
+}
diff --git a/jdk/src/share/classes/com/sun/nio/file/SensitivityWatchEventModifier.java b/jdk/src/share/classes/com/sun/nio/file/SensitivityWatchEventModifier.java
new file mode 100644
index 0000000..57ab111
--- /dev/null
+++ b/jdk/src/share/classes/com/sun/nio/file/SensitivityWatchEventModifier.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package com.sun.nio.file;
+
+import java.nio.file.WatchEvent.Modifier;
+
+/**
+ * Defines the <em>sensitivity levels</em> when registering objects with a
+ * watch service implementation that polls the file system.
+ *
+ * @since 1.7
+ */
+
+public enum SensitivityWatchEventModifier implements Modifier {
+    /**
+     * High sensitivity.
+     */
+    HIGH(2),
+    /**
+     * Medium sensitivity.
+     */
+    MEDIUM(10),
+    /**
+     * Low sensitivity.
+     */
+    LOW(30);
+
+    /**
+     * Returns the sensitivity in seconds.
+     */
+    public int sensitivityValueInSeconds() {
+        return sensitivity;
+    }
+
+    private final int sensitivity;
+    private SensitivityWatchEventModifier(int sensitivity) {
+        this.sensitivity = sensitivity;
+    }
+}
diff --git a/jdk/src/share/classes/java/io/File.java b/jdk/src/share/classes/java/io/File.java
index d573b89..6a04151 100644
--- a/jdk/src/share/classes/java/io/File.java
+++ b/jdk/src/share/classes/java/io/File.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 1994-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1994-2009 Sun Microsystems, Inc.  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
@@ -30,12 +30,12 @@
 import java.net.URL;
 import java.net.MalformedURLException;
 import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Map;
-import java.util.Hashtable;
-import java.util.Random;
+import java.util.*;
+import java.nio.file.*;
+import java.nio.file.attribute.*;
 import java.security.AccessController;
-import java.security.AccessControlException;
+import java.security.PrivilegedAction;
+import java.security.SecureRandom;
 import sun.security.action.GetPropertyAction;
 
 
@@ -131,6 +131,18 @@
  * created, the abstract pathname represented by a <code>File</code> object
  * will never change.
  *
+ * <h4>Interoperability with {@code java.nio.file} package</h4>
+ *
+ * <p> The <a href="../../java/nio/file/package-summary.html">{@code java.nio.file}</a>
+ * package defines interfaces and classes for the Java virtual machine to access
+ * files, file attributes, and file systems. This API may be used to overcome
+ * 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.
+ *
  * @author  unascribed
  * @since   JDK1.0
  */
@@ -573,6 +585,7 @@
      *          read access to the file
      *
      * @since   JDK1.1
+     * @see     Path#toRealPath
      */
     public String getCanonicalPath() throws IOException {
         return fs.canonicalize(fs.resolve(this));
@@ -597,6 +610,7 @@
      *          read access to the file
      *
      * @since 1.2
+     * @see     Path#toRealPath
      */
     public File getCanonicalFile() throws IOException {
         String canonPath = getCanonicalPath();
@@ -663,6 +677,14 @@
      * system is converted into an abstract pathname in a virtual machine on a
      * different operating system.
      *
+     * <p> Note that when this abstract pathname represents a UNC pathname then
+     * all components of the UNC (including the server name component) are encoded
+     * in the {@code URI} path. The authority component is undefined, meaning
+     * that it is represented as {@code null}. The {@link Path} class defines the
+     * {@link Path#toUri toUri} method to encode the server name in the authority
+     * component of the resulting {@code URI}. The {@link #toPath toPath} method
+     * may be used to obtain a {@code Path} representing this abstract pathname.
+     *
      * @return  An absolute, hierarchical URI with a scheme equal to
      *          <tt>"file"</tt>, a path representing this abstract pathname,
      *          and undefined authority, query, and fragment components
@@ -764,6 +786,8 @@
      *          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 Attributes#readBasicFileAttributes
      */
     public boolean isDirectory() {
         SecurityManager security = System.getSecurityManager();
@@ -788,6 +812,8 @@
      *          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 Attributes#readBasicFileAttributes
      */
     public boolean isFile() {
         SecurityManager security = System.getSecurityManager();
@@ -836,6 +862,8 @@
      *          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 Attributes#readBasicFileAttributes
      */
     public long lastModified() {
         SecurityManager security = System.getSecurityManager();
@@ -858,6 +886,8 @@
      *          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 Attributes#readBasicFileAttributes
      */
     public long length() {
         SecurityManager security = System.getSecurityManager();
@@ -907,6 +937,12 @@
      * 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.
+     *
      * @return  <code>true</code> if and only if the file or directory is
      *          successfully deleted; <code>false</code> otherwise
      *
@@ -973,6 +1009,13 @@
      * 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.
+     *
      * @return  An array of strings naming the files and directories in the
      *          directory denoted by this abstract pathname.  The array will be
      *          empty if the directory is empty.  Returns {@code null} if
@@ -1024,13 +1067,13 @@
         if ((names == null) || (filter == null)) {
             return names;
         }
-        ArrayList v = new ArrayList();
+        List<String> v = new ArrayList<String>();
         for (int i = 0 ; i < names.length ; i++) {
             if (filter.accept(this, names[i])) {
                 v.add(names[i]);
             }
         }
-        return (String[])(v.toArray(new String[v.size()]));
+        return v.toArray(new String[v.size()]);
     }
 
     /**
@@ -1052,6 +1095,13 @@
      * 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.
+     *
      * @return  An array of abstract pathnames denoting the files and
      *          directories in the directory denoted by this abstract pathname.
      *          The array will be empty if the directory is empty.  Returns
@@ -1157,6 +1207,12 @@
     /**
      * 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
      *
@@ -1222,6 +1278,11 @@
      * 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.
+     *
      * @param  dest  The new abstract pathname for the named file
      *
      * @return  <code>true</code> if and only if the renaming succeeded;
@@ -1304,10 +1365,14 @@
         return fs.setReadOnly(this);
     }
 
-   /**
+    /**
      * Sets the owner's or everybody's write permission for this abstract
      * pathname.
      *
+     * <p> The {@link 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.
+     *
      * @param   writable
      *          If <code>true</code>, sets the access permission to allow write
      *          operations; if <code>false</code> to disallow write operations
@@ -1371,6 +1436,10 @@
      * Sets the owner's or everybody's read permission for this abstract
      * pathname.
      *
+     * <p> The {@link 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.
+     *
      * @param   readable
      *          If <code>true</code>, sets the access permission to allow read
      *          operations; if <code>false</code> to disallow read operations
@@ -1440,6 +1509,10 @@
      * Sets the owner's or everybody's execute permission for this abstract
      * pathname.
      *
+     * <p> The {@link 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.
+     *
      * @param   executable
      *          If <code>true</code>, sets the access permission to allow execute
      *          operations; if <code>false</code> to disallow execute operations
@@ -1678,44 +1751,44 @@
 
     /* -- Temporary files -- */
 
-    private static final Object tmpFileLock = new Object();
+    private static class TemporaryDirectory {
+        private TemporaryDirectory() { }
 
-    private static int counter = -1; /* Protected by tmpFileLock */
+        static final String valueAsString = fs.normalize(
+            AccessController.doPrivileged(new GetPropertyAction("java.io.tmpdir")));
+        static final File valueAsFile =
+            new File(valueAsString, fs.prefixLength(valueAsString));
 
-    private static File generateFile(String prefix, String suffix, File dir)
-        throws IOException
-    {
-        if (counter == -1) {
-            counter = new Random().nextInt() & 0xffff;
-        }
-        counter++;
-        return new File(dir, prefix + Integer.toString(counter) + suffix);
-    }
-
-    private static String tmpdir; /* Protected by tmpFileLock */
-
-    private static String getTempDir() {
-        if (tmpdir == null)
-            tmpdir = fs.normalize(
-                AccessController.doPrivileged(
-                    new GetPropertyAction("java.io.tmpdir")));
-        return tmpdir;
-    }
-
-    private static boolean checkAndCreate(String filename, SecurityManager sm)
-        throws IOException
-    {
-        if (sm != null) {
-            try {
-                sm.checkWrite(filename);
-            } catch (AccessControlException x) {
-                /* Throwing the original AccessControlException could disclose
-                   the location of the default temporary directory, so we
-                   re-throw a more innocuous SecurityException */
-                throw new SecurityException("Unable to create temporary file");
+        // file name generation
+        private static final SecureRandom random = new SecureRandom();
+        static File generateFile(String prefix, String suffix, File dir) {
+            long n = random.nextLong();
+            if (n == Long.MIN_VALUE) {
+                n = 0;      // corner case
+            } else {
+                n = Math.abs(n);
             }
+            return new File(dir, prefix + Long.toString(n) + suffix);
         }
-        return fs.createFileExclusively(filename);
+
+        // default file permissions
+        static final FileAttribute<Set<PosixFilePermission>> defaultPosixFilePermissions =
+            PosixFilePermissions.asFileAttribute(EnumSet
+                .of(PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE));
+        static final boolean isPosix = isPosix();
+        static boolean isPosix() {
+            return AccessController.doPrivileged(
+                new PrivilegedAction<Boolean>() {
+                    public Boolean run() {
+                        try {
+                            return FileSystems.getDefault().getPath(valueAsString)
+                                .getFileStore().supportsFileAttributeView("posix");
+                        } catch (IOException e) {
+                            throw new IOError(e);
+                        }
+                    }
+                });
+        }
     }
 
     /**
@@ -1791,22 +1864,29 @@
                                       File directory)
         throws IOException
     {
-        if (prefix == null) throw new NullPointerException();
         if (prefix.length() < 3)
             throw new IllegalArgumentException("Prefix string too short");
-        String s = (suffix == null) ? ".tmp" : suffix;
-        synchronized (tmpFileLock) {
-            if (directory == null) {
-                String tmpDir = getTempDir();
-                directory = new File(tmpDir, fs.prefixLength(tmpDir));
+        if (suffix == null)
+            suffix = ".tmp";
+
+        File tmpdir = (directory != null) ?
+            directory : TemporaryDirectory.valueAsFile;
+        SecurityManager sm = System.getSecurityManager();
+        File f;
+        do {
+            f = TemporaryDirectory.generateFile(prefix, suffix, tmpdir);
+            if (sm != null) {
+                try {
+                    sm.checkWrite(f.getPath());
+                } catch (SecurityException se) {
+                    // don't reveal temporary directory location
+                    if (directory == null)
+                        throw new SecurityException("Unable to create temporary file");
+                    throw se;
+                }
             }
-            SecurityManager sm = System.getSecurityManager();
-            File f;
-            do {
-                f = generateFile(prefix, s, directory);
-            } while (!checkAndCreate(f.getPath(), sm));
-            return f;
-        }
+        } while (!fs.createFileExclusively(f.getPath()));
+        return f;
     }
 
     /**
@@ -1844,6 +1924,122 @@
         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. This method is
+     * equivalent to invoking the {@link #createTempFile(String,String)
+     * createTempFile(prefix,&nbsp;suffix)} method with the addition that the
+     * resulting pathname may be requested to be deleted when the Java virtual
+     * machine terminates, and the initial file attributes to set atomically
+     * when creating the file may be specified.
+     *
+     * <p> When the value of the {@code deleteOnExit} method is {@code true}
+     * then the resulting file is requested to be deleted when the Java virtual
+     * machine terminates as if by invoking the {@link #deleteOnExit deleteOnExit}
+     * method.
+     *
+     * <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.
+     *
+     * @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   deleteOnExit
+     *          {@code true} if the file denoted by resulting pathname be
+     *          deleted when the Java virtual machine terminates
+     * @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</code> 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. When the {@code
+     *          deleteOnExit} parameter has the value {@code true} then the
+     *          security manager's {@link
+     *          java.lang.SecurityManager#checkDelete(java.lang.String)} is
+     *          invoked to check delete access to the file.
+     * @since 1.7
+     */
+    public static File createTempFile(String prefix,
+                                      String suffix,
+                                      boolean deleteOnExit,
+                                      FileAttribute<?>... attrs)
+        throws IOException
+    {
+        if (prefix.length() < 3)
+            throw new IllegalArgumentException("Prefix string too short");
+        suffix = (suffix == null) ? ".tmp" : suffix;
+
+        // special case POSIX environments so that 0600 is used as the file mode
+        if (TemporaryDirectory.isPosix) {
+            if (attrs.length == 0) {
+                // no attributes so use default permissions
+                attrs = new FileAttribute<?>[1];
+                attrs[0] = TemporaryDirectory.defaultPosixFilePermissions;
+            } 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] =
+                        TemporaryDirectory.defaultPosixFilePermissions;
+                }
+            }
+        }
+
+        // use Path#createFile to create file
+        SecurityManager sm = System.getSecurityManager();
+        for (;;) {
+            File f = TemporaryDirectory
+                .generateFile(prefix, suffix, TemporaryDirectory.valueAsFile);
+            if (sm != null && deleteOnExit)
+                sm.checkDelete(f.getPath());
+            try {
+                f.toPath().createFile(attrs);
+                if (deleteOnExit)
+                    DeleteOnExitHook.add(f.getPath());
+                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
+            }
+        }
+    }
 
     /* -- Basic infrastructure -- */
 
@@ -1963,5 +2159,46 @@
         );
     }
 
+    // -- Integration with java.nio.file --
 
+    private volatile transient Path filePath;
+
+    /**
+     * Returns a {@link Path java.nio.file.Path} object constructed from the
+     * this abstract path. The first invocation of this method works as if
+     * invoking it were equivalent to evaluating the expression:
+     * <blockquote><pre>
+     * {@link FileSystems#getDefault FileSystems.getDefault}().{@link FileSystem#getPath getPath}(this.{@link #getPath getPath}());
+     * </pre></blockquote>
+     * Subsequent invocations of this method return the same {@code Path}.
+     *
+     * <p> If this abstract pathname is the empty abstract pathname then this
+     * method returns a {@code Path} that may be used to access to the current
+     * user directory.
+     *
+     * @return  A {@code Path} constructed from this abstract path. The resulting
+     *          {@code Path} is associated with the {@link FileSystems#getDefault
+     *          default-filesystem}.
+     *
+     * @throws  InvalidPathException
+     *          If a {@code Path} object cannot be constructed from the abstract
+     *          path (see {@link java.nio.file.FileSystem#getPath FileSystem.getPath})
+     *
+     * @since   1.7
+     */
+    public Path toPath() {
+        if (filePath == null) {
+            synchronized (this) {
+                if (filePath == null) {
+                    if (path.length() == 0) {
+                        // assume default file system treats "." as current directory
+                        filePath = Paths.get(".");
+                    } else {
+                        filePath = Paths.get(path);
+                    }
+                }
+            }
+        }
+        return filePath;
+    }
 }
diff --git a/jdk/src/share/classes/java/io/FilePermission.java b/jdk/src/share/classes/java/io/FilePermission.java
index 9758e35..88c98fb 100644
--- a/jdk/src/share/classes/java/io/FilePermission.java
+++ b/jdk/src/share/classes/java/io/FilePermission.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc.  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
@@ -29,7 +29,6 @@
 import java.util.Enumeration;
 import java.util.List;
 import java.util.ArrayList;
-import java.util.StringTokenizer;
 import java.util.Vector;
 import java.util.Collections;
 import java.io.ObjectStreamField;
@@ -58,7 +57,8 @@
  * <P>
  * The actions to be granted are passed to the constructor in a string containing
  * a list of one or more comma-separated keywords. The possible keywords are
- * "read", "write", "execute", and "delete". Their meaning is defined as follows:
+ * "read", "write", "execute", "delete", and "readlink". Their meaning is
+ * defined as follows:
  * <P>
  * <DL>
  *    <DT> read <DD> read permission
@@ -69,6 +69,11 @@
  *    <DT> delete
  *    <DD> delete permission. Allows <code>File.delete</code> to
  *         be called. Corresponds to <code>SecurityManager.checkDelete</code>.
+ *    <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
+ *         readSymbolicLink } method.
  * </DL>
  * <P>
  * The actions string is converted to lowercase before processing.
@@ -114,11 +119,15 @@
      * Delete action.
      */
     private final static int DELETE  = 0x8;
+    /**
+     * Read link action.
+     */
+    private final static int READLINK    = 0x10;
 
     /**
-     * All actions (read,write,execute,delete)
+     * All actions (read,write,execute,delete,readlink)
      */
-    private final static int ALL     = READ|WRITE|EXECUTE|DELETE;
+    private final static int ALL     = READ|WRITE|EXECUTE|DELETE|READLINK;
     /**
      * No actions.
      */
@@ -235,7 +244,7 @@
      * <i>path</i> is the pathname of a file or directory, and <i>actions</i>
      * contains a comma-separated list of the desired actions granted on the
      * file or directory. Possible actions are
-     * "read", "write", "execute", and "delete".
+     * "read", "write", "execute", "delete", and "readlink".
      *
      * <p>A pathname that ends in "/*" (where "/" is
      * the file separator character, <code>File.separatorChar</code>)
@@ -425,6 +434,8 @@
             return EXECUTE;
         } else if (actions == SecurityConstants.FILE_DELETE_ACTION) {
             return DELETE;
+        } else if (actions == SecurityConstants.FILE_READLINK_ACTION) {
+            return READLINK;
         }
 
         char[] a = actions.toCharArray();
@@ -485,6 +496,18 @@
                 matchlen = 6;
                 mask |= DELETE;
 
+            } else if (i >= 7 && (a[i-7] == 'r' || a[i-7] == 'R') &&
+                                 (a[i-6] == 'e' || a[i-6] == 'E') &&
+                                 (a[i-5] == 'a' || a[i-5] == 'A') &&
+                                 (a[i-4] == 'd' || a[i-4] == 'D') &&
+                                 (a[i-3] == 'l' || a[i-3] == 'L') &&
+                                 (a[i-2] == 'i' || a[i-2] == 'I') &&
+                                 (a[i-1] == 'n' || a[i-1] == 'N') &&
+                                 (a[i] == 'k' || a[i] == 'K'))
+            {
+                matchlen = 8;
+                mask |= READLINK;
+
             } else {
                 // parse error
                 throw new IllegalArgumentException(
@@ -529,7 +552,7 @@
     /**
      * Return the canonical string representation of the actions.
      * Always returns present actions in the following order:
-     * read, write, execute, delete.
+     * read, write, execute, delete, readlink.
      *
      * @return the canonical string representation of the actions.
      */
@@ -561,14 +584,20 @@
             sb.append("delete");
         }
 
+        if ((mask & READLINK) == READLINK) {
+            if (comma) sb.append(',');
+            else comma = true;
+            sb.append("readlink");
+        }
+
         return sb.toString();
     }
 
     /**
      * Returns the "canonical string representation" of the actions.
      * That is, this method always returns present actions in the following order:
-     * read, write, execute, delete. For example, if this FilePermission object
-     * allows both write and read actions, a call to <code>getActions</code>
+     * read, write, execute, delete, readlink. For example, if this FilePermission
+     * object allows both write and read actions, a call to <code>getActions</code>
      * will return the string "read,write".
      *
      * @return the canonical string representation of the actions.
@@ -678,7 +707,7 @@
 implements Serializable {
 
     // Not serialized; see serialization section at end of class
-    private transient List perms;
+    private transient List<Permission> perms;
 
     /**
      * Create an empty FilePermissions object.
@@ -686,7 +715,7 @@
      */
 
     public FilePermissionCollection() {
-        perms = new ArrayList();
+        perms = new ArrayList<Permission>();
     }
 
     /**
@@ -791,7 +820,7 @@
         // Don't call out.defaultWriteObject()
 
         // Write out Vector
-        Vector permissions = new Vector(perms.size());
+        Vector<Permission> permissions = new Vector<Permission>(perms.size());
         synchronized (this) {
             permissions.addAll(perms);
         }
@@ -804,6 +833,7 @@
     /*
      * Reads in a Vector of FilePermissions and saves them in the perms field.
      */
+    @SuppressWarnings("unchecked")
     private void readObject(ObjectInputStream in) throws IOException,
     ClassNotFoundException {
         // Don't call defaultReadObject()
@@ -812,8 +842,8 @@
         ObjectInputStream.GetField gfields = in.readFields();
 
         // Get the one we want
-        Vector permissions = (Vector)gfields.get("permissions", null);
-        perms = new ArrayList(permissions.size());
+        Vector<Permission> permissions = (Vector<Permission>)gfields.get("permissions", null);
+        perms = new ArrayList<Permission>(permissions.size());
         perms.addAll(permissions);
     }
 }
diff --git a/jdk/src/share/classes/java/lang/Thread.java b/jdk/src/share/classes/java/lang/Thread.java
index 60300eb..3922f70 100644
--- a/jdk/src/share/classes/java/lang/Thread.java
+++ b/jdk/src/share/classes/java/lang/Thread.java
@@ -25,13 +25,17 @@
 
 package java.lang;
 
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
 import java.security.AccessController;
 import java.security.AccessControlContext;
 import java.security.PrivilegedAction;
 import java.util.Map;
 import java.util.HashMap;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.locks.LockSupport;
-import sun.misc.SoftCache;
 import sun.nio.ch.Interruptible;
 import sun.security.util.SecurityConstants;
 
@@ -1640,8 +1644,17 @@
                     new RuntimePermission("enableContextClassLoaderOverride");
 
     /** cache of subclass security audit results */
-    private static final SoftCache subclassAudits = new SoftCache(10);
+    /* Replace with ConcurrentReferenceHashMap when/if it appears in a future
+     * release */
+    private static class Caches {
+        /** cache of subclass security audit results */
+        static final ConcurrentMap<WeakClassKey,Boolean> subclassAudits =
+            new ConcurrentHashMap<WeakClassKey,Boolean>();
 
+        /** queue for WeakReferences to audited subclasses */
+        static final ReferenceQueue<Class<?>> subclassAuditsQueue =
+            new ReferenceQueue<Class<?>>();
+    }
 
     /**
      * Verifies that this (possibly subclass) instance can be constructed
@@ -1652,19 +1665,15 @@
     private static boolean isCCLOverridden(Class cl) {
         if (cl == Thread.class)
             return false;
-        Boolean result = null;
-        synchronized (subclassAudits) {
-            result = (Boolean) subclassAudits.get(cl);
-            if (result == null) {
-                /*
-                 * Note: only new Boolean instances (i.e., not Boolean.TRUE or
-                 * Boolean.FALSE) must be used as cache values, otherwise cache
-                 * entry will pin associated class.
-                 */
-                result = new Boolean(auditSubclass(cl));
-                subclassAudits.put(cl, result);
-            }
+
+        processQueue(Caches.subclassAuditsQueue, Caches.subclassAudits);
+        WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue);
+        Boolean result = Caches.subclassAudits.get(key);
+        if (result == null) {
+            result = Boolean.valueOf(auditSubclass(cl));
+            Caches.subclassAudits.putIfAbsent(key, result);
         }
+
         return result.booleanValue();
     }
 
@@ -1967,6 +1976,68 @@
         getUncaughtExceptionHandler().uncaughtException(this, e);
     }
 
+    /**
+     * Removes from the specified map any keys that have been enqueued
+     * on the specified reference queue.
+     */
+    static void processQueue(ReferenceQueue<Class<?>> queue,
+                             ConcurrentMap<? extends
+                             WeakReference<Class<?>>, ?> map)
+    {
+        Reference<? extends Class<?>> ref;
+        while((ref = queue.poll()) != null) {
+            map.remove(ref);
+        }
+    }
+
+    /**
+     *  Weak key for Class objects.
+     **/
+    static class WeakClassKey extends WeakReference<Class<?>> {
+        /**
+         * saved value of the referent's identity hash code, to maintain
+         * a consistent hash code after the referent has been cleared
+         */
+        private final int hash;
+
+        /**
+         * Create a new WeakClassKey to the given object, registered
+         * with a queue.
+         */
+        WeakClassKey(Class<?> cl, ReferenceQueue<Class<?>> refQueue) {
+            super(cl, refQueue);
+            hash = System.identityHashCode(cl);
+        }
+
+        /**
+         * Returns the identity hash code of the original referent.
+         */
+        @Override
+        public int hashCode() {
+            return hash;
+        }
+
+        /**
+         * Returns true if the given object is this identical
+         * WeakClassKey instance, or, if this object's referent has not
+         * been cleared, if the given object is another WeakClassKey
+         * instance with the identical non-null referent as this one.
+         */
+        @Override
+        public boolean equals(Object obj) {
+            if (obj == this)
+                return true;
+
+            if (obj instanceof WeakClassKey) {
+                Object referent = get();
+                return (referent != null) &&
+                       (referent == ((WeakClassKey) obj).get());
+            } else {
+                return false;
+            }
+        }
+    }
+
     /* Some private helper methods */
     private native void setPriority0(int newPriority);
     private native void stop0(Object o);
diff --git a/jdk/src/share/classes/java/net/StandardProtocolFamily.java b/jdk/src/share/classes/java/net/StandardProtocolFamily.java
index 7c11b32..d4b03ed 100644
--- a/jdk/src/share/classes/java/net/StandardProtocolFamily.java
+++ b/jdk/src/share/classes/java/net/StandardProtocolFamily.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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
@@ -26,7 +26,7 @@
 package java.net;
 
 /**
- * Defines the standard family of communication protocols.
+ * Defines the standard families of communication protocols.
  *
  * @since 1.7
  */
diff --git a/jdk/src/share/classes/java/net/StandardSocketOption.java b/jdk/src/share/classes/java/net/StandardSocketOption.java
index 405038c..dba8ff2 100644
--- a/jdk/src/share/classes/java/net/StandardSocketOption.java
+++ b/jdk/src/share/classes/java/net/StandardSocketOption.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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
@@ -59,6 +59,7 @@
      *
      * @see <a href="http://www.ietf.org/rfc/rfc919.txt">RFC&nbsp;929:
      * Broadcasting Internet Datagrams</a>
+     * @see DatagramSocket#setBroadcast
      */
     public static final SocketOption<Boolean> SO_BROADCAST =
         new StdSocketOption<Boolean>("SO_BROADCAST", Boolean.class);
@@ -78,6 +79,7 @@
      *
      * @see <a href="http://www.ietf.org/rfc/rfc1122.txt">RFC&nbsp;1122
      * Requirements for Internet Hosts -- Communication Layers</a>
+     * @see Socket#setKeepAlive
      */
     public static final SocketOption<Boolean> SO_KEEPALIVE =
         new StdSocketOption<Boolean>("SO_KEEPALIVE", Boolean.class);
@@ -107,6 +109,8 @@
      * socket is bound or connected. Whether an implementation allows the
      * socket send buffer to be changed after the socket is bound is system
      * dependent.
+     *
+     * @see Socket#setSendBufferSize
      */
     public static final SocketOption<Integer> SO_SNDBUF =
         new StdSocketOption<Integer>("SO_SNDBUF", Integer.class);
@@ -145,6 +149,8 @@
      *
      * @see <a href="http://www.ietf.org/rfc/rfc1323.txt">RFC&nbsp;1323: TCP
      * Extensions for High Performance</a>
+     * @see Socket#setReceiveBufferSize
+     * @see ServerSocket#setReceiveBufferSize
      */
     public static final SocketOption<Integer> SO_RCVBUF =
         new StdSocketOption<Integer>("SO_RCVBUF", Integer.class);
@@ -175,6 +181,7 @@
      *
      * @see <a href="http://www.ietf.org/rfc/rfc793.txt">RFC&nbsp;793: Transmission
      * Control Protocol</a>
+     * @see ServerSocket#setReuseAddress
      */
     public static final SocketOption<Boolean> SO_REUSEADDR =
         new StdSocketOption<Boolean>("SO_REUSEADDR", Boolean.class);
@@ -205,6 +212,8 @@
      * is system dependent. Setting the linger interval to a value that is
      * greater than its maximum value causes the linger interval to be set to
      * its maximum value.
+     *
+     * @see Socket#setSoLinger
      */
     public static final SocketOption<Integer> SO_LINGER =
         new StdSocketOption<Integer>("SO_LINGER", Integer.class);
@@ -215,15 +224,15 @@
     /**
      * The Type of Service (ToS) octet in the Internet Protocol (IP) header.
      *
-     * <p> The value of this socket option is an {@code Integer}, the least
-     * significant 8 bits of which represents the value of the ToS octet in IP
-     * packets sent by sockets to an {@link StandardProtocolFamily#INET IPv4}
-     * socket. The interpretation of the ToS octet is network specific and
-     * is not defined by this class. Further information on the ToS octet can be
-     * found in <a href="http://www.ietf.org/rfc/rfc1349.txt">RFC&nbsp;1349</a>
-     * and <a href="http://www.ietf.org/rfc/rfc2474.txt">RFC&nbsp;2474</a>. The
-     * value of the socket option is a <em>hint</em>. An implementation may
-     * ignore the value, or ignore specific values.
+     * <p> The value of this socket option is an {@code Integer} representing
+     * the value of the ToS octet in IP packets sent by sockets to an {@link
+     * StandardProtocolFamily#INET IPv4} socket. The interpretation of the ToS
+     * octet is network specific and is not defined by this class. Further
+     * information on the ToS octet can be found in <a
+     * href="http://www.ietf.org/rfc/rfc1349.txt">RFC&nbsp;1349</a> and <a
+     * href="http://www.ietf.org/rfc/rfc2474.txt">RFC&nbsp;2474</a>. The value
+     * of the socket option is a <em>hint</em>. An implementation may ignore the
+     * value, or ignore specific values.
      *
      * <p> The initial/default value of the TOS field in the ToS octet is
      * implementation specific but will typically be {@code 0}. For
@@ -235,6 +244,8 @@
      * <p> The behavior of this socket option on a stream-oriented socket, or an
      * {@link StandardProtocolFamily#INET6 IPv6} socket, is not defined in this
      * release.
+     *
+     * @see DatagramSocket#setTrafficClass
      */
     public static final SocketOption<Integer> IP_TOS =
         new StdSocketOption<Integer>("IP_TOS", Integer.class);
@@ -257,6 +268,7 @@
      * is system dependent.
      *
      * @see java.nio.channels.MulticastChannel
+     * @see MulticastSocket#setInterface
      */
     public static final SocketOption<NetworkInterface> IP_MULTICAST_IF =
         new StdSocketOption<NetworkInterface>("IP_MULTICAST_IF", NetworkInterface.class);
@@ -283,6 +295,7 @@
      * prior to binding the socket is system dependent.
      *
      * @see java.nio.channels.MulticastChannel
+     * @see MulticastSocket#setTimeToLive
      */
     public static final SocketOption<Integer> IP_MULTICAST_TTL =
         new StdSocketOption<Integer>("IP_MULTICAST_TTL", Integer.class);
@@ -307,6 +320,7 @@
      * binding the socket is system dependent.
      *
      * @see java.nio.channels.MulticastChannel
+     *  @see MulticastSocket#setLoopbackMode
      */
     public static final SocketOption<Boolean> IP_MULTICAST_LOOP =
         new StdSocketOption<Boolean>("IP_MULTICAST_LOOP", Boolean.class);
@@ -328,11 +342,12 @@
      * coalescing impacts performance. The socket option may be enabled at any
      * time. In other words, the Nagle Algorithm can be disabled. Once the option
      * is enabled, it is system dependent whether it can be subsequently
-     * disabled. In that case, invoking the {@code setOption} method to disable
-     * the option has no effect.
+     * disabled. If it cannot, then invoking the {@code setOption} method to
+     * disable the option has no effect.
      *
      * @see <a href="http://www.ietf.org/rfc/rfc1122.txt">RFC&nbsp;1122:
      * Requirements for Internet Hosts -- Communication Layers</a>
+     * @see Socket#setTcpNoDelay
      */
     public static final SocketOption<Boolean> TCP_NODELAY =
         new StdSocketOption<Boolean>("TCP_NODELAY", Boolean.class);
diff --git a/jdk/src/share/classes/java/nio/channels/AsynchronousByteChannel.java b/jdk/src/share/classes/java/nio/channels/AsynchronousByteChannel.java
new file mode 100644
index 0000000..7bc4335
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/channels/AsynchronousByteChannel.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.channels;
+
+import java.nio.ByteBuffer;
+import java.util.concurrent.Future;
+
+/**
+ * An asynchronous channel that can read and write bytes.
+ *
+ * <p> Some channels may not allow more than one read or write to be outstanding
+ * at any given time. If a thread invokes a read method before a previous read
+ * operation has completed then a {@link ReadPendingException} will be thrown.
+ * Similarly, if a write method is invoked before a previous write has completed
+ * then {@link WritePendingException} is thrown. Whether or not other kinds of
+ * I/O operations may proceed concurrently with a read operation depends upon
+ * the type of the channel.
+ *
+ * <p> Note that {@link java.nio.ByteBuffer ByteBuffers} are not safe for use by
+ * multiple concurrent threads. When a read or write operation is initiated then
+ * care must be taken to ensure that the buffer is not accessed until the
+ * operation completes.
+ *
+ * @see Channels#newInputStream(AsynchronousByteChannel)
+ * @see Channels#newOutputStream(AsynchronousByteChannel)
+ *
+ * @since 1.7
+ */
+
+public interface AsynchronousByteChannel
+    extends AsynchronousChannel
+{
+    /**
+     * Reads a sequence of bytes from this channel into the given buffer.
+     *
+     * <p> This method initiates an operation to read a sequence of bytes from
+     * this channel into the given buffer. The method returns a {@link Future}
+     * representing the pending result of the operation. The result of the
+     * operation, obtained by invoking the {@code Future} 's {@link
+     * Future#get() get} method, is the number of bytes read or {@code -1} if
+     * all bytes have been read and the channel has reached end-of-stream.
+     *
+     * <p> This method initiates a read operation to read up to <i>r</i> bytes
+     * from the channel, where <i>r</i> is the number of bytes remaining in the
+     * buffer, that is, {@code dst.remaining()} at the time that the read is
+     * attempted. Where <i>r</i> is 0, the read operation completes immediately
+     * with a result of {@code 0} without initiating an I/O operation.
+     *
+     * <p> Suppose that a byte sequence of length <i>n</i> is read, where
+     * <tt>0</tt>&nbsp;<tt>&lt;</tt>&nbsp;<i>n</i>&nbsp;<tt>&lt;=</tt>&nbsp;<i>r</i>.
+     * This byte sequence will be transferred into the buffer so that the first
+     * byte in the sequence is at index <i>p</i> and the last byte is at index
+     * <i>p</i>&nbsp;<tt>+</tt>&nbsp;<i>n</i>&nbsp;<tt>-</tt>&nbsp;<tt>1</tt>,
+     * where <i>p</i> is the buffer's position at the moment the read is
+     * performed. Upon completion the buffer's position will be equal to
+     * <i>p</i>&nbsp;<tt>+</tt>&nbsp;<i>n</i>; its limit will not have changed.
+     *
+     * <p> Buffers are not safe for use by multiple concurrent threads so care
+     * should be taken to not to access the buffer until the operaton has completed.
+     *
+     * <p> This method may be invoked at any time. Some channel types may not
+     * allow more than one read to be outstanding at any given time. If a thread
+     * initiates a read operation before a previous read operation has
+     * completed then a {@link ReadPendingException} will be thrown.
+     *
+     * <p> The <tt>handler</tt> parameter is used to specify a {@link
+     * CompletionHandler}. When the read operation completes the handler's
+     * {@link CompletionHandler#completed completed} method is executed.
+     *
+     *
+     * @param   dst
+     *          The buffer into which bytes are to be transferred
+     * @param   attachment
+     *          The object to attach to the I/O operation; can be {@code null}
+     * @param   handler
+     *          The completion handler object; can be {@code null}
+     *
+     * @return  A Future representing the result of the operation
+     *
+     * @throws  IllegalArgumentException
+     *          If the buffer is read-only
+     * @throws  ReadPendingException
+     *          If the channel does not allow more than one read to be outstanding
+     *          and a previous read has not completed
+     */
+    <A> Future<Integer> read(ByteBuffer dst,
+                             A attachment,
+                             CompletionHandler<Integer,? super A> handler);
+
+    /**
+     * Reads a sequence of bytes from this channel into the given buffer.
+     *
+     * <p> An invocation of this method of the form <tt>c.read(dst)</tt>
+     * behaves in exactly the same manner as the invocation
+     * <blockquote><pre>
+     * c.read(dst, null, null);</pre></blockquote>
+     *
+     * @param   dst
+     *          The buffer into which bytes are to be transferred
+     *
+     * @return  A Future representing the result of the operation
+     *
+     * @throws  IllegalArgumentException
+     *          If the buffer is read-only
+     * @throws  ReadPendingException
+     *          If the channel does not allow more than one read to be outstanding
+     *          and a previous read has not completed
+     */
+    Future<Integer> read(ByteBuffer dst);
+
+    /**
+     * Writes a sequence of bytes to this channel from the given buffer.
+     *
+     * <p> This method initiates an operation to write a sequence of bytes to
+     * this channel from the given buffer. This method returns a {@link
+     * Future} representing the pending result of the operation. The result
+     * of the operation, obtained by invoking the <tt>Future</tt>'s {@link
+     * Future#get() get} method, is the number of bytes written, possibly zero.
+     *
+     * <p> This method initiates a write operation to write up to <i>r</i> bytes
+     * to the channel, where <i>r</i> is the number of bytes remaining in the
+     * buffer, that is, {@code src.remaining()}  at the moment the write is
+     * attempted. Where <i>r</i> is 0, the write operation completes immediately
+     * with a result of {@code 0} without initiating an I/O operation.
+     *
+     * <p> Suppose that a byte sequence of length <i>n</i> is written, where
+     * <tt>0</tt>&nbsp;<tt>&lt;</tt>&nbsp;<i>n</i>&nbsp;<tt>&lt;=</tt>&nbsp;<i>r</i>.
+     * This byte sequence will be transferred from the buffer starting at index
+     * <i>p</i>, where <i>p</i> is the buffer's position at the moment the
+     * write is performed; the index of the last byte written will be
+     * <i>p</i>&nbsp;<tt>+</tt>&nbsp;<i>n</i>&nbsp;<tt>-</tt>&nbsp;<tt>1</tt>.
+     * Upon completion the buffer's position will be equal to
+     * <i>p</i>&nbsp;<tt>+</tt>&nbsp;<i>n</i>; its limit will not have changed.
+     *
+     * <p> Buffers are not safe for use by multiple concurrent threads so care
+     * should be taken to not to access the buffer until the operaton has completed.
+     *
+     * <p> This method may be invoked at any time. Some channel types may not
+     * allow more than one write to be outstanding at any given time. If a thread
+     * initiates a write operation before a previous write operation has
+     * completed then a {@link WritePendingException} will be thrown.
+     *
+     * <p> The <tt>handler</tt> parameter is used to specify a {@link
+     * CompletionHandler}. When the write operation completes the handler's
+     * {@link CompletionHandler#completed completed} method is executed.
+     *
+     * @param   src
+     *          The buffer from which bytes are to be retrieved
+     * @param   attachment
+     *          The object to attach to the I/O operation; can be {@code null}
+     * @param   handler
+     *          The completion handler object; can be {@code null}
+     *
+     * @return  A Future representing the result of the operation
+     *
+     * @throws  WritePendingException
+     *          If the channel does not allow more than one write to be outstanding
+     *          and a previous write has not completed
+     */
+    <A> Future<Integer> write(ByteBuffer src,
+                              A attachment,
+                              CompletionHandler<Integer,? super A> handler);
+
+    /**
+     * Writes a sequence of bytes to this channel from the given buffer.
+     *
+     * <p> An invocation of this method of the form <tt>c.write(src)</tt>
+     * behaves in exactly the same manner as the invocation
+     * <blockquote><pre>
+     * c.write(src, null, null);</pre></blockquote>
+     *
+     * @param   src
+     *          The buffer from which bytes are to be retrieved
+     *
+     * @return A Future representing the result of the operation
+     *
+     * @throws  WritePendingException
+     *          If the channel does not allow more than one write to be outstanding
+     *          and a previous write has not completed
+     */
+    Future<Integer> write(ByteBuffer src);
+}
diff --git a/jdk/src/share/classes/java/nio/channels/AsynchronousChannel.java b/jdk/src/share/classes/java/nio/channels/AsynchronousChannel.java
new file mode 100644
index 0000000..f3e4ffe
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/channels/AsynchronousChannel.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.channels;
+
+import java.io.IOException;
+import java.util.concurrent.Future;  // javadoc
+
+/**
+ * A channel that supports asynchronous I/O operations. Asynchronous I/O
+ * operations will usually take one of two forms:
+ *
+ * <ol>
+ * <li><pre>{@link Future}&lt;V&gt; <em>operation</em>(<em>...</em>)</pre></li>
+ * <li><pre>Future&lt;V&gt; <em>operation</em>(<em>...</em> A attachment, {@link CompletionHandler}&lt;V,? super A&gt handler)</pre></li>
+ * </ol>
+ *
+ * where <i>operation</i> is the name of the I/O operation (read or write for
+ * example), <i>V</i> is the result type of the I/O operation, and <i>A</i> is
+ * the type of an object attached to the I/O operation to provide context when
+ * consuming the result. The attachment is important for cases where a
+ * <em>state-less</em> {@code CompletionHandler} is used to consume the result
+ * of many I/O operations.
+ *
+ * <p> In the first form, the methods defined by the {@link Future Future}
+ * interface may be used to check if the operation has completed, wait for its
+ * completion, and to retrieve the result. In the second form, a {@link
+ * CompletionHandler} is invoked to consume the result of the I/O operation when
+ * it completes, fails, or is cancelled.
+ *
+ * <p> A channel that implements this interface is <em>asynchronously
+ * closeable</em>: If an I/O operation is outstanding on the channel and the
+ * channel's {@link #close close} method is invoked, then the I/O operation
+ * fails with the exception {@link AsynchronousCloseException}.
+ *
+ * <p> Asynchronous channels are safe for use by multiple concurrent threads.
+ * Some channel implementations may support concurrent reading and writing, but
+ * may not allow more than one read and one write operation to be outstanding at
+ * any given time.
+ *
+ * <h4>Cancellation</h4>
+ *
+ * <p> The {@code Future} interface defines the {@link Future#cancel cancel}
+ * method to cancel execution of a task.
+ *
+ * <p> Where the {@code cancel} method is invoked with the {@code
+ * mayInterruptIfRunning} parameter set to {@code true} then the I/O operation
+ * may be interrupted by closing the channel. This will cause any other I/O
+ * operations outstanding on the channel to complete with the exception {@link
+ * AsynchronousCloseException}.
+ *
+ * <p> If a {@code CompletionHandler} is specified when initiating an I/O
+ * operation, and the {@code cancel} method is invoked to cancel the I/O
+ * operation before it completes, then the {@code CompletionHandler}'s {@link
+ * CompletionHandler#cancelled cancelled} method is invoked.
+ *
+ * <p> If an implementation of this interface supports a means to cancel I/O
+ * operations, and where cancellation may leave the channel, or the entity to
+ * which it is connected, in an inconsistent state, then the channel is put into
+ * an implementation specific <em>error state</em> that prevents further
+ * attempts to initiate I/O operations on the channel. For example, if a read
+ * operation is cancelled but the implementation cannot guarantee that bytes
+ * have not been read from the channel then it puts the channel into error state
+ * state; further attempts to initiate a {@code read} operation causes an
+ * unspecified runtime exception to be thrown.
+ *
+ * <p> Where the {@code cancel} method is invoked to cancel read or write
+ * operations then it recommended that all buffers used in the I/O operations be
+ * discarded or care taken to ensure that the buffers are not accessed while the
+ * channel remains open.
+ *
+ *  @since 1.7
+ */
+
+public interface AsynchronousChannel
+    extends Channel
+{
+    /**
+     * Closes this channel.
+     *
+     * <p> Any outstanding asynchronous operations upon this channel will
+     * complete with the exception {@link AsynchronousCloseException}. After a
+     * channel is closed then further attempts to initiate asynchronous I/O
+     * operations complete immediately with cause {@link ClosedChannelException}.
+     *
+     * <p>  This method otherwise behaves exactly as specified by the {@link
+     * Channel} interface.
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    @Override
+    void close() throws IOException;
+}
diff --git a/jdk/src/share/classes/java/nio/channels/AsynchronousChannelGroup.java b/jdk/src/share/classes/java/nio/channels/AsynchronousChannelGroup.java
new file mode 100644
index 0000000..1199e16
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/channels/AsynchronousChannelGroup.java
@@ -0,0 +1,344 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.channels;
+
+import java.nio.channels.spi.AsynchronousChannelProvider;
+import java.io.IOException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A grouping of asynchronous channels for the purpose of resource sharing.
+ *
+ * <p> An asynchronous channel group encapsulates the mechanics required to
+ * handle the completion of I/O operations initiated by {@link AsynchronousChannel
+ * asynchronous channels} that are bound to the group. A group has an associated
+ * thread pool to which tasks are submitted to handle I/O events and dispatch to
+ * {@link CompletionHandler completion-handlers} that consume the result of
+ * asynchronous operations performed on channels in the group. In addition to
+ * handling I/O events, the pooled threads may also execute other tasks required
+ * to support the execution of asynchronous I/O operations.
+ *
+ * <p> An asynchronous channel group is created by invoking the {@link
+ * #withFixedThreadPool withFixedThreadPool} or {@link #withCachedThreadPool
+ * withCachedThreadPool} methods defined here. Channels are bound to a group by
+ * specifying the group when constructing the channel. The associated thread
+ * pool is <em>owned</em> by the group; termination of the group results in the
+ * shutdown of the associated thread pool.
+ *
+ * <p> In addition to groups created explicitly, the Java virtual machine
+ * maintains a system-wide <em>default group</em> that is constructed
+ * automatically. Asynchronous channels that do not specify a group at
+ * construction time are bound to the default group. The default group has an
+ * associated thread pool that creates new threads as needed. The default group
+ * may be configured by means of system properties defined in the table below.
+ * Where the {@link java.util.concurrent.ThreadFactory ThreadFactory} for the
+ * default group is not configured then the pooled threads of the default group
+ * are {@link Thread#isDaemon daemon} threads.
+ *
+ * <table border>
+ *   <tr>
+ *     <th>System property</th>
+ *     <th>Description</th>
+ *   </tr>
+ *   <tr>
+ *   <tr>
+ *     <td> {@code java.nio.channels.DefaultThreadPool.threadFactory} </td>
+ *     <td> The value of this property is taken to be the fully-qualified name
+ *     of a concrete {@link java.util.concurrent.ThreadFactory ThreadFactory}
+ *     class. The class is loaded using the system class loader and instantiated.
+ *     The factory's {@link java.util.concurrent.ThreadFactory#newThread
+ *     newThread} method is invoked to create each thread for the default
+ *     group's thread pool. If the process to load and instantiate the value
+ *     of the property fails then an unspecified error is thrown during the
+ *     construction of the default group. </td>
+ *   </tr>
+ *   <tr>
+ *     <td> {@code java.nio.channels.DefaultThreadPool.initialSize} </td>
+ *     <td> The value of the {@code initialSize} parameter for the default
+ *     group (see {@link #withCachedThreadPool withCachedThreadPool}).
+ *     The value of the property is taken to be the {@code String}
+ *     representation of an {@code Integer} that is the initial size parameter.
+ *     If the value cannot be parsed as an {@code Integer} it causes an
+ *     unspecified error to be thrown during the construction of the default
+ *     group. </td>
+ *   </tr>
+ * </table>
+ *
+ * <a name="threading"><h4>Threading</h4></a>
+ *
+ * <p> The completion handler for an I/O operation initiated on a channel bound
+ * to a group is guaranteed to be invoked by one of the pooled threads in the
+ * group. This ensures that the completion handler is run by a thread with the
+ * expected <em>identity</em>.
+ *
+ * <p> Where an I/O operation completes immediately, and the initiating thread
+ * is one of the pooled threads in the group then the completion handler may
+ * be invoked directly by the initiating thread. To avoid stack overflow, an
+ * implementation may impose a limit as to the number of activations on the
+ * thread stack. Some I/O operations may prohibit invoking the completion
+ * handler directly by the initiating thread (see {@link
+ * AsynchronousServerSocketChannel#accept(Object,CompletionHandler) accept}).
+ *
+ * <a name="shutdown"><h4>Shutdown and Termination</h4></a>
+ *
+ * <p> The {@link #shutdown() shutdown} method is used to initiate an <em>orderly
+ * shutdown</em> of a group. An orderly shutdown marks the group as shutdown;
+ * further attempts to construct a channel that binds to the group will throw
+ * {@link ShutdownChannelGroupException}. Whether or not a group is shutdown can
+ * be tested using the {@link #isShutdown() isShutdown} method. Once shutdown,
+ * the group <em>terminates</em> when all asynchronous channels that are bound to
+ * the group are closed, all actively executing completion handlers have run to
+ * completion, and resources used by the group are released. No attempt is made
+ * to stop or interrupt threads that are executing completion handlers. The
+ * {@link #isTerminated() isTerminated} method is used to test if the group has
+ * terminated, and the {@link #awaitTermination awaitTermination} method can be
+ * used to block until the group has terminated.
+ *
+ * <p> The {@link #shutdownNow() shutdownNow} method can be used to initiate a
+ * <em>forceful shutdown</em> of the group. In addition to the actions performed
+ * by an orderly shutdown, the {@code shutdownNow} method closes all open channels
+ * in the group as if by invoking the {@link AsynchronousChannel#close close}
+ * method.
+ *
+ * @since 1.7
+ *
+ * @see AsynchronousSocketChannel#open(AsynchronousChannelGroup)
+ * @see AsynchronousServerSocketChannel#open(AsynchronousChannelGroup)
+ */
+
+public abstract class AsynchronousChannelGroup {
+    private final AsynchronousChannelProvider provider;
+
+    /**
+     * Initialize a new instance of this class.
+     *
+     * @param   provider
+     *          The asynchronous channel provider for this group
+     */
+    protected AsynchronousChannelGroup(AsynchronousChannelProvider provider) {
+        this.provider = provider;
+    }
+
+    /**
+     * Returns the provider that created this channel group.
+     *
+     * @return  The provider that created this channel group
+     */
+    public final AsynchronousChannelProvider provider() {
+        return provider;
+    }
+
+    /**
+     * Creates an asynchronous channel group with a fixed thread pool.
+     *
+     * <p> The resulting asynchronous channel group reuses a fixed number of
+     * threads. At any point, at most {@code nThreads} threads will be active
+     * processing tasks that are submitted to handle I/O events and dispatch
+     * completion results for operations initiated on asynchronous channels in
+     * the group.
+     *
+     * <p> The group is created by invoking the {@link
+     * AsynchronousChannelProvider#openAsynchronousChannelGroup(int,ThreadFactory)
+     * openAsynchronousChannelGroup(int,ThreadFactory)} method of the system-wide
+     * default {@link AsynchronousChannelProvider} object.
+     *
+     * @param   nThreads
+     *          The number of threads in the pool
+     * @param   threadFactory
+     *          The factory to use when creating new threads
+     *
+     * @return  A new asynchronous channel group
+     *
+     * @throws  IllegalArgumentException
+     *          If {@code nThreads <= 0}
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    public static AsynchronousChannelGroup withFixedThreadPool(int nThreads,
+                                                               ThreadFactory threadFactory)
+        throws IOException
+    {
+        return AsynchronousChannelProvider.provider()
+            .openAsynchronousChannelGroup(nThreads, threadFactory);
+    }
+
+    /**
+     * Creates an asynchronous channel group with a given thread pool that
+     * creates new threads as needed.
+     *
+     * <p> The {@code executor} parameter is an {@code ExecutorService} that
+     * creates new threads as needed to execute tasks that are submitted to
+     * handle I/O events and dispatch completion results for operations initiated
+     * on asynchronous channels in the group. It may reuse previously constructed
+     * threads when they are available.
+     *
+     * <p> The {@code initialSize} parameter may be used by the implementation
+     * as a <em>hint</em> as to the initial number of tasks it may submit. For
+     * example, it may be used to indictae the initial number of threads that
+     * wait on I/O events.
+     *
+     * <p> The executor is intended to be used exclusively by the resulting
+     * asynchronous channel group. Termination of the group results in the
+     * orderly  {@link ExecutorService#shutdown shutdown} of the executor
+     * service. Shutting down the executor service by other means results in
+     * unspecified behavior.
+     *
+     * <p> The group is created by invoking the {@link
+     * AsynchronousChannelProvider#openAsynchronousChannelGroup(ExecutorService,int)
+     * openAsynchronousChannelGroup(ExecutorService,int)} method of the system-wide
+     * default {@link AsynchronousChannelProvider} object.
+     *
+     * @param   executor
+     *          The thread pool for the resulting group
+     * @param   initialSize
+     *          A value {@code >=0} or a negative value for implementation
+     *          specific default
+     *
+     * @return  A new asynchronous channel group
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     *
+     * @see java.util.concurrent.Executors#newCachedThreadPool
+     */
+    public static AsynchronousChannelGroup withCachedThreadPool(ExecutorService executor,
+                                                                int initialSize)
+        throws IOException
+    {
+        return AsynchronousChannelProvider.provider()
+            .openAsynchronousChannelGroup(executor, initialSize);
+    }
+
+    /**
+     * Creates an asynchronous channel group with a given thread pool.
+     *
+     * <p> The {@code executor} parameter is an {@code ExecutorService} that
+     * executes tasks submitted to dispatch completion results for operations
+     * initiated on asynchronous channels in the group.
+     *
+     * <p> Care should be taken when configuring the executor service. It
+     * should support <em>direct handoff</em> or <em>unbounded queuing</em> of
+     * submitted tasks, and the thread that invokes the {@link
+     * ExecutorService#execute execute} method should never invoke the task
+     * directly. An implementation may mandate additional constraints.
+     *
+     * <p> The executor is intended to be used exclusively by the resulting
+     * asynchronous channel group. Termination of the group results in the
+     * orderly  {@link ExecutorService#shutdown shutdown} of the executor
+     * service. Shutting down the executor service by other means results in
+     * unspecified behavior.
+     *
+     * <p> The group is created by invoking the {@link
+     * AsynchronousChannelProvider#openAsynchronousChannelGroup(ExecutorService,int)
+     * openAsynchronousChannelGroup(ExecutorService,int)} method of the system-wide
+     * default {@link AsynchronousChannelProvider} object with an {@code
+     * initialSize} of {@code 0}.
+     *
+     * @param   executor
+     *          The thread pool for the resulting group
+     *
+     * @return  A new asynchronous channel group
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    public static AsynchronousChannelGroup withThreadPool(ExecutorService executor)
+        throws IOException
+    {
+        return AsynchronousChannelProvider.provider()
+            .openAsynchronousChannelGroup(executor, 0);
+    }
+
+    /**
+     * Tells whether or not this asynchronous channel group is shutdown.
+     *
+     * @return  {@code true} if this asynchronous channel group is shutdown or
+     *          has been marked for shutdown.
+     */
+    public abstract boolean isShutdown();
+
+    /**
+     * Tells whether or not this group has terminated.
+     *
+     * <p> Where this method returns {@code true}, then the associated thread
+     * pool has also {@link ExecutorService#isTerminated terminated}.
+     *
+     * @return  {@code true} if this group has terminated
+     */
+    public abstract boolean isTerminated();
+
+    /**
+     * Initiates an orderly shutdown of the group.
+     *
+     * <p> This method marks the group as shutdown. Further attempts to construct
+     * channel that binds to this group will throw {@link ShutdownChannelGroupException}.
+     * The group terminates when all asynchronous channels in the group are
+     * closed, all actively executing completion handlers have run to completion,
+     * and all resources have been released. This method has no effect if the
+     * group is already shutdown.
+     */
+    public abstract void shutdown();
+
+    /**
+     * Shuts down the group and closes all open channels in the group.
+     *
+     * <p> In addition to the actions performed by the {@link #shutdown() shutdown}
+     * method, this method invokes the {@link AsynchronousChannel#close close}
+     * method on all open channels in the group. This method does not attempt to
+     * stop or interrupt threads that are executing completion handlers. The
+     * group terminates when all actively executing completion handlers have run
+     * to completion and all resources have been released. This method may be
+     * invoked at any time. If some other thread has already invoked it, then
+     * another invocation will block until the first invocation is complete,
+     * after which it will return without effect.
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    public abstract void shutdownNow() throws IOException;
+
+    /**
+     * Awaits termination of the group.
+
+     * <p> This method blocks until the group has terminated, or the timeout
+     * occurs, or the current thread is interrupted, whichever happens first.
+     *
+     * @param   timeout
+     *          The maximum time to wait, or zero or less to not wait
+     * @param   unit
+     *          The time unit of the timeout argument
+     *
+     * @return  {@code true} if the group has terminated; {@code false} if the
+     *          timeout elapsed before termination
+     *
+     * @throws  InterruptedException
+     *          If interrupted while waiting
+     */
+    public abstract boolean awaitTermination(long timeout, TimeUnit unit)
+        throws InterruptedException;
+}
diff --git a/jdk/src/share/classes/java/nio/channels/AsynchronousDatagramChannel.java b/jdk/src/share/classes/java/nio/channels/AsynchronousDatagramChannel.java
new file mode 100644
index 0000000..6a9d9f0
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/channels/AsynchronousDatagramChannel.java
@@ -0,0 +1,718 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.channels;
+
+import java.nio.channels.spi.*;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.Future;
+import java.io.IOException;
+import java.net.SocketOption;
+import java.net.SocketAddress;
+import java.net.ProtocolFamily;
+import java.nio.ByteBuffer;
+
+/**
+ * An asynchronous channel for datagram-oriented sockets.
+ *
+ * <p> An asynchronous datagram channel is created by invoking one of the {@link
+ * #open open} methods defined by this class. It is not possible to create a channel
+ * for an arbitrary, pre-existing datagram socket. A newly-created asynchronous
+ * datagram channel is open but not connected. It need not be connected in order
+ * for the {@link #send send} and {@link #receive receive} methods to be used.
+ * A datagram channel may be connected, by invoking its {@link #connect connect}
+ * method, in order to avoid the overhead of the security checks that are otherwise
+ * performed as part of every send and receive operation when a security manager
+ * is set. The channel must be connected in order to use the {@link #read read}
+ * and {@link #write write} methods, since those methods do not accept or return
+ * socket addresses. Once connected, an asynchronous datagram channel remains
+ * connected until it is disconnected or closed.
+ *
+ * <p> Socket options are configured using the {@link #setOption(SocketOption,Object)
+ * setOption} method. An asynchronous datagram channel to an Internet Protocol
+ * (IP) socket supports the following options:
+ * <blockquote>
+ * <table border>
+ *   <tr>
+ *     <th>Option Name</th>
+ *     <th>Description</th>
+ *   </tr>
+ *   <tr>
+ *     <td> {@link java.net.StandardSocketOption#SO_SNDBUF SO_SNDBUF} </td>
+ *     <td> The size of the socket send buffer </td>
+ *   </tr>
+ *   <tr>
+ *     <td> {@link java.net.StandardSocketOption#SO_RCVBUF SO_RCVBUF} </td>
+ *     <td> The size of the socket receive buffer </td>
+ *   </tr>
+ *   <tr>
+ *     <td> {@link java.net.StandardSocketOption#SO_REUSEADDR SO_REUSEADDR} </td>
+ *     <td> Re-use address </td>
+ *   </tr>
+ *   <tr>
+ *     <td> {@link java.net.StandardSocketOption#SO_BROADCAST SO_BROADCAST} </td>
+ *     <td> Allow transmission of broadcast datagrams </td>
+ *   </tr>
+ *   <tr>
+ *     <td> {@link java.net.StandardSocketOption#IP_TOS IP_TOS} </td>
+ *     <td> The Type of Service (ToS) octet in the Internet Protocol (IP) header </td>
+ *   </tr>
+ *   <tr>
+ *     <td> {@link java.net.StandardSocketOption#IP_MULTICAST_IF IP_MULTICAST_IF} </td>
+ *     <td> The network interface for Internet Protocol (IP) multicast datagrams </td>
+ *   </tr>
+ *   <tr>
+ *     <td> {@link java.net.StandardSocketOption#IP_MULTICAST_TTL
+ *       IP_MULTICAST_TTL} </td>
+ *     <td> The <em>time-to-live</em> for Internet Protocol (IP) multicast
+ *       datagrams </td>
+ *   </tr>
+ *   <tr>
+ *     <td> {@link java.net.StandardSocketOption#IP_MULTICAST_LOOP
+ *       IP_MULTICAST_LOOP} </td>
+ *     <td> Loopback for Internet Protocol (IP) multicast datagrams </td>
+ *   </tr>
+ * </table>
+ * </blockquote>
+ * Additional (implementation specific) options may also be supported.
+ *
+ * <p> Asynchronous datagram channels allow more than one read/receive and
+ * write/send to be oustanding at any given time.
+ *
+ * <p> <b>Usage Example:</b>
+ * <pre>
+ *  final AsynchronousDatagramChannel dc = AsynchronousDatagramChannel.open()
+ *      .bind(new InetSocketAddress(4000));
+ *
+ *  // print the source address of all packets that we receive
+ *  dc.receive(buffer, buffer, new CompletionHandler&lt;SocketAddress,ByteBuffer&gt;() {
+ *      public void completed(SocketAddress sa, ByteBuffer buffer) {
+ *          try {
+ *               System.out.println(sa);
+ *
+ *               buffer.clear();
+ *               dc.receive(buffer, buffer, this);
+ *           } catch (...) { ... }
+ *      }
+ *      public void failed(Throwable exc, ByteBuffer buffer) {
+ *          ...
+ *      }
+ *      public void cancelled(ByteBuffer buffer) {
+ *          ...
+ *      }
+ *  });
+ * </pre>
+ *
+ * @since 1.7
+ */
+
+public abstract class AsynchronousDatagramChannel
+    implements AsynchronousByteChannel, MulticastChannel
+{
+    private final AsynchronousChannelProvider provider;
+
+    /**
+     * Initializes a new instance of this class.
+     */
+    protected AsynchronousDatagramChannel(AsynchronousChannelProvider provider) {
+        this.provider = provider;
+    }
+
+    /**
+     * Returns the provider that created this channel.
+     */
+    public final AsynchronousChannelProvider provider() {
+        return provider;
+    }
+
+    /**
+     * Opens an asynchronous datagram channel.
+     *
+     * <p> The new channel is created by invoking the {@link
+     * java.nio.channels.spi.AsynchronousChannelProvider#openAsynchronousDatagramChannel
+     * openAsynchronousDatagramChannel} method on the {@link
+     * java.nio.channels.spi.AsynchronousChannelProvider} object that created
+     * the given group (or the default provider where {@code group} is {@code
+     * null}).
+     *
+     * <p> The {@code family} parameter is used to specify the {@link ProtocolFamily}.
+     * If the datagram channel is to be used for Internet Protocol {@link
+     * MulticastChannel multicasting} then this parameter should correspond to
+     * the address type of the multicast groups that this channel will join.
+     *
+     * @param   family
+     *          The protocol family, or {@code null} to use the default protocol
+     *          family
+     * @param   group
+     *          The group to which the newly constructed channel should be bound,
+     *          or {@code null} for the default group
+     *
+     * @return  A new asynchronous datagram channel
+     *
+     * @throws  UnsupportedOperationException
+     *          If the specified protocol family is not supported. For example,
+     *          suppose the parameter is specified as {@link
+     *          java.net.StandardProtocolFamily#INET6 INET6} but IPv6 is not
+     *          enabled on the platform.
+     * @throws  ShutdownChannelGroupException
+     *          The specified group is shutdown
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    public static AsynchronousDatagramChannel open(ProtocolFamily family,
+                                                   AsynchronousChannelGroup group)
+        throws IOException
+    {
+        AsynchronousChannelProvider provider = (group == null) ?
+            AsynchronousChannelProvider.provider() : group.provider();
+        return provider.openAsynchronousDatagramChannel(family, group);
+    }
+
+    /**
+     * Opens an asynchronous datagram channel.
+     *
+     * <p> This method returns an asynchronous datagram channel that is
+     * bound to the <em>default group</em>. This method is equivalent to evaluating
+     * the expression:
+     * <blockquote><pre>
+     * open((ProtocolFamily)null,&nbsp;(AsynchronousChannelGroup)null);
+     * </pre></blockquote>
+     *
+     * @return  A new asynchronous datagram channel
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    public static AsynchronousDatagramChannel open()
+        throws IOException
+    {
+        return open(null, null);
+    }
+
+    // -- Socket-specific operations --
+
+    /**
+     * @throws  AlreadyBoundException               {@inheritDoc}
+     * @throws  UnsupportedAddressTypeException     {@inheritDoc}
+     * @throws  ClosedChannelException              {@inheritDoc}
+     * @throws  IOException                         {@inheritDoc}
+     * @throws  SecurityException
+     *          If a security manager has been installed and its {@link
+     *          SecurityManager#checkListen checkListen} method denies the
+     *          operation
+     */
+    @Override
+    public abstract AsynchronousDatagramChannel bind(SocketAddress local)
+        throws IOException;
+
+    /**
+     * @throws  IllegalArgumentException                {@inheritDoc}
+     * @throws  ClosedChannelException                  {@inheritDoc}
+     * @throws  IOException                             {@inheritDoc}
+     */
+    @Override
+    public abstract <T> AsynchronousDatagramChannel setOption(SocketOption<T> name, T value)
+        throws IOException;
+
+    /**
+     * Returns the remote address to which this channel is connected.
+     *
+     * <p> Where the channel is connected to an Internet Protocol socket address
+     * then the return value from this method is of type {@link
+     * java.net.InetSocketAddress}.
+     *
+     * @return  The remote address; {@code null} if the channel's socket is not
+     *          connected
+     *
+     * @throws  ClosedChannelException
+     *          If the channel is closed
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    public abstract SocketAddress getRemoteAddress() throws IOException;
+
+    /**
+     * Connects this channel's socket.
+     *
+     * <p> The channel's socket is configured so that it only receives
+     * datagrams from, and sends datagrams to, the given remote <i>peer</i>
+     * address.  Once connected, datagrams may not be received from or sent to
+     * any other address.  A datagram socket remains connected until it is
+     * explicitly disconnected or until it is closed.
+     *
+     * <p> This method performs exactly the same security checks as the {@link
+     * java.net.DatagramSocket#connect connect} method of the {@link
+     * java.net.DatagramSocket} class.  That is, if a security manager has been
+     * installed then this method verifies that its {@link
+     * java.lang.SecurityManager#checkAccept checkAccept} and {@link
+     * java.lang.SecurityManager#checkConnect checkConnect} methods permit
+     * datagrams to be received from and sent to, respectively, the given
+     * remote address.
+     *
+     * <p> This method may be invoked at any time. Whether it has any effect
+     * on outstanding read or write operations is implementation specific and
+     * therefore not specified.
+     *
+     * @param  remote
+     *         The remote address to which this channel is to be connected
+     *
+     * @return  This datagram channel
+     *
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     *
+     * @throws  SecurityException
+     *          If a security manager has been installed
+     *          and it does not permit access to the given remote address
+     *
+     * @throws  IOException
+     *          If some other I/O error occurs
+     */
+    public abstract AsynchronousDatagramChannel connect(SocketAddress remote)
+        throws IOException;
+
+    /**
+     * Disconnects this channel's socket.
+     *
+     * <p> The channel's socket is configured so that it can receive datagrams
+     * from, and sends datagrams to, any remote address so long as the security
+     * manager, if installed, permits it.
+     *
+     * <p> This method may be invoked at any time. Whether it has any effect
+     * on outstanding read or write operations is implementation specific and
+     * therefore not specified.
+     *
+     * @return  This datagram channel
+     *
+     * @throws  IOException
+     *          If some other I/O error occurs
+     */
+    public abstract AsynchronousDatagramChannel disconnect() throws IOException;
+
+    /**
+     * Receives a datagram via this channel.
+     *
+     * <p> This method initiates the receiving of a datagram, returning a
+     * {@code Future} representing the pending result of the operation.
+     * The {@code Future}'s {@link Future#get() get} method returns
+     * the source address of the datagram upon successful completion.
+     *
+     * <p> The datagram is transferred into the given byte buffer starting at
+     * its current position, as if by a regular {@link AsynchronousByteChannel#read
+     * read} operation. If there are fewer bytes remaining in the buffer
+     * than are required to hold the datagram then the remainder of the datagram
+     * is silently discarded.
+     *
+     * <p> If a timeout is specified and the timeout elapses before the operation
+     * completes then the operation completes with the exception {@link
+     * InterruptedByTimeoutException}. When a timeout elapses then the state of
+     * the {@link ByteBuffer} is not defined. The buffers should be discarded or
+     * at least care must be taken to ensure that the buffer is not accessed
+     * while the channel remains open.
+     *
+     * <p> When a security manager has been installed and the channel is not
+     * connected, then it verifies that the source's address and port number are
+     * permitted by the security manager's {@link SecurityManager#checkAccept
+     * checkAccept} method. The permission check is performed with privileges that
+     * are restricted by the calling context of this method. If the permission
+     * check fails then the operation completes with a {@link SecurityException}.
+     * The overhead of this security check can be avoided by first connecting the
+     * socket via the {@link #connect connect} method.
+     *
+     * @param   dst
+     *          The buffer into which the datagram is to be transferred
+     * @param   timeout
+     *          The timeout, or {@code 0L} for no timeout
+     * @param   unit
+     *          The time unit of the {@code timeout} argument
+     * @param   attachment
+     *          The object to attach to the I/O operation; can be {@code null}
+     * @param   handler
+     *          The handler for consuming the result; can be {@code null}
+     *
+     * @return  a {@code Future} object representing the pending result
+     *
+     * @throws  IllegalArgumentException
+     *          If the timeout is negative or the buffer is read-only
+     * @throws  ShutdownChannelGroupException
+     *          If a handler is specified, and the channel group is shutdown
+     */
+    public abstract <A> Future<SocketAddress> receive(ByteBuffer dst,
+                                                      long timeout,
+                                                      TimeUnit unit,
+                                                      A attachment,
+                                                      CompletionHandler<SocketAddress,? super A> handler);
+
+    /**
+     * Receives a datagram via this channel.
+     *
+     * <p> This method initiates the receiving of a datagram, returning a
+     * {@code Future} representing the pending result of the operation.
+     * The {@code Future}'s {@link Future#get() get} method returns
+     * the source address of the datagram upon successful completion.
+     *
+     * <p> This method is equivalent to invoking {@link
+     * #receive(ByteBuffer,long,TimeUnit,Object,CompletionHandler)} with a
+     * timeout of {@code 0L}.
+     *
+     * @param   dst
+     *          The buffer into which the datagram is to be transferred
+     * @param   attachment
+     *          The object to attach to the I/O operation; can be {@code null}
+     * @param   handler
+     *          The handler for consuming the result; can be {@code null}
+     *
+     * @return  a {@code Future} object representing the pending result
+     *
+     * @throws  IllegalArgumentException
+     *          If the buffer is read-only
+     * @throws  ShutdownChannelGroupException
+     *          If a handler is specified, and the channel group is shutdown
+     */
+    public final <A> Future<SocketAddress> receive(ByteBuffer dst,
+                                                   A attachment,
+                                                   CompletionHandler<SocketAddress,? super A> handler)
+    {
+        return receive(dst, 0L, TimeUnit.MILLISECONDS, attachment, handler);
+    }
+
+    /**
+     * Receives a datagram via this channel.
+     *
+     * <p> This method initiates the receiving of a datagram, returning a
+     * {@code Future} representing the pending result of the operation.
+     * The {@code Future}'s {@link Future#get() get} method returns
+     * the source address of the datagram upon successful completion.
+     *
+     * <p> This method is equivalent to invoking {@link
+     * #receive(ByteBuffer,long,TimeUnit,Object,CompletionHandler)} with a
+     * timeout of {@code 0L}, and an attachment and completion handler
+     * of {@code null}.
+     *
+     * @param   dst
+     *          The buffer into which the datagram is to be transferred
+     *
+     * @return  a {@code Future} object representing the pending result
+     *
+     * @throws  IllegalArgumentException
+     *          If the buffer is read-only
+     */
+    public final <A> Future<SocketAddress> receive(ByteBuffer dst) {
+        return receive(dst, 0L, TimeUnit.MILLISECONDS, null, null);
+    }
+
+    /**
+     * Sends a datagram via this channel.
+     *
+     * <p> This method initiates sending of a datagram, returning a
+     * {@code Future} representing the pending result of the operation.
+     * The operation sends the remaining bytes in the given buffer as a single
+     * datagram to the given target address. The result of the operation, obtained
+     * by invoking the {@code Future}'s {@link Future#get() get}
+     * method, is the number of bytes sent.
+     *
+     * <p> The datagram is transferred from the byte buffer as if by a regular
+     * {@link AsynchronousByteChannel#write write} operation.
+     *
+     * <p> If a timeout is specified and the timeout elapses before the operation
+     * completes then the operation completes with the exception {@link
+     * InterruptedByTimeoutException}. When a timeout elapses then the state of
+     * the {@link ByteBuffer} is not defined. The buffers should be discarded or
+     * at least care must be taken to ensure that the buffer is not accessed
+     * while the channel remains open.
+     *
+     * <p> If there is a security manager installed and the the channel is not
+     * connected then this method verifies that the target address and port number
+     * are permitted by the security manager's {@link SecurityManager#checkConnect
+     * checkConnect} method.  The overhead of this security check can be avoided
+     * by first connecting the socket via the {@link #connect connect} method.
+     *
+     * @param   src
+     *          The buffer containing the datagram to be sent
+     * @param   target
+     *          The address to which the datagram is to be sent
+     * @param   timeout
+     *          The timeout, or {@code 0L} for no timeout
+     * @param   unit
+     *          The time unit of the {@code timeout} argument
+     * @param   attachment
+     *          The object to attach to the I/O operation; can be {@code null}
+     * @param   handler
+     *          The handler for consuming the result; can be {@code null}
+     *
+     * @return  a {@code Future} object representing the pending result
+     *
+     * @throws  UnresolvedAddressException
+     *          If the given remote address is not fully resolved
+     * @throws  UnsupportedAddressTypeException
+     *          If the type of the given remote address is not supported
+     * @throws  IllegalArgumentException
+     *          If the timeout is negative, or if the channel's socket is
+     *          connected to an address that is not equal to {@code target}
+     * @throws  SecurityException
+     *          If a security manager has been installed and it does not permit
+     *          datagrams to be sent to the given address
+     * @throws  ShutdownChannelGroupException
+     *          If a handler is specified, and the channel group is shutdown
+     */
+    public abstract <A> Future<Integer> send(ByteBuffer src,
+                                             SocketAddress target,
+                                             long timeout,
+                                             TimeUnit unit,
+                                             A attachment,
+                                             CompletionHandler<Integer,? super A> handler);
+
+    /**
+     * Sends a datagram via this channel.
+     *
+     * <p> This method initiates sending of a datagram, returning a
+     * {@code Future} representing the pending result of the operation.
+     * The operation sends the remaining bytes in the given buffer as a single
+     * datagram to the given target address. The result of the operation, obtained
+     * by invoking the {@code Future}'s {@link Future#get() get}
+     * method, is the number of bytes sent.
+     *
+     * <p> This method is equivalent to invoking {@link
+     * #send(ByteBuffer,SocketAddress,long,TimeUnit,Object,CompletionHandler)}
+     * with a timeout of {@code 0L}.
+     *
+     * @param   src
+     *          The buffer containing the datagram to be sent
+     * @param   target
+     *          The address to which the datagram is to be sent
+     * @param   attachment
+     *          The object to attach to the I/O operation; can be {@code null}
+     * @param   handler
+     *          The handler for consuming the result; can be {@code null}
+     *
+     * @return  a {@code Future} object representing the pending result
+     *
+     * @throws  UnresolvedAddressException
+     *          If the given remote address is not fully resolved
+     * @throws  UnsupportedAddressTypeException
+     *          If the type of the given remote address is not supported
+     * @throws  IllegalArgumentException
+     *          If the channel's socket is connected and is connected to an
+     *          address that is not equal to {@code target}
+     * @throws  SecurityException
+     *          If a security manager has been installed and it does not permit
+     *          datagrams to be sent to the given address
+     * @throws  ShutdownChannelGroupException
+     *          If a handler is specified, and the channel group is shutdown
+     */
+    public final <A> Future<Integer> send(ByteBuffer src,
+                                          SocketAddress target,
+                                          A attachment,
+                                          CompletionHandler<Integer,? super A> handler)
+    {
+        return send(src, target, 0L, TimeUnit.MILLISECONDS, attachment, handler);
+    }
+
+    /**
+     * Sends a datagram via this channel.
+     *
+     * <p> This method initiates sending of a datagram, returning a
+     * {@code Future} representing the pending result of the operation.
+     * The operation sends the remaining bytes in the given buffer as a single
+     * datagram to the given target address. The result of the operation, obtained
+     * by invoking the {@code Future}'s {@link Future#get() get}
+     * method, is the number of bytes sent.
+     *
+     * <p> This method is equivalent to invoking {@link
+     * #send(ByteBuffer,SocketAddress,long,TimeUnit,Object,CompletionHandler)}
+     * with a timeout of {@code 0L} and an attachment and completion handler
+     * of {@code null}.
+     *
+     * @param   src
+     *          The buffer containing the datagram to be sent
+     * @param   target
+     *          The address to which the datagram is to be sent
+     *
+     * @return  a {@code Future} object representing the pending result
+     *
+     * @throws  UnresolvedAddressException
+     *          If the given remote address is not fully resolved
+     * @throws  UnsupportedAddressTypeException
+     *          If the type of the given remote address is not supported
+     * @throws  IllegalArgumentException
+     *          If the channel's socket is connected and is connected to an
+     *          address that is not equal to {@code target}
+     * @throws  SecurityException
+     *          If a security manager has been installed and it does not permit
+     *          datagrams to be sent to the given address
+     */
+    public final Future<Integer> send(ByteBuffer src, SocketAddress target) {
+        return send(src, target, 0L, TimeUnit.MILLISECONDS, null, null);
+    }
+
+    /**
+     * Receives a datagram via this channel.
+     *
+     * <p> This method initiates the receiving of a datagram, returning a
+     * {@code Future} representing the pending result of the operation.
+     * The {@code Future}'s {@link Future#get() get} method returns
+     * the number of bytes transferred upon successful completion.
+     *
+     * <p> This method may only be invoked if this channel is connected, and it
+     * only accepts datagrams from the peer that the channel is connected too.
+     * The datagram is transferred into the given byte buffer starting at
+     * its current position and exactly as specified in the {@link
+     * AsynchronousByteChannel} interface. If there are fewer bytes
+     * remaining in the buffer than are required to hold the datagram then the
+     * remainder of the datagram is silently discarded.
+     *
+     * <p> If a timeout is specified and the timeout elapses before the operation
+     * completes then the operation completes with the exception {@link
+     * InterruptedByTimeoutException}. When a timeout elapses then the state of
+     * the {@link ByteBuffer} is not defined. The buffers should be discarded or
+     * at least care must be taken to ensure that the buffer is not accessed
+     * while the channel remains open.
+     *
+     * @param   dst
+     *          The buffer into which the datagram is to be transferred
+     * @param   timeout
+     *          The timeout, or {@code 0L} for no timeout
+     * @param   unit
+     *          The time unit of the {@code timeout} argument
+     * @param   attachment
+     *          The object to attach to the I/O operation; can be {@code null}
+     * @param   handler
+     *          The handler for consuming the result; can be {@code null}
+     *
+     * @return  a {@code Future} object representing the pending result
+     *
+     * @throws  IllegalArgumentException
+     *          If the timeout is negative or buffer is read-only
+     * @throws  NotYetConnectedException
+     *          If this channel is not connected
+     * @throws  ShutdownChannelGroupException
+     *          If a handler is specified, and the channel group is shutdown
+     */
+    public abstract <A> Future<Integer> read(ByteBuffer dst,
+                                             long timeout,
+                                             TimeUnit unit,
+                                             A attachment,
+                                             CompletionHandler<Integer,? super A> handler);
+
+    /**
+     * @throws  NotYetConnectedException
+     *          If this channel is not connected
+     * @throws  ShutdownChannelGroupException
+     *          If a handler is specified, and the channel group is shutdown
+     */
+    @Override
+    public final <A> Future<Integer> read(ByteBuffer dst,
+                                          A attachment,
+                                          CompletionHandler<Integer,? super A> handler)
+    {
+        return read(dst, 0L, TimeUnit.MILLISECONDS, attachment, handler);
+    }
+
+    /**
+     * @throws  NotYetConnectedException
+     *          If this channel is not connected
+     * @throws  ShutdownChannelGroupException
+     *          If a handler is specified, and the channel group is shutdown
+     */
+    @Override
+    public final Future<Integer> read(ByteBuffer dst) {
+        return read(dst, 0L, TimeUnit.MILLISECONDS, null, null);
+    }
+
+    /**
+     * Writes a datagram to this channel.
+     *
+     * <p> This method initiates sending of a datagram, returning a
+     * {@code Future} representing the pending result of the operation.
+     * The operation sends the remaining bytes in the given buffer as a single
+     * datagram. The result of the operation, obtained by invoking the
+     * {@code Future}'s {@link Future#get() get} method, is the
+     * number of bytes sent.
+     *
+     * <p> The datagram is transferred from the byte buffer as if by a regular
+     * {@link AsynchronousByteChannel#write write} operation.
+     *
+     * <p> This method may only be invoked if this channel is connected,
+     * in which case it sends datagrams directly to the socket's peer.  Otherwise
+     * it behaves exactly as specified in the {@link
+     * AsynchronousByteChannel} interface.
+     *
+     * <p> If a timeout is specified and the timeout elapses before the operation
+     * completes then the operation completes with the exception {@link
+     * InterruptedByTimeoutException}. When a timeout elapses then the state of
+     * the {@link ByteBuffer} is not defined. The buffers should be discarded or
+     * at least care must be taken to ensure that the buffer is not accessed
+     * while the channel remains open.
+     *
+     * @param   src
+     *          The buffer containing the datagram to be sent
+     * @param   timeout
+     *          The timeout, or {@code 0L} for no timeout
+     * @param   unit
+     *          The time unit of the {@code timeout} argument
+     * @param   attachment
+     *          The object to attach to the I/O operation; can be {@code null}
+     * @param   handler
+     *          The handler for consuming the result; can be {@code null}
+     *
+     * @return  a {@code Future} object representing the pending result
+     *
+     * @throws  IllegalArgumentException
+     *          If the timeout is negative
+     * @throws  NotYetConnectedException
+     *          If this channel is not connected
+     * @throws  ShutdownChannelGroupException
+     *          If a handler is specified, and the channel group is shutdown
+     */
+    public abstract <A> Future<Integer> write(ByteBuffer src,
+                                              long timeout,
+                                              TimeUnit unit,
+                                              A attachment,
+                                              CompletionHandler<Integer,? super A> handler);
+    /**
+     * @throws  NotYetConnectedException
+     *          If this channel is not connected
+     * @throws  ShutdownChannelGroupException
+     *          If a handler is specified, and the channel group is shutdown
+     */
+    @Override
+    public final <A> Future<Integer> write(ByteBuffer src,
+                                           A attachment,
+                                           CompletionHandler<Integer,? super A> handler)
+    {
+        return write(src, 0L, TimeUnit.MILLISECONDS, attachment, handler);
+    }
+
+    /**
+     * @throws  NotYetConnectedException
+     *          If this channel is not connected
+     * @throws  ShutdownChannelGroupException
+     *          If a handler is specified, and the channel group is shutdown
+     */
+    @Override
+    public final Future<Integer> write(ByteBuffer src) {
+        return write(src, 0L, TimeUnit.MILLISECONDS, null, null);
+    }
+}
diff --git a/jdk/src/share/classes/java/nio/channels/AsynchronousFileChannel.java b/jdk/src/share/classes/java/nio/channels/AsynchronousFileChannel.java
new file mode 100644
index 0000000..a9bff5f
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/channels/AsynchronousFileChannel.java
@@ -0,0 +1,774 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.channels;
+
+import java.nio.file.*;
+import java.nio.file.attribute.FileAttribute;
+import java.nio.file.spi.*;
+import java.nio.ByteBuffer;
+import java.io.IOException;
+import java.util.concurrent.Future;
+import java.util.concurrent.ExecutorService;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Collections;
+
+/**
+ * An asynchronous channel for reading, writing, and manipulating a file.
+ *
+ * <p> An asynchronous file channel is created when a file is opened by invoking
+ * one of the {@link #open open} methods defined by this class. The file contains
+ * a variable-length sequence of bytes that can be read and written and whose
+ * current size can be {@link #size() queried}. The size of the file increases
+ * when bytes are written beyond its  current size; the size of the file decreases
+ * when it is {@link #truncate truncated}.
+ *
+ * <p> An asynchronous file channel does not have a <i>current position</i>
+ * within the file. Instead, the file position is specified to each read and
+ * write operation.
+ *
+ * <p> In addition to read and write operations, this class defines the
+ * following operations: </p>
+ *
+ * <ul>
+ *
+ *   <li><p> Updates made to a file may be {@link #force <i>forced
+ *   out</i>} to the underlying storage device, ensuring that data are not
+ *   lost in the event of a system crash.  </p></li>
+ *
+ *   <li><p> A region of a file may be {@link FileLock <i>locked</i>}
+ *   against access by other programs.  </p></li>
+ *
+ * </ul>
+ *
+ * <p> The {@link #read read}, {@link #write write}, and {@link #lock lock}
+ * methods defined by this class are asynchronous  and return a {@link Future}
+ * to represent the pending result of the operation. This may be used to check
+ * if the operation has completed, to wait for its completion, and to retrieve
+ * the result. These method may optionally specify a {@link CompletionHandler}
+ * that is invoked to consume the result of the I/O operation when it completes.
+ *
+ * <p> An {@code AsynchronousFileChannel} is associated with a thread pool to
+ * which tasks are submitted to handle I/O events and dispatch to completion
+ * handlers that consume the results of I/O operations on the channel. The
+ * completion handler for an I/O operation initiated on a channel is guaranteed
+ * to be invoked by one threads in the thread pool (This ensures that the
+ * completion handler is run by a thread with the expected <em>identity</em>).
+ * Where an I/O operation completes immediately, and the initiating thread is
+ * itself a thread in the thread pool, then the completion handler may be invoked
+ * directly by the initiating thread. When an {@code AsynchronousFileChannel} is
+ * created without specifying a thread pool then the channel is associated with
+ * a system-dependent and default thread pool that may be shared with other
+ * channels. The default thread pool is configured by the system properties
+ * defined by the {@link AsynchronousChannelGroup} class.
+ *
+ * <p> Channels of this type are safe for use by multiple concurrent threads. The
+ * {@link Channel#close close} method may be invoked at any time, as specified
+ * by the {@link Channel} interface. This causes all outstanding asynchronous
+ * operations on the channel to complete with the exception {@link
+ * AsynchronousCloseException}. Multiple read and write operations may be
+ * outstanding at the same time. When multiple read and write operations are
+ * outstanding then the ordering of the I/O operations, and the order that the
+ * completion handlers are invoked, is not specified; they are not, in particular,
+ * guaranteed to execute in the order that the operations were initiated. The
+ * {@link java.nio.ByteBuffer ByteBuffers} used when reading or writing are not
+ * safe for use by multiple concurrent I/O operations. Furthermore, after an I/O
+ * operation is initiated then care should be taken to ensure that the buffer is
+ * not accessed until after the operation has completed.
+ *
+ * <p> As with {@link FileChannel}, the view of a file provided by an instance of
+ * this class is guaranteed to be consistent with other views of the same file
+ * provided by other instances in the same program.  The view provided by an
+ * instance of this class may or may not, however, be consistent with the views
+ * seen by other concurrently-running programs due to caching performed by the
+ * underlying operating system and delays induced by network-filesystem protocols.
+ * This is true regardless of the language in which these other programs are
+ * written, and whether they are running on the same machine or on some other
+ * machine.  The exact nature of any such inconsistencies are system-dependent
+ * and are therefore unspecified.
+ *
+ * @since 1.7
+ */
+
+public abstract class AsynchronousFileChannel
+    implements AsynchronousChannel
+{
+    /**
+     * Initializes a new instance of this class.
+     */
+    protected AsynchronousFileChannel() {
+    }
+
+    /**
+     * Closes this channel.
+     *
+     * <p> If this channel is associated with its own thread pool then closing
+     * the channel causes the thread pool to shutdown after all actively
+     * executing completion handlers have completed. No attempt is made to stop
+     * or interrupt actively completion handlers.
+     *
+     * <p> This method otherwise behaves exactly as specified by the {@link
+     * AsynchronousChannel} interface.
+     *
+     * @throws  IOException     {@inheritDoc}
+     */
+    @Override
+    public abstract void close() throws IOException;
+
+    /**
+     * Opens or creates a file for reading and/or writing, returning an
+     * asynchronous file 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 determines if the file should be opened for reading and/or
+     * writing. If neither option is contained in the array then an existing file
+     * is opened for  reading.
+     *
+     * <p> In 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#TRUNCATE_EXISTING TRUNCATE_EXISTING} </td>
+     *   <td> When opening an existing file, the file is first 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. 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. 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 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
+     *   the {@link #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="../file/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="../file/package-summary.html#integrity"> Synchronized I/O file
+     *   integrity</a>). </td>
+     * </tr>
+     * </table>
+     *
+     * <p> An implementation may also support additional options.
+     *
+     * <p> The {@code executor} parameter is the {@link ExecutorService} to
+     * which tasks are submitted to handle I/O events and dispatch completion
+     * results for operations initiated on resulting channel.
+     * The nature of these tasks is highly implementation specific and so care
+     * should be taken when configuring the {@code Executor}. Minimally it
+     * should support an unbounded work queue and should not run tasks on the
+     * caller thread of the {@link ExecutorService#execute execute} method.
+     * {@link #close Closing} the channel results in the orderly {@link
+     * ExecutorService#shutdown shutdown} of the executor service. Shutting down
+     * the executor service by other means results in unspecified behavior.
+     *
+     * <p> The {@code attrs} parameter is an optional array of file {@link
+     * FileAttribute file-attributes} to set atomically when creating the file.
+     *
+     * <p> The new channel is created by invoking the {@link
+     * FileSystemProvider#newFileChannel newFileChannel} method on the
+     * provider that created the {@code Path}.
+     *
+     * @param   file
+     *          The path of the file to open or create
+     * @param   options
+     *          Options specifying how the file is opened
+     * @param   executor
+     *          The thread pool or {@code null} to associate the channel with
+     *          the default thread pool
+     * @param   attrs
+     *          An optional list of file attributes to set atomically when
+     *          creating the file
+     *
+     * @return  A new asynchronous file channel
+     *
+     * @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
+     *          support creating asynchronous file channels, or an unsupported
+     *          open option is specified, or the array contains an attribute that
+     *          cannot be set atomically when creating the file
+     * @throws  IOException
+     *          If an I/O error occurs
+     * @throws  SecurityException
+     *          If a security manager is installed and it denies an
+     *          unspecified permission required by the implementation.
+     *          In the case of the default provider, the {@link
+     *          SecurityManager#checkRead(String)} method is invoked to check
+     *          read access if the file is opened for reading. The {@link
+     *          SecurityManager#checkWrite(String)} method is invoked to check
+     *          write access if the file is opened for writing
+     */
+    public static AsynchronousFileChannel open(Path file,
+                                               Set<? extends OpenOption> options,
+                                               ExecutorService executor,
+                                               FileAttribute<?>... attrs)
+        throws IOException
+    {
+        FileSystemProvider provider = file.getFileSystem().provider();
+        return provider.newAsynchronousFileChannel(file, options, executor, attrs);
+    }
+
+    private static final FileAttribute<?>[] NO_ATTRIBUTES = new FileAttribute[0];
+
+    /**
+     * Opens or creates a file for reading and/or writing, returning an
+     * asynchronous file channel to access the file.
+     *
+     * <p> An invocation of this method behaves in exactly the same way as the
+     * invocation
+     * <pre>
+     *     ch.{@link #open(Path,Set,ExecutorService,FileAttribute[]) open}(file, opts, null, new FileAttribute&lt;?&gt;[0]);
+     * </pre>
+     * where {@code opts} is a {@code Set} containing the options specified to
+     * this method.
+     *
+     * <p> The resulting channel is associated with default thread pool to which
+     * tasks are submitted to handle I/O events and dispatch to completion
+     * handlers that consume the result of asynchronous operations performed on
+     * the resulting channel.
+     *
+     * @param   file
+     *          The path of the file to open or create
+     * @param   options
+     *          Options specifying how the file is opened
+     *
+     * @return  A new asynchronous file channel
+     *
+     * @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
+     *          support creating file channels, or an unsupported open option is
+     *          specified
+     * @throws  IOException
+     *          If an I/O error occurs
+     * @throws  SecurityException
+     *          If a security manager is installed and it denies an
+     *          unspecified permission required by the implementation.
+     *          In the case of the default provider, the {@link
+     *          SecurityManager#checkRead(String)} method is invoked to check
+     *          read access if the file is opened for reading. The {@link
+     *          SecurityManager#checkWrite(String)} method is invoked to check
+     *          write access if the file is opened for writing
+     */
+    public static AsynchronousFileChannel open(Path file, OpenOption... options)
+        throws IOException
+    {
+        Set<OpenOption> set = new HashSet<OpenOption>(options.length);
+        Collections.addAll(set, options);
+        return open(file, set, null, NO_ATTRIBUTES);
+    }
+
+    /**
+     * Returns the current size of this channel's file.
+     *
+     * @return  The current size of this channel's file, measured in bytes
+     *
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     * @throws  IOException
+     *          If some other I/O error occurs
+     */
+    public abstract long size() throws IOException;
+
+    /**
+     * Truncates this channel's file to the given size.
+     *
+     * <p> If the given size is less than the file's current size then the file
+     * is truncated, discarding any bytes beyond the new end of the file.  If
+     * the given size is greater than or equal to the file's current size then
+     * the file is not modified. </p>
+     *
+     * @param  size
+     *         The new size, a non-negative byte count
+     *
+     * @return  This file channel
+     *
+     * @throws  NonWritableChannelException
+     *          If this channel was not opened for writing
+     *
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     *
+     * @throws  IllegalArgumentException
+     *          If the new size is negative
+     *
+     * @throws  IOException
+     *          If some other I/O error occurs
+     */
+    public abstract AsynchronousFileChannel truncate(long size) throws IOException;
+
+    /**
+     * Forces any updates to this channel's file to be written to the storage
+     * device that contains it.
+     *
+     * <p> If this channel's file resides on a local storage device then when
+     * this method returns it is guaranteed that all changes made to the file
+     * since this channel was created, or since this method was last invoked,
+     * will have been written to that device.  This is useful for ensuring that
+     * critical information is not lost in the event of a system crash.
+     *
+     * <p> If the file does not reside on a local device then no such guarantee
+     * is made.
+     *
+     * <p> The {@code metaData} parameter can be used to limit the number of
+     * I/O operations that this method is required to perform.  Passing
+     * {@code false} for this parameter indicates that only updates to the
+     * file's content need be written to storage; passing {@code true}
+     * indicates that updates to both the file's content and metadata must be
+     * written, which generally requires at least one more I/O operation.
+     * Whether this parameter actually has any effect is dependent upon the
+     * underlying operating system and is therefore unspecified.
+     *
+     * <p> Invoking this method may cause an I/O operation to occur even if the
+     * channel was only opened for reading.  Some operating systems, for
+     * example, maintain a last-access time as part of a file's metadata, and
+     * this time is updated whenever the file is read.  Whether or not this is
+     * actually done is system-dependent and is therefore unspecified.
+     *
+     * <p> This method is only guaranteed to force changes that were made to
+     * this channel's file via the methods defined in this class.
+     *
+     * @param   metaData
+     *          If {@code true} then this method is required to force changes
+     *          to both the file's content and metadata to be written to
+     *          storage; otherwise, it need only force content changes to be
+     *          written
+     *
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     *
+     * @throws  IOException
+     *          If some other I/O error occurs
+     */
+    public abstract void force(boolean metaData) throws IOException;
+
+    /**
+     * Acquires a lock on the given region of this channel's file.
+     *
+     * <p> This method initiates an operation to acquire a lock on the given region
+     * of this channel's file. The method returns a {@code Future} representing
+     * the pending result of the operation. Its {@link Future#get() get}
+     * method returns the {@link FileLock} on successful completion.
+     *
+     * <p> The region specified by the {@code position} and {@code size}
+     * parameters need not be contained within, or even overlap, the actual
+     * underlying file.  Lock regions are fixed in size; if a locked region
+     * initially contains the end of the file and the file grows beyond the
+     * region then the new portion of the file will not be covered by the lock.
+     * If a file is expected to grow in size and a lock on the entire file is
+     * required then a region starting at zero, and no smaller than the
+     * expected maximum size of the file, should be locked.  The two-argument
+     * {@link #lock(Object,CompletionHandler)} method simply locks a region
+     * of size {@link Long#MAX_VALUE}. If a lock that overlaps the requested
+     * region is already held by this Java virtual machine, or this method has
+     * been invoked to lock an overlapping region and that operation has not
+     * completed, then this method throws {@link OverlappingFileLockException}.
+     *
+     * <p> Some operating systems do not support a mechanism to acquire a file
+     * lock in an asynchronous manner. Consequently an implementation may
+     * acquire the file lock in a background thread or from a task executed by
+     * a thread in the associated thread pool. If there are many lock operations
+     * outstanding then it may consume threads in the Java virtual machine for
+     * indefinite periods.
+     *
+     * <p> Some operating systems do not support shared locks, in which case a
+     * request for a shared lock is automatically converted into a request for
+     * an exclusive lock.  Whether the newly-acquired lock is shared or
+     * exclusive may be tested by invoking the resulting lock object's {@link
+     * FileLock#isShared() isShared} method.
+     *
+     * <p> File locks are held on behalf of the entire Java virtual machine.
+     * They are not suitable for controlling access to a file by multiple
+     * threads within the same virtual machine.
+     *
+     * @param   position
+     *          The position at which the locked region is to start; must be
+     *          non-negative
+     * @param   size
+     *          The size of the locked region; must be non-negative, and the sum
+     *          {@code position}&nbsp;+&nbsp;{@code size} must be non-negative
+     * @param   shared
+     *          {@code true} to request a shared lock, in which case this
+     *          channel must be open for reading (and possibly writing);
+     *          {@code false} to request an exclusive lock, in which case this
+     *          channel must be open for writing (and possibly reading)
+     * @param   attachment
+     *          The object to attach to the I/O operation; can be {@code null}
+     * @param   handler
+     *          The handler for consuming the result; can be {@code null}
+     *
+     * @return  a {@code Future} object representing the pending result
+     *
+     * @throws  OverlappingFileLockException
+     *          If a lock that overlaps the requested region is already held by
+     *          this Java virtual machine, or there is already a pending attempt
+     *          to lock an overlapping region
+     * @throws  IllegalArgumentException
+     *          If the preconditions on the parameters do not hold
+     * @throws  NonReadableChannelException
+     *          If {@code shared} is true this channel but was not opened for reading
+     * @throws  NonWritableChannelException
+     *          If {@code shared} is false but this channel was not opened for writing
+     * @throws  ShutdownChannelGroupException
+     *          If a handler is specified, the channel is closed, and the channel
+     *          was originally created with its own thread pool
+     */
+    public abstract <A> Future<FileLock> lock(long position,
+                                              long size,
+                                              boolean shared,
+                                              A attachment,
+                                              CompletionHandler<FileLock,? super A> handler);
+
+    /**
+     * Acquires an exclusive lock on this channel's file.
+     *
+     * <p> This method initiates an operation to acquire an exclusive lock on this
+     * channel's file. The method returns a {@code Future} representing
+     * the pending result of the operation. Its {@link Future#get() get}
+     * method returns the {@link FileLock} on successful completion.
+     *
+     * <p> An invocation of this method of the form {@code ch.lock(att,handler)}
+     * behaves in exactly the same way as the invocation
+     * <pre>
+     *     ch.{@link #lock(long,long,boolean,Object,CompletionHandler) lock}(0L, Long.MAX_VALUE, false, att, handler)
+     * </pre>
+     *
+     * @param   attachment
+     *          The object to attach to the I/O operation; can be {@code null}
+     * @param   handler
+     *          The handler for consuming the result; can be {@code null}
+     *
+     * @return  a {@code Future} object representing the pending result
+     *
+     * @throws  OverlappingFileLockException
+     *          If a lock is already held by this Java virtual machine, or there
+     *          is already a pending attempt to lock a region
+     * @throws  NonWritableChannelException
+     *          If this channel was not opened for writing
+     * @throws  ShutdownChannelGroupException
+     *          If a handler is specified, the channel is closed, and the channel
+     *          was originally created with its own thread pool
+     */
+    public final <A> Future<FileLock> lock(A attachment,
+                                           CompletionHandler<FileLock,? super A> handler)
+    {
+        return lock(0L, Long.MAX_VALUE, false, attachment, handler);
+    }
+
+    /**
+     * Acquires an exclusive lock on this channel's file.
+     *
+     * <p> This method initiates an operation to acquire an exclusive lock on this
+     * channel's file. The method returns a {@code Future} representing the
+     * pending result of the operation. Its {@link Future#get() get} method
+     * returns the {@link FileLock} on successful completion.
+     *
+     * <p> An invocation of this method behaves in exactly the same way as the
+     * invocation
+     * <pre>
+     *     ch.{@link #lock(long,long,boolean,Object,CompletionHandler) lock}(0L, Long.MAX_VALUE, false, null, null)
+     * </pre>
+     *
+     * @return  A {@code Future} object representing the pending result
+     *
+     * @throws  OverlappingFileLockException
+     *          If a lock is already held by this Java virtual machine, or there
+     *          is already a pending attempt to lock a region
+     * @throws  NonWritableChannelException
+     *          If this channel was not opened for writing
+     */
+    public final Future<FileLock> lock() {
+        return lock(0L, Long.MAX_VALUE, false, null, null);
+    }
+
+    /**
+     * Attempts to acquire a lock on the given region of this channel's file.
+     *
+     * <p> This method does not block. An invocation always returns immediately,
+     * either having acquired a lock on the requested region or having failed to
+     * do so.  If it fails to acquire a lock because an overlapping lock is held
+     * by another program then it returns {@code null}.  If it fails to acquire
+     * a lock for any other reason then an appropriate exception is thrown.
+     *
+     * @param  position
+     *         The position at which the locked region is to start; must be
+     *         non-negative
+     *
+     * @param  size
+     *         The size of the locked region; must be non-negative, and the sum
+     *         {@code position}&nbsp;+&nbsp;{@code size} must be non-negative
+     *
+     * @param  shared
+     *         {@code true} to request a shared lock,
+     *         {@code false} to request an exclusive lock
+     *
+     * @return  A lock object representing the newly-acquired lock,
+     *          or {@code null} if the lock could not be acquired
+     *          because another program holds an overlapping lock
+     *
+     * @throws  IllegalArgumentException
+     *          If the preconditions on the parameters do not hold
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     * @throws  OverlappingFileLockException
+     *          If a lock that overlaps the requested region is already held by
+     *          this Java virtual machine, or if another thread is already
+     *          blocked in this method and is attempting to lock an overlapping
+     *          region of the same file
+     * @throws  NonReadableChannelException
+     *          If {@code shared} is true this channel but was not opened for reading
+     * @throws  NonWritableChannelException
+     *          If {@code shared} is false but this channel was not opened for writing
+     *
+     * @throws  IOException
+     *          If some other I/O error occurs
+     *
+     * @see     #lock(Object,CompletionHandler)
+     * @see     #lock(long,long,boolean,Object,CompletionHandler)
+     * @see     #tryLock()
+     */
+    public abstract FileLock tryLock(long position, long size, boolean shared)
+        throws IOException;
+
+    /**
+     * Attempts to acquire an exclusive lock on this channel's file.
+     *
+     * <p> An invocation of this method of the form {@code ch.tryLock()}
+     * behaves in exactly the same way as the invocation
+     *
+     * <pre>
+     *     ch.{@link #tryLock(long,long,boolean) tryLock}(0L, Long.MAX_VALUE, false) </pre>
+     *
+     * @return  A lock object representing the newly-acquired lock,
+     *          or {@code null} if the lock could not be acquired
+     *          because another program holds an overlapping lock
+     *
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     * @throws  OverlappingFileLockException
+     *          If a lock that overlaps the requested region is already held by
+     *          this Java virtual machine, or if another thread is already
+     *          blocked in this method and is attempting to lock an overlapping
+     *          region
+     * @throws  NonWritableChannelException
+     *          If {@code shared} is false but this channel was not opened for writing
+     *
+     * @throws  IOException
+     *          If some other I/O error occurs
+     *
+     * @see     #lock(Object,CompletionHandler)
+     * @see     #lock(long,long,boolean,Object,CompletionHandler)
+     * @see     #tryLock(long,long,boolean)
+     */
+    public final FileLock tryLock() throws IOException {
+        return tryLock(0L, Long.MAX_VALUE, false);
+    }
+
+    /**
+     * Reads a sequence of bytes from this channel into the given buffer,
+     * starting at the given file position.
+     *
+     * <p> This method initiates the reading of a sequence of bytes from this
+     * channel into the given buffer, starting at the given file position. This
+     * method returns a {@code Future} representing the pending result of the
+     * operation. The Future's {@link Future#get() get} method returns the
+     * number of bytes read or {@code -1} if the given position is greater than
+     * or equal to the file's size at the time that the read is attempted.
+     *
+     * <p> This method works in the same manner as the {@link
+     * AsynchronousByteChannel#read(ByteBuffer,Object,CompletionHandler)}
+     * method, except that bytes are read starting at the given file position.
+     * If the given file position is greater than the file's size at the time
+     * that the read is attempted then no bytes are read.
+     *
+     * @param   dst
+     *          The buffer into which bytes are to be transferred
+     * @param   position
+     *          The file position at which the transfer is to begin;
+     *          must be non-negative
+     * @param   attachment
+     *          The object to attach to the I/O operation; can be {@code null}
+     * @param   handler
+     *          The handler for consuming the result; can be {@code null}
+     *
+     * @return  A {@code Future} object representing the pending result
+     *
+     * @throws  IllegalArgumentException
+     *          If the position is negative or the buffer is read-only
+     * @throws  NonReadableChannelException
+     *          If this channel was not opened for reading
+     * @throws  ShutdownChannelGroupException
+     *          If a handler is specified, the channel is closed, and the channel
+     *          was originally created with its own thread pool
+     */
+    public abstract <A> Future<Integer> read(ByteBuffer dst,
+                                             long position,
+                                             A attachment,
+                                             CompletionHandler<Integer,? super A> handler);
+
+    /**
+     * Reads a sequence of bytes from this channel into the given buffer,
+     * starting at the given file position.
+     *
+     * <p> This method initiates the reading of a sequence of bytes from this
+     * channel into the given buffer, starting at the given file position. This
+     * method returns a {@code Future} representing the pending result of the
+     * operation. The Future's {@link Future#get() get} method returns the
+     * number of bytes read or {@code -1} if the given position is greater
+     * than or equal to the file's size at the time that the read is attempted.
+     *
+     * <p> This method is equivalent to invoking {@link
+     * #read(ByteBuffer,long,Object,CompletionHandler)} with the {@code attachment}
+     * and handler parameters set to {@code null}.
+     *
+     * @param   dst
+     *          The buffer into which bytes are to be transferred
+     * @param   position
+     *          The file position at which the transfer is to begin;
+     *          must be non-negative
+     *
+     * @return  A {@code Future} object representing the pending result
+     *
+     * @throws  IllegalArgumentException
+     *          If the position is negative or the buffer is read-only
+     * @throws  NonReadableChannelException
+     *          If this channel was not opened for reading
+     */
+    public final Future<Integer> read(ByteBuffer dst, long position) {
+        return read(dst, position, null, null);
+    }
+
+    /**
+     * Writes a sequence of bytes to this channel from the given buffer, starting
+     * at the given file position.
+     *
+     * <p> This method initiates the writing of a sequence of bytes to this channel
+     * from the given buffer, starting at the given file position. The method
+     * returns a {@code Future} representing the pending result of the write
+     * operation. The Future's {@link Future#get() get} method returns the
+     * number of bytes written.
+     *
+     * <p> This method works in the same manner as the {@link
+     * AsynchronousByteChannel#write(ByteBuffer,Object,CompletionHandler)}
+     * method, except that bytes are written starting at the given file position.
+     * If the given position is greater than the file's size, at the time that
+     * the write is attempted, then the file will be grown to accommodate the new
+     * bytes; the values of any bytes between the previous end-of-file and the
+     * newly-written bytes are unspecified.
+     *
+     * @param   src
+     *          The buffer from which bytes are to be transferred
+     * @param   position
+     *          The file position at which the transfer is to begin;
+     *          must be non-negative
+     * @param   attachment
+     *          The object to attach to the I/O operation; can be {@code null}
+     * @param   handler
+     *          The handler for consuming the result; can be {@code null}
+     *
+     * @return  A {@code Future} object representing the pending result
+     *
+     * @throws  IllegalArgumentException
+     *          If the position is negative
+     * @throws  NonWritableChannelException
+     *          If this channel was not opened for writing
+     * @throws  ShutdownChannelGroupException
+     *          If a handler is specified, the channel is closed, and the channel
+     *          was originally created with its own thread pool
+     */
+    public abstract <A> Future<Integer> write(ByteBuffer src,
+                                              long position,
+                                              A attachment,
+                                              CompletionHandler<Integer,? super A> handler);
+
+    /**
+     * Writes a sequence of bytes to this channel from the given buffer, starting
+     * at the given file position.
+     *
+     * <p> This method initiates the writing of a sequence of bytes to this channel
+     * from the given buffer, starting at the given file position. The method
+     * returns a {@code Future} representing the pending result of the write
+     * operation. The Future's {@link Future#get() get} method returns the
+     * number of bytes written.
+     *
+     * <p> This method is equivalent to invoking {@link
+     * #write(ByteBuffer,long,Object,CompletionHandler)} with the {@code attachment}
+     * and handler parameters set to {@code null}.
+     *
+     * @param   src
+     *          The buffer from which bytes are to be transferred
+     * @param   position
+     *          The file position at which the transfer is to begin;
+     *          must be non-negative
+     *
+     * @return  A {@code Future} object representing the pending result
+     *
+     * @throws  IllegalArgumentException
+     *          If the position is negative
+     * @throws  NonWritableChannelException
+     *          If this channel was not opened for writing
+     */
+    public final Future<Integer> write(ByteBuffer src, long position) {
+        return write(src, position, null, null);
+    }
+}
diff --git a/jdk/src/share/classes/java/nio/channels/AsynchronousServerSocketChannel.java b/jdk/src/share/classes/java/nio/channels/AsynchronousServerSocketChannel.java
new file mode 100644
index 0000000..99c56fa
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/channels/AsynchronousServerSocketChannel.java
@@ -0,0 +1,303 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.channels;
+
+import java.nio.channels.spi.*;
+import java.net.SocketOption;
+import java.net.SocketAddress;
+import java.util.concurrent.Future;
+import java.io.IOException;
+
+/**
+ * An asynchronous channel for stream-oriented listening sockets.
+ *
+ * <p> An asynchronous server-socket channel is created by invoking the
+ * {@link #open open} method of this class.
+ * A newly-created asynchronous server-socket channel is open but not yet bound.
+ * It can be bound to a local address and configured to listen for connections
+ * by invoking the {@link #bind(SocketAddress,int) bind} method. Once bound,
+ * the {@link #accept(Object,CompletionHandler) accept} method
+ * is used to initiate the accepting of connections to the channel's socket.
+ * An attempt to invoke the <tt>accept</tt> method on an unbound channel will
+ * cause a {@link NotYetBoundException} to be thrown.
+ *
+ * <p> Channels of this type are safe for use by multiple concurrent threads
+ * though at most one accept operation can be outstanding at any time.
+ * If a thread initiates an accept operation before a previous accept operation
+ * has completed then an {@link AcceptPendingException} will be thrown.
+ *
+ * <p> Socket options are configured using the {@link #setOption(SocketOption,Object)
+ * setOption} method. Channels of this type support the following options:
+ * <blockquote>
+ * <table border>
+ *   <tr>
+ *     <th>Option Name</th>
+ *     <th>Description</th>
+ *   </tr>
+ *   <tr>
+ *     <td> {@link java.net.StandardSocketOption#SO_RCVBUF SO_RCVBUF} </td>
+ *     <td> The size of the socket receive buffer </td>
+ *   </tr>
+ *   <tr>
+ *     <td> {@link java.net.StandardSocketOption#SO_REUSEADDR SO_REUSEADDR} </td>
+ *     <td> Re-use address </td>
+ *   </tr>
+ * </table>
+ * </blockquote>
+ * Additional (implementation specific) options may also be supported.
+ *
+ * <p> <b>Usage Example:</b>
+ * <pre>
+ *  final AsynchronousServerSocketChannel listener =
+ *      AsynchronousServerSocketChannel.open().bind(new InetSocketAddress(5000));
+ *
+ *  listener.accept(null, new CompletionHandler&lt;AsynchronousSocketChannel,Void&gt;() {
+ *      public void completed(AsynchronousSocketChannel ch, Void att) {
+ *          // accept the next connection
+ *          listener.accept(null, this);
+ *
+ *          // handle this connection
+ *          handle(ch);
+ *      }
+ *      public void failed(Throwable exc, Void att) {
+ *          ...
+ *      }
+ *      public void cancelled(Void att) {
+ *          ...
+ *      }
+ *  });
+ * </pre>
+ *
+ * @since 1.7
+ */
+
+public abstract class AsynchronousServerSocketChannel
+    implements AsynchronousChannel, NetworkChannel
+{
+    private final AsynchronousChannelProvider provider;
+
+    /**
+     * Initializes a new instance of this class.
+     */
+    protected AsynchronousServerSocketChannel(AsynchronousChannelProvider provider) {
+        this.provider = provider;
+    }
+
+    /**
+     * Returns the provider that created this channel.
+     */
+    public final AsynchronousChannelProvider provider() {
+        return provider;
+    }
+
+    /**
+     * Opens an asynchronous server-socket channel.
+     *
+     * <p> The new channel is created by invoking the {@link
+     * java.nio.channels.spi.AsynchronousChannelProvider#openAsynchronousServerSocketChannel
+     * openAsynchronousServerSocketChannel} method on the {@link
+     * java.nio.channels.spi.AsynchronousChannelProvider} object that created
+     * the given group. If the group parameter is <tt>null</tt> then the
+     * resulting channel is created by the system-wide default provider, and
+     * bound to the <em>default group</em>.
+     *
+     * @param   group
+     *          The group to which the newly constructed channel should be bound,
+     *          or <tt>null</tt> for the default group
+     *
+     * @return  A new asynchronous server socket channel
+     *
+     * @throws  ShutdownChannelGroupException
+     *          If the channel group is shutdown
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    public static AsynchronousServerSocketChannel open(AsynchronousChannelGroup group)
+        throws IOException
+    {
+        AsynchronousChannelProvider provider = (group == null) ?
+            AsynchronousChannelProvider.provider() : group.provider();
+        return provider.openAsynchronousServerSocketChannel(group);
+    }
+
+    /**
+     * Opens an asynchronous server-socket channel.
+     *
+     * <p> This method returns an asynchronous server socket channel that is
+     * bound to the <em>default group</em>. This method is equivalent to evaluating
+     * the expression:
+     * <blockquote><pre>
+     * open((AsynchronousChannelGroup)null);
+     * </pre></blockquote>
+     *
+     * @return  A new asynchronous server socket channel
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    public static AsynchronousServerSocketChannel open()
+        throws IOException
+    {
+        return open(null);
+    }
+
+    /**
+     * Binds the channel's socket to a local address and configures the socket to
+     * listen for connections.
+     *
+     * <p> An invocation of this method is equivalent to the following:
+     * <blockquote><pre>
+     * bind(local, 0);
+     * </pre></blockquote>
+     *
+     * @param   local
+     *          The local address to bind the socket, or <tt>null</tt> to bind
+     *          to an automatically assigned socket address
+     *
+     * @return  This channel
+     *
+     * @throws  AlreadyBoundException               {@inheritDoc}
+     * @throws  UnsupportedAddressTypeException     {@inheritDoc}
+     * @throws  SecurityException                   {@inheritDoc}
+     * @throws  ClosedChannelException              {@inheritDoc}
+     * @throws  IOException                         {@inheritDoc}
+     */
+    public final AsynchronousServerSocketChannel bind(SocketAddress local)
+        throws IOException
+    {
+        return bind(local, 0);
+    }
+
+    /**
+     * Binds the channel's socket to a local address and configures the socket to
+     * listen for connections.
+     *
+     * <p> This method is used to establish an association between the socket and
+     * a local address. Once an association is established then the socket remains
+     * bound until the associated channel is closed.
+     *
+     * <p> The {@code backlog} parameter is the maximum number of pending
+     * connections on the socket. Its exact semantics are implementation specific.
+     * In particular, an implementation may impose a maximum length or may choose
+     * to ignore the parameter altogther. If the {@code backlog} parameter has
+     * the value {@code 0}, or a negative value, then an implementation specific
+     * default is used.
+     *
+     * @param   local
+     *          The local address to bind the socket, or {@code null} to bind
+     *          to an automatically assigned socket address
+     * @param   backlog
+     *          The maximum number of pending connections
+     *
+     * @return  This channel
+     *
+     * @throws  AlreadyBoundException
+     *          If the socket is already bound
+     * @throws  UnsupportedAddressTypeException
+     *          If the type of the given address is not supported
+     * @throws  SecurityException
+     *          If a security manager has been installed and its {@link
+     *          SecurityManager#checkListen checkListen} method denies the operation
+     * @throws  ClosedChannelException
+     *          If the channel is closed
+     * @throws  IOException
+     *          If some other I/O error occurs
+     */
+    public abstract AsynchronousServerSocketChannel bind(SocketAddress local, int backlog)
+        throws IOException;
+
+    /**
+     * @throws  IllegalArgumentException                {@inheritDoc}
+     * @throws  ClosedChannelException                  {@inheritDoc}
+     * @throws  IOException                             {@inheritDoc}
+     */
+    public abstract <T> AsynchronousServerSocketChannel setOption(SocketOption<T> name, T value)
+        throws IOException;
+
+    /**
+     * Accepts a connection.
+     *
+     * <p> This method initiates accepting a connection made to this channel's
+     * socket, returning a {@link Future} representing the pending result
+     * of the operation. The {@code Future}'s {@link Future#get() get}
+     * method will return the {@link AsynchronousSocketChannel} for the new
+     * connection on successful completion.
+     *
+     * <p> When a new connection is accepted then the resulting {@code
+     * AsynchronousSocketChannel} will be bound to the same {@link
+     * AsynchronousChannelGroup} as this channel. If the group is {@link
+     * AsynchronousChannelGroup#isShutdown shutdown} and a connection is accepted,
+     * then the connection is closed, and the operation completes with an {@code
+     * IOException} and cause {@link ShutdownChannelGroupException}.
+     *
+     * <p> To allow for concurrent handling of new connections, the completion
+     * handler is not invoked directly by the initiating thread when a new
+     * connection is accepted immediately (see <a
+     * href="AsynchronousChannelGroup.html#threading">Threading<a>).
+     *
+     * <p> If a security manager has been installed then it verifies that the
+     * address and port number of the connection's remote endpoint are permitted
+     * by the security manager's {@link SecurityManager#checkAccept checkAccept}
+     * method. The permission check is performed with privileges that are restricted
+     * by the calling context of this method. If the permission check fails then
+     * the connection is closed and the operation completes with a {@link
+     * SecurityException}.
+     *
+     * @param   attachment
+     *          The object to attach to the I/O operation; can be {@code null}
+     * @param   handler
+     *          The handler for consuming the result; can be {@code null}
+     *
+     * @return  an <tt>Future</tt> object representing the pending result
+     *
+     * @throws  AcceptPendingException
+     *          If an accept operation is already in progress on this channel
+     * @throws  NotYetBoundException
+     *          If this channel's socket has not yet been bound
+     * @throws  ShutdownChannelGroupException
+     *          If a handler is specified, and the channel group is shutdown
+     */
+    public abstract <A> Future<AsynchronousSocketChannel>
+        accept(A attachment, CompletionHandler<AsynchronousSocketChannel,? super A> handler);
+
+    /**
+     * Accepts a connection.
+     *
+     * <p> This method is equivalent to invoking {@link
+     * #accept(Object,CompletionHandler)} with the {@code attachment}
+     * and {@code handler} parameters set to {@code null}.
+     *
+     * @return  an <tt>Future</tt> object representing the pending result
+     *
+     * @throws  AcceptPendingException
+     *          If an accept operation is already in progress on this channel
+     * @throws  NotYetBoundException
+     *          If this channel's socket has not yet been bound
+     */
+    public final Future<AsynchronousSocketChannel> accept() {
+        return accept(null, null);
+    }
+}
diff --git a/jdk/src/share/classes/java/nio/channels/AsynchronousSocketChannel.java b/jdk/src/share/classes/java/nio/channels/AsynchronousSocketChannel.java
new file mode 100644
index 0000000..b6a5da8
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/channels/AsynchronousSocketChannel.java
@@ -0,0 +1,670 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.channels;
+
+import java.nio.channels.spi.*;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.Future;
+import java.io.IOException;
+import java.net.SocketOption;
+import java.net.SocketAddress;
+import java.nio.ByteBuffer;
+
+/**
+ * An asynchronous channel for stream-oriented connecting sockets.
+ *
+ * <p> Asynchronous socket channels are created in one of two ways. A newly-created
+ * {@code AsynchronousSocketChannel} is created by invoking one of the {@link
+ * #open open} methods defined by this class. A newly-created channel is open but
+ * not yet connected. A connected {@code AsynchronousSocketChannel} is created
+ * when a connection is made to the socket of an {@link AsynchronousServerSocketChannel}.
+ * It is not possible to create an asynchronous socket channel for an arbitrary,
+ * pre-existing {@link java.net.Socket socket}.
+ *
+ * <p> A newly-created channel is connected by invoking its {@link #connect connect}
+ * method; once connected, a channel remains connected until it is closed.  Whether
+ * or not a socket channel is connected may be determined by invoking its {@link
+ * #getRemoteAddress getRemoteAddress} method. An attempt to invoke an I/O
+ * operation upon an unconnected channel will cause a {@link NotYetConnectedException}
+ * to be thrown.
+ *
+ * <p> Channels of this type are safe for use by multiple concurrent threads.
+ * They support concurrent reading and writing, though at most one read operation
+ * and one write operation can be outstanding at any time.
+ * If a thread initiates a read operation before a previous read operation has
+ * completed then a {@link ReadPendingException} will be thrown. Similarly, an
+ * attempt to initiate a write operation before a previous write has completed
+ * will throw a {@link WritePendingException}.
+ *
+ * <p> Socket options are configured using the {@link #setOption(SocketOption,Object)
+ * setOption} method. Asynchronous socket channels support the following options:
+ * <blockquote>
+ * <table border>
+ *   <tr>
+ *     <th>Option Name</th>
+ *     <th>Description</th>
+ *   </tr>
+ *   <tr>
+ *     <td> {@link java.net.StandardSocketOption#SO_SNDBUF SO_SNDBUF} </td>
+ *     <td> The size of the socket send buffer </td>
+ *   </tr>
+ *   <tr>
+ *     <td> {@link java.net.StandardSocketOption#SO_RCVBUF SO_RCVBUF} </td>
+ *     <td> The size of the socket receive buffer </td>
+ *   </tr>
+ *   <tr>
+ *     <td> {@link java.net.StandardSocketOption#SO_KEEPALIVE SO_KEEPALIVE} </td>
+ *     <td> Keep connection alive </td>
+ *   </tr>
+ *   <tr>
+ *     <td> {@link java.net.StandardSocketOption#SO_REUSEADDR SO_REUSEADDR} </td>
+ *     <td> Re-use address </td>
+ *   </tr>
+ *   <tr>
+ *     <td> {@link java.net.StandardSocketOption#TCP_NODELAY TCP_NODELAY} </td>
+ *     <td> Disable the Nagle algorithm </td>
+ *   </tr>
+ * </table>
+ * </blockquote>
+ * Additional (implementation specific) options may also be supported.
+ *
+ * <h4>Timeouts</h4>
+ *
+ * <p> The {@link #read(ByteBuffer,long,TimeUnit,Object,CompletionHandler) read}
+ * and {@link #write(ByteBuffer,long,TimeUnit,Object,CompletionHandler) write}
+ * methods defined by this class allow a timeout to be specified when initiating
+ * a read or write operation. If the timeout elapses before an operation completes
+ * then the operation completes with the exception {@link
+ * InterruptedByTimeoutException}. A timeout may leave the channel, or the
+ * underlying connection, in an inconsistent state. Where the implementation
+ * cannot guarantee that bytes have not been read from the channel then it puts
+ * the channel into an implementation specific <em>error state</em>. A subsequent
+ * attempt to initiate a {@code read} operation causes an unspecified runtime
+ * exception to be thrown. Similarly if a {@code write} operation times out and
+ * the implementation cannot guarantee bytes have not been written to the
+ * channel then further attempts to {@code write} to the channel cause an
+ * unspecified runtime exception to be thrown. When a timeout elapses then the
+ * state of the {@link ByteBuffer}, or the sequence of buffers, for the I/O
+ * operation is not defined. Buffers should be discarded or at least care must
+ * be taken to ensure that the buffers are not accessed while the channel remains
+ * open.
+ *
+ * @since 1.7
+ */
+
+public abstract class AsynchronousSocketChannel
+    implements AsynchronousByteChannel, NetworkChannel
+{
+    private final AsynchronousChannelProvider provider;
+
+    /**
+     * Initializes a new instance of this class.
+     */
+    protected AsynchronousSocketChannel(AsynchronousChannelProvider provider) {
+        this.provider = provider;
+    }
+
+    /**
+     * Returns the provider that created this channel.
+     */
+    public final AsynchronousChannelProvider provider() {
+        return provider;
+    }
+
+    /**
+     * Opens an asynchronous socket channel.
+     *
+     * <p> The new channel is created by invoking the {@link
+     * AsynchronousChannelProvider#openAsynchronousSocketChannel
+     * openAsynchronousSocketChannel} method on the {@link
+     * AsynchronousChannelProvider} that created the group. If the group parameter
+     * is {@code null} then the resulting channel is created by the system-wide
+     * default provider, and bound to the <em>default group</em>.
+     *
+     * @param   group
+     *          The group to which the newly constructed channel should be bound,
+     *          or {@code null} for the default group
+     *
+     * @return  A new asynchronous socket channel
+     *
+     * @throws  ShutdownChannelGroupException
+     *          If the channel group is shutdown
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    public static AsynchronousSocketChannel open(AsynchronousChannelGroup group)
+        throws IOException
+    {
+        AsynchronousChannelProvider provider = (group == null) ?
+            AsynchronousChannelProvider.provider() : group.provider();
+        return provider.openAsynchronousSocketChannel(group);
+    }
+
+    /**
+     * Opens an asynchronous socket channel.
+     *
+     * <p> This method returns an asynchronous socket channel that is bound to
+     * the <em>default group</em>.This method is equivalent to evaluating the
+     * expression:
+     * <blockquote><pre>
+     * open((AsynchronousChannelGroup)null);
+     * </pre></blockquote>
+     *
+     * @return  A new asynchronous socket channel
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    public static AsynchronousSocketChannel open()
+        throws IOException
+    {
+        return open(null);
+    }
+
+
+    // -- socket options and related --
+
+    /**
+     * @throws  ConnectionPendingException
+     *          If a connection operation is already in progress on this channel
+     * @throws  AlreadyBoundException               {@inheritDoc}
+     * @throws  UnsupportedAddressTypeException     {@inheritDoc}
+     * @throws  ClosedChannelException              {@inheritDoc}
+     * @throws  IOException                         {@inheritDoc}
+     */
+    @Override
+    public abstract AsynchronousSocketChannel bind(SocketAddress local)
+        throws IOException;
+
+    /**
+     * @throws  IllegalArgumentException                {@inheritDoc}
+     * @throws  ClosedChannelException                  {@inheritDoc}
+     * @throws  IOException                             {@inheritDoc}
+     */
+    @Override
+    public abstract <T> AsynchronousSocketChannel setOption(SocketOption<T> name, T value)
+        throws IOException;
+
+    /**
+     * Shutdown the connection for reading without closing the channel.
+     *
+     * <p> Once shutdown for reading then further reads on the channel will
+     * return {@code -1}, the end-of-stream indication. If the input side of the
+     * connection is already shutdown then invoking this method has no effect.
+     * The effect on an outstanding read operation is system dependent and
+     * therefore not specified. The effect, if any, when there is data in the
+     * socket receive buffer that has not been read, or data arrives subsequently,
+     * is also system dependent.
+     *
+     * @return  The channel
+     *
+     * @throws  NotYetConnectedException
+     *          If this channel is not yet connected
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     * @throws  IOException
+     *          If some other I/O error occurs
+     */
+    public abstract AsynchronousSocketChannel shutdownInput() throws IOException;
+
+    /**
+     * Shutdown the connection for writing without closing the channel.
+     *
+     * <p> Once shutdown for writing then further attempts to write to the
+     * channel will throw {@link ClosedChannelException}. If the output side of
+     * the connection is already shutdown then invoking this method has no
+     * effect. The effect on an outstanding write operation is system dependent
+     * and therefore not specified.
+     *
+     * @return  The channel
+     *
+     * @throws  NotYetConnectedException
+     *          If this channel is not yet connected
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     * @throws  IOException
+     *          If some other I/O error occurs
+     */
+    public abstract AsynchronousSocketChannel shutdownOutput() throws IOException;
+
+    // -- state --
+
+    /**
+     * Returns the remote address to which this channel's socket is connected.
+     *
+     * <p> Where the channel is bound and connected to an Internet Protocol
+     * socket address then the return value from this method is of type {@link
+     * java.net.InetSocketAddress}.
+     *
+     * @return  The remote address; {@code null} if the channel's socket is not
+     *          connected
+     *
+     * @throws  ClosedChannelException
+     *          If the channel is closed
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    public abstract SocketAddress getRemoteAddress() throws IOException;
+
+    // -- asynchronous operations --
+
+    /**
+     * Connects this channel.
+     *
+     * <p> This method initiates an operation to connect this channel, returning
+     * a {@code Future} representing the pending result of the operation. If
+     * the connection is successfully established then the {@code Future}'s
+     * {@link Future#get() get} method will return {@code null}. If the
+     * connection cannot be established then the channel is closed. In that case,
+     * invoking the {@code get} method throws {@link
+     * java.util.concurrent.ExecutionException} with an {@code IOException} as
+     * the cause.
+     *
+     * <p> This method performs exactly the same security checks as the {@link
+     * java.net.Socket} class.  That is, if a security manager has been
+     * installed then this method verifies that its {@link
+     * java.lang.SecurityManager#checkConnect checkConnect} method permits
+     * connecting to the address and port number of the given remote endpoint.
+     *
+     * @param   remote
+     *          The remote address to which this channel is to be connected
+     * @param   attachment
+     *          The object to attach to the I/O operation; can be {@code null}
+     * @param   handler
+     *          The handler for consuming the result; can be {@code null}
+     *
+     * @return  A {@code Future} object representing the pending result
+     *
+     * @throws  UnresolvedAddressException
+     *          If the given remote address is not fully resolved
+     * @throws  UnsupportedAddressTypeException
+     *          If the type of the given remote address is not supported
+     * @throws  AlreadyConnectedException
+     *          If this channel is already connected
+     * @throws  ConnectionPendingException
+     *          If a connection operation is already in progress on this channel
+     * @throws  ShutdownChannelGroupException
+     *          If a handler is specified, and the channel group is shutdown
+     * @throws  SecurityException
+     *          If a security manager has been installed
+     *          and it does not permit access to the given remote endpoint
+     *
+     * @see #getRemoteAddress
+     */
+    public abstract <A> Future<Void> connect(SocketAddress remote,
+                                             A attachment,
+                                             CompletionHandler<Void,? super A> handler);
+
+    /**
+     * Connects this channel.
+     *
+     * <p> This method is equivalent to invoking {@link
+     * #connect(SocketAddress,Object,CompletionHandler)} with the {@code attachment}
+     * and handler parameters set to {@code null}.
+     *
+     * @param   remote
+     *          The remote address to which this channel is to be connected
+     *
+     * @return  A {@code Future} object representing the pending result
+     *
+     * @throws  UnresolvedAddressException
+     *          If the given remote address is not fully resolved
+     * @throws  UnsupportedAddressTypeException
+     *          If the type of the given remote address is not supported
+     * @throws  AlreadyConnectedException
+     *          If this channel is already connected
+     * @throws  ConnectionPendingException
+     *          If a connection operation is already in progress on this channel
+     * @throws  SecurityException
+     *          If a security manager has been installed
+     *          and it does not permit access to the given remote endpoint
+     */
+    public final Future<Void> connect(SocketAddress remote) {
+        return connect(remote, null, null);
+    }
+
+    /**
+     * Reads a sequence of bytes from this channel into the given buffer.
+     *
+     * <p> This method initiates the reading of a sequence of bytes from this
+     * channel into the given buffer, returning a {@code Future} representing
+     * the pending result of the operation. The {@code Future}'s {@link
+     * Future#get() get} method returns the number of bytes read or {@code -1}
+     * if all bytes have been read and channel has reached end-of-stream.
+     *
+     * <p> If a timeout is specified and the timeout elapses before the operation
+     * completes then the operation completes with the exception {@link
+     * InterruptedByTimeoutException}. Where a timeout occurs, and the
+     * implementation cannot guarantee that bytes have not been read, or will not
+     * be read from the channel into the given buffer, then further attempts to
+     * read from the channel will cause an unspecific runtime exception to be
+     * thrown.
+     *
+     * <p> Otherwise this method works in the same manner as the {@link
+     * AsynchronousByteChannel#read(ByteBuffer,Object,CompletionHandler)}
+     * method.
+     *
+     * @param   dst
+     *          The buffer into which bytes are to be transferred
+     * @param   timeout
+     *          The timeout, or {@code 0L} for no timeout
+     * @param   unit
+     *          The time unit of the {@code timeout} argument
+     * @param   attachment
+     *          The object to attach to the I/O operation; can be {@code null}
+     * @param   handler
+     *          The handler for consuming the result; can be {@code null}
+     *
+     * @return  A {@code Future} object representing the pending result
+     *
+     * @throws  IllegalArgumentException
+     *          If the {@code timeout} parameter is negative or the buffer is
+     *          read-only
+     * @throws  ReadPendingException
+     *          If a read operation is already in progress on this channel
+     * @throws  NotYetConnectedException
+     *          If this channel is not yet connected
+     * @throws  ShutdownChannelGroupException
+     *          If a handler is specified, and the channel group is shutdown
+     */
+    public abstract <A> Future<Integer> read(ByteBuffer dst,
+                                             long timeout,
+                                             TimeUnit unit,
+                                             A attachment,
+                                             CompletionHandler<Integer,? super A> handler);
+
+    /**
+     * @throws  IllegalArgumentException        {@inheritDoc}
+     * @throws  ReadPendingException            {@inheritDoc}
+     * @throws  NotYetConnectedException
+     *          If this channel is not yet connected
+     * @throws  ShutdownChannelGroupException
+     *          If a handler is specified, and the channel group is shutdown
+     */
+    @Override
+    public final <A> Future<Integer> read(ByteBuffer dst,
+                                          A attachment,
+                                          CompletionHandler<Integer,? super A> handler)
+    {
+        return read(dst, 0L, TimeUnit.MILLISECONDS, attachment, handler);
+    }
+
+    /**
+     * @throws  IllegalArgumentException        {@inheritDoc}
+     * @throws  ReadPendingException            {@inheritDoc}
+     * @throws  NotYetConnectedException
+     *          If this channel is not yet connected
+     */
+    @Override
+    public final Future<Integer> read(ByteBuffer dst) {
+        return read(dst, 0L, TimeUnit.MILLISECONDS, null, null);
+    }
+
+    /**
+     * Reads a sequence of bytes from this channel into a subsequence of the
+     * given buffers. This operation, sometimes called a <em>scattering read</em>,
+     * is often useful when implementing network protocols that group data into
+     * segments consisting of one or more fixed-length headers followed by a
+     * variable-length body.
+     *
+     * <p> This method initiates a read of up to <i>r</i> bytes from this channel,
+     * where <i>r</i> is the total number of bytes remaining in the specified
+     * subsequence of the given buffer array, that is,
+     *
+     * <blockquote><pre>
+     * dsts[offset].remaining()
+     *     + dsts[offset+1].remaining()
+     *     + ... + dsts[offset+length-1].remaining()</pre></blockquote>
+     *
+     * at the moment that the read is attempted.
+     *
+     * <p> Suppose that a byte sequence of length <i>n</i> is read, where
+     * <tt>0</tt>&nbsp;<tt>&lt;</tt>&nbsp;<i>n</i>&nbsp;<tt>&lt;=</tt>&nbsp;<i>r</i>.
+     * Up to the first <tt>dsts[offset].remaining()</tt> bytes of this sequence
+     * are transferred into buffer <tt>dsts[offset]</tt>, up to the next
+     * <tt>dsts[offset+1].remaining()</tt> bytes are transferred into buffer
+     * <tt>dsts[offset+1]</tt>, and so forth, until the entire byte sequence
+     * is transferred into the given buffers.  As many bytes as possible are
+     * transferred into each buffer, hence the final position of each updated
+     * buffer, except the last updated buffer, is guaranteed to be equal to
+     * that buffer's limit. The underlying operating system may impose a limit
+     * on the number of buffers that may be used in an I/O operation. Where the
+     * number of buffers (with bytes remaining), exceeds this limit, then the
+     * I/O operation is performed with the maximum number of buffers allowed by
+     * the operating system.
+     *
+     * <p> The return value from this method is a {@code Future} representing
+     * the pending result of the operation. The {@code Future}'s {@link
+     * Future#get() get} method returns the number of bytes read or {@code -1L}
+     * if all bytes have been read and the channel has reached end-of-stream.
+     *
+     * <p> If a timeout is specified and the timeout elapses before the operation
+     * completes then it completes with the exception {@link
+     * InterruptedByTimeoutException}. Where a timeout occurs, and the
+     * implementation cannot guarantee that bytes have not been read, or will not
+     * be read from the channel into the given buffers, then further attempts to
+     * read from the channel will cause an unspecific runtime exception to be
+     * thrown.
+     *
+     * @param   dsts
+     *          The buffers into which bytes are to be transferred
+     * @param   offset
+     *          The offset within the buffer array of the first buffer into which
+     *          bytes are to be transferred; must be non-negative and no larger than
+     *          {@code dsts.length}
+     * @param   length
+     *          The maximum number of buffers to be accessed; must be non-negative
+     *          and no larger than {@code dsts.length - offset}
+     * @param   timeout
+     *          The timeout, or {@code 0L} for no timeout
+     * @param   unit
+     *          The time unit of the {@code timeout} argument
+     * @param   attachment
+     *          The object to attach to the I/O operation; can be {@code null}
+     * @param   handler
+     *          The handler for consuming the result; can be {@code null}
+     *
+     * @return  A {@code Future} object representing the pending result
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If the pre-conditions for the {@code offset}  and {@code length}
+     *          parameter aren't met
+     * @throws  IllegalArgumentException
+     *          If the {@code timeout} parameter is negative, or a buffer is
+     *          read-only
+     * @throws  ReadPendingException
+     *          If a read operation is already in progress on this channel
+     * @throws  NotYetConnectedException
+     *          If this channel is not yet connected
+     * @throws  ShutdownChannelGroupException
+     *          If a handler is specified, and the channel group is shutdown
+     */
+    public abstract <A> Future<Long> read(ByteBuffer[] dsts,
+                                          int offset,
+                                          int length,
+                                          long timeout,
+                                          TimeUnit unit,
+                                          A attachment,
+                                          CompletionHandler<Long,? super A> handler);
+
+    /**
+     * Writes a sequence of bytes to this channel from the given buffer.
+     *
+     * <p> This method initiates the writing of a sequence of bytes to this channel
+     * from the given buffer, returning a {@code Future} representing the
+     * pending result of the operation. The {@code Future}'s {@link Future#get()
+     * get} method will return the number of bytes written.
+     *
+     * <p> If a timeout is specified and the timeout elapses before the operation
+     * completes then it completes with the exception {@link
+     * InterruptedByTimeoutException}. Where a timeout occurs, and the
+     * implementation cannot guarantee that bytes have not been written, or will
+     * not be written to the channel from the given buffer, then further attempts
+     * to write to the channel will cause an unspecific runtime exception to be
+     * thrown.
+     *
+     * <p> Otherwise this method works in the same manner as the {@link
+     * AsynchronousByteChannel#write(ByteBuffer,Object,CompletionHandler)}
+     * method.
+     *
+     * @param   src
+     *          The buffer from which bytes are to be retrieved
+     * @param   timeout
+     *          The timeout, or {@code 0L} for no timeout
+     * @param   unit
+     *          The time unit of the {@code timeout} argument
+     * @param   attachment
+     *          The object to attach to the I/O operation; can be {@code null}
+     * @param   handler
+     *          The handler for consuming the result; can be {@code null}
+     *
+     * @return  A {@code Future} object representing the pending result
+     *
+     * @throws  IllegalArgumentException
+     *          If the {@code timeout} parameter is negative
+     * @throws  WritePendingException
+     *          If a write operation is already in progress on this channel
+     * @throws  NotYetConnectedException
+     *          If this channel is not yet connected
+     * @throws  ShutdownChannelGroupException
+     *          If a handler is specified, and the channel group is shutdown
+     */
+    public abstract <A> Future<Integer> write(ByteBuffer src,
+                                              long timeout,
+                                              TimeUnit unit,
+                                              A attachment,
+                                              CompletionHandler<Integer,? super A> handler);
+
+    /**
+     * @throws  WritePendingException          {@inheritDoc}
+     * @throws  NotYetConnectedException
+     *          If this channel is not yet connected
+     * @throws  ShutdownChannelGroupException
+     *          If a handler is specified, and the channel group is shutdown
+     */
+    @Override
+    public final <A> Future<Integer> write(ByteBuffer src,
+                                           A attachment,
+                                           CompletionHandler<Integer,? super A> handler)
+
+    {
+        return write(src, 0L, TimeUnit.MILLISECONDS, attachment, handler);
+    }
+
+    /**
+     * @throws  WritePendingException       {@inheritDoc}
+     * @throws  NotYetConnectedException
+     *          If this channel is not yet connected
+     */
+    @Override
+    public final Future<Integer> write(ByteBuffer src) {
+        return write(src, 0L, TimeUnit.MILLISECONDS, null, null);
+    }
+
+    /**
+     * Writes a sequence of bytes to this channel from a subsequence of the given
+     * buffers. This operation, sometimes called a <em>gathering write</em>, is
+     * often useful when implementing network protocols that group data into
+     * segments consisting of one or more fixed-length headers followed by a
+     * variable-length body.
+     *
+     * <p> This method initiates a write of up to <i>r</i> bytes to this channel,
+     * where <i>r</i> is the total number of bytes remaining in the specified
+     * subsequence of the given buffer array, that is,
+     *
+     * <blockquote><pre>
+     * srcs[offset].remaining()
+     *     + srcs[offset+1].remaining()
+     *     + ... + srcs[offset+length-1].remaining()</pre></blockquote>
+     *
+     * at the moment that the write is attempted.
+     *
+     * <p> Suppose that a byte sequence of length <i>n</i> is written, where
+     * <tt>0</tt>&nbsp;<tt>&lt;</tt>&nbsp;<i>n</i>&nbsp;<tt>&lt;=</tt>&nbsp;<i>r</i>.
+     * Up to the first <tt>srcs[offset].remaining()</tt> bytes of this sequence
+     * are written from buffer <tt>srcs[offset]</tt>, up to the next
+     * <tt>srcs[offset+1].remaining()</tt> bytes are written from buffer
+     * <tt>srcs[offset+1]</tt>, and so forth, until the entire byte sequence is
+     * written.  As many bytes as possible are written from each buffer, hence
+     * the final position of each updated buffer, except the last updated
+     * buffer, is guaranteed to be equal to that buffer's limit. The underlying
+     * operating system may impose a limit on the number of buffers that may be
+     * used in an I/O operation. Where the number of buffers (with bytes
+     * remaining), exceeds this limit, then the I/O operation is performed with
+     * the maximum number of buffers allowed by the operating system.
+     *
+     * <p> The return value from this method is a {@code Future} representing
+     * the pending result of the operation. The {@code Future}'s {@link
+     * Future#get() get} method will return the number of bytes written.
+     *
+     * <p> If a timeout is specified and the timeout elapses before the operation
+     * completes then it completes with the exception {@link
+     * InterruptedByTimeoutException}. Where a timeout occurs, and the
+     * implementation cannot guarantee that bytes have not been written, or will
+     * not be written to the channel from the given buffers, then further attempts
+     * to write to the channel will cause an unspecific runtime exception to be
+     * thrown.
+     *
+     * @param   srcs
+     *          The buffers from which bytes are to be retrieved
+     * @param   offset
+     *          The offset within the buffer array of the first buffer from which
+     *          bytes are to be retrieved; must be non-negative and no larger
+     *          than {@code srcs.length}
+     * @param   length
+     *          The maximum number of buffers to be accessed; must be non-negative
+     *          and no larger than {@code srcs.length - offset}
+     * @param   timeout
+     *          The timeout, or {@code 0L} for no timeout
+     * @param   unit
+     *          The time unit of the {@code timeout} argument
+     * @param   attachment
+     *          The object to attach to the I/O operation; can be {@code null}
+     * @param   handler
+     *          The handler for consuming the result; can be {@code null}
+     *
+     * @return  A {@code Future} object representing the pending result
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If the pre-conditions for the {@code offset}  and {@code length}
+     *          parameter aren't met
+     * @throws  IllegalArgumentException
+     *          If the {@code timeout} parameter is negative
+     * @throws  WritePendingException
+     *          If a write operation is already in progress on this channel
+     * @throws  NotYetConnectedException
+     *          If this channel is not yet connected
+     * @throws  ShutdownChannelGroupException
+     *          If a handler is specified, and the channel group is shutdown
+     */
+    public abstract <A> Future<Long> write(ByteBuffer[] srcs,
+                                           int offset,
+                                           int length,
+                                           long timeout,
+                                           TimeUnit unit,
+                                           A attachment,
+                                           CompletionHandler<Long,? super A> handler);
+}
diff --git a/jdk/src/share/classes/java/nio/channels/Channels.java b/jdk/src/share/classes/java/nio/channels/Channels.java
index cab9604..4fdcef8 100644
--- a/jdk/src/share/classes/java/nio/channels/Channels.java
+++ b/jdk/src/share/classes/java/nio/channels/Channels.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2009 Sun Microsystems, Inc.  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
@@ -33,15 +33,12 @@
 import java.io.Writer;
 import java.io.IOException;
 import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
-import java.nio.BufferOverflowException;
-import java.nio.BufferUnderflowException;
 import java.nio.charset.Charset;
 import java.nio.charset.CharsetDecoder;
 import java.nio.charset.CharsetEncoder;
-import java.nio.charset.CoderResult;
 import java.nio.charset.UnsupportedCharsetException;
 import java.nio.channels.spi.AbstractInterruptibleChannel;
+import java.util.concurrent.ExecutionException;
 import sun.nio.ch.ChannelInputStream;
 import sun.nio.cs.StreamDecoder;
 import sun.nio.cs.StreamEncoder;
@@ -184,6 +181,155 @@
             };
     }
 
+    /**
+     * {@note new}
+     * Constructs a stream that reads bytes from the given channel.
+     *
+     * <p> The stream will not be buffered, and it will not support the {@link
+     * InputStream#mark mark} or {@link InputStream#reset reset} methods.  The
+     * stream will be safe for access by multiple concurrent threads.  Closing
+     * the stream will in turn cause the channel to be closed.  </p>
+     *
+     * @param  ch
+     *         The channel from which bytes will be read
+     *
+     * @return  A new input stream
+     *
+     * @since 1.7
+     */
+    public static InputStream newInputStream(final AsynchronousByteChannel ch) {
+        checkNotNull(ch, "ch");
+        return new InputStream() {
+
+            private ByteBuffer bb = null;
+            private byte[] bs = null;           // Invoker's previous array
+            private byte[] b1 = null;
+
+            @Override
+            public synchronized int read() throws IOException {
+                if (b1 == null)
+                    b1 = new byte[1];
+                int n = this.read(b1);
+                if (n == 1)
+                    return b1[0] & 0xff;
+                return -1;
+            }
+
+            @Override
+            public synchronized int read(byte[] bs, int off, int len)
+                throws IOException
+            {
+                if ((off < 0) || (off > bs.length) || (len < 0) ||
+                    ((off + len) > bs.length) || ((off + len) < 0)) {
+                    throw new IndexOutOfBoundsException();
+                } else if (len == 0)
+                    return 0;
+
+                ByteBuffer bb = ((this.bs == bs)
+                                 ? this.bb
+                                 : ByteBuffer.wrap(bs));
+                bb.position(off);
+                bb.limit(Math.min(off + len, bb.capacity()));
+                this.bb = bb;
+                this.bs = bs;
+
+                boolean interrupted = false;
+                try {
+                    for (;;) {
+                        try {
+                            return ch.read(bb).get();
+                        } catch (ExecutionException ee) {
+                            throw new IOException(ee.getCause());
+                        } catch (InterruptedException ie) {
+                            interrupted = true;
+                        }
+                    }
+                } finally {
+                    if (interrupted)
+                        Thread.currentThread().interrupt();
+                }
+            }
+
+            @Override
+            public void close() throws IOException {
+                ch.close();
+            }
+        };
+    }
+
+    /**
+     * {@note new}
+     * Constructs a stream that writes bytes to the given channel.
+     *
+     * <p> The stream will not be buffered. The stream will be safe for access
+     * by multiple concurrent threads.  Closing the stream will in turn cause
+     * the channel to be closed.  </p>
+     *
+     * @param  ch
+     *         The channel to which bytes will be written
+     *
+     * @return  A new output stream
+     *
+     * @since 1.7
+     */
+    public static OutputStream newOutputStream(final AsynchronousByteChannel ch) {
+        checkNotNull(ch, "ch");
+        return new OutputStream() {
+
+            private ByteBuffer bb = null;
+            private byte[] bs = null;   // Invoker's previous array
+            private byte[] b1 = null;
+
+            @Override
+            public synchronized void write(int b) throws IOException {
+               if (b1 == null)
+                    b1 = new byte[1];
+                b1[0] = (byte)b;
+                this.write(b1);
+            }
+
+            @Override
+            public synchronized void write(byte[] bs, int off, int len)
+                throws IOException
+            {
+                if ((off < 0) || (off > bs.length) || (len < 0) ||
+                    ((off + len) > bs.length) || ((off + len) < 0)) {
+                    throw new IndexOutOfBoundsException();
+                } else if (len == 0) {
+                    return;
+                }
+                ByteBuffer bb = ((this.bs == bs)
+                                 ? this.bb
+                                 : ByteBuffer.wrap(bs));
+                bb.limit(Math.min(off + len, bb.capacity()));
+                bb.position(off);
+                this.bb = bb;
+                this.bs = bs;
+
+                boolean interrupted = false;
+                try {
+                    while (bb.remaining() > 0) {
+                        try {
+                            ch.write(bb).get();
+                        } catch (ExecutionException ee) {
+                            throw new IOException(ee.getCause());
+                        } catch (InterruptedException ie) {
+                            interrupted = true;
+                        }
+                    }
+                } finally {
+                    if (interrupted)
+                        Thread.currentThread().interrupt();
+                }
+            }
+
+            @Override
+            public void close() throws IOException {
+                ch.close();
+            }
+        };
+    }
+
 
     // -- Channels from streams --
 
@@ -468,5 +614,4 @@
         checkNotNull(csName, "csName");
         return newWriter(ch, Charset.forName(csName).newEncoder(), -1);
     }
-
 }
diff --git a/jdk/src/share/classes/java/nio/channels/CompletionHandler.java b/jdk/src/share/classes/java/nio/channels/CompletionHandler.java
new file mode 100644
index 0000000..c4d4add
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/channels/CompletionHandler.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.channels;
+
+/**
+ * A handler for consuming the result of an asynchronous I/O operation.
+ *
+ * <p> The asynchronous channels defined in this package allow a completion
+ * handler to be specified to consume the result of an asynchronous operation.
+ * The {@link #completed completed} method is invoked when the I/O operation
+ * completes successfully. The {@link #failed failed} method is invoked if the
+ * I/O operations fails. The {@link #cancelled cancelled} method is invoked when
+ * the I/O operation is cancelled by invoking the {@link
+ * java.util.concurrent.Future#cancel cancel} method. The implementations of
+ * these methods should complete in a timely manner so as to avoid keeping the
+ * invoking thread from dispatching to other completion handlers.
+ *
+ * @param   <V>     The result type of the I/O operation
+ * @param   <A>     The type of the object attached to the I/O operation
+ *
+ * @since 1.7
+ */
+
+public interface CompletionHandler<V,A> {
+
+    /**
+     * Invoked when an operation has completed.
+     *
+     * @param   result
+     *          The result of the I/O operation.
+     * @param   attachment
+     *          The object attached to the I/O operation when it was initiated.
+     */
+    void completed(V result, A attachment);
+
+    /**
+     * Invoked when an operation fails.
+     *
+     * @param   exc
+     *          The exception to indicate why the I/O operation failed
+     * @param   attachment
+     *          The object attached to the I/O operation when it was initiated.
+     */
+    void failed(Throwable exc, A attachment);
+
+    /**
+     * Invoked when an operation is cancelled by invoking the {@link
+     * java.util.concurrent.Future#cancel cancel} method.
+     *
+     * @param   attachment
+     *          The object attached to the I/O operation when it was initiated.
+     */
+    void cancelled(A attachment);
+}
diff --git a/jdk/src/share/classes/java/nio/channels/DatagramChannel.java b/jdk/src/share/classes/java/nio/channels/DatagramChannel.java
index b8697fa..c7bd3df 100644
--- a/jdk/src/share/classes/java/nio/channels/DatagramChannel.java
+++ b/jdk/src/share/classes/java/nio/channels/DatagramChannel.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2009 Sun Microsystems, Inc.  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
@@ -31,7 +31,8 @@
 import java.net.SocketOption;
 import java.net.SocketAddress;
 import java.nio.ByteBuffer;
-import java.nio.channels.spi.*;
+import java.nio.channels.spi.AbstractSelectableChannel;
+import java.nio.channels.spi.SelectorProvider;
 
 /**
  * A selectable channel for datagram-oriented sockets.
@@ -53,7 +54,8 @@
  * be determined by invoking its {@link #isConnected isConnected} method.
  *
  * <p> Socket options are configured using the {@link #setOption(SocketOption,Object)
- * setOption} method. Datagram channels support the following options:
+ * setOption} method. A datagram channel to an Internet Protocol socket supports
+ * the following options:
  * <blockquote>
  * <table border>
  *   <tr>
@@ -211,6 +213,7 @@
         throws IOException;
 
     /**
+     * @throws  UnsupportedOperationException           {@inheritDoc}
      * @throws  IllegalArgumentException                {@inheritDoc}
      * @throws  ClosedChannelException                  {@inheritDoc}
      * @throws  IOException                             {@inheritDoc}
@@ -220,7 +223,6 @@
     public abstract <T> DatagramChannel setOption(SocketOption<T> name, T value)
         throws IOException;
 
-
     /**
      * Retrieves a datagram socket associated with this channel.
      *
@@ -313,15 +315,17 @@
     /**
      * Returns the remote address to which this channel's socket is connected.
      *
-     * @return  The remote address; {@code null} if the channel is not {@link
-     *          #isOpen open} or the channel's socket is not connected
+     * @return  The remote address; {@code null} if the channel's socket is not
+     *          connected
      *
+     * @throws  ClosedChannelException
+     *          If the channel is closed
      * @throws  IOException
      *          If an I/O error occurs
      *
      * @since 1.7
      */
-    public abstract SocketAddress getConnectedAddress() throws IOException;
+    public abstract SocketAddress getRemoteAddress() throws IOException;
 
     /**
      * Receives a datagram via this channel.
diff --git a/jdk/src/share/classes/java/nio/channels/FileChannel.java b/jdk/src/share/classes/java/nio/channels/FileChannel.java
index e3b5f5b..ab780a5 100644
--- a/jdk/src/share/classes/java/nio/channels/FileChannel.java
+++ b/jdk/src/share/classes/java/nio/channels/FileChannel.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2009 Sun Microsystems, Inc.  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
@@ -29,16 +29,23 @@
 import java.nio.ByteBuffer;
 import java.nio.MappedByteBuffer;
 import java.nio.channels.spi.AbstractInterruptibleChannel;
-
+import java.nio.file.*;
+import java.nio.file.attribute.FileAttribute;
+import java.nio.file.spi.*;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Collections;
 
 /**
  * A channel for reading, writing, mapping, and manipulating a file.
  *
- * <p> A file channel has a current <i>position</i> within its file which can
- * be both {@link #position() </code>queried<code>} and {@link #position(long)
- * </code>modified<code>}.  The file itself contains a variable-length sequence
+ * <p> {@note revised}
+ * A file channel is a {@link SeekableByteChannel} that is connected to
+ * a file. It has a current <i>position</i> within its file which can
+ * be both {@link #position() <i>queried</i>} and {@link #position(long)
+ * <i>modified</i>}.  The file itself contains a variable-length sequence
  * of bytes that can be read and written and whose current {@link #size
- * </code><i>size</i><code>} can be queried.  The size of the file increases
+ * <i>size</i>} can be queried.  The size of the file increases
  * when bytes are written beyond its current size; the size of the file
  * decreases when it is {@link #truncate </code><i>truncated</i><code>}.  The
  * file may also have some associated <i>metadata</i> such as access
@@ -50,27 +57,27 @@
  *
  * <ul>
  *
- *   <li><p> Bytes may be {@link #read(ByteBuffer, long) </code>read<code>} or
- *   {@link #write(ByteBuffer, long) </code>written<code>} at an absolute
+ *   <li><p> Bytes may be {@link #read(ByteBuffer, long) read} or
+ *   {@link #write(ByteBuffer, long) <i>written</i>} at an absolute
  *   position in a file in a way that does not affect the channel's current
  *   position.  </p></li>
  *
- *   <li><p> A region of a file may be {@link #map </code>mapped<code>}
+ *   <li><p> A region of a file may be {@link #map <i>mapped</i>}
  *   directly into memory; for large files this is often much more efficient
  *   than invoking the usual <tt>read</tt> or <tt>write</tt> methods.
  *   </p></li>
  *
- *   <li><p> Updates made to a file may be {@link #force </code>forced
- *   out<code>} to the underlying storage device, ensuring that data are not
+ *   <li><p> Updates made to a file may be {@link #force <i>forced
+ *   out</i>} to the underlying storage device, ensuring that data are not
  *   lost in the event of a system crash.  </p></li>
  *
- *   <li><p> Bytes can be transferred from a file {@link #transferTo </code>to
- *   some other channel<code>}, and {@link #transferFrom </code>vice
- *   versa<code>}, in a way that can be optimized by many operating systems
+ *   <li><p> Bytes can be transferred from a file {@link #transferTo <i>to
+ *   some other channel</i>}, and {@link #transferFrom <i>vice
+ *   versa</i>}, in a way that can be optimized by many operating systems
  *   into a very fast transfer directly to or from the filesystem cache.
  *   </p></li>
  *
- *   <li><p> A region of a file may be {@link FileLock </code>locked<code>}
+ *   <li><p> A region of a file may be {@link FileLock <i>locked</i>}
  *   against access by other programs.  </p></li>
  *
  * </ul>
@@ -96,25 +103,23 @@
  * machine.  The exact nature of any such inconsistencies are system-dependent
  * and are therefore unspecified.
  *
- * <p> This class does not define methods for opening existing files or for
- * creating new ones; such methods may be added in a future release.  In this
- * release a file channel can be obtained from an existing {@link
- * java.io.FileInputStream#getChannel FileInputStream}, {@link
+ * <p> A file channel is created by invoking one of the {@link #open open}
+ * methods defined by this class. A file channel can also be obtained from an
+ * existing {@link java.io.FileInputStream#getChannel FileInputStream}, {@link
  * java.io.FileOutputStream#getChannel FileOutputStream}, or {@link
  * java.io.RandomAccessFile#getChannel RandomAccessFile} object by invoking
  * that object's <tt>getChannel</tt> method, which returns a file channel that
- * is connected to the same underlying file.
+ * is connected to the same underlying file. Where the file channel is obtained
+ * from an existing stream or random access file then the state of the file
+ * channel is intimately connected to that of the object whose <tt>getChannel</tt>
+ * method returned the channel.  Changing the channel's position, whether
+ * explicitly or by reading or writing bytes, will change the file position of
+ * the originating object, and vice versa. Changing the file's length via the
+ * file channel will change the length seen via the originating object, and vice
+ * versa.  Changing the file's content by writing bytes will change the content
+ * seen by the originating object, and vice versa.
  *
- * <p> The state of a file channel is intimately connected to that of the
- * object whose <tt>getChannel</tt> method returned the channel.  Changing the
- * channel's position, whether explicitly or by reading or writing bytes, will
- * change the file position of the originating object, and vice versa.
- * Changing the file's length via the file channel will change the length seen
- * via the originating object, and vice versa.  Changing the file's content by
- * writing bytes will change the content seen by the originating object, and
- * vice versa.
- *
- * <a name="open-mode"><p> At various points this class specifies that an
+ * <a name="open-mode"></a> <p> At various points this class specifies that an
  * instance that is "open for reading," "open for writing," or "open for
  * reading and writing" is required.  A channel obtained via the {@link
  * java.io.FileInputStream#getChannel getChannel} method of a {@link
@@ -127,7 +132,7 @@
  * was created with mode <tt>"r"</tt> and will be open for reading and writing
  * if the instance was created with mode <tt>"rw"</tt>.
  *
- * <a name="append-mode"><p> A file channel that is open for writing may be in
+ * <a name="append-mode"></a><p> A file channel that is open for writing may be in
  * <i>append mode</i>, for example if it was obtained from a file-output stream
  * that was created by invoking the {@link
  * java.io.FileOutputStream#FileOutputStream(java.io.File,boolean)
@@ -138,7 +143,6 @@
  * of the data are done in a single atomic operation is system-dependent and
  * therefore unspecified.
  *
- *
  * @see java.io.FileInputStream#getChannel()
  * @see java.io.FileOutputStream#getChannel()
  * @see java.io.RandomAccessFile#getChannel()
@@ -147,18 +151,190 @@
  * @author Mike McCloskey
  * @author JSR-51 Expert Group
  * @since 1.4
+ * @updated 1.7
  */
 
 public abstract class FileChannel
     extends AbstractInterruptibleChannel
-    implements ByteChannel, GatheringByteChannel, ScatteringByteChannel
+    implements SeekableByteChannel, GatheringByteChannel, ScatteringByteChannel
 {
-
     /**
      * Initializes a new instance of this class.
      */
     protected FileChannel() { }
 
+    /**
+     * {@note new}
+     * Opens or creates a file, returning a file 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. 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. 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 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
+     *   the {@link #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="../file/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="../file/package-summary.html#integrity"> Synchronized I/O file
+     *   integrity</a>). </td>
+     * </tr>
+     * </table>
+     *
+     * <p> An implementation may also support additional options.
+     *
+     * <p> The {@code attrs} parameter is an optional array of file {@link
+     * FileAttribute file-attributes} to set atomically when creating the file.
+     *
+     * <p> The new channel is created by invoking the {@link
+     * FileSystemProvider#newFileChannel newFileChannel} method on the
+     * provider that created the {@code Path}.
+     *
+     * @param   file
+     *          The path of the file to open or create
+     * @param   options
+     *          Options specifying how the file is opened
+     * @param   attrs
+     *          An optional list of file attributes to set atomically when
+     *          creating the file
+     *
+     * @return  A new file channel
+     *
+     * @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
+     *          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
+     * @throws  IOException
+     *          If an I/O error occurs
+     * @throws  SecurityException
+     *          If a security manager is installed and it denies an
+     *          unspecified permission required by the implementation.
+     *          In the case of the default provider, the {@link
+     *          SecurityManager#checkRead(String)} method is invoked to check
+     *          read access if the file is opened for reading. The {@link
+     *          SecurityManager#checkWrite(String)} method is invoked to check
+     *          write access if the file is opened for writing
+     *
+     * @since   1.7
+     */
+    public static FileChannel open(Path file,
+                                   Set<? extends OpenOption> options,
+                                   FileAttribute<?>... attrs)
+        throws IOException
+    {
+        FileSystemProvider provider = file.getFileSystem().provider();
+        return provider.newFileChannel(file, options, attrs);
+    }
+
+    private static final FileAttribute<?>[] NO_ATTRIBUTES = new FileAttribute[0];
+
+    /**
+     * {@note new}
+     * Opens or creates a file, returning a file channel to access the file.
+     *
+     * <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]);
+     * </pre>
+     *
+     * @param   file
+     *          The path of the file to open or create
+     * @param   options
+     *          Options specifying how the file is opened
+     *
+     * @return  A new file channel
+     *
+     * @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
+     *          support creating file channels, or an unsupported open option is
+     *          specified
+     * @throws  IOException
+     *          If an I/O error occurs
+     * @throws  SecurityException
+     *          If a security manager is installed and it denies an
+     *          unspecified permission required by the implementation.
+     *          In the case of the default provider, the {@link
+     *          SecurityManager#checkRead(String)} method is invoked to check
+     *          read access if the file is opened for reading. The {@link
+     *          SecurityManager#checkWrite(String)} method is invoked to check
+     *          write access if the file is opened for writing
+     *
+     * @since   1.7
+     */
+    public static FileChannel open(Path file, OpenOption... options)
+        throws IOException
+    {
+        Set<OpenOption> set = new HashSet<OpenOption>(options.length);
+        Collections.addAll(set, options);
+        return open(file, set, NO_ATTRIBUTES);
+    }
 
     // -- Channel operations --
 
@@ -286,7 +462,7 @@
     public abstract FileChannel position(long newPosition) throws IOException;
 
     /**
-     * Returns the current size of this channel's file. </p>
+     * Returns the current size of this channel's file.  </p>
      *
      * @return  The current size of this channel's file,
      *          measured in bytes
@@ -359,7 +535,7 @@
      * <p> This method is only guaranteed to force changes that were made to
      * this channel's file via the methods defined in this class.  It may or
      * may not force changes that were made by modifying the content of a
-     * {@link MappedByteBuffer </code>mapped byte buffer<code>} obtained by
+     * {@link MappedByteBuffer <i>mapped byte buffer</i>} obtained by
      * invoking the {@link #map map} method.  Invoking the {@link
      * MappedByteBuffer#force force} method of the mapped byte buffer will
      * force changes made to the buffer's content to be written.  </p>
@@ -678,7 +854,7 @@
      * reading; for a read/write or private mapping, this channel must have
      * been opened for both reading and writing.
      *
-     * <p> The {@link MappedByteBuffer </code>mapped byte buffer<code>}
+     * <p> The {@link MappedByteBuffer <i>mapped byte buffer</i>}
      * returned by this method will have a position of zero and a limit and
      * capacity of <tt>size</tt>; its mark will be undefined.  The buffer and
      * the mapping that it represents will remain valid until the buffer itself
@@ -717,6 +893,8 @@
      *         The size of the region to be mapped; must be non-negative and
      *         no greater than {@link java.lang.Integer#MAX_VALUE}
      *
+     * @return  The mapped byte buffer
+     *
      * @throws NonReadableChannelException
      *         If the <tt>mode</tt> is {@link MapMode#READ_ONLY READ_ONLY} but
      *         this channel was not opened for reading
diff --git a/jdk/src/share/classes/java/nio/channels/FileLock.java b/jdk/src/share/classes/java/nio/channels/FileLock.java
index 9219222..b0ec37f 100644
--- a/jdk/src/share/classes/java/nio/channels/FileLock.java
+++ b/jdk/src/share/classes/java/nio/channels/FileLock.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2001-2009 Sun Microsystems, Inc.  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
@@ -27,14 +27,16 @@
 
 import java.io.IOException;
 
-
 /**
  * A token representing a lock on a region of a file.
  *
  * <p> A file-lock object is created each time a lock is acquired on a file via
  * one of the {@link FileChannel#lock(long,long,boolean) lock} or {@link
- * FileChannel#tryLock(long,long,boolean) tryLock} methods of the {@link
- * FileChannel} class.
+ * FileChannel#tryLock(long,long,boolean) tryLock} methods of the
+ * {@link FileChannel} class, or the {@link
+ * AsynchronousFileChannel#lock(long,long,boolean,Object,CompletionHandler) lock}
+ * or {@link AsynchronousFileChannel#tryLock(long,long,boolean) tryLock}
+ * methods of the {@link AsynchronousFileChannel} class.
  *
  * <p> A file-lock object is initially valid.  It remains valid until the lock
  * is released by invoking the {@link #release release} method, by closing the
@@ -70,8 +72,7 @@
  * <p> File-lock objects are safe for use by multiple concurrent threads.
  *
  *
- * <a name="pdep">
- * <h4> Platform dependencies </h4>
+ * <a name="pdep"><h4> Platform dependencies </h4></a>
  *
  * <p> This file-locking API is intended to map directly to the native locking
  * facility of the underlying operating system.  Thus the locks held on a file
@@ -93,7 +94,7 @@
  *
  * <p> On some systems, acquiring a mandatory lock on a region of a file
  * prevents that region from being {@link java.nio.channels.FileChannel#map
- * </code>mapped into memory<code>}, and vice versa.  Programs that combine
+ * <i>mapped into memory</i>}, and vice versa.  Programs that combine
  * locking and mapping should be prepared for this combination to fail.
  *
  * <p> On some systems, closing a channel releases all locks held by the Java
@@ -113,11 +114,12 @@
  * @author Mark Reinhold
  * @author JSR-51 Expert Group
  * @since 1.4
+ * @updated 1.7
  */
 
 public abstract class FileLock {
 
-    private final FileChannel channel;
+    private final Channel channel;
     private final long position;
     private final long size;
     private final boolean shared;
@@ -159,11 +161,66 @@
     }
 
     /**
-     * Returns the file channel upon whose file this lock is held.  </p>
+     * {@note new} Initializes a new instance of this class.
      *
-     * @return  The file channel
+     * @param  channel
+     *         The channel upon whose file this lock is held
+     *
+     * @param  position
+     *         The position within the file at which the locked region starts;
+     *         must be non-negative
+     *
+     * @param  size
+     *         The size of the locked region; must be non-negative, and the sum
+     *         <tt>position</tt>&nbsp;+&nbsp;<tt>size</tt> must be non-negative
+     *
+     * @param  shared
+     *         <tt>true</tt> if this lock is shared,
+     *         <tt>false</tt> if it is exclusive
+     *
+     * @throws IllegalArgumentException
+     *         If the preconditions on the parameters do not hold
+     *
+     * @since 1.7
+     */
+    protected FileLock(AsynchronousFileChannel channel,
+                       long position, long size, boolean shared)
+    {
+        if (position < 0)
+            throw new IllegalArgumentException("Negative position");
+        if (size < 0)
+            throw new IllegalArgumentException("Negative size");
+        if (position + size < 0)
+            throw new IllegalArgumentException("Negative position + size");
+        this.channel = channel;
+        this.position = position;
+        this.size = size;
+        this.shared = shared;
+    }
+
+    /**
+     * {@note revised}
+     * Returns the file channel upon whose file this lock was acquired.
+     *
+     * <p> This method has been superseded by the {@link #acquiredBy acquiredBy}
+     * method.
+     *
+     * @return  The file channel, or {@code null} if the file lock was not
+     *          acquired by a file channel.
      */
     public final FileChannel channel() {
+        return (channel instanceof FileChannel) ? (FileChannel)channel : null;
+    }
+
+    /**
+     * {@note new}
+     * Returns the channel upon whose file this lock was acquired.
+     *
+     * @return  The channel upon whose file this lock was acquired.
+     *
+     * @since 1.7
+     */
+    public Channel acquiredBy() {
         return channel;
     }
 
diff --git a/jdk/src/share/classes/java/nio/channels/MembershipKey.java b/jdk/src/share/classes/java/nio/channels/MembershipKey.java
index 0d2fc52..804e672 100644
--- a/jdk/src/share/classes/java/nio/channels/MembershipKey.java
+++ b/jdk/src/share/classes/java/nio/channels/MembershipKey.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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
@@ -28,7 +28,6 @@
 import java.net.InetAddress;
 import java.net.NetworkInterface;
 import java.io.IOException;
-import java.util.List;
 
 /**
  * A token representing the membership of an Internet Protocol (IP) multicast
@@ -38,7 +37,7 @@
  * to the group, or it may be <em>source-specific</em>, meaning that it
  * represents a membership that receives only datagrams from a specific source
  * address. Whether or not a membership key is source-specific may be determined
- * by invoking its {@link #getSourceAddress() getSourceAddress} method.
+ * by invoking its {@link #sourceAddress() sourceAddress} method.
  *
  * <p> A membership key is valid upon creation and remains valid until the
  * membership is dropped by invoking the {@link #drop() drop} method, or
@@ -93,11 +92,8 @@
      * If the multicast group membership is already invalid then invoking this
      * method has no effect. Once a multicast group membership is invalid,
      * it remains invalid forever.
-     *
-     * @throws  IOException
-     *          If an I/O error occurs
      */
-    public abstract void drop() throws IOException;
+    public abstract void drop();
 
     /**
      * Block multicast datagrams from the given source address.
@@ -140,10 +136,8 @@
      * @throws  IllegalStateException
      *          If the given source address is not currently blocked or the
      *          membership key is no longer valid
-     * @throws  IOException
-     *          If an I/O error occurs
      */
-    public abstract MembershipKey unblock(InetAddress source) throws IOException;
+    public abstract MembershipKey unblock(InetAddress source);
 
     /**
      * Returns the channel for which this membership key was created. This
@@ -152,7 +146,7 @@
      *
      * @return  the channel
      */
-    public abstract MulticastChannel getChannel();
+    public abstract MulticastChannel channel();
 
     /**
      * Returns the multicast group for which this membership key was created.
@@ -161,7 +155,7 @@
      *
      * @return  the multicast group
      */
-    public abstract InetAddress getGroup();
+    public abstract InetAddress group();
 
     /**
      * Returns the network interface for which this membership key was created.
@@ -170,7 +164,7 @@
      *
      * @return  the network interface
      */
-    public abstract NetworkInterface getNetworkInterface();
+    public abstract NetworkInterface networkInterface();
 
     /**
      * Returns the source address if this membership key is source-specific,
@@ -179,5 +173,5 @@
      * @return  The source address if this membership key is source-specific,
      *          otherwise {@code null}
      */
-    public abstract InetAddress getSourceAddress();
+    public abstract InetAddress sourceAddress();
 }
diff --git a/jdk/src/share/classes/java/nio/channels/MulticastChannel.java b/jdk/src/share/classes/java/nio/channels/MulticastChannel.java
index 440dd2a..1cacf98 100644
--- a/jdk/src/share/classes/java/nio/channels/MulticastChannel.java
+++ b/jdk/src/share/classes/java/nio/channels/MulticastChannel.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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
@@ -123,6 +123,22 @@
     extends NetworkChannel
 {
     /**
+     * Closes this channel.
+     *
+     * <p> If the channel is a member of a multicast group then the membership
+     * is {@link MembershipKey#drop dropped}. Upon return, the {@link
+     * MembershipKey membership-key} will be {@link MembershipKey#isValid
+     * invalid}.
+     *
+     * <p> This method otherwise behaves exactly as specified by the {@link
+     * Channel} interface.
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    @Override void close() throws IOException;
+
+    /**
      * Joins a multicast group to begin receiving all datagrams sent to the group,
      * returning a membership key.
      *
@@ -130,7 +146,7 @@
      * interface to receive all datagrams then the membership key, representing
      * that membership, is returned. Otherwise this channel joins the group and
      * the resulting new membership key is returned. The resulting membership key
-     * is not {@link MembershipKey#getSourceAddress source-specific}.
+     * is not {@link MembershipKey#sourceAddress source-specific}.
      *
      * <p> A multicast channel may join several multicast groups, including
      * the same group on more than one interface. An implementation may impose a
@@ -150,6 +166,8 @@
      * @throws  IllegalStateException
      *          If the channel already has source-specific membership of the
      *          group on the interface
+     * @throws  UnsupportedOperationException
+     *          If the channel's socket is not an Internet Protocol socket
      * @throws  ClosedChannelException
      *          If this channel is closed
      * @throws  IOException
@@ -170,7 +188,7 @@
      * interface to receive datagrams from the given source address then the
      * membership key, representing that membership, is returned. Otherwise this
      * channel joins the group and the resulting new membership key is returned.
-     * The resulting membership key is {@link MembershipKey#getSourceAddress
+     * The resulting membership key is {@link MembershipKey#sourceAddress
      * source-specific}.
      *
      * <p> Membership is <em>cumulative</em> and this method may be invoked
@@ -196,7 +214,8 @@
      *          If the channel is currently a member of the group on the given
      *          interface to receive all datagrams
      * @throws  UnsupportedOperationException
-     *          If the underlying operation system does not support source filtering
+     *          If the channel's socket is not an Internet Protocol socket or
+     *          source filtering is not supported
      * @throws  ClosedChannelException
      *          If this channel is closed
      * @throws  IOException
diff --git a/jdk/src/share/classes/java/nio/channels/NetworkChannel.java b/jdk/src/share/classes/java/nio/channels/NetworkChannel.java
index fae642f..1034277 100644
--- a/jdk/src/share/classes/java/nio/channels/NetworkChannel.java
+++ b/jdk/src/share/classes/java/nio/channels/NetworkChannel.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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
@@ -95,9 +95,10 @@
      * java.net.InetSocketAddress}.
      *
      * @return  The socket address that the socket is bound to, or {@code null}
-     *          if the channel is not {@link #isOpen open} or the channel's socket
-     *          is not bound
+     *          if the channel's socket is not bound
      *
+     * @throws  ClosedChannelException
+     *          If the channel is closed
      * @throws  IOException
      *          If an I/O error occurs
      */
@@ -114,9 +115,10 @@
      *
      * @return  This channel
      *
+     * @throws  UnsupportedOperationException
+     *          If the socket option is not supported by this channel
      * @throws  IllegalArgumentException
-     *          If the socket option is not supported by this channel, or
-     *          the value is not a valid value for this socket option
+     *          If the value is not a valid value for this socket option
      * @throws  ClosedChannelException
      *          If this channel is closed
      * @throws  IOException
@@ -135,7 +137,7 @@
      * @return  The value of the socket option. A value of {@code null} may be
      *          a valid value for some socket options.
      *
-     * @throws  IllegalArgumentException
+     * @throws  UnsupportedOperationException
      *          If the socket option is not supported by this channel
      * @throws  ClosedChannelException
      *          If this channel is closed
@@ -154,5 +156,5 @@
      *
      * @return  A set of the socket options supported by this channel
      */
-    Set<SocketOption<?>> options();
+    Set<SocketOption<?>> supportedOptions();
 }
diff --git a/jdk/src/share/classes/java/nio/channels/SeekableByteChannel.java b/jdk/src/share/classes/java/nio/channels/SeekableByteChannel.java
new file mode 100644
index 0000000..33efc24
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/channels/SeekableByteChannel.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.channels;
+
+import java.nio.ByteBuffer;
+import java.io.IOException;
+
+/**
+ * A byte channel that maintains a current <i>position</i> and allows the
+ * position to be changed.
+ *
+ * <p> A seekable byte channel is connected to an entity, typically a file,
+ * that contains a variable-length sequence of bytes that can be read and
+ * written. The current position can be {@link #position() <i>queried</i>} and
+ * {@link #position(long) <i>modified</i>}. The channel also provides access to
+ * the current <i>size</i> of the entity to which the channel is connected. The
+ * size increases when bytes are written beyond its current size; the size
+ * decreases when it is {@link #truncate <i>truncated</i>}.
+ *
+ * <p> The {@link #position(long) position} and {@link #truncate truncate} methods
+ * which do not otherwise have a value to return are specified to return the
+ * channel upon which they are invoked. This allows method invocations to be
+ * chained. Implementations of this interface should specialize the return type
+ * so that method invocations on the implementation class can be chained.
+ *
+ * @since 1.7
+ * @see java.nio.file.FileRef#newByteChannel
+ */
+
+public interface SeekableByteChannel
+    extends ByteChannel
+{
+    /**
+     * Reads a sequence of bytes from this channel into the given buffer.
+     *
+     * <p> Bytes are read starting at this channel's current position, and
+     * then the position is updated with the number of bytes actually read.
+     * Otherwise this method behaves exactly as specified in the {@link
+     * ReadableByteChannel} interface.
+     */
+    @Override
+    int read(ByteBuffer dst) throws IOException;
+
+    /**
+     * Writes a sequence of bytes to this channel from the given buffer.
+     *
+     * <p> Bytes are written starting at this channel's current position, unless
+     * the channel is connected to an entity such as a file that is opened with
+     * the {@link java.nio.file.StandardOpenOption#APPEND APPEND} option, in
+     * which case the position is first advanced to the end. The entity to which
+     * the channel is connected is grown, if necessary, to accommodate the
+     * written bytes, and then the position is updated with the number of bytes
+     * actually written. Otherwise this method behaves exactly as specified by
+     * the {@link WritableByteChannel} interface.
+     */
+    @Override
+    int write(ByteBuffer src) throws IOException;
+
+    /**
+     * Returns this channel's position.
+     *
+     * @return  This channel's position,
+     *          a non-negative integer counting the number of bytes
+     *          from the beginning of the entity to the current position
+     *
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     * @throws  IOException
+     *          If some other I/O error occurs
+     */
+    long position() throws IOException;
+
+    /**
+     * Sets this channel's position.
+     *
+     * <p> Setting the position to a value that is greater than the current size
+     * is legal but does not change the size of the entity.  A later attempt to
+     * read bytes at such a position will immediately return an end-of-file
+     * indication.  A later attempt to write bytes at such a position will cause
+     * the entity to grow to accommodate the new bytes; the values of any bytes
+     * between the previous end-of-file and the newly-written bytes are
+     * unspecified.
+     *
+     * <p> Setting the channel's position is not recommended when connected to
+     * an entity, typically a file, that is opened with the {@link
+     * java.nio.file.StandardOpenOption#APPEND APPEND} option. When opened for
+     * append, the position is first advanced to the end before writing.
+     *
+     * @param  newPosition
+     *         The new position, a non-negative integer counting
+     *         the number of bytes from the beginning of the entity
+     *
+     * @return  This channel
+     *
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     * @throws  IllegalArgumentException
+     *          If the new position is negative
+     * @throws  IOException
+     *          If some other I/O error occurs
+     */
+    SeekableByteChannel position(long newPosition) throws IOException;
+
+    /**
+     * Returns the current size of entity to which this channel is connected.
+     *
+     * @return  The current size, measured in bytes
+     *
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     * @throws  IOException
+     *          If some other I/O error occurs
+     */
+    long size() throws IOException;
+
+    /**
+     * Truncates the entity, to which this channel is connected, to the given
+     * size.
+     *
+     * <p> If the given size is less than the current size then the entity is
+     * truncated, discarding any bytes beyond the new end. If the given size is
+     * greater than or equal to the current size then the entity is not modified.
+     * In either case, if the current position is greater than the given size
+     * then it is set to that size.
+     *
+     * <p> An implementation of this interface may prohibit truncation when
+     * connected to an entity, typically a file, opened with the {@link
+     * java.nio.file.StandardOpenOption#APPEND APPEND} option.
+     *
+     * @param  size
+     *         The new size, a non-negative byte count
+     *
+     * @return  This channel
+     *
+     * @throws  NonWritableChannelException
+     *          If this channel was not opened for writing
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     * @throws  IllegalArgumentException
+     *          If the new size is negative
+     * @throws  IOException
+     *          If some other I/O error occurs
+     */
+    SeekableByteChannel truncate(long size) throws IOException;
+}
diff --git a/jdk/src/share/classes/java/nio/channels/ServerSocketChannel.java b/jdk/src/share/classes/java/nio/channels/ServerSocketChannel.java
index 84ea062..5be9bc7 100644
--- a/jdk/src/share/classes/java/nio/channels/ServerSocketChannel.java
+++ b/jdk/src/share/classes/java/nio/channels/ServerSocketChannel.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2009 Sun Microsystems, Inc.  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
@@ -29,7 +29,8 @@
 import java.net.ServerSocket;
 import java.net.SocketOption;
 import java.net.SocketAddress;
-import java.nio.channels.spi.*;
+import java.nio.channels.spi.AbstractSelectableChannel;
+import java.nio.channels.spi.SelectorProvider;
 
 /**
  * A selectable channel for stream-oriented listening sockets.
@@ -195,6 +196,7 @@
         throws IOException;
 
     /**
+     * @throws  UnsupportedOperationException           {@inheritDoc}
      * @throws  IllegalArgumentException                {@inheritDoc}
      * @throws  ClosedChannelException                  {@inheritDoc}
      * @throws  IOException                             {@inheritDoc}
diff --git a/jdk/src/share/classes/java/nio/channels/SocketChannel.java b/jdk/src/share/classes/java/nio/channels/SocketChannel.java
index 2e96bd2..975048d 100644
--- a/jdk/src/share/classes/java/nio/channels/SocketChannel.java
+++ b/jdk/src/share/classes/java/nio/channels/SocketChannel.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2009 Sun Microsystems, Inc.  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
@@ -30,7 +30,8 @@
 import java.net.SocketOption;
 import java.net.SocketAddress;
 import java.nio.ByteBuffer;
-import java.nio.channels.spi.*;
+import java.nio.channels.spi.AbstractSelectableChannel;
+import java.nio.channels.spi.SelectorProvider;
 
 /**
  * A selectable channel for stream-oriented connecting sockets.
@@ -212,7 +213,7 @@
 
     /**
      * @throws  ConnectionPendingException
-     *          If a non-blocking connection operation is already in progress on
+     *          If a non-blocking connect operation is already in progress on
      *          this channel
      * @throws  AlreadyBoundException               {@inheritDoc}
      * @throws  UnsupportedAddressTypeException     {@inheritDoc}
@@ -226,6 +227,7 @@
         throws IOException;
 
     /**
+     * @throws  UnsupportedOperationException           {@inheritDoc}
      * @throws  IllegalArgumentException                {@inheritDoc}
      * @throws  ClosedChannelException                  {@inheritDoc}
      * @throws  IOException                             {@inheritDoc}
@@ -432,15 +434,17 @@
      * socket address then the return value from this method is of type {@link
      * java.net.InetSocketAddress}.
      *
-     * @return  The remote address; {@code null} if the channel is not {@link
-     *          #isOpen open} or the channel's socket is not connected
+     * @return  The remote address; {@code null} if the channel's socket is not
+     *          connected
      *
+     * @throws  ClosedChannelException
+     *          If the channel is closed
      * @throws  IOException
      *          If an I/O error occurs
      *
      * @since 1.7
      */
-    public abstract SocketAddress getConnectedAddress() throws IOException;
+    public abstract SocketAddress getRemoteAddress() throws IOException;
 
     // -- ByteChannel operations --
 
diff --git a/jdk/src/share/classes/java/nio/channels/exceptions b/jdk/src/share/classes/java/nio/channels/exceptions
index 04cfbe0..fed9f72 100644
--- a/jdk/src/share/classes/java/nio/channels/exceptions
+++ b/jdk/src/share/classes/java/nio/channels/exceptions
@@ -1,5 +1,5 @@
 #
-# Copyright 2000-2008 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2000-2009 Sun Microsystems, Inc.  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
@@ -150,6 +150,21 @@
 
 SINCE=1.7
 
+SUPER=java.io.IOException
+
+gen InterruptedByTimeoutException "
+ * Checked exception received by a thread when a timeout elapses before an
+ * asynchronous operation completes." \
+ -4268008601014042947L
+
+SUPER=IllegalArgumentException
+
+gen IllegalChannelGroupException "
+ * Unchecked exception thrown when an attempt is made to open a channel
+ * in a group that was not created by the same provider. " \
+ -2495041211157744253L
+
+
 SUPER=IllegalStateException
 
 gen AlreadyBoundException "
@@ -157,3 +172,23 @@
  * network oriented channel that is already bound." \
  6796072983322737592L
 
+gen AcceptPendingException "
+ * Unchecked exception thrown when an attempt is made to initiate an accept
+ * operation on a channel and a previous accept operation has not completed." \
+ 2721339977965416421L
+
+gen ReadPendingException "
+ * Unchecked exception thrown when an attempt is made to read from an
+ * asynchronous socket channel and a previous read has not completed." \
+ 1986315242191227217L
+
+gen WritePendingException "
+ * Unchecked exception thrown when an attempt is made to write to an
+ * asynchronous socket channel and a previous write has not completed." \
+ 7031871839266032276L
+
+gen ShutdownChannelGroupException "
+ * Unchecked exception thrown when an attempt is made to construct a channel in 
+ * a group that is shutdown or the completion handler for an I/O operation 
+ * cannot be invoked because the channel group is shutdown." \
+ -3903801676350154157L
diff --git a/jdk/src/share/classes/java/nio/channels/package-info.java b/jdk/src/share/classes/java/nio/channels/package-info.java
index e8c2a92..47a1cb5 100644
--- a/jdk/src/share/classes/java/nio/channels/package-info.java
+++ b/jdk/src/share/classes/java/nio/channels/package-info.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2001-2009 Sun Microsystems, Inc.  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
@@ -46,6 +46,10 @@
  *     <td>Can read/write to/from a&nbsp;buffer</td></tr>
  * <tr><td valign=top><tt>&nbsp;&nbsp;&nbsp;&nbsp;<i>{@link java.nio.channels.SeekableByteChannel}</i></tt></td>
  *     <td>A {@code ByteChannel} connected to an entity that contains a variable-length sequence of bytes</td></tr>
+ * <tr><td valign=top><tt>&nbsp;&nbsp;<i>{@link java.nio.channels.AsynchronousChannel}</i></tt></td>
+ *     <td>Supports asynchronous I/O operations.</td></tr>
+ * <tr><td valign=top><tt>&nbsp;&nbsp;&nbsp;&nbsp;<i>{@link java.nio.channels.AsynchronousByteChannel}</i></tt></td>
+ *     <td>Can read and write bytes asynchronously</td></tr>
  * <tr><td valign=top><tt>&nbsp;&nbsp;<i>{@link java.nio.channels.NetworkChannel}</i></tt></td>
  *     <td>A channel to a network socket</td></tr>
  * <tr><td valign=top><tt>&nbsp;&nbsp;&nbsp;&nbsp;<i>{@link java.nio.channels.MulticastChannel}</i></tt></td>
@@ -218,12 +222,70 @@
  * directly; custom channel classes should extend the appropriate {@link
  * java.nio.channels.SelectableChannel} subclasses defined in this package.
  *
+ * <a name="async"></a>
+ *
+ * <blockquote><table cellspacing=1 cellpadding=0 summary="Lists asynchronous channels and their descriptions">
+ * <tr><th><p align="left">Asynchronous I/O</p></th><th><p align="left">Description</p></th></tr>
+ * <tr><td valign=top><tt>{@link java.nio.channels.AsynchronousFileChannel}</tt></td>
+ *     <td>An asynchronous channel for reading, writing, and manipulating a file</td></tr>
+ * <tr><td valign=top><tt>{@link java.nio.channels.AsynchronousSocketChannel}</tt></td>
+ *     <td>An asynchronous channel to a stream-oriented connecting socket</td></tr>
+ * <tr><td valign=top><tt>{@link java.nio.channels.AsynchronousServerSocketChannel}&nbsp;&nbsp;</tt></td>
+ *     <td>An asynchronous channel to a stream-oriented listening socket</td></tr>
+ * <tr><td valign=top><tt>{@link java.nio.channels.AsynchronousDatagramChannel}</tt></td>
+ *     <td>An asynchronous channel to a datagram-oriented socket</td></tr>
+ * <tr><td valign=top><tt>{@link java.nio.channels.CompletionHandler}</tt></td>
+ *     <td>A handler for consuming the result of an asynchronous operation</td></tr>
+ * <tr><td valign=top><tt>{@link java.nio.channels.AsynchronousChannelGroup}</tt></td>
+ *     <td>A grouping of asynchronous channels for the purpose of resource sharing</td></tr>
+ * </table></blockquote>
+ *
+ * <p> {@link java.nio.channels.AsynchronousChannel Asynchronous channels} are a
+ * special type of channel capable of asynchronous I/O operations. Asynchronous
+ * channels are non-blocking and define methods to initiate asynchronous
+ * operations, returning a {@link java.util.concurrent.Future} representing the
+ * pending result of each operation. The {@code Future} can be used to poll or
+ * wait for the result of the operation. Asynchronous I/O operations can also
+ * specify a {@link java.nio.channels.CompletionHandler} to invoke when the
+ * operation completes. A completion handler is user provided code that is executed
+ * to consume the result of I/O operation.
+ *
+ * <p> This package defines asynchronous-channel classes that are connected to
+ * a stream-oriented connecting or listening socket, or a datagram-oriented socket.
+ * It also defines the {@link java.nio.channels.AsynchronousFileChannel} class
+ * for asynchronous reading, writing, and manipulating a file. As with the {@link
+ * java.nio.channels.FileChannel} it supports operations to truncate the file
+ * to a specific size, force updates to the file to be written to the storage
+ * device, or acquire locks on the whole file or on a specific region of the file.
+ * Unlike the {@code FileChannel} it does not define methods for mapping a
+ * region of the file directly into memory. Where memory mapped I/O is required,
+ * then a {@code FileChannel} can be used.
+ *
+ * <p> Asynchronous channels are bound to an asynchronous channel group for the
+ * purpose of resource sharing. A group has an associated {@link
+ * java.util.concurrent.ExecutorService} to which tasks are submitted to handle
+ * I/O events and dispatch to completion handlers that consume the result of
+ * asynchronous operations performed on channels in the group. The group can
+ * optionally be specified when creating the channel or the channel can be bound
+ * to a <em>default group</em>. Sophisticated users may wish to create their
+ * own asynchronous channel groups or configure the {@code ExecutorService}
+ * that will be used for the default group.
+ *
+ * <p> As with selectors, the implementatin of asynchronous channels can be
+ * replaced by "plugging in" an alternative definition or instance of the {@link
+ * java.nio.channels.spi.AsynchronousChannelProvider} class defined in the
+ * <tt>{@link java.nio.channels.spi}</tt> package.  It is not expected that many
+ * developers will actually make use of this facility; it is provided primarily
+ * so that sophisticated users can take advantage of operating-system-specific
+ * asynchronous I/O mechanisms when very high performance is required.
+ *
  * <hr width="80%">
  * <p> Unless otherwise noted, passing a <tt>null</tt> argument to a constructor
  * or method in any class or interface in this package will cause a {@link
  * java.lang.NullPointerException NullPointerException} to be thrown.
  *
  * @since 1.4
+ * @updated 1.7
  * @author Mark Reinhold
  * @author JSR-51 Expert Group
  */
diff --git a/jdk/src/share/classes/java/nio/channels/spi/AsynchronousChannelProvider.java b/jdk/src/share/classes/java/nio/channels/spi/AsynchronousChannelProvider.java
new file mode 100644
index 0000000..9413648
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/channels/spi/AsynchronousChannelProvider.java
@@ -0,0 +1,264 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.channels.spi;
+
+import java.nio.channels.*;
+import java.net.ProtocolFamily;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.ServiceLoader;
+import java.util.ServiceConfigurationError;
+import java.util.concurrent.*;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * Service-provider class for asynchronous channels.
+ *
+ * <p> An asynchronous channel provider is a concrete subclass of this class that
+ * has a zero-argument constructor and implements the abstract methods specified
+ * below.  A given invocation of the Java virtual machine maintains a single
+ * system-wide default provider instance, which is returned by the {@link
+ * #provider() provider} method.  The first invocation of that method will locate
+ * the default provider as specified below.
+ *
+ * <p> All of the methods in this class are safe for use by multiple concurrent
+ * threads.  </p>
+ *
+ * @since 1.7
+ */
+
+public abstract class AsynchronousChannelProvider {
+    private static Void checkPermission() {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null)
+            sm.checkPermission(new RuntimePermission("asynchronousChannelProvider"));
+        return null;
+    }
+    private AsynchronousChannelProvider(Void ignore) { }
+
+    /**
+     * Initializes a new instance of this class.
+     *
+     * @throws  SecurityException
+     *          If a security manager has been installed and it denies
+     *          {@link RuntimePermission}<tt>("asynchronousChannelProvider")</tt>
+     */
+    protected AsynchronousChannelProvider() {
+        this(checkPermission());
+    }
+
+    // lazy initialization of default provider
+    private static class ProviderHolder {
+        static final AsynchronousChannelProvider provider = load();
+
+        private static AsynchronousChannelProvider load() {
+            return AccessController
+                .doPrivileged(new PrivilegedAction<AsynchronousChannelProvider>() {
+                    public AsynchronousChannelProvider run() {
+                        AsynchronousChannelProvider p;
+                        p = loadProviderFromProperty();
+                        if (p != null)
+                            return p;
+                        p = loadProviderAsService();
+                        if (p != null)
+                            return p;
+                        return sun.nio.ch.DefaultAsynchronousChannelProvider.create();
+                    }});
+        }
+
+        private static AsynchronousChannelProvider loadProviderFromProperty() {
+            String cn = System.getProperty("java.nio.channels.spi.AsynchronousChannelProvider");
+            if (cn == null)
+                return null;
+            try {
+                Class<?> c = Class.forName(cn, true,
+                                           ClassLoader.getSystemClassLoader());
+                return (AsynchronousChannelProvider)c.newInstance();
+            } catch (ClassNotFoundException x) {
+                throw new ServiceConfigurationError(null, x);
+            } catch (IllegalAccessException x) {
+                throw new ServiceConfigurationError(null, x);
+            } catch (InstantiationException x) {
+                throw new ServiceConfigurationError(null, x);
+            } catch (SecurityException x) {
+                throw new ServiceConfigurationError(null, x);
+            }
+        }
+
+        private static AsynchronousChannelProvider loadProviderAsService() {
+            ServiceLoader<AsynchronousChannelProvider> sl =
+                ServiceLoader.load(AsynchronousChannelProvider.class,
+                                   ClassLoader.getSystemClassLoader());
+            Iterator<AsynchronousChannelProvider> i = sl.iterator();
+            for (;;) {
+                try {
+                    return (i.hasNext()) ? i.next() : null;
+                } catch (ServiceConfigurationError sce) {
+                    if (sce.getCause() instanceof SecurityException) {
+                        // Ignore the security exception, try the next provider
+                        continue;
+                    }
+                    throw sce;
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns the system-wide default asynchronous channel provider for this
+     * invocation of the Java virtual machine.
+     *
+     * <p> The first invocation of this method locates the default provider
+     * object as follows: </p>
+     *
+     * <ol>
+     *
+     *   <li><p> If the system property
+     *   <tt>java.nio.channels.spi.AsynchronousChannelProvider</tt> is defined
+     *   then it is taken to be the fully-qualified name of a concrete provider class.
+     *   The class is loaded and instantiated; if this process fails then an
+     *   unspecified error is thrown.  </p></li>
+     *
+     *   <li><p> If a provider class has been installed in a jar file that is
+     *   visible to the system class loader, and that jar file contains a
+     *   provider-configuration file named
+     *   <tt>java.nio.channels.spi.AsynchronousChannelProvider</tt> in the resource
+     *   directory <tt>META-INF/services</tt>, then the first class name
+     *   specified in that file is taken.  The class is loaded and
+     *   instantiated; if this process fails then an unspecified error is
+     *   thrown.  </p></li>
+     *
+     *   <li><p> Finally, if no provider has been specified by any of the above
+     *   means then the system-default provider class is instantiated and the
+     *   result is returned.  </p></li>
+     *
+     * </ol>
+     *
+     * <p> Subsequent invocations of this method return the provider that was
+     * returned by the first invocation.  </p>
+     *
+     * @return  The system-wide default AsynchronousChannel provider
+     */
+    public static AsynchronousChannelProvider provider() {
+        return ProviderHolder.provider;
+    }
+
+    /**
+     * Constructs a new asynchronous channel group with a fixed thread pool.
+     *
+     * @param   nThreads
+     *          The number of threads in the pool
+     * @param   threadFactory
+     *          The factory to use when creating new threads
+     *
+     * @throws  IllegalArgumentException
+     *          If {@code nThreads <= 0}
+     * @throws  IOException
+     *          If an I/O error occurs
+     *
+     * @see AsynchronousChannelGroup#withFixedThreadPool
+     */
+    public abstract AsynchronousChannelGroup
+        openAsynchronousChannelGroup(int nThreads, ThreadFactory threadFactory) throws IOException;
+
+    /**
+     * Constructs a new asynchronous channel group with the given thread pool.
+     *
+     * @param   executor
+     *          The thread pool
+     * @param   initialSize
+     *          A value {@code >=0} or a negative value for implementation
+     *          specific default
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     *
+     * @see AsynchronousChannelGroup#withCachedThreadPool
+     */
+    public abstract AsynchronousChannelGroup
+        openAsynchronousChannelGroup(ExecutorService executor, int initialSize) throws IOException;
+
+    /**
+     * Opens an asynchronous server-socket channel.
+     *
+     * @param   group
+     *          The group to which the channel is bound, or {@code null} to
+     *          bind to the default group
+     *
+     * @return  The new channel
+     *
+     * @throws  IllegalChannelGroupException
+     *          If the provider that created the group differs from this provider
+     * @throws  ShutdownChannelGroupException
+     *          The group is shutdown
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    public abstract AsynchronousServerSocketChannel openAsynchronousServerSocketChannel
+        (AsynchronousChannelGroup group) throws IOException;
+
+    /**
+     * Opens an asynchronous socket channel.
+     *
+     * @param   group
+     *          The group to which the channel is bound, or {@code null} to
+     *          bind to the default group
+     *
+     * @return  The new channel
+     *
+     * @throws  IllegalChannelGroupException
+     *          If the provider that created the group differs from this provider
+     * @throws  ShutdownChannelGroupException
+     *          The group is shutdown
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    public abstract AsynchronousSocketChannel openAsynchronousSocketChannel
+        (AsynchronousChannelGroup group) throws IOException;
+
+    /**
+     * Opens an asynchronous datagram channel.
+     *
+     * @param   family
+     *          The protocol family, or {@code null} for the default protocol
+     *          family
+     * @param   group
+     *          The group to which the channel is bound, or {@code null} to
+     *          bind to the default group
+     *
+     * @return  The new channel
+     *
+     * @throws  IllegalChannelGroupException
+     *          If the provider that created the group differs from this provider
+     * @throws  ShutdownChannelGroupException
+     *          The group is shutdown
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    public abstract AsynchronousDatagramChannel openAsynchronousDatagramChannel
+        (ProtocolFamily family, AsynchronousChannelGroup group) throws IOException;
+}
diff --git a/jdk/src/share/classes/java/nio/channels/spi/SelectorProvider.java b/jdk/src/share/classes/java/nio/channels/spi/SelectorProvider.java
index dc61c9c..d03800e 100644
--- a/jdk/src/share/classes/java/nio/channels/spi/SelectorProvider.java
+++ b/jdk/src/share/classes/java/nio/channels/spi/SelectorProvider.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2009 Sun Microsystems, Inc.  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
@@ -89,8 +89,8 @@
         if (cn == null)
             return false;
         try {
-            Class c = Class.forName(cn, true,
-                                    ClassLoader.getSystemClassLoader());
+            Class<?> c = Class.forName(cn, true,
+                                       ClassLoader.getSystemClassLoader());
             provider = (SelectorProvider)c.newInstance();
             return true;
         } catch (ClassNotFoundException x) {
diff --git a/jdk/src/share/classes/java/nio/channels/spi/package.html b/jdk/src/share/classes/java/nio/channels/spi/package.html
index 5b3ddd2..5960da3 100644
--- a/jdk/src/share/classes/java/nio/channels/spi/package.html
+++ b/jdk/src/share/classes/java/nio/channels/spi/package.html
@@ -1,5 +1,5 @@
 <!--
- Copyright 2000-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ Copyright 2000-2009 Sun Microsystems, Inc.  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
@@ -29,8 +29,8 @@
 
 Service-provider classes for the <tt>{@link java.nio.channels}</tt> package.
 
-<p> Only developers who are defining new selector providers should need to make
-direct use of this package.  </p>
+<p> Only developers who are defining new selector providers or asynchronous
+channel providers should need to make direct use of this package.  </p>
 
 <p> Unless otherwise noted, passing a <tt>null</tt> argument to a constructor
 or method in any class or interface in this package will cause a {@link
diff --git a/jdk/src/share/classes/java/nio/file/AccessDeniedException.java b/jdk/src/share/classes/java/nio/file/AccessDeniedException.java
new file mode 100644
index 0000000..82a4fd2
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/AccessDeniedException.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Checked exception thrown when a file system operation is denied, typically
+ * due to a file permission or other access check.
+ *
+ * <p> This exception is not related to the {@link
+ * java.security.AccessControlException AccessControlException} or {@link
+ * SecurityException} thrown by access controllers or security managers when
+ * access to a file is denied.
+ *
+ * @since 1.7
+ */
+
+public class AccessDeniedException
+    extends FileSystemException
+{
+    private static final long serialVersionUID = 4943049599949219617L;
+
+    /**
+     * Constructs an instance of this class.
+     *
+     * @param   file
+     *          a string identifying the file or {@code null} if not known
+     */
+    public AccessDeniedException(String file) {
+        super(file);
+    }
+
+    /**
+     * Constructs an instance of this class.
+     *
+     * @param   file
+     *          a string identifying the file or {@code null} if not known
+     * @param   other
+     *          a string identifying the other file or {@code null} if not known
+     * @param   reason
+     *          a reason message with additional information or {@code null}
+     */
+    public AccessDeniedException(String file, String other, String reason) {
+        super(file, other, reason);
+    }
+}
diff --git a/jdk/src/share/classes/java/nio/file/AccessMode.java b/jdk/src/share/classes/java/nio/file/AccessMode.java
new file mode 100644
index 0000000..2408376
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/AccessMode.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Defines access modes used to test the accessibility of a file.
+ *
+ * @since 1.7
+ *
+ * @see FileRef#checkAccess
+ */
+
+public enum AccessMode {
+    /**
+     * Test read access.
+     */
+    READ,
+    /**
+     * Test write access.
+     */
+    WRITE,
+    /**
+     * Test execute access.
+     */
+    EXECUTE;
+}
diff --git a/jdk/src/share/classes/java/nio/file/AtomicMoveNotSupportedException.java b/jdk/src/share/classes/java/nio/file/AtomicMoveNotSupportedException.java
new file mode 100644
index 0000000..503d24c
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/AtomicMoveNotSupportedException.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Checked exception thrown when a file cannot be moved as an atomic file system
+ * operation.
+ *
+ * @since 1.7
+ */
+
+public class AtomicMoveNotSupportedException
+    extends FileSystemException
+{
+    static final long serialVersionUID = 5402760225333135579L;
+
+    /**
+     * Constructs an instance of this class.
+     *
+     * @param   source
+     *          a string identifying the source file or {@code null} if not known
+     * @param   target
+     *          a string identifying the target file or {@code null} if not known
+     * @param   reason
+     *          a reason message with additional information
+     */
+    public AtomicMoveNotSupportedException(String source,
+                                           String target,
+                                           String reason)
+    {
+        super(source, target, reason);
+    }
+}
diff --git a/jdk/src/share/classes/java/nio/file/ClosedDirectoryStreamException.java b/jdk/src/share/classes/java/nio/file/ClosedDirectoryStreamException.java
new file mode 100644
index 0000000..f938776
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/ClosedDirectoryStreamException.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Unchecked exception thrown when an attempt is made to invoke an operation on
+ * a directory stream that is closed.
+ *
+ * @since 1.7
+ */
+
+public class ClosedDirectoryStreamException
+    extends IllegalStateException
+{
+    static final long serialVersionUID = 4228386650900895400L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public ClosedDirectoryStreamException() {
+    }
+}
diff --git a/jdk/src/share/classes/java/nio/file/ClosedFileSystemException.java b/jdk/src/share/classes/java/nio/file/ClosedFileSystemException.java
new file mode 100644
index 0000000..fcd720a
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/ClosedFileSystemException.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Unchecked exception thrown when an attempt is made to invoke an operation on
+ * a file and the file system is closed.
+ */
+
+public class ClosedFileSystemException
+    extends IllegalStateException
+{
+    static final long serialVersionUID = -8158336077256193488L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public ClosedFileSystemException() {
+    }
+}
diff --git a/jdk/src/share/classes/java/nio/file/ClosedWatchServiceException.java b/jdk/src/share/classes/java/nio/file/ClosedWatchServiceException.java
new file mode 100644
index 0000000..662d0b6
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/ClosedWatchServiceException.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Unchecked exception thrown when an attempt is made to invoke an operation on
+ * a watch service that is closed.
+ */
+
+public class ClosedWatchServiceException
+    extends IllegalStateException
+{
+    static final long serialVersionUID = 1853336266231677732L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public ClosedWatchServiceException() {
+    }
+}
diff --git a/jdk/src/share/classes/java/nio/file/CopyOption.java b/jdk/src/share/classes/java/nio/file/CopyOption.java
new file mode 100644
index 0000000..2453474
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/CopyOption.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+/**
+ * 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> The {@link StandardCopyOption} enumeration type defines the
+ * <i>standard</i> options.
+ *
+ * @since 1.7
+ */
+
+public interface CopyOption {
+}
diff --git a/jdk/src/share/classes/java/nio/file/DirectoryNotEmptyException.java b/jdk/src/share/classes/java/nio/file/DirectoryNotEmptyException.java
new file mode 100644
index 0000000..482b476
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/DirectoryNotEmptyException.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Checked exception thrown when a file system operation fails because a
+ * directory is not empty.
+ *
+ * @since 1.7
+ */
+
+public class DirectoryNotEmptyException
+    extends FileSystemException
+{
+    static final long serialVersionUID = 3056667871802779003L;
+
+    /**
+     * Constructs an instance of this class.
+     *
+     * @param   dir
+     *          a string identifying the directory or {@code null} if not known
+     */
+    public DirectoryNotEmptyException(String dir) {
+        super(dir);
+    }
+}
diff --git a/jdk/src/share/classes/java/nio/file/DirectoryStream.java b/jdk/src/share/classes/java/nio/file/DirectoryStream.java
new file mode 100644
index 0000000..589d7b4
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/DirectoryStream.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+import java.util.Iterator;
+import java.io.Closeable;
+
+/**
+ * An object to iterate over the entries in a directory. A directory stream
+ * allows for convenient use of the for-each construct:
+ * <pre>
+ *   Path dir = ...
+ *   DirectoryStream&lt;Path&gt; stream = dir.newDirectoryStream();
+ *   try {
+ *       for (Path entry: stream) {
+ *         ..
+ *       }
+ *   } finally {
+ *       stream.close();
+ *   }
+ * </pre>
+ *
+ * <p><b> A {@code DirectoryStream} is not a general-purpose {@code Iterable}.
+ * While this interface extends {@code Iterable}, the {@code iterator} method
+ * may only be invoked once to obtain the iterator; a second, or subsequent,
+ * call to the {@code iterator} method throws {@code IllegalStateException}. </b>
+ *
+ * <p> A {@code DirectoryStream} is opened upon creation and is closed by
+ * invoking the {@link #close close} method. Closing the directory stream
+ * releases any resources associated with the stream. The {@link
+ * Files#withDirectory Files.withDirectory} utility method is useful for cases
+ * where a task is performed on entries in a directory. This method automatically
+ * closes the directory stream when iteration is complete (or an error occurs).
+ * Once a directory stream is closed, all further method invocations on the
+ * iterator throw {@link java.util.concurrent.ConcurrentModificationException}
+ * with cause {@link ClosedDirectoryStreamException}.
+ *
+ * <p> A directory stream is not required to be <i>asynchronously closeable</i>.
+ * If a thread is blocked on the directory stream's iterator reading from the
+ * directory, and another thread invokes the {@code close} method, then the
+ * second thread may block until the read operation is complete.
+ *
+ * <p> The {@link Iterator#hasNext() hasNext} and {@link Iterator#next() next}
+ * methods can encounter an I/O error when iterating over the directory in which
+ * case {@code ConcurrentModificationException} is thrown with cause
+ * {@link java.io.IOException}. The {@code hasNext} method is guaranteed to
+ * read-ahead by at least one element. This means that if the {@code hasNext}
+ * method returns {@code true} and is followed by a call to the {@code next}
+ * method then it is guaranteed not to fail with a {@code
+ * ConcurrentModificationException}.
+ *
+ * <p> The elements returned by the iterator are in no specific order. Some file
+ * systems maintain special links to the directory itself and the directory's
+ * parent directory. Entries representing these links are not returned by the
+ * iterator.
+ *
+ * <p> The iterator's {@link Iterator#remove() remove} method removes the
+ * directory entry for the last element returned by the iterator, as if by
+ * invoking the {@link FileRef#delete delete} method. If an I/O error or
+ * security exception occurs then {@code ConcurrentModificationException} is
+ * thrown with the cause.
+ *
+ * <p> The iterator is <i>weakly consistent</i>. It is thread safe but does not
+ * freeze the directory while iterating, so it may (or may not) reflect updates
+ * to the directory that occur after the {@code DirectoryStream} is created.
+ *
+ * @param   <T>     The type of element returned by the iterator
+ *
+ * @since 1.7
+ *
+ * @see Path#newDirectoryStream
+ */
+
+public interface DirectoryStream<T>
+    extends Closeable, Iterable<T>
+{
+    /**
+     * 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.
+     *
+     * <p> The {@link DirectoryStreamFilters} class defines factory methods to
+     * create filters for a number of common usages and also methods to combine
+     * filters.
+     *
+     * @param   <T>     the type of the directory entry
+     *
+     * @since 1.7
+     */
+    public static interface Filter<T> {
+        /**
+         * Decides if the given directory entry should be accepted or filtered.
+         *
+         * @param   entry
+         *          the directory entry to be tested
+         *
+         * @return  {@code true} if the directory entry should be accepted
+         */
+        boolean accept(T entry);
+    }
+
+    /**
+     * Returns the iterator associated with this {@code DirectoryStream}.
+     *
+     * @return  the iterator associated with this {@code DirectoryStream}
+     *
+     * @throws  IllegalStateException
+     *          if this directory stream is closed or the iterator has already
+     *          been returned
+     */
+    @Override
+    Iterator<T> iterator();
+}
diff --git a/jdk/src/share/classes/java/nio/file/DirectoryStreamFilters.java b/jdk/src/share/classes/java/nio/file/DirectoryStreamFilters.java
new file mode 100644
index 0000000..b582bbf
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/DirectoryStreamFilters.java
@@ -0,0 +1,210 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+import java.io.IOException;
+import java.io.IOError;
+import sun.nio.fs.MimeType;
+
+/**
+ * This class consists exclusively of static methods that construct or combine
+ * filters.
+ *
+ * @since 1.7
+ */
+
+public final class DirectoryStreamFilters {
+    private DirectoryStreamFilters() { }
+
+    /**
+     * Constructs a directory stream filter that filters directory entries by
+     * their  <a href="http://www.ietf.org/rfc/rfc2045.txt">MIME</a> content
+     * type. The directory stream filter's {@link
+     * java.nio.file.DirectoryStream.Filter#accept accept} method returns {@code
+     * true} if the content type of the directory entry can be determined by
+     * invoking the {@link Files#probeContentType probeContentType} method, and
+     * the content type matches the given content type.
+     *
+     * <p> The {@code type} parameter is the value of a Multipurpose Internet
+     * Mail Extension (MIME) content type as defined by <a
+     * href="http://www.ietf.org/rfc/rfc2045.txt"><i>RFC&nbsp;2045: Multipurpose
+     * Internet Mail Extensions (MIME) Part One: Format of Internet Message
+     * Bodies</i></a>. It is parsable according to the grammar in the RFC. Any
+     * space characters (<code>'&#92;u0020'</code>) surrounding its components are
+     * ignored. The {@code type} parameter is parsed into its primary and subtype
+     * components which are used to match the primary and subtype components of
+     * each directory entry's content type. Parameters are not allowed. The
+     * primary type matches if it has value {@code '*'} or is equal to the
+     * primary type of the directory entry's content type without regard to
+     * case. The subtype matches if has the value {@code '*'} or is equal to the
+     * subtype of the directory entry's content type without regard to case. If
+     * both the primary and subtype match then the filter's {@code accept} method
+     * returns {@code true}. If the content type of a directory entry cannot be
+     * determined then the entry is filtered.
+     *
+     * <p> The {@code accept} method of the resulting directory stream filter
+     * throws {@link IOError} if the probing of the content type fails by
+     * throwing an {@link IOException}. Security exceptions are also propogated
+     * to the caller of the {@code accept} method.
+     *
+     * <p> <b>Usage Example:</b>
+     * Suppose we require to list only the HTML files in a directory.
+     * <pre>
+     *     DirectoryStream.Filter&lt;FileRef&gt; filter =
+     *         DirectoryStreamFilters.newContentTypeFilter("text/html");
+     * </pre>
+     *
+     * @param   type
+     *          the content type
+     *
+     * @return  a new directory stream filter
+     *
+     * @throws  IllegalArgumentException
+     *          if the {@code type} parameter cannot be parsed as a MIME type
+     *          or it has parameters
+     */
+    public static <T extends FileRef> DirectoryStream.Filter<T>
+        newContentTypeFilter(String type)
+    {
+        final MimeType matchType = MimeType.parse(type);
+        if (matchType.hasParameters())
+            throw new IllegalArgumentException("Parameters not allowed");
+        return new DirectoryStream.Filter<T>() {
+            @Override
+            public boolean accept(T entry) {
+                String fileType;
+                try {
+                    fileType = Files.probeContentType(entry);
+                } catch (IOException x) {
+                    throw new IOError(x);
+                }
+                if (fileType != null) {
+                    return matchType.match(fileType);
+                }
+                return false;
+            }
+        };
+    }
+
+    /**
+     * Returns a directory stream filter that {@link DirectoryStream.Filter#accept
+     * accepts} a directory entry if the entry is accepted by all of the given
+     * filters.
+     *
+     * <p> This method returns a filter that invokes, in iterator order, the
+     * {@code accept} method of each of the filters. If {@code false} is returned
+     * by any of the filters then the directory entry is filtered. If the
+     * directory entry is not filtered then the resulting filter accepts the
+     * entry. If the iterator returns zero elements then the resulting filter
+     * accepts all directory entries.
+     *
+     * <p> <b>Usage Example:</b>
+     * <pre>
+     *     List&lt;DirectoryStream.Filter&lt;? super Path&gt;&gt; filters = ...
+     *     DirectoryStream.Filter&lt;Path&gt; filter = DirectoryStreamFilters.allOf(filters);
+     * </pre>
+     *
+     * @param   filters
+     *          the sequence of filters
+     *
+     * @return  the resulting filter
+     */
+    public static <T> DirectoryStream.Filter<T>
+        allOf(final Iterable<? extends DirectoryStream.Filter<? super T>> filters)
+    {
+        if (filters == null)
+            throw new NullPointerException("'filters' is null");
+        return new DirectoryStream.Filter<T>() {
+            @Override
+            public boolean accept(T entry) {
+                for (DirectoryStream.Filter<? super T> filter: filters) {
+                    if (!filter.accept(entry))
+                        return false;
+                }
+                return true;
+            }
+        };
+    }
+
+    /**
+     * Returns a directory stream filter that {@link DirectoryStream.Filter#accept
+     * accepts} a directory entry if the entry is accepted by one or more of
+     * the given filters.
+     *
+     * <p> This method returns a filter that invokes, in iteration order, the
+     * {@code accept} method of each of filter. If {@code true} is returned by
+     * any of the filters then the directory entry is accepted. If none of the
+     * filters accepts the directory entry then it is filtered. If the iterator
+     * returns zero elements then the resulting filter filters all directory
+     * entries.
+     *
+     * @param   filters
+     *          the sequence of filters
+     *
+     * @return  the resulting filter
+     */
+    public static <T> DirectoryStream.Filter<T>
+        anyOf(final Iterable<? extends DirectoryStream.Filter<? super T>> filters)
+    {
+        if (filters == null)
+            throw new NullPointerException("'filters' is null");
+        return new DirectoryStream.Filter<T>() {
+            @Override
+            public boolean accept(T entry) {
+                for (DirectoryStream.Filter<? super T> filter: filters) {
+                    if (filter.accept(entry))
+                        return true;
+                }
+                return false;
+            }
+        };
+    }
+
+    /**
+     * Returns a directory stream filter that is the <em>complement</em> of the
+     * given filter. The resulting filter {@link
+     * java.nio.file.DirectoryStream.Filter#accept accepts} a directory entry
+     * if filtered by the given filter, and filters any entries that are accepted
+     * by the given filter.
+     *
+     * @param   filter
+     *          the given filter
+     *
+     * @return  the resulting filter that is the complement of the given filter
+     */
+    public static <T> DirectoryStream.Filter<T>
+        complementOf(final DirectoryStream.Filter<T> filter)
+    {
+        if (filter == null)
+            throw new NullPointerException("'filter' is null");
+        return new DirectoryStream.Filter<T>() {
+            @Override
+            public boolean accept(T entry) {
+                return !filter.accept(entry);
+            }
+        };
+    }
+}
diff --git a/jdk/src/share/classes/java/nio/file/FileAction.java b/jdk/src/share/classes/java/nio/file/FileAction.java
new file mode 100644
index 0000000..58088c2
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/FileAction.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+import java.io.IOException;
+
+/**
+ * An interface that is implemented by objects that operate on a file. An
+ * implementation of this interface is provided to the {@link Files#withDirectory
+ * withDirectory} utility method so that the file action is {@link #invoke
+ * invoked} for all accepted entries in the directory, after which, the directory
+ * is automatically closed.
+ *
+ * <p> <b>Usage Example:</b>
+ * Suppose we require to perform a task on all class files in a directory:
+ * <pre>
+ *     Path dir = ...
+ *     Files.withDirectory(dir, "*.class", new FileAction&lt;Path&gt;() {
+ *         public void invoke(Path entry) {
+ *             :
+ *         }
+ *     });
+ * </pre>
+ *
+ * @param   <T>     the type of file reference
+ *
+ * @since 1.7
+ */
+
+public interface FileAction<T extends FileRef> {
+    /**
+     * Invoked for a file.
+     *
+     * @param   file
+     *          the file
+     *
+     * @throws  IOException
+     *          if the block terminates due an uncaught I/O exception
+     */
+    void invoke(T file) throws IOException;
+}
diff --git a/jdk/src/share/classes/java/nio/file/FileAlreadyExistsException.java b/jdk/src/share/classes/java/nio/file/FileAlreadyExistsException.java
new file mode 100644
index 0000000..ff60e63
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/FileAlreadyExistsException.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Checked exception thrown when an attempt is made to create a file or
+ * directory and a file of that name already exists.
+ *
+ * @since 1.7
+ */
+
+public class FileAlreadyExistsException
+    extends FileSystemException
+{
+    static final long serialVersionUID = 7579540934498831181L;
+
+    /**
+     * Constructs an instance of this class.
+     *
+     * @param   file
+     *          a string identifying the file or {@code null} if not known
+     */
+    public FileAlreadyExistsException(String file) {
+        super(file);
+    }
+
+    /**
+     * Constructs an instance of this class.
+     *
+     * @param   file
+     *          a string identifying the file or {@code null} if not known
+     * @param   other
+     *          a string identifying the other file or {@code null} if not known
+     * @param   reason
+     *          a reason message with additional information or {@code null}
+     */
+    public FileAlreadyExistsException(String file, String other, String reason) {
+        super(file, other, reason);
+    }
+}
diff --git a/jdk/src/share/classes/java/nio/file/FileRef.java b/jdk/src/share/classes/java/nio/file/FileRef.java
new file mode 100644
index 0000000..2606a87
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/FileRef.java
@@ -0,0 +1,424 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+import java.nio.file.attribute.*;
+import java.nio.channels.SeekableByteChannel;
+import java.io.IOException;
+
+/**
+ * A reference to a file.
+ *
+ * <p> A {@code FileRef} is an object that locates a file and defines methods to
+ * access the file. The means by which the file is located depends on the
+ * implementation. In many cases, a file is located by a {@link Path} but it may
+ * be located by other means such as a file-system identifier.
+ *
+ * <p> This interface 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> 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>
+ * </ul>
+ *
+ * <p> Access to associated metadata or file attributes requires an appropriate
+ * {@link FileAttributeView FileAttributeView}. The {@link
+ * #getFileAttributeView(Class,LinkOption[]) getFileAttributeView(Class,LinkOption[])}
+ * method may be used to obtain a file attribute view that defines type-safe
+ * methods to read or update file attributes. The {@link
+ * #getFileAttributeView(String,LinkOption[]) getFileAttributeView(String,LinkOption[])}
+ * method may be used to obtain a file attribute view where dynamic access to
+ * file attributes where required.
+ *
+ * <p> A {@code FileRef} is immutable and safe for use by multiple concurrent
+ * threads.
+ *
+ * @since 1.7
+ */
+
+public interface FileRef {
+
+    /**
+     * Opens the file referenced by this object, 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#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 of this interface may support additional options
+     * defined by the {@link StandardOpenOption} enumeration type or other
+     * implementation specific options.
+     *
+     * <p> The {@link java.nio.channels.Channels} utility classes defines methods
+     * to construct input and output streams where inter-operation with the
+     * {@link java.io} package is required.
+     *
+     * @param   options
+     *          Options specifying how the file is opened
+     *
+     * @return  a new seekable byte channel
+     *
+     * @throws  IllegalArgumentException
+     *          If an invalid combination of options is specified
+     * @throws  UnsupportedOperationException
+     *          If an unsupported open 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 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.
+     */
+    SeekableByteChannel newByteChannel(OpenOption... options)
+        throws IOException;
+
+    /**
+     * Returns the {@link FileStore} representing the file store where the file
+     * referenced by this object 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>
+     */
+    FileStore getFileStore() throws IOException;
+
+    /**
+     * Checks the existence and optionally the accessibility of the file
+     * referenced by this object.
+     *
+     * <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.
+     */
+    void checkAccess(AccessMode... modes) 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);
+
+    /**
+     * Returns a file attribute view of the given name.
+     *
+     * <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
+     * <em>dynamic access</em> to the file attributes is required. The {@code
+     * name} parameter specifies the {@link FileAttributeView#name name} of the
+     * file attribute view and this method returns an instance of that view if
+     * supported. The {@link BasicFileAttributeView} type supports access to the
+     * basic attributes of a file and is name {@code "basic"}. Invoking this
+     * method to select a file attribute view named {@code "basic"} 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   name
+     *          The name of the file attribute view
+     * @param   options
+     *          Options indicating how symbolic links are handled
+     *
+     * @return  A file attribute view of the given name, or {@code null} if
+     *          the attribute view 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.
+     */
+    FileAttributeView getFileAttributeView(String name, LinkOption... options);
+
+    /**
+     * Tests if the file referenced by this object is the same file referenced
+     * by another object.
+     *
+     * <p> If this {@code FileRef} and the given {@code FileRef} are {@link
+     * #equals(Object) equal} then this method returns {@code true} without checking
+     * if the file exists. If the {@code FileRef} and the given {@code FileRef}
+     * are associated with different providers, or the given {@code FileRef} is
+     * {@code null} then this method returns {@code false}. Otherwise, this method
+     * checks if both {@code FileRefs} 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 FileRefs}.
+     * <ul>
+     * <li>It is <i>reflexive</i>: for a non-null {@code FileRef} {@code f},
+     *     {@code f.isSameFile(f)} should return {@code true}.
+     * <li>It is <i>symmetric</i>: for two non-null {@code FileRefs}
+     *     {@code f} and {@code g}, {@code f.isSameFile(g)} will equal
+     *     {@code g.isSameFile(f)}.
+     * <li>It is <i>transitive</i>: for three {@code FileRefs}
+     *     {@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
+     */
+    boolean isSameFile(FileRef other) throws IOException;
+
+    /**
+     * Deletes the file referenced by this object.
+     *
+     * <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
+     * link is deleted and not the final target of the link.
+     *
+     * <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
+     */
+    void delete() throws IOException;
+
+    /**
+     * Tests this object for equality with another object.
+     *
+     * <p> If the given object is not a {@code FileRef} then this method
+     * immediately returns {@code false}.
+     *
+     * <p> For two file references to be considered equal requires that they
+     * are both the same type of {@code FileRef} and encapsulate components
+     * to locate the same file. This method does not access the file system and
+     * the file may not exist.
+     *
+     * <p> This method satisfies the general contract of the {@link
+     * java.lang.Object#equals(Object) Object.equals} method. </p>
+     *
+     * @param   ob   The object to which this object is to be compared
+     *
+     * @return  {@code true} if, and only if, the given object is a {@code FileRef}
+     *          that is identical to this {@code FileRef}
+     *
+     * @see #isSameFile
+     */
+    boolean equals(Object ob);
+
+    /**
+     * Returns the hash-code value for this object.
+     *
+     * <p> This method satisfies the general contract of the
+     * {@link java.lang.Object#hashCode() Object.hashCode} method.
+     */
+    int hashCode();
+}
diff --git a/jdk/src/share/classes/java/nio/file/FileStore.java b/jdk/src/share/classes/java/nio/file/FileStore.java
new file mode 100644
index 0000000..3f8df10
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/FileStore.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+import java.nio.file.attribute.*;
+
+/**
+ * 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 FileRef#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
+ */
+
+public abstract class FileStore {
+
+    /**
+     * Initializes a new instance of this class.
+     */
+    protected FileStore() {
+    }
+
+    /**
+     * Returns the name of this file store. The format of the name is highly
+     * implementation specific. It will typically be the name of the storage
+     * pool or volume.
+     *
+     * <p> The string returned by this method may differ from the string
+     * returned by the {@link Object#toString() toString} method.
+     *
+     * @return  the name of this file store
+     */
+    public abstract String name();
+
+    /**
+     * Returns the <em>type</em> of this file store. The format of the string
+     * returned by this method is highly implementation specific. It may
+     * indicate, for example, the format used or if the file store is local
+     * or remote.
+     *
+     * @return  a string representing the type of this file store
+     */
+    public abstract String type();
+
+    /**
+     * Tells whether this file store is read-only. A file store is read-only if
+     * it does not support write operations or other changes to files. Any
+     * attempt to create a file, open an existing file for writing etc. causes
+     * an {@code IOException} to be thrown.
+     *
+     * @return  {@code true} if, and only if, this file store is read-only
+     */
+    public abstract boolean isReadOnly();
+
+    /**
+     * Tells whether or not this file store supports the file attributes
+     * identified by the given file attribute view.
+     *
+     * <p> Invoking this method to test if the file store supports {@link
+     * BasicFileAttributeView} will always return {@code true}. In the case of
+     * the default provider, this method cannot guarantee to give the correct
+     * result when the file store is not a local storage device. The reasons for
+     * this are implementation specific and therefore unspecified.
+     *
+     * @param   type
+     *          the file attribute view type
+     *
+     * @return  {@code true} if, and only if, the file attribute view is
+     *          supported
+     */
+    public abstract boolean supportsFileAttributeView(Class<? extends FileAttributeView> type);
+
+    /**
+     * Tells whether or not this file store supports the file attributes
+     * identified by the given file attribute view.
+     *
+     * <p> Invoking this method to test if the file store supports {@link
+     * BasicFileAttributeView}, identified by the name "{@code basic}" will
+     * always return {@code true}. In the case of the default provider, this
+     * method cannot guarantee to give the correct result when the file store is
+     * not a local storage device. The reasons for this are implementation
+     * specific and therefore unspecified.
+     *
+     * @param   name
+     *          the {@link FileAttributeView#name name} of file attribute view
+     *
+     * @return  {@code true} if, and only if, the file attribute view is
+     *          supported
+     */
+    public abstract boolean supportsFileAttributeView(String name);
+
+    /**
+     * Returns a {@code FileStoreAttributeView} of the given type.
+     *
+     * <p> This method is intended to be used where the file store attribute
+     * view defines type-safe methods to read or update the file store attributes.
+     * 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
+     *
+     * @return  a file store attribute view of the specified type or
+     *          {@code null} if the attribute view is not available
+     */
+    public abstract <V extends FileStoreAttributeView> V
+        getFileStoreAttributeView(Class<V> type);
+
+    /**
+     * Returns a {@code FileStoreAttributeView} of the given name.
+     *
+     * <p> This method is intended to be used where <em>dynamic access</em> to
+     * file store attributes is required. The {@code name} parameter specifies
+     * the {@link FileAttributeView#name name} of the file store attribute view
+     * and this method returns an instance of that view 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 "space"} will always return an instance
+     * of that class.
+     *
+     * @param   name
+     *          the name of the attribute view
+     *
+     * @return  a file store attribute view of the given name, or {@code null}
+     *          if the attribute view is not available
+     */
+    public abstract FileStoreAttributeView getFileStoreAttributeView(String name);
+}
diff --git a/jdk/src/share/classes/java/nio/file/FileSystem.java b/jdk/src/share/classes/java/nio/file/FileSystem.java
new file mode 100644
index 0000000..b7cb063
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/FileSystem.java
@@ -0,0 +1,453 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+import java.nio.file.attribute.*;
+import java.nio.file.spi.FileSystemProvider;
+import java.util.Set;
+import java.io.Closeable;
+import java.io.IOException;
+
+/**
+ * Provides an interface to a file system and is the factory for objects to
+ * access files and other objects in the file system.
+ *
+ * <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.
+ *
+ * <p> A file system is the factory for several types of objects:
+ *
+ * <ul>
+ *   <li><p> The {@link #getPath getPath} method converts a system dependent
+ *     <em>path string</em>, returning a {@link Path} object that may be used
+ *     to locate and access a file. </p></li>
+ *   <li><p> The {@link #getPathMatcher  getPathMatcher} method is used
+ *     to create a {@link PathMatcher} that performs match operations on
+ *     paths. </p></li>
+ *   <li><p> The {@link #getFileStores getFileStores} method returns an iterator
+ *     over the underlying {@link FileStore file-stores}. </p></li>
+ *   <li><p> The {@link #getUserPrincipalLookupService getUserPrincipalLookupService}
+ *     method returns the {@link UserPrincipalLookupService} to lookup users or
+ *     groups by name. </p></li>
+ *   <li><p> The {@link #newWatchService newWatchService} method creates a
+ *     {@link WatchService} that may be used to watch objects for changes and
+ *     events. </p></li>
+ * </ul>
+ *
+ * <p> File systems vary greatly. In some cases the file system is a single
+ * hierarchy of files with one top-level root directory. In other cases it may
+ * have several distinct file hierarchies, each with its own top-level root
+ * directory. The {@link #getRootDirectories getRootDirectories} method may be
+ * used to iterate over the root directories in the file system. A file system
+ * is typically composed of one or more underlying {@link FileStore file-stores}
+ * that provide the storage for the files. Theses file stores can also vary in
+ * the features they support, and the file attributes or <em>meta-data</em> that
+ * they associate with files.
+ *
+ * <p> A file system is open upon creation and can be closed by invoking its
+ * {@link #close() close} method. Once closed, any further attempt to access
+ * objects in the file system cause {@link ClosedFileSystemException} to be
+ * thrown. File systems created by the default {@link FileSystemProvider provider}
+ * cannot be closed.
+ *
+ * <p> A {@code FileSystem} can provide read-only or read-write access to the
+ * file system. Whether or not a file system provides read-only access is
+ * established when the {@code FileSystem} is created and can be tested by invoking
+ * its {@link #isReadOnly() isReadOnly} method. Attempts to write to file stores
+ * by means of an object associated with a read-only file system throws {@link
+ * ReadOnlyFileSystemException}.
+ *
+ * <p> File systems are safe for use by multiple concurrent threads. The {@link
+ * #close close} method may be invoked at any time to close a file system but
+ * whether a file system is <i>asynchronously closeable</i> is provider specific
+ * and therefore unspecified. In other words, if a thread is accessing an
+ * object in a file system, and another thread invokes the {@code close} method
+ * then it may require to block until the first operation is complete. Closing
+ * a file system causes all open channels, watch services, and other {@link
+ * Closeable closeable} objects associated with the file system to be closed.
+ *
+ * @since 1.7
+ */
+
+public abstract class FileSystem
+    implements Closeable
+{
+    /**
+     * Initializes a new instance of this class.
+     */
+    protected FileSystem() {
+    }
+
+    /**
+     * Returns the provider that created this file system.
+     *
+     * @return  The provider that created this file system.
+     */
+    public abstract FileSystemProvider provider();
+
+    /**
+     * Closes this file system.
+     *
+     * <p> After a file system is closed then all subsequent access to the file
+     * system, either by methods defined by this class or on objects associated
+     * with this file system, throw {@link ClosedFileSystemException}. If the
+     * file system is already closed then invoking this method has no effect.
+     *
+     * <p> Closing a file system will close all open {@link
+     * java.nio.channels.Channel channels}, {@link DirectoryStream directory-streams},
+     * {@link WatchService watch-service}, and other closeable objects associated
+     * with this file system. The {@link FileSystems#getDefault default} file
+     * system cannot be closed.
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     * @throws  UnsupportedOperationException
+     *          Thrown in the case of the default file system
+     */
+    @Override
+    public abstract void close() throws IOException;
+
+    /**
+     * Tells whether or not this file system is open.
+     *
+     * <p> File systems created by the default provider are always open.
+     *
+     * @return  {@code true} if, and only if, this file system is open
+     */
+    public abstract boolean isOpen();
+
+    /**
+     * Tells whether or not this file system allows only read-only access to
+     * its file stores.
+     *
+     * @return  {@code true} if, and only if, this file system provides
+     *          read-only access
+     */
+    public abstract boolean isReadOnly();
+
+    /**
+     * Returns the name separator, represented as a string.
+     *
+     * <p> The name separator is used to separate names in a path string. An
+     * implementation may support multiple name separators in which case this
+     * method returns an implementation specific <em>default</em> name separator.
+     * This separator is used when creating path strings by invoking the {@link
+     * Path#toString() toString()} method.
+     *
+     * <p> In the case of the default provider, this method returns the same
+     * separator as {@link java.io.File#separator}.
+     *
+     * @return  The name separator
+     */
+    public abstract String getSeparator();
+
+    /**
+     * Returns an object to iterate over the paths of the root directories.
+     *
+     * <p> A file system provides access to a file store that may be composed
+     * of a number of distinct file hierarchies, each with its own top-level
+     * root directory. Unless denied by the security manager, each element in
+     * the returned iterator corresponds to the root directory of a distinct
+     * file hierarchy. The order of the elements is not defined. The file
+     * hierarchies may change during the lifetime of the Java virtual machine.
+     * For example, in some implementations, the insertion of removable media
+     * may result in the creation of a new file hierarchy with its own
+     * top-level directory.
+     *
+     * <p> When a security manager is installed, it is invoked to check access
+     * to the each root directory. If denied, the root directory is not returned
+     * by the iterator. In the case of the default provider, the {@link
+     * SecurityManager#checkRead(String)} method is invoked to check read access
+     * to each root directory. It is system dependent if the permission checks
+     * are done when the iterator is obtained or during iteration.
+     *
+     * @return  An object to iterate over the root directories
+     */
+    public abstract Iterable<Path> getRootDirectories();
+
+    /**
+     * Returns an object to iterate over the underlying file stores.
+     *
+     * <p> The elements of the returned iterator are the {@link
+     * FileStore FileStores} for this file system. The order of the elements is
+     * not defined and the file stores may change during the lifetime of the
+     * Java virtual machine. When an I/O error occurs, perhaps because a file
+     * store is not accessible, then it is not returned by the iterator.
+     *
+     * <p> In the case of the default provider, and a security manager is
+     * installed, the security manager is invoked to check {@link
+     * RuntimePermission}<tt>("getFileStoreAttributes")</tt>. If denied, then
+     * no file stores are returned by the iterator. In addition, the security
+     * manager's {@link SecurityManager#checkRead(String)} method is invoked to
+     * check read access to the file store's <em>top-most</em> directory. If
+     * denied, the file store is not returned by the iterator. It is system
+     * dependent if the permission checks are done when the iterator is obtained
+     * or during iteration.
+     *
+     * <p> <b>Usage Example:</b>
+     * 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;
+     *         System.out.format("%-20s %12d %12d %12d%n", store, total, used, avail);
+     *     }
+     * </pre>
+     *
+     * @return  An object to iterate over the backing file stores
+     */
+    public abstract Iterable<FileStore> getFileStores();
+
+    /**
+     * Returns the set of the {@link FileAttributeView#name names} of the file
+     * attribute views supported by this {@code FileSystem}.
+     *
+     * <p> The {@link BasicFileAttributeView} is required to be supported and
+     * therefore the set contains at least one element, "basic".
+     *
+     * <p> The {@link FileStore#supportsFileAttributeView(String)
+     * supportsFileAttributeView(String)} method may be used to test if an
+     * underlying {@link FileStore} supports the file attributes identified by a
+     * file attribute view.
+     *
+     * @return  An unmodifiable set of the names of the supported file attribute
+     *          views
+     */
+    public abstract Set<String> supportedFileAttributeViews();
+
+    /**
+     * Converts a path string to a {@code Path}.
+     *
+     * <p> The parsing and conversion to a path object is inherently
+     * implementation dependent. In the simplest case, the path string is rejected,
+     * and {@link InvalidPathException} thrown, if the path string contains
+     * characters that cannot be converted to characters that are <em>legal</em>
+     * to the file store. For example, on UNIX systems, the NUL (&#92;u0000)
+     * character is not allowed to be present in a path. An implementation may
+     * choose to reject path strings that contain names that are longer than those
+     * allowed by any file store, and where an implementation supports a complex
+     * path syntax, it may choose to reject path strings that are <em>badly
+     * formed</em>.
+     *
+     * <p> In the case of the default provider, path strings are parsed based
+     * on the definition of paths at the platform or virtual file system level.
+     * For example, an operating system may not allow specific characters to be
+     * present in a file name, but a specific underlying file store may impose
+     * different or additional restrictions on the set of legal
+     * characters.
+     *
+     * <p> This method throws {@link InvalidPathException} when the path string
+     * cannot be converted to a path. Where possible, and where applicable,
+     * the exception is created with an {@link InvalidPathException#getIndex
+     * 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   path
+     *          The path string
+     *
+     * @return  A {@code Path} object
+     *
+     * @throws  InvalidPathException
+     *          If the path string cannot be converted
+     */
+    public abstract Path getPath(String path);
+
+    /**
+     * Returns a {@code PathMatcher} that performs match operations on the
+     * {@code String} representation of {@link Path} objects by interpreting a
+     * given pattern.
+     *
+     * The {@code syntaxAndPattern} parameter identifies the syntax and the
+     * pattern and takes the form:
+     * <blockquote>
+     * <i>syntax</i><b>:</b><i>pattern</i>
+     * </blockquote>
+     * where {@code ':'} stands for itself.
+     *
+     * <p> A {@code FileSystem} implementation supports the "{@code glob}" and
+     * "{@code regex}" syntaxes, and may support others. The value of the syntax
+     * component is compared without regard to case.
+     *
+     * <p> When the syntax is "{@code glob}" then the {@code String}
+     * representation of the path is matched using a limited pattern language
+     * that resembles regular expressions but with a simpler syntax. For example:
+     *
+     * <blockquote>
+     * <table border="0">
+     * <tr>
+     *   <td>{@code *.java}</td>
+     *   <td>Matches a path that represents a file name ending in {@code .java}</td>
+     * </tr>
+     * <tr>
+     *   <td>{@code *.*}</td>
+     *   <td>Matches file names containing a dot</td>
+     * </tr>
+     * <tr>
+     * <tr>
+     *   <td>{@code *.{java,class}}</td>
+     *   <td>Matches file names ending with {@code .java} or {@code .class}</td>
+     * </tr>
+     * <tr>
+     *   <td>{@code foo.?}</td>
+     *   <td>Matches file names starting with {@code foo.} and a single
+     *   character extension</td>
+     * </tr>
+     * <tr>
+     *   <td><tt>&#47;home&#47;*&#47;*</tt>
+     *   <td>Matches <tt>&#47;home&#47;gus&#47;data</tt> on UNIX platforms</td>
+     * </tr>
+     * <tr>
+     *   <td><tt>&#47;home&#47;**</tt>
+     *   <td>Matches <tt>&#47;home&#47;gus</tt> and
+     *   <tt>&#47;home&#47;gus&#47;data</tt> on UNIX platforms</td>
+     * </tr>
+     * <tr>
+     *   <td><tt>C:&#92;&#92;*</tt>
+     *   <td>Matches <tt>C:&#92;foo</tt> and <tt>C:&#92;bar</tt> on the Windows
+     *   platform (note that the backslash is escaped; as a string literal in the
+     *   Java Language the pattern would be <tt>"C:&#92;&#92;&#92;&#92*"</tt>) </td>
+     * </tr>
+     *
+     * </table>
+     * </blockquote>
+     *
+     * <p> The following rules are used to interpret glob patterns:
+     *
+     * <p> <ul>
+     *   <li><p> The {@code *} character matches zero or more {@link Character
+     *   characters} of a {@link Path#getName(int) name} component without
+     *   crossing directory boundaries. </p></li>
+     *
+     *   <li><p> The {@code **} characters matches zero or more {@link Character
+     *   characters} crossing directory boundaries. </p></li>
+     *
+     *   <li><p> The {@code ?} character matches exactly one character of a
+     *   name component.</p></li>
+     *
+     *   <li><p> The backslash character ({@code \}) is used to escape characters
+     *   that would otherwise be interpreted as special characters. The expression
+     *   {@code \\} matches a single backslash and "\{" matches a left brace
+     *   for example.  </p></li>
+     *
+     *   <li><p> The {@code [ ]} characters are a <i>bracket expression</i> that
+     *   match a single character of a name component out of a set of characters.
+     *   For example, {@code [abc]} matches {@code "a"}, {@code "b"}, or {@code "c"}.
+     *   The hyphen ({@code -}) may be used to specify a range so {@code [a-z]}
+     *   specifies a range that matches from {@code "a"} to {@code "z"} (inclusive).
+     *   These forms can be mixed so [abce-g] matches {@code "a"}, {@code "b"},
+     *   {@code "c"}, {@code "e"}, {@code "f"} or {@code "g"}. If the character
+     *   after the {@code [} is a {@code !} then it is used for negation so {@code
+     *   [!a-c]} matches any character except {@code "a"}, {@code "b"}, or {@code
+     *   "c"}.
+     *   <p> Within a bracket expression the {@code *}, {@code ?} and {@code \}
+     *   characters match themselves. The ({@code -}) character matches itself if
+     *   it is the first character within the brackets, or the first character
+     *   after the {@code !} if negating.</p></li>
+     *
+     *   <li><p> The {@code { }} characters are a group of subpatterns, where
+     *   the group matches if any subpattern in the group matches. The {@code ","}
+     *   character is used to separate the subpatterns. Groups cannot be nested.
+     *   </p></li>
+     *
+     *   <li><p> All other characters match themselves in an implementation
+     *   dependent manner. This includes characters representing any {@link
+     *   FileSystem#getSeparator name-separators}. </p></li>
+     *
+     *   <li><p> The matching of {@link Path#getRoot root} components is highly
+     *   implementation-dependent and is not specified. </p></li>
+     *
+     * </ul>
+     *
+     * <p> When the syntax is "{@code regex}" then the pattern component is a
+     * regular expression as defined by the {@link java.util.regex.Pattern}
+     * class.
+     *
+     * <p>  For both the glob and regex syntaxes, the matching details, such as
+     * whether the matching is case sensitive, are implementation-dependent
+     * and therefore not specified.
+     *
+     * @param   syntaxAndPattern
+     *          The syntax and pattern
+     *
+     * @return  A path matcher that may be used to match paths against the pattern
+     *
+     * @throws  IllegalArgumentException
+     *          If the parameter does not take the form: {@code syntax:pattern}
+     * @throws  java.util.regex.PatternSyntaxException
+     *          If the pattern is invalid
+     * @throws  UnsupportedOperationException
+     *          If the pattern syntax is not known to the implementation
+     *
+     * @see Path#newDirectoryStream(String)
+     */
+    public abstract PathMatcher getPathMatcher(String syntaxAndPattern);
+
+    /**
+     * Returns the {@code UserPrincipalLookupService} for this file system
+     * <i>(optional operation)</i>. The resulting lookup service may be used to
+     * lookup user or group names.
+     *
+     * <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);
+     * </pre>
+     *
+     * @throws  UnsupportedOperationException
+     *          If this {@code FileSystem} does not does have a lookup service
+     *
+     * @return  The {@code UserPrincipalLookupService} for this file system
+     */
+    public abstract UserPrincipalLookupService getUserPrincipalLookupService();
+
+    /**
+     * Constructs a new {@link WatchService} <i>(optional operation)</i>.
+     *
+     * <p> This method constructs a new watch service that may be used to watch
+     * registered objects for changes and events.
+     *
+     * @return  a new watch service
+     *
+     * @throws  UnsupportedOperationException
+     *          If this {@code FileSystem} does not support watching file system
+     *          objects for changes and events. This exception is not thrown
+     *          by {@code FileSystems} created by the default provider.
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    public abstract WatchService newWatchService() throws IOException;
+}
diff --git a/jdk/src/share/classes/java/nio/file/FileSystemAlreadyExistsException.java b/jdk/src/share/classes/java/nio/file/FileSystemAlreadyExistsException.java
new file mode 100644
index 0000000..68c4e15
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/FileSystemAlreadyExistsException.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Runtime exception thrown when an attempt is made to create a file system that
+ * already exists.
+ */
+
+public class FileSystemAlreadyExistsException
+    extends RuntimeException
+{
+    static final long serialVersionUID = -5438419127181131148L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public FileSystemAlreadyExistsException() {
+    }
+
+    /**
+     * Constructs an instance of this class.
+     *
+     * @param   msg
+     *          the detail message
+     */
+    public FileSystemAlreadyExistsException(String msg) {
+        super(msg);
+    }
+}
diff --git a/jdk/src/share/classes/java/nio/file/FileSystemException.java b/jdk/src/share/classes/java/nio/file/FileSystemException.java
new file mode 100644
index 0000000..8735dd8
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/FileSystemException.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+import java.io.IOException;
+
+/**
+ * Thrown when a file system operation fails on one or two files. This class is
+ * the general class for file system exceptions.
+ *
+ * @since 1.7
+ */
+
+public class FileSystemException
+    extends IOException
+{
+    static final long serialVersionUID = -3055425747967319812L;
+
+    private final String file;
+    private final String other;
+
+    /**
+     * Constructs an instance of this class. This constructor should be used
+     * when an operation involving one file fails and there isn't any additional
+     * information to explain the reason.
+     *
+     * @param   file
+     *          a string identifying the file or {@code null} if not known.
+     */
+    public FileSystemException(String file) {
+        super((String)null);
+        this.file = file;
+        this.other = null;
+    }
+
+    /**
+     * Constructs an instance of this class. This constructor should be used
+     * when an operation involving two files fails, or there is additional
+     * information to explain the reason.
+     *
+     * @param   file
+     *          a string identifying the file or {@code null} if not known.
+     * @param   other
+     *          a string identifying the other file or {@code null} if there
+     *          isn't another file or if not known
+     * @param   reason
+     *          a reason message with additional information or {@code null}
+     */
+    public FileSystemException(String file, String other, String reason) {
+        super(reason);
+        this.file = file;
+        this.other = other;
+    }
+
+    /**
+     * Returns the file used to create this exception.
+     *
+     * @return  the file (can be {@code null})
+     */
+    public String getFile() {
+        return file;
+    }
+
+    /**
+     * Returns the other file used to create this exception.
+     *
+     * @return  the other file (can be {@code null})
+     */
+    public String getOtherFile() {
+        return other;
+    }
+
+    /**
+     * Returns the string explaining why the file system operation failed.
+     *
+     * @return  the string explaining why the file system operation failed
+     */
+    public String getReason() {
+        return super.getMessage();
+    }
+
+    /**
+     * Returns the detail message string.
+     */
+    @Override
+    public String getMessage() {
+        if (file == null && other == null)
+            return getReason();
+        StringBuilder sb = new StringBuilder();
+        if (file != null)
+            sb.append(file);
+        if (other != null) {
+            sb.append(" -> ");
+            sb.append(other);
+        }
+        if (getReason() != null) {
+            sb.append(": ");
+            sb.append(getReason());
+        }
+        return sb.toString();
+    }
+}
diff --git a/jdk/src/share/classes/java/nio/file/FileSystemNotFoundException.java b/jdk/src/share/classes/java/nio/file/FileSystemNotFoundException.java
new file mode 100644
index 0000000..7cb58ca
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/FileSystemNotFoundException.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Runtime exception thrown when a file system cannot be found.
+ */
+
+public class FileSystemNotFoundException
+    extends RuntimeException
+{
+    static final long serialVersionUID = 7999581764446402397L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public FileSystemNotFoundException() {
+    }
+
+    /**
+     * Constructs an instance of this class.
+     *
+     * @param   msg
+     *          the detail message
+     */
+    public FileSystemNotFoundException(String msg) {
+        super(msg);
+    }
+}
diff --git a/jdk/src/share/classes/java/nio/file/FileSystems.java b/jdk/src/share/classes/java/nio/file/FileSystems.java
new file mode 100644
index 0000000..28885f8
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/FileSystems.java
@@ -0,0 +1,413 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+import java.nio.file.spi.FileSystemProvider;
+import java.net.URI;
+import java.io.IOException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.*;
+import java.lang.reflect.Constructor;
+
+/**
+ * Factory methods for file systems. This class defines the {@link #getDefault
+ * getDefault} method to get the default file system and factory methods to
+ * construct other types of file systems.
+ *
+ * <p> The first invocation of any of the methods defined by this class causes
+ * the default {@link FileSystemProvider provider} to be loaded. The default
+ * provider, identified by the URI scheme "file", creates the {@link FileSystem}
+ * that provides access to the file systems accessible to the Java virtual
+ * machine. If the process of loading or initializing the default provider fails
+ * then an unspecified error is thrown.
+ *
+ * <p> The first invocation of the {@link FileSystemProvider#installedProviders
+ * installedProviders} method, by way of invoking any of the {@code
+ * newFileSystem} methods defined by this class, locates and loads all
+ * installed file system providers. Installed providers are loaded using the
+ * service-provider loading facility defined by the {@link ServiceLoader} class.
+ * Installed providers are loaded using the system class loader. If the
+ * system class loader cannot be found then the extension class loader is used;
+ * if there is no extension class loader then the bootstrap class loader is used.
+ * Providers are typically installed by placing them in a JAR file on the
+ * application class path or in the extension directory, the JAR file contains a
+ * provider-configuration file named {@code java.nio.file.spi.FileSystemProvider}
+ * in the resource directory {@code META-INF/services}, and the file lists one or
+ * more fully-qualified names of concrete subclass of {@link FileSystemProvider}
+ * that have a zero argument constructor.
+ * The ordering that installed providers are located is implementation specific.
+ * If a provider is instantiated and its {@link FileSystemProvider#getScheme()
+ * getScheme} returns the same URI scheme of a provider that was previously
+ * instantiated then the most recently instantiated duplicate is discarded. URI
+ * schemes are compared without regard to case. During construction a provider
+ * may safely access files associated with the default provider but care needs
+ * to be taken to avoid circular loading of other installed providers. If
+ * circular loading of installed providers is detected then an unspecified error
+ * is thrown.
+ *
+ * <p> This class also defines factory methods that allow a {@link ClassLoader}
+ * to be specified when locating a provider. As with installed providers, the
+ * provider classes are identified by placing the provider configuration file
+ * in the resource directory {@code META-INF/services}.
+ *
+ * <p> If a thread initiates the loading of the installed file system providers
+ * and another thread invokes a method that also attempts to load the providers
+ * then the method will block until the loading completes.
+ *
+ * @since 1.7
+ */
+
+public final class FileSystems {
+    private FileSystems() {
+    }
+
+    // lazy initialization of default file system
+    private static class DefaultFileSystemHolder {
+        static final FileSystem defaultFileSystem = defaultFileSystem();
+
+        // returns default file system
+        private static FileSystem defaultFileSystem() {
+            // load default provider
+            FileSystemProvider provider = AccessController
+                .doPrivileged(new PrivilegedAction<FileSystemProvider>() {
+                    public FileSystemProvider run() {
+                        return getDefaultProvider();
+                    }
+                });
+
+            // return file system
+            return provider.getFileSystem(URI.create("file:///"));
+        }
+
+        // returns default provider
+        private static FileSystemProvider getDefaultProvider() {
+            FileSystemProvider provider = sun.nio.fs.DefaultFileSystemProvider.create();
+
+            // if the property java.nio.file.spi.DefaultFileSystemProvider is
+            // set then its value is the name of the default provider (or a list)
+            String propValue = System
+                .getProperty("java.nio.file.spi.DefaultFileSystemProvider");
+            if (propValue != null) {
+                for (String cn: propValue.split(",")) {
+                    try {
+                        Class<?> c = Class
+                            .forName(cn, true, ClassLoader.getSystemClassLoader());
+                        Constructor<?> ctor = c
+                            .getDeclaredConstructor(FileSystemProvider.class);
+                        provider = (FileSystemProvider)ctor.newInstance(provider);
+
+                        // must be "file"
+                        if (!provider.getScheme().equals("file"))
+                            throw new Error("Default provider must use scheme 'file'");
+
+                    } catch (Exception x) {
+                        throw new Error(x);
+                    }
+                }
+            }
+            return provider;
+        }
+    }
+
+    /**
+     * Returns the default {@code FileSystem}. The default file system creates
+     * objects that provide access to the file systems accessible to the Java
+     * virtual machine. The <em>working directory</em> of the file system is
+     * the current user directory, named by the system property {@code user.dir}.
+     * This allows for interoperability with the {@link java.io.File java.io.File}
+     * class.
+     *
+     * <p> The first invocation of any of the methods defined by this class
+     * locates the default {@link FileSystemProvider provider} object. Where the
+     * system property {@code java.nio.file.spi.DefaultFileSystemProvider} is
+     * not defined then the default provider is a system-default provider that
+     * is invoked to create the default file system.
+     *
+     * <p> If the system property {@code java.nio.file.spi.DefaultFileSystemProvider}
+     * is defined then it is taken to be a list of one or more fully-qualified
+     * names of concrete provider classes identified by the URI scheme
+     * {@code "file"}. Where the property is a list of more than one name then
+     * the names are separated by a comma. Each class is loaded, using the system
+     * class loader, and instantiated by invoking a one argument constructor
+     * whose formal parameter type is {@code FileSystemProvider}. The providers
+     * are loaded and instantiated in the order they are listed in the property.
+     * If this process fails or a provider's scheme is not equal to {@code "file"}
+     * then an unspecified error is thrown. URI schemes are normally compared
+     * without regard to case but for the default provider, the scheme is
+     * required to be {@code "file"}. The first provider class is instantiated
+     * by invoking it with a reference to the system-default provider.
+     * The second provider class is instantiated by invoking it with a reference
+     * 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.
+     *
+     * <p> Subsequent invocations of this method return the file system that was
+     * returned by the first invocation.
+     *
+     * @return  the default file system
+     */
+    public static FileSystem getDefault() {
+        return DefaultFileSystemHolder.defaultFileSystem;
+    }
+
+    /**
+     * Returns a reference to an existing {@code FileSystem}.
+     *
+     * <p> This method iterates over the {@link FileSystemProvider#installedProviders()
+     * installed} providers to locate the provider that is identified by the URI
+     * {@link URI#getScheme scheme} of the given URI. URI schemes are compared
+     * without regard to case. The exact form of the URI is highly provider
+     * dependent. If found, the provider's {@link FileSystemProvider#getFileSystem
+     * getFileSystem} method is invoked to obtain a reference to the {@code
+     * FileSystem}.
+     *
+     * <p> Once a file system created by this provider is {@link FileSystem#close
+     * closed} it is provider-dependent if this method returns a reference to
+     * the closed file system or throws {@link FileSystemNotFoundException}.
+     * If the provider allows a new file system to be created with the same URI
+     * as a file system it previously created then this method throws the
+     * exception if invoked after the file system is closed (and before a new
+     * instance is created by the {@link #newFileSystem newFileSystem} method).
+     *
+     * <p> If a security manager is installed then a provider implementation
+     * may require to check a permission before returning a reference to an
+     * existing file system. In the case of the {@link FileSystems#getDefault
+     * default} file system, no permission check is required.
+     *
+     * @throws  IllegalArgumentException
+     *          if the pre-conditions for the {@code uri} parameter are not met
+     * @throws  FileSystemNotFoundException
+     *          if the file system, identified by the URI, does not exist
+     * @throws  ProviderNotFoundException
+     *          if a provider supporting the URI scheme is not installed
+     * @throws  SecurityException
+     *          if a security manager is installed and it denies an unspecified
+     *          permission
+     */
+    public static FileSystem getFileSystem(URI uri) {
+        String scheme = uri.getScheme();
+        for (FileSystemProvider provider: FileSystemProvider.installedProviders()) {
+            if (scheme.equalsIgnoreCase(provider.getScheme())) {
+                return provider.getFileSystem(uri);
+            }
+        }
+        throw new ProviderNotFoundException("Provider \"" + scheme + "\" not found");
+    }
+
+    /**
+     * Constructs a new file system that is identified by a {@link URI}
+     *
+     * <p> This method iterates over the {@link FileSystemProvider#installedProviders()
+     * installed} providers to locate the provider that is identified by the URI
+     * {@link URI#getScheme scheme} of the given URI. URI schemes are compared
+     * without regard to case. The exact form of the URI is highly provider
+     * dependent. If found, the provider's {@link FileSystemProvider#newFileSystem(URI,Map)
+     * newFileSystem(URI,Map)} method is invoked to construct the new file system.
+     *
+     * <p> Once a file system is {@link FileSystem#close closed} it is
+     * provider-dependent if the provider allows a new file system to be created
+     * with the same URI as a file system it previously created.
+     *
+     * <p> <b>Usage Example:</b>
+     * 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;();
+     *   env.put("capacity", "16G");
+     *   env.put("blockSize", "4k");
+     *   FileSystem fs = FileSystems.newFileSystem(URI.create("memory:///?name=logfs"), env);
+     * </pre>
+     *
+     * @param   uri
+     *          the URI identifying the file system
+     * @param   env
+     *          a map of provider specific properties to configure the file system;
+     *          may be empty
+     *
+     * @return  a new file system
+     *
+     * @throws  IllegalArgumentException
+     *          if the pre-conditions for the {@code uri} parameter are not met,
+     *          or the {@code env} parameter does not contain properties required
+     *          by the provider, or a property value is invalid
+     * @throws  FileSystemAlreadyExistsException
+     *          if the file system has already been created
+     * @throws  ProviderNotFoundException
+     *          if a provider supporting the URI scheme is not installed
+     * @throws  IOException
+     *          if an I/O error occurs creating the file system
+     * @throws  SecurityException
+     *          if a security manager is installed and it denies an unspecified
+     *          permission required by the file system provider implementation
+     */
+    public static FileSystem newFileSystem(URI uri, Map<String,?> env)
+        throws IOException
+    {
+        return newFileSystem(uri, env, null);
+    }
+
+    /**
+     * Constructs a new file system that is identified by a {@link URI}
+     *
+     * <p> This method first attempts to locate an installed provider in exactly
+     * the same manner as the {@link #newFileSystem(URI,Map) newFileSystem(URI,Map)}
+     * method. If none of the installed providers support the URI scheme then an
+     * attempt is made to locate the provider using the given class loader. If a
+     * provider supporting the URI scheme is located then its {@link
+     * FileSystemProvider#newFileSystem(URI,Map) newFileSystem(URI,Map)} is
+     * invoked to construct the new file system.
+     *
+     * @param   uri
+     *          the URI identifying the file system
+     * @param   env
+     *          a map of provider specific properties to configure the file system;
+     *          may be empty
+     * @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 pre-conditions for the {@code uri} parameter are not met,
+     *          or the {@code env} parameter does not contain properties required
+     *          by the provider, or a property value is invalid
+     * @throws  FileSystemAlreadyExistsException
+     *          if the URI scheme identifies an installed provider and the file
+     *          system has already been created
+     * @throws  ProviderNotFoundException
+     *          if a provider supporting the URI scheme is not found
+     * @throws  ServiceConfigurationError
+     *          when an error occurs while loading a service provider
+     * @throws  IOException
+     *          an I/O error occurs creating the file system
+     * @throws  SecurityException
+     *          if a security manager is installed and it denies an unspecified
+     *          permission required by the file system provider implementation
+     */
+    public static FileSystem newFileSystem(URI uri, Map<String,?> env, ClassLoader loader)
+        throws IOException
+    {
+        String scheme = uri.getScheme();
+
+        // check installed providers
+        for (FileSystemProvider provider: FileSystemProvider.installedProviders()) {
+            if (scheme.equalsIgnoreCase(provider.getScheme())) {
+                return provider.newFileSystem(uri, env);
+            }
+        }
+
+        // if not found, use service-provider loading facility
+        if (loader != null) {
+            ServiceLoader<FileSystemProvider> sl = ServiceLoader
+                .load(FileSystemProvider.class, loader);
+            for (FileSystemProvider provider: sl) {
+                if (scheme.equalsIgnoreCase(provider.getScheme())) {
+                    return provider.newFileSystem(uri, env);
+                }
+            }
+        }
+
+        throw new ProviderNotFoundException("Provider \"" + scheme + "\" not found");
+    }
+
+    /**
+     * Constructs a new {@code FileSystem} to access the contents of a file as a
+     * file system.
+     *
+     * <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.
+     *
+     * <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.
+     *
+     * @param   file
+     *          a reference to a file
+     * @param   env
+     *          a map of provider specific properties to configure the file system;
+     *          may be empty
+     * @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
+     *          when an error occurs while loading a service provider
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          if a security manager is installed and it denies an unspecified
+     *          permission
+     */
+    public static FileSystem newFileSystem(FileRef file,
+                                           Map<String,?> env,
+                                           ClassLoader loader)
+        throws IOException
+    {
+        if (file == null)
+            throw new NullPointerException();
+
+        // check installed providers
+        for (FileSystemProvider provider: FileSystemProvider.installedProviders()) {
+            try {
+                return provider.newFileSystem(file, env);
+            } catch (UnsupportedOperationException uoe) {
+            }
+        }
+
+        // if not found, use service-provider loading facility
+        if (loader != null) {
+            ServiceLoader<FileSystemProvider> sl = ServiceLoader
+                .load(FileSystemProvider.class, loader);
+            for (FileSystemProvider provider: sl) {
+                try {
+                    return provider.newFileSystem(file, env);
+                } catch (UnsupportedOperationException uoe) {
+                }
+            }
+        }
+
+        throw new ProviderNotFoundException("Provider not found");
+    }
+}
diff --git a/jdk/src/share/classes/java/nio/file/FileTreeWalker.java b/jdk/src/share/classes/java/nio/file/FileTreeWalker.java
new file mode 100644
index 0000000..95148a5
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/FileTreeWalker.java
@@ -0,0 +1,255 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+import java.nio.file.attribute.*;
+import java.io.IOException;
+import java.util.*;
+import sun.nio.fs.BasicFileAttributesHolder;
+
+/**
+ * Simple file tree walker that works in a similar manner to nftw(3C).
+ *
+ * @see Files#walkFileTree
+ */
+
+class FileTreeWalker {
+    private final boolean followLinks;
+    private final boolean detectCycles;
+    private final LinkOption[] linkOptions;
+    private final FileVisitor<? super Path> visitor;
+
+    FileTreeWalker(Set<FileVisitOption> options, FileVisitor<? super Path> visitor) {
+        boolean fl = false;
+        boolean dc = false;
+        for (FileVisitOption option: options) {
+            switch (option) {
+                case FOLLOW_LINKS  : fl = true; break;
+                case DETECT_CYCLES : dc = true; break;
+                default:
+                    if (option == null)
+                        throw new NullPointerException("Visit options contains 'null'");
+                    throw new AssertionError("Should not get here");
+            }
+        }
+        this.followLinks = fl;
+        this.detectCycles = fl | dc;
+        this.linkOptions = (fl) ? new LinkOption[0] :
+            new LinkOption[] { LinkOption.NOFOLLOW_LINKS };
+        this.visitor = visitor;
+    }
+
+    /**
+     * Walk file tree starting at the given file
+     */
+    void walk(Path start, int maxDepth) {
+        // don't use attributes of starting file as they may be stale
+        if (start instanceof BasicFileAttributesHolder) {
+            ((BasicFileAttributesHolder)start).invalidate();
+        }
+        FileVisitResult result = walk(start,
+                                      maxDepth,
+                                      new ArrayList<AncestorDirectory>());
+        if (result == null) {
+            throw new NullPointerException("Visitor returned 'null'");
+        }
+    }
+
+    /**
+     * @param   file
+     *          the directory to visit
+     * @param   depth
+     *          depth remaining
+     * @param   ancestors
+     *          use when cycle detection is enabled
+     */
+    private FileVisitResult walk(Path file,
+                                 int depth,
+                                 List<AncestorDirectory> ancestors)
+    {
+        // depth check
+        if (depth-- < 0)
+            return FileVisitResult.CONTINUE;
+
+        // if attributes are cached then use them if possible
+        BasicFileAttributes attrs = null;
+        if (file instanceof BasicFileAttributesHolder) {
+            BasicFileAttributes cached = ((BasicFileAttributesHolder)file).get();
+            if (!followLinks || !cached.isSymbolicLink())
+                attrs = cached;
+        }
+        IOException exc = null;
+
+        // attempt to get attributes of file. If fails and we are following
+        // links then a link target might not exist so get attributes of link
+        if (attrs == null) {
+            try {
+                try {
+                    attrs = Attributes.readBasicFileAttributes(file, linkOptions);
+                } catch (IOException x1) {
+                    if (followLinks) {
+                        try {
+                            attrs = Attributes
+                                .readBasicFileAttributes(file, LinkOption.NOFOLLOW_LINKS);
+                        } catch (IOException x2) {
+                            exc = x2;
+                        }
+                    } else {
+                        exc = x1;
+                    }
+                }
+            } catch (SecurityException x) {
+                return FileVisitResult.CONTINUE;
+            }
+        }
+
+        // unable to get attributes of file
+        if (exc != null) {
+            return visitor.visitFileFailed(file, exc);
+        }
+
+        // file is not a directory so invoke visitFile method
+        if (!attrs.isDirectory()) {
+            return visitor.visitFile(file, attrs);
+        }
+
+        // check for cycles
+        if (detectCycles) {
+            Object key = attrs.fileKey();
+
+            // if this directory and ancestor has a file key then we compare
+            // them; otherwise we use less efficient isSameFile test.
+            for (AncestorDirectory ancestor: ancestors) {
+                Object ancestorKey = ancestor.fileKey();
+                if (key != null && ancestorKey != null) {
+                    if (key.equals(ancestorKey)) {
+                        // cycle detected
+                        return visitor.visitFile(file, attrs);
+                    }
+                } else {
+                    try {
+                        if (file.isSameFile(ancestor.file())) {
+                            // cycle detected
+                            return visitor.visitFile(file, attrs);
+                        }
+                    } catch (IOException x) {
+                        // ignore
+                    } catch (SecurityException x) {
+                        // ignore
+                    }
+                }
+            }
+
+            ancestors.add(new AncestorDirectory(file, key));
+        }
+
+        // visit directory
+        try {
+            DirectoryStream<Path> stream = null;
+            FileVisitResult result;
+
+            // open the directory
+            try {
+                stream = file.newDirectoryStream();
+            } catch (IOException x) {
+                return visitor.preVisitDirectoryFailed(file, x);
+            } catch (SecurityException x) {
+                // ignore, as per spec
+                return FileVisitResult.CONTINUE;
+            }
+
+            // the exception notified to the postVisitDirectory method
+            IOException ioe = null;
+
+            // invoke preVisitDirectory and then visit each entry
+            try {
+                result = visitor.preVisitDirectory(file);
+                if (result != FileVisitResult.CONTINUE) {
+                    return result;
+                }
+
+                // if an I/O occurs during iteration then a CME is thrown. We
+                // need to distinguish this from a CME thrown by the visitor.
+                boolean inAction = false;
+
+                try {
+                    for (Path entry: stream) {
+                        inAction = true;
+                        result = walk(entry, depth, ancestors);
+                        inAction = false;
+
+                        // returning null will cause NPE to be thrown
+                        if (result == null || result == FileVisitResult.TERMINATE)
+                            return result;
+
+                        // skip remaining siblings in this directory
+                        if (result == FileVisitResult.SKIP_SIBLINGS)
+                            break;
+                    }
+                } catch (ConcurrentModificationException x) {
+                    // if CME thrown because the iteration failed then remember
+                    // the IOException so that it is notified to postVisitDirectory
+                    if (!inAction) {
+                        // iteration failed
+                        Throwable t = x.getCause();
+                        if (t instanceof IOException)
+                            ioe = (IOException)t;
+                    }
+                    if (ioe == null)
+                        throw x;
+                }
+            } finally {
+                try {
+                    stream.close();
+                } catch (IOException x) { }
+            }
+
+            // invoke postVisitDirectory last
+            return visitor.postVisitDirectory(file, ioe);
+
+        } finally {
+            // remove key from trail if doing cycle detection
+            if (detectCycles) {
+                ancestors.remove(ancestors.size()-1);
+            }
+        }
+    }
+
+    private static class AncestorDirectory {
+        private final FileRef dir;
+        private final Object key;
+        AncestorDirectory(FileRef dir, Object key) {
+            this.dir = dir;
+            this.key = key;
+        }
+        FileRef file() {
+            return dir;
+        }
+        Object fileKey() {
+            return key;
+        }
+    }
+}
diff --git a/jdk/src/share/classes/java/nio/file/FileVisitOption.java b/jdk/src/share/classes/java/nio/file/FileVisitOption.java
new file mode 100644
index 0000000..c02e3e2
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/FileVisitOption.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Defines the file tree traversal options.
+ *
+ * @since 1.7
+ *
+ * @see Files#walkFileTree
+ */
+
+public enum FileVisitOption {
+    /**
+     * Follow symbolic links.
+     */
+    FOLLOW_LINKS,
+    /**
+     * Detect cycles in the file tree.
+     */
+    DETECT_CYCLES;
+}
diff --git a/jdk/src/share/classes/java/nio/file/FileVisitResult.java b/jdk/src/share/classes/java/nio/file/FileVisitResult.java
new file mode 100644
index 0000000..28e628b
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/FileVisitResult.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+/**
+ * The result type of a {@link FileVisitor FileVisitor}.
+ *
+ * @since 1.7
+ *
+ * @see Files#walkFileTree
+ */
+
+public enum FileVisitResult {
+    /**
+     * Continue. When returned from a {@link FileVisitor#preVisitDirectory
+     * preVisitDirectory} method then the entries in the directory should also
+     * be visited.
+     */
+    CONTINUE,
+    /**
+     * Terminate.
+     */
+    TERMINATE,
+    /**
+     * Continue without visiting the entries in this directory. This result
+     * is only meaningful when returned from the {@link
+     * FileVisitor#preVisitDirectory preVisitDirectory} method; otherwise
+     * this result type is the same as returning {@link #CONTINUE}.
+     */
+    SKIP_SUBTREE,
+    /**
+     * Continue without visiting the <em>siblings</em> of this file or directory.
+     * If returned from the {@link FileVisitor#preVisitDirectory
+     * preVisitDirectory} method then the entries in the directory are also
+     * skipped and the {@link FileVisitor#postVisitDirectory postVisitDirectory}
+     * method is not invoked.
+     */
+    SKIP_SIBLINGS;
+}
diff --git a/jdk/src/share/classes/java/nio/file/FileVisitor.java b/jdk/src/share/classes/java/nio/file/FileVisitor.java
new file mode 100644
index 0000000..6d65eba
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/FileVisitor.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+import java.nio.file.attribute.BasicFileAttributes;
+import java.io.IOException;
+
+/**
+ * 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.
+ *
+ * <p> <b>Usage Examples:</b>
+ * Suppose we want to delete a file tree. In that case, each directory should
+ * be deleted after the entries in the directory are deleted.
+ * <pre>
+ *     Path start = ...
+ *     Files.walkFileTree(start, new SimpleFileVisitor&lt;Path&gt;() {
+ *         &#64;Override
+ *         public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
+ *             try {
+ *                 file.delete(false);
+ *             } catch (IOException exc) {
+ *                 // failed to delete
+ *             }
+ *             return FileVisitResult.CONTINUE;
+ *         }
+ *         &#64;Override
+ *         public FileVisitResult postVisitDirectory(Path dir, IOException e) {
+ *             if (e == null) {
+ *                 try {
+ *                     dir.delete(false);
+ *                 } catch (IOException exc) {
+ *                     // failed to delete
+ *                 }
+ *             } else {
+ *                 // directory iteration failed
+ *             }
+ *             return FileVisitResult.CONTINUE;
+ *         }
+ *     });
+ * </pre>
+ * <p> Furthermore, suppose we want to copy a file tree rooted at a source
+ * directory to a target location. In that case, symbolic links should be
+ * followed and the target directory should be created before the entries in
+ * the directory are copied.
+ * <pre>
+ *     final Path source = ...
+ *     final Path target = ...
+ *
+ *     Files.walkFileTree(source, EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE,
+ *         new SimpleFileVisitor&lt;Path&gt;() {
+ *             &#64;Override
+ *             public FileVisitResult preVisitDirectory(Path dir) {
+ *                 try {
+ *                     dir.copyTo(target.resolve(source.relativize(dir)));
+ *                 } catch (FileAlreadyExistsException e) {
+ *                      // ignore
+ *                 } catch (IOException e) {
+ *                     // copy failed, skip rest of directory and descendants
+ *                     return SKIP_SUBTREE;
+ *                 }
+ *                 return CONTINUE;
+ *             }
+ *             &#64;Override
+ *             public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
+ *                 try {
+ *                     file.copyTo(target.resolve(source.relativize(file)));
+ *                 } catch (IOException e) {
+ *                     // copy failed
+ *                 }
+ *                 return CONTINUE;
+ *             }
+ *         });
+ * </pre>
+ *
+ * @since 1.7
+ */
+
+public interface FileVisitor<T extends FileRef> {
+
+    /**
+     * Invoked for a directory before entries in the directory are visited.
+     *
+     * <p> If this method returns {@link FileVisitResult#CONTINUE CONTINUE},
+     * then entries in the directory are visited. If this method returns {@link
+     * FileVisitResult#SKIP_SUBTREE SKIP_SUBTREE} or {@link
+     * FileVisitResult#SKIP_SIBLINGS SKIP_SIBLINGS} then entries in the
+     * directory (and any descendants) will not be visited.
+     *
+     * @param   dir
+     *          a reference to the directory
+     *
+     * @return  the visit result
+     */
+    FileVisitResult preVisitDirectory(T dir);
+
+    /**
+     * Invoked for a directory that could not be opened.
+     *
+     * @param   dir
+     *          a reference to the directory
+     * @param   exc
+     *          the I/O exception thrown from the attempt to open the directory
+     *
+     * @return  the visit result
+     */
+    FileVisitResult preVisitDirectoryFailed(T dir, IOException exc);
+
+    /**
+     * Invoked for a file in a directory.
+     *
+     * @param   file
+     *          a reference to the file
+     * @param   attrs
+     *          the file's basic attributes
+     *
+     * @return  the visit result
+     */
+    FileVisitResult visitFile(T file, BasicFileAttributes attrs);
+
+    /**
+     * Invoked for a file when its basic file attributes could not be read.
+     *
+     * @param   file
+     *          a reference to the file
+     * @param   exc
+     *          the I/O exception thrown from the attempt to read the file
+     *          attributes
+     *
+     * @return  the visit result
+     */
+    FileVisitResult visitFileFailed(T file, IOException exc);
+
+    /**
+     * Invoked for a directory after entries in the directory, and all of their
+     * descendants, have been visited. This method is also invoked when iteration
+     * of the directory completes prematurely (by a {@link #visitFile visitFile}
+     * method returning {@link FileVisitResult#SKIP_SIBLINGS SKIP_SIBLINGS},
+     * or an I/O error when iterating over the directory).
+     *
+     * @param   dir
+     *          a reference to the directory
+     * @param   exc
+     *          {@code null} if the iteration of the directory completes without
+     *          an error; otherwise the I/O exception that caused the iteration
+     *          of the directory to complete prematurely
+     *
+     * @return  the visit result
+     */
+    FileVisitResult postVisitDirectory(T dir, IOException exc);
+}
diff --git a/jdk/src/share/classes/java/nio/file/Files.java b/jdk/src/share/classes/java/nio/file/Files.java
new file mode 100644
index 0000000..42fdad8
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/Files.java
@@ -0,0 +1,406 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+import java.nio.file.spi.FileTypeDetector;
+import java.io.IOException;
+import java.util.*;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * Utility methods for files and directories.
+ *
+ * @since 1.7
+ */
+
+public final class Files {
+    private Files() { }
+
+    // lazy loading of default and installed file type detectors
+    private static class DefaultFileTypeDetectorHolder {
+        static final FileTypeDetector defaultFileTypeDetector =
+            sun.nio.fs.DefaultFileTypeDetector.create();
+        static final List<FileTypeDetector> installeDetectors =
+            loadInstalledDetectors();
+
+        // loads all installed file type detectors
+        private static List<FileTypeDetector> loadInstalledDetectors() {
+            return AccessController
+                .doPrivileged(new PrivilegedAction<List<FileTypeDetector>>() {
+                    @Override public List<FileTypeDetector> run() {
+                        List<FileTypeDetector> list = new ArrayList<FileTypeDetector>();
+                        ServiceLoader<FileTypeDetector> loader = ServiceLoader
+                            .load(FileTypeDetector.class, ClassLoader.getSystemClassLoader());
+                        for (FileTypeDetector detector: loader) {
+                            list.add(detector);
+                        }
+                        return list;
+                }});
+        }
+    }
+
+    /**
+     * Probes the content type of a file.
+     *
+     * <p> This method uses the installed {@link FileTypeDetector} implementations
+     * to probe the given file to determine its content type. Each file type
+     * detector's {@link FileTypeDetector#probeContentType probeContentType} is
+     * invoked, in turn, to probe the file type. If the file is recognized then
+     * the content type is returned. If the file is not recognized by any of the
+     * installed file type detectors then a system-default file type detector is
+     * invoked to guess the content type.
+     *
+     * <p> A given invocation of the Java virtual machine maintains a system-wide
+     * list of file type detectors. Installed file type detectors are loaded
+     * using the service-provider loading facility defined by the {@link ServiceLoader}
+     * class. Installed file type detectors are loaded using the system class
+     * loader. If the system class loader cannot be found then the extension class
+     * loader is used; If the extension class loader cannot be found then the
+     * bootstrap class loader is used. File type detectors are typically installed
+     * by placing them in a JAR file on the application class path or in the
+     * extension directory, the JAR file contains a provider-configuration file
+     * named {@code java.nio.file.spi.FileTypeDetector} in the resource directory
+     * {@code META-INF/services}, and the file lists one or more fully-qualified
+     * names of concrete subclass of {@code FileTypeDetector } that have a zero
+     * argument constructor. If the process of locating or instantiating the
+     * installed file type detectors fails then an unspecified error is thrown.
+     * The ordering that installed providers are located is implementation
+     * specific.
+     *
+     * <p> The return value of this method is the string form of the value of a
+     * Multipurpose Internet Mail Extension (MIME) content type as
+     * defined by <a href="http://www.ietf.org/rfc/rfc2045.txt"><i>RFC&nbsp;2045:
+     * Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet
+     * Message Bodies</i></a>. The string is guaranteed to be parsable according
+     * to the grammar in the RFC.
+     *
+     * @param   file
+     *          The file reference
+     *
+     * @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
+     * @throws  SecurityException
+     *          If a security manager is installed and it denies an unspecified
+     *          permission required by a file type detector implementation.
+     *
+     * @see DirectoryStreamFilters#newContentTypeFilter
+     */
+    public static String probeContentType(FileRef file)
+        throws IOException
+    {
+        // try installed file type detectors
+        for (FileTypeDetector detector: DefaultFileTypeDetectorHolder.installeDetectors) {
+            String result = detector.probeContentType(file);
+            if (result != null)
+                return result;
+        }
+
+        // fallback to default
+        return DefaultFileTypeDetectorHolder.defaultFileTypeDetector
+            .probeContentType(file);
+    }
+
+    /**
+     * Invokes a {@link FileAction} for each entry in a directory accepted
+     * by a given {@link java.nio.file.DirectoryStream.Filter filter}.
+     *
+     * <p> This method opens the given directory and invokes the file action's
+     * {@link FileAction#invoke invoke} method for each entry accepted by the
+     * filter. When iteration is completed then the directory is closed. If the
+     * {@link DirectoryStream#close close} method throws an {@code IOException}
+     * then it is silently ignored.
+     *
+     * <p> If the {@code FileAction}'s {@code invoke} method terminates due
+     * to an uncaught {@link IOException}, {@code Error} or {@code RuntimeException}
+     * then the exception is propagated by this method after closing the
+     * directory.
+     *
+     * @param   dir
+     *          The directory
+     * @param   filter
+     *          The filter
+     * @param   action
+     *          The {@code FileAction} to invoke for each accepted entry
+     *
+     * @throws  NotDirectoryException
+     *          If the {@code dir} parameter is not a directory <i>(optional
+     *          specific exception)</i>
+     * @throws  IOException
+     *          If an I/O error occurs or the {@code invoke} method terminates
+     *          due to an uncaught {@code IOException}
+     * @throws  SecurityException
+     *          In the case of the default provider, the {@link
+     *          SecurityManager#checkRead(String) checkRead} method is invoked
+     *          to check read access to the directory.
+     */
+    public static void withDirectory(Path dir,
+                                     DirectoryStream.Filter<? super Path> filter,
+                                     FileAction<? super Path> action)
+        throws IOException
+    {
+        // explicit null check required in case directory is empty
+        if (action == null)
+            throw new NullPointerException();
+
+        DirectoryStream<Path> stream = dir.newDirectoryStream(filter);
+        try {
+            // set to true when invoking the action so as to distinguish a
+            // CME thrown by the iteration from a CME thrown by the invoke
+            boolean inAction = false;
+            try {
+                for (Path entry: stream) {
+                    inAction = true;
+                    action.invoke(entry);
+                    inAction = false;
+                }
+            } catch (ConcurrentModificationException cme) {
+                if (!inAction) {
+                    Throwable cause = cme.getCause();
+                    if (cause instanceof IOException)
+                        throw (IOException)cause;
+                }
+                throw cme;
+            }
+        } finally {
+            try {
+                stream.close();
+            } catch (IOException x) { }
+        }
+    }
+
+    /**
+     * Invokes a {@link FileAction} for each entry in a directory with a
+     * file name that matches a given pattern.
+     *
+     * <p> This method opens the given directory and invokes the file action's
+     * {@link FileAction#invoke invoke} method for each entry that matches the
+     * given pattern. When iteration is completed then the directory is closed.
+     * If the {@link DirectoryStream#close close} method throws an {@code
+     * IOException} then it is silently ignored.
+     *
+     * <p> If the {@code FileAction}'s {@code invoke} method terminates due
+     * to an uncaught {@link IOException}, {@code Error} or {@code RuntimeException}
+     * then the exception is propagated by this method after closing the
+     * directory.
+     *
+     * <p> The globbing pattern language supported by this method is as
+     * specified by the {@link FileSystem#getPathMatcher getPathMatcher} method.
+     *
+     * @param   dir
+     *          The directory
+     * @param   glob
+     *          The globbing pattern
+     * @param   action
+     *          The {@code FileAction} to invoke for each entry
+     *
+     * @throws  NotDirectoryException
+     *          If the {@code dir} parameter is not a directory <i>(optional
+     *          specific exception)</i>
+     * @throws  IOException
+     *          If an I/O error occurs or the {@code invoke} method terminates
+     *          due to an uncaught {@code IOException}
+     * @throws  SecurityException
+     *          In the case of the default provider, the {@link
+     *          SecurityManager#checkRead(String) checkRead} method is invoked
+     *          to check read access to the directory.
+     */
+    public static void withDirectory(Path dir,
+                                     String glob,
+                                     FileAction<? super Path> action)
+        throws IOException
+    {
+        if (glob == null)
+            throw new NullPointerException("'glob' is null");
+        final PathMatcher matcher = dir.getFileSystem().getPathMatcher("glob:" + glob);
+        DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
+            @Override
+            public boolean accept(Path entry)  {
+                return matcher.matches(entry.getName());
+            }
+        };
+        withDirectory(dir, filter, action);
+    }
+
+    /**
+     * Invokes a {@link FileAction} for all entries in a directory.
+     *
+     * <p> This method works as if invoking it were equivalent to evaluating the
+     * expression:
+     * <blockquote><pre>
+     * withDirectory(dir, "*", action)
+     * </pre></blockquote>
+     *
+     * @param   dir
+     *          The directory
+     * @param   action
+     *          The {@code FileAction} to invoke for each entry
+     *
+     * @throws  NotDirectoryException
+     *          If the {@code dir} parameter is not a directory <i>(optional
+     *          specific exception)</i>
+     * @throws  IOException
+     *          If an I/O error occurs or the {@code invoke} method terminates
+     *          due to an uncaught {@code IOException}
+     * @throws  SecurityException
+     *          In the case of the default provider, the {@link
+     *          SecurityManager#checkRead(String) checkRead} method is invoked
+     *          to check read access to the directory.
+     */
+    public static void withDirectory(Path dir, FileAction<? super Path> action)
+        throws IOException
+    {
+        withDirectory(dir, "*", action);
+    }
+
+    /**
+     * Walks a file tree.
+     *
+     * <p> This method walks a file tree rooted at a given starting file. The
+     * file tree traversal is <em>depth-first</em> with the given {@link
+     * FileVisitor} invoked for each file encountered. File tree traversal
+     * completes when all accessible files in the tree have been visited, a
+     * visitor returns a result of {@link FileVisitResult#TERMINATE TERMINATE},
+     * or the visitor terminates due to an uncaught {@code Error} or {@code
+     * RuntimeException}.
+     *
+     * <p> For each file encountered this method attempts to gets 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,
+     * due to an I/O exception, then the {@link FileVisitor#visitFileFailed
+     * visitFileFailed} method is invoked with the I/O exception.
+     *
+     * <p> Where the file is a directory, this method attempts to open it by
+     * invoking its {@link Path#newDirectoryStream newDirectoryStream} method.
+     * Where the directory could not be opened, due to an {@code IOException},
+     * then the {@link FileVisitor#preVisitDirectoryFailed preVisitDirectoryFailed}
+     * method is invoked with the I/O exception, after which, the file tree walk
+     * continues, by default, at the next <em>sibling</em> of the directory.
+     *
+     * <p> Where the directory is opened successfully, then the entries in the
+     * directory, and their <em>descendants</em> are visited. When all entries
+     * have been visited, or an I/O error occurs during iteration of the
+     * directory, then the directory is closed and the visitor's {@link
+     * FileVisitor#postVisitDirectory postVisitDirectory} method is invoked.
+     * The file tree walk then continues, by default, at the next <em>sibling</em>
+     * of the directory.
+     *
+     * <p> By default, symbolic links are not automatically followed by this
+     * method. If the {@code options} parameter contains the {@link
+     * FileVisitOption#FOLLOW_LINKS FOLLOW_LINKS} option then symbolic links are
+     * followed. When following links, and the attributes of the target cannot
+     * be read, then this method attempts to get the {@code BasicFileAttributes}
+     * of the link. If they can be read then the {@code visitFile} method is
+     * invoked with the attributes of the link (otherwise the {@code visitFileFailed}
+     * method is invoked as specified above).
+     *
+     * <p> If the {@code options} parameter contains the {@link
+     * FileVisitOption#DETECT_CYCLES DETECT_CYCLES} or {@link
+     * FileVisitOption#FOLLOW_LINKS FOLLOW_LINKS} options then this method keeps
+     * track of directories visited so that cycles can be detected. A cycle
+     * 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 FileRef#isSameFile
+     * isSameFile} method to test if a directory is the same file as an
+     * ancestor. When a cycle is detected the {@link FileVisitor#visitFile
+     * visitFile} is invoked with the attributes of the directory. The {@link
+     * java.nio.file.attribute.BasicFileAttributes#isDirectory isDirectory}
+     * method may be used to test if the file is a directory and that a cycle is
+     * detected. The {@code preVisitDirectory} and {@code postVisitDirectory}
+     * methods are not invoked.
+     *
+     * <p> The {@code maxDepth} parameter is the maximum number of levels of
+     * directories to visit. A value of {@code 0} means that only the starting
+     * file is visited, unless denied by the security manager. A value of
+     * {@link Integer#MAX_VALUE MAX_VALUE} may be used to indicate that all
+     * levels should be visited.
+     *
+     * <p> If a visitor returns a result of {@code null} then {@code
+     * NullPointerException} is thrown.
+     *
+     * <p> When a security manager is installed and it denies access to a file
+     * (or directory), then it is ignored and the visitor is not invoked for
+     * that file (or directory).
+     *
+     * @param   start
+     *          The starting file
+     * @param   options
+     *          Options to configure the traversal
+     * @param   maxDepth
+     *          The maximum number of directory levels to visit
+     * @param   visitor
+     *          The file visitor to invoke for each file
+     *
+     * @throws  IllegalArgumentException
+     *          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.
+     */
+    public static void walkFileTree(Path start,
+                                    Set<FileVisitOption> options,
+                                    int maxDepth,
+                                    FileVisitor<? super Path> visitor)
+    {
+        if (maxDepth < 0)
+            throw new IllegalArgumentException("'maxDepth' is negative");
+        new FileTreeWalker(options, visitor).walk(start, maxDepth);
+    }
+
+    /**
+     * Walks a file tree.
+     *
+     * <p> This method works as if invoking it were equivalent to evaluating the
+     * expression:
+     * <blockquote><pre>
+     * walkFileTree(start, EnumSet.noneOf(FileVisitOption.class), Integer.MAX_VALUE, visitor)
+     * </pre></blockquote>
+     *
+     * @param   start
+     *          The starting file
+     * @param   visitor
+     *          The file visitor to invoke for each file
+     *
+     * @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.
+     */
+    public static void walkFileTree(Path start, FileVisitor<? super Path> visitor) {
+        walkFileTree(start,
+                     EnumSet.noneOf(FileVisitOption.class),
+                     Integer.MAX_VALUE,
+                     visitor);
+    }
+}
diff --git a/jdk/src/share/classes/java/nio/file/InvalidPathException.java b/jdk/src/share/classes/java/nio/file/InvalidPathException.java
new file mode 100644
index 0000000..37f2320
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/InvalidPathException.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Unchecked exception thrown when path string cannot be converted into a
+ * {@link Path} because the path string contains invalid characters, or
+ * the path string is invalid for other file system specific reasons.
+ */
+
+public class InvalidPathException
+    extends IllegalArgumentException
+{
+    static final long serialVersionUID = 4355821422286746137L;
+
+    private String input;
+    private int index;
+
+    /**
+     * Constructs an instance from the given input string, reason, and error
+     * index.
+     *
+     * @param  input   the input string
+     * @param  reason  a string explaining why the input was rejected
+     * @param  index   the index at which the error occurred,
+     *                 or <tt>-1</tt> if the index is not known
+     *
+     * @throws  NullPointerException
+     *          if either the input or reason strings are <tt>null</tt>
+     *
+     * @throws  IllegalArgumentException
+     *          if the error index is less than <tt>-1</tt>
+     */
+    public InvalidPathException(String input, String reason, int index) {
+        super(reason);
+        if ((input == null) || (reason == null))
+            throw new NullPointerException();
+        if (index < -1)
+            throw new IllegalArgumentException();
+        this.input = input;
+        this.index = index;
+    }
+
+    /**
+     * Constructs an instance from the given input string and reason.  The
+     * resulting object will have an error index of <tt>-1</tt>.
+     *
+     * @param  input   the input string
+     * @param  reason  a string explaining why the input was rejected
+     *
+     * @throws  NullPointerException
+     *          if either the input or reason strings are <tt>null</tt>
+     */
+    public InvalidPathException(String input, String reason) {
+        this(input, reason, -1);
+    }
+
+    /**
+     * Returns the input string.
+     *
+     * @return  the input string
+     */
+    public String getInput() {
+        return input;
+    }
+
+    /**
+     * Returns a string explaining why the input string was rejected.
+     *
+     * @return  the reason string
+     */
+    public String getReason() {
+        return super.getMessage();
+    }
+
+    /**
+     * Returns an index into the input string of the position at which the
+     * error occurred, or <tt>-1</tt> if this position is not known.
+     *
+     * @return  the error index
+     */
+    public int getIndex() {
+        return index;
+    }
+
+    /**
+     * Returns a string describing the error.  The resulting string
+     * consists of the reason string followed by a colon character
+     * (<tt>':'</tt>), a space, and the input string.  If the error index is
+     * defined then the string <tt>" at index "</tt> followed by the index, in
+     * decimal, is inserted after the reason string and before the colon
+     * character.
+     *
+     * @return  a string describing the error
+     */
+    public String getMessage() {
+        StringBuffer sb = new StringBuffer();
+        sb.append(getReason());
+        if (index > -1) {
+            sb.append(" at index ");
+            sb.append(index);
+        }
+        sb.append(": ");
+        sb.append(input);
+        return sb.toString();
+    }
+}
diff --git a/jdk/src/share/classes/java/nio/file/LinkOption.java b/jdk/src/share/classes/java/nio/file/LinkOption.java
new file mode 100644
index 0000000..08e5c1e
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/LinkOption.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Defines the options as to how symbolic links are handled.
+ *
+ * @since 1.7
+ */
+
+public enum LinkOption implements OpenOption, CopyOption {
+    /**
+     * Do not follow symbolic links.
+     *
+     * @see FileRef#getFileAttributeView(Class,LinkOption[])
+     * @see Path#copyTo
+     * @see SecureDirectoryStream#newByteChannel
+     */
+    NOFOLLOW_LINKS;
+}
diff --git a/jdk/src/share/classes/java/nio/file/LinkPermission.java b/jdk/src/share/classes/java/nio/file/LinkPermission.java
new file mode 100644
index 0000000..d17788f
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/LinkPermission.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+import java.security.BasicPermission;
+
+/**
+ * The {@code Permission} class for link creation operations.
+ *
+ * <p> The following table provides a summary description of what the permission
+ * allows, and discusses the risks of granting code the permission.
+ *
+ * <table border=1 cellpadding=5
+ *        summary="Table shows permission target name, what the permission allows, and associated risks">
+ * <tr>
+ * <th>Permission Target Name</th>
+ * <th>What the Permission Allows</th>
+ * <th>Risks of Allowing this Permission</th>
+ * </tr>
+ * <tr>
+ *   <td>hard</td>
+ *   <td> Ability to add an existing file to a directory. This is sometimes
+ *   known as creating a link, or hard link. </td>
+ *   <td> Extreme care should be taken when granting this permission. It allows
+ *   linking to any file or directory in the file system thus allowing the
+ *   attacker to access to all files. </td>
+ * </tr>
+ * <tr>
+ *   <td>symbolic</td>
+ *   <td> Ability to create symbolic links. </td>
+ *   <td> Extreme care should be taken when granting this permission. It allows
+ *   linking to any file or directory in the file system thus allowing the
+ *   attacker to access to all files. </td>
+ * </tr>
+ * </table>
+ *
+ * @since 1.7
+ *
+ * @see Path#createLink
+ * @see Path#createSymbolicLink
+ */
+public final class LinkPermission extends BasicPermission {
+    static final long serialVersionUID = -1441492453772213220L;
+
+    private void checkName(String name) {
+        if (!name.equals("hard") && !name.equals("symbolic")) {
+            throw new IllegalArgumentException("name: " + name);
+        }
+    }
+
+    /**
+     * Constructs a {@code LinkPermission} with the specified name.
+     *
+     * @param   name
+     *          the name of the permission. It must be "hard" or "symbolic".
+     *
+     * @throws  IllegalArgumentException
+     *          if name is empty or invalid
+     */
+    public LinkPermission(String name) {
+        super(name);
+        checkName(name);
+    }
+
+    /**
+     * Constructs a {@code LinkPermission} with the specified name.
+     *
+     * @param   name
+     *          the name of the permission; must be "hard" or "symbolic".
+     * @param   actions
+     *          the actions for the permission; must be the empty string or
+     *          {@code null}
+     *
+     * @throws  IllegalArgumentException
+     *          if name is empty or invalid
+     */
+    public LinkPermission(String name, String actions) {
+        super(name);
+        checkName(name);
+        if (actions != null && actions.length() > 0) {
+            throw new IllegalArgumentException("actions: " + actions);
+        }
+    }
+}
diff --git a/jdk/src/share/classes/java/nio/file/NoSuchFileException.java b/jdk/src/share/classes/java/nio/file/NoSuchFileException.java
new file mode 100644
index 0000000..ccde9ae
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/NoSuchFileException.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Checked exception thrown when an attempt is made to access a file that does
+ * not exist.
+ *
+ * @since 1.7
+ */
+
+public class NoSuchFileException
+    extends FileSystemException
+{
+    static final long serialVersionUID = -1390291775875351931L;
+
+    /**
+     * Constructs an instance of this class.
+     *
+     * @param   file
+     *          a string identifying the file or {@code null} if not known.
+     */
+    public NoSuchFileException(String file) {
+        super(file);
+    }
+
+    /**
+     * Constructs an instance of this class.
+     *
+     * @param   file
+     *          a string identifying the file or {@code null} if not known.
+     * @param   other
+     *          a string identifying the other file or {@code null} if not known.
+     * @param   reason
+     *          a reason message with additional information or {@code null}
+     */
+    public NoSuchFileException(String file, String other, String reason) {
+        super(file, other, reason);
+    }
+}
diff --git a/jdk/src/share/classes/java/nio/file/NotDirectoryException.java b/jdk/src/share/classes/java/nio/file/NotDirectoryException.java
new file mode 100644
index 0000000..684bd2d
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/NotDirectoryException.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Checked exception thrown when a file system operation, intended for a
+ * directory, fails because the file is not a directory.
+ *
+ * @since 1.7
+ */
+
+public class NotDirectoryException
+    extends FileSystemException
+{
+    private static final long serialVersionUID = -9011457427178200199L;
+
+    /**
+     * Constructs an instance of this class.
+     *
+     * @param   file
+     *          a string identifying the file or {@code null} if not known
+     */
+    public NotDirectoryException(String file) {
+        super(file);
+    }
+}
diff --git a/jdk/src/share/classes/java/nio/file/NotLinkException.java b/jdk/src/share/classes/java/nio/file/NotLinkException.java
new file mode 100644
index 0000000..bdc1fc3
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/NotLinkException.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Checked exception thrown when a file system operation fails because a file
+ * is not a link.
+ *
+ * @since 1.7
+ */
+
+public class NotLinkException
+    extends FileSystemException
+{
+    static final long serialVersionUID = -388655596416518021L;
+
+    /**
+     * Constructs an instance of this class.
+     *
+     * @param   file
+     *          a string identifying the file or {@code null} if not known
+     */
+    public NotLinkException(String file) {
+        super(file);
+    }
+
+    /**
+     * Constructs an instance of this class.
+     *
+     * @param   file
+     *          a string identifying the file or {@code null} if not known
+     * @param   other
+     *          a string identifying the other file or {@code null} if not known
+     * @param   reason
+     *          a reason message with additional information or {@code null}
+     */
+    public NotLinkException(String file, String other, String reason) {
+        super(file, other, reason);
+    }
+}
diff --git a/jdk/src/share/classes/java/nio/file/OpenOption.java b/jdk/src/share/classes/java/nio/file/OpenOption.java
new file mode 100644
index 0000000..c525307
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/OpenOption.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+/**
+ * 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
+ * FileRef#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.
+ *
+ * <p> The {@link StandardOpenOption} enumeration type defines the
+ * <i>standard</i> options.
+ *
+ * @since 1.7
+ */
+
+public interface OpenOption {
+}
diff --git a/jdk/src/share/classes/java/nio/file/Path.java b/jdk/src/share/classes/java/nio/file/Path.java
new file mode 100644
index 0000000..55bf8fd
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/Path.java
@@ -0,0 +1,1613 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+import java.nio.file.attribute.*;
+import java.nio.channels.*;
+import java.io.*;
+import java.net.URI;
+import java.util.*;
+
+/**
+ * A file reference that locates a file using a system dependent path. The file
+ * is not required to exist.
+ *
+ * <p> On many platforms a <em>path</em> is the means to locate and access files
+ * in a file system. A path is hierarchical and composed of a sequence of
+ * directory and file name elements separated by a special separator or
+ * delimiter.
+ *
+ * <h4>Path operations</h4>
+ *
+ * <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> In addition to accessing the components of a path, a {@code Path} also
+ * defines {@link #resolve(Path) resolve} and {@link #relativize relativize}
+ * operations. Paths can also be {@link #compareTo compared}, and tested
+ * against each other using using the {@link #startsWith startsWith} and {@link
+ * #endsWith endWith} methods.
+ *
+ * <h4>File operations</h4>
+ *
+ * <p> A {@code Path} is either <em>absolute</em> or <em>relative</em>. An
+ * absolute path is complete in that does not need to be combined with another
+ * path in order to locate a file. All operations on relative paths are first
+ * resolved against a file system's default directory as if by invoking the
+ * {@link #toAbsolutePath toAbsolutePath} method.
+ *
+ * <p> In addition to the operations defined by the {@link FileRef} interface,
+ * this class defines the following operations:
+ *
+ * <ul>
+ *   <li><p> Files may be {@link #createFile(FileAttribute[]) created}, or
+ *     directories may be {@link #createDirectory(FileAttribute[]) created}.
+ *     </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 link may be {@link #readSymbolicLink read}. </p></li>
+ *   <li><p> {@link #newInputStream InputStream} or {@link #newOutputStream
+ *     OutputStream} streams can be created to allow for interoperation with the
+ *     <a href="../../../java/io/package-summary.html">{@code java.io}</a> package
+ *     where required. </li></p>
+ *   <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>
+ *
+ * The <a href="attribute/package-summary.html">{@code java.nio.file.attribute}</a>
+ * package provides 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:
+ * <pre>
+ *     Path file = ...
+ *     BasicFileAttributes attrs = Attributes.readBasicFileAttributes(file);
+ * </pre>
+ *
+ * <a name="interop"><h4>Interoperability</h4></a>
+ *
+ * <p> Paths created by file systems 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.
+ *
+ * <h4>Concurrency</h4></a>
+ *
+ * <p> Instances of this class are immutable and safe for use by multiple concurrent
+ * threads.
+ *
+ * @since 1.7
+ */
+
+public abstract class Path
+    implements FileRef, 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();
+
+    /**
+     * 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.
+     *
+     * @return  {@code true} if, and only if, this path is absolute
+     */
+    public abstract boolean isAbsolute();
+
+    /**
+     * Returns the root component of this path as a {@code Path} object,
+     * or {@code null} if this path does not have a root component.
+     *
+     * @return  a path representing the root component of this path,
+     *          or {@code null}
+     */
+    public abstract 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.
+     *
+     * @return  a path representing the name of the file or directory, or
+     *          {@code null} if this path has zero elements
+     */
+    public abstract Path getName();
+
+    /**
+     * Returns the <em>parent path</em>, or {@code null} if this path does not
+     * have a parent.
+     *
+     * <p> The parent of this path object consists of this path's root
+     * component, if any, and each element in the path except for the
+     * <em>farthest</em> from the root in the directory hierarchy. This method
+     * does not access the file system; the path or its parent may not exist.
+     * Furthermore, this method does not eliminate special names such as "."
+     * and ".." that may be used in some implementations. On UNIX for example,
+     * the parent of "{@code /a/b/c}" is "{@code /a/b}", and the parent of
+     * {@code "x/y/.}" is "{@code x/y}". This method may be used with the {@link
+     * #normalize normalize} method, to eliminate redundant names, for cases where
+     * <em>shell-like</em> navigation is required.
+     *
+     * <p> If this path has one or more elements, and no root component, then
+     * this method is equivalent to evaluating the expression:
+     * <blockquote><pre>
+     * subpath(0,&nbsp;getNameCount()-1);
+     * </pre></blockquote>
+     *
+     * @return  a path representing the path's parent
+     */
+    public abstract Path getParent();
+
+    /**
+     * Returns the number of name elements in the path.
+     *
+     * @return  the number of elements in the path, or {@code 0} if this path
+     *          only represents a root component
+     */
+    public abstract int getNameCount();
+
+   /**
+     * Returns a name element of this path.
+     *
+     * <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
+     * has index {@code 0}. The element that is <em>farthest</em> from the root
+     * has index {@link #getNameCount count}{@code -1}.
+     *
+     * @param   index
+     *          the index of the element
+     *
+     * @return  the name element
+     *
+     * @throws  IllegalArgumentException
+     *          if {@code index} is negative, {@code index} is greater than or
+     *          equal to the number of elements, or this path has zero name
+     *          elements
+     */
+    public abstract Path getName(int index);
+
+    /**
+     * Returns a relative {@code Path} that is a subsequence of the name
+     * elements of this path.
+     *
+     * <p> The {@code beginIndex} and {@code endIndex} parameters specify the
+     * subsequence of name elements. The name that is <em>closest</em> to the root
+     * in the directory hierarchy has index {@code 0}. The name that is
+     * <em>farthest</em> from the root has index {@link #getNameCount
+     * count}{@code -1}. The returned {@code Path} object has the name elements
+     * that begin at {@code beginIndex} and extend to the element at index {@code
+     * endIndex-1}.
+     *
+     * @param   beginIndex
+     *          the index of the first element, inclusive
+     * @param   endIndex
+     *          the index of the last element, exclusive
+     *
+     * @return  a new {@code Path} object that is a subsequence of the name
+     *          elements in this {@code Path}
+     *
+     * @throws  IllegalArgumentException
+     *          if {@code beginIndex} is negative, or greater than or equal to
+     *          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);
+
+    /**
+     * Tests if this path starts with the given path.
+     *
+     * <p> This path <em>starts</em> with the given path if this path's root
+     * component <em>starts</em> with the root component of the given path,
+     * and this path starts with the same name elements as the given path.
+     * If the given path has more name elements than this path then {@code false}
+     * is returned.
+     *
+     * <p> Whether or not the root component of this path starts with the root
+     * component of the given path is file system specific. If this path does
+     * not have a root component and the given path has a root component then
+     * this path does not start with the given path.
+     *
+     * @param   other
+     *          the given path
+     *
+     * @return  {@code true} if this path starts with the given path; otherwise
+     *          {@code false}
+     */
+    public abstract boolean startsWith(Path other);
+
+    /**
+     * Tests if this path ends with the given path.
+     *
+     * <p> If the given path has <em>N</em> elements, and no root component,
+     * and this path has <em>N</em> or more elements, then this path ends with
+     * the given path if the last <em>N</em> elements of each path, starting at
+     * the element farthest from the root, are equal.
+     *
+     * <p> If the given path has a root component then this path ends with the
+     * given path if the root component of this path <em>ends with</em> the root
+     * component of the given path, and the corresponding elements of both paths
+     * are equal. Whether or not the root component of this path ends with the
+     * root component of the given path is file system specific. If this path
+     * does not have a root component and the given path has a root component
+     * then this path does not end with the given path.
+     *
+     * @param   other
+     *          the given path
+     *
+     * @return  {@code true} if this path ends with the given path; otherwise
+     *          {@code false}
+     */
+    public abstract boolean endsWith(Path other);
+
+    /**
+     * Returns a path that is this path with redundant name elements eliminated.
+     *
+     * <p> The precise definition of this method is implementation dependent but
+     * in general it derives from this path, a path that does not contain
+     * <em>redundant</em> name elements. In many file systems, the "{@code .}"
+     * and "{@code ..}" are special names used to indicate the current directory
+     * and parent directory. In such file systems all occurrences of "{@code .}"
+     * are considered redundant. If a "{@code ..}" is preceded by a
+     * non-"{@code ..}" name then both names are considered redundant (the
+     * process to identify such names is repeated until is it no longer
+     * applicable).
+     *
+     * <p> This method does not access the file system; the path may not locate
+     * a file that exists. Eliminating "{@code ..}" and a preceding name from a
+     * 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
+     *
+     * @see #getParent
+     * @see #toRealPath
+     */
+    public abstract Path normalize();
+
+    // -- resolution and relativization --
+
+    /**
+     * Resolve the given path against this path.
+     *
+     * <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.
+     *
+     * @param   other
+     *          the path to resolve against this path; can be {@code null}
+     *
+     * @return  the resulting path
+     *
+     * @see #relativize
+     */
+    public abstract 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.
+     *
+     * @param   other
+     *          the path string to resolve against this path
+     *
+     * @return  the resulting path
+     *
+     * @throws  InvalidPathException
+     *          If the path string cannot be converted to a Path.
+     *
+     * @see FileSystem#getPath
+     */
+    public abstract Path resolve(String other);
+
+    /**
+     * Constructs a relative path between this path and a given path.
+     *
+     * <p> Relativization is the inverse of {@link #resolve(Path) resolution}.
+     * This method attempts to construct a {@link #isAbsolute relative} path
+     * that when {@link #resolve(Path) resolved} against this path, yields a
+     * path that locates the same file as the given path. For example, on UNIX,
+     * if this path is {@code "/a/b"} and the given path is {@code "/a/b/c/d"}
+     * then the resulting relative path would be {@code "c/d"}. Where this
+     * path and the given path do not have a {@link #getRoot root} component,
+     * then a relative path can be constructed. A relative path cannot be
+     * 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.
+     *
+     * <p> For any two 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
+     * 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
+     * dependent if {@code "a/b/../x"} would locate the same file as {@code "/a/x"}.
+     *
+     * @param   other
+     *          the resulting path
+     *
+     * @return  the resulting relative path, or {@code null} 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> The {@code failIfNotExists} parameter determines how the method
+     * behaves when the file does not exist. When {@code true}, and the file
+     * does not exist, then the method fails. When {@code false} then the method
+     * does not fail.
+     *
+     * <p> As with the {@link FileRef#delete delete()} method, 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 link is
+     * deleted and not the final target of the link.
+     *
+     * <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   failIfNotExists
+     *          {@code true} if the method should fail when the file does not
+     *          exist
+     *
+     * @throws  NoSuchFileException
+     *          if the value of the {@code failIfNotExists} is {@code true} and
+     *          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(boolean failIfNotExists) 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 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 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 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.
+     *
+     * @see BasicFileAttributes#linkCount
+     */
+    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 read the target of the link, failing
+     * if the file is not a 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 link <i>(optional specific exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the 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;
+
+    /**
+     * Returns a URI to represent this path.
+     *
+     * <p> This method constructs a hierarchical {@link URI} that is absolute
+     * with a non-empty path component. Its {@link URI#getScheme() scheme} is
+     * equal to the URI scheme that identifies the provider. The exact form of
+     * the other URI components is highly provider dependent. In particular, it
+     * is implementation dependent if its query, fragment, and authority
+     * components are defined or undefined.
+     *
+     * <p> For the default provider the {@link URI#getPath() path} component
+     * will represent the {@link #toAbsolutePath absolute} path; the query,
+     * fragment components are undefined. Whether the authority component is
+     * defined or not is implementation dependent. There is no guarantee that
+     * the {@code URI} may be used to construct a {@link java.io.File java.io.File}.
+     * In particular, if this path represents a Universal Naming Convention (UNC)
+     * path, then the UNC server name may be encoded in the authority component
+     * of the resulting URI. In the case of the default provider, and the file
+     * exists, and it can be determined that the file is a directory, then the
+     * resulting {@code URI} will end with a slash.
+     *
+     * <p> The default provider provides a similar <em>round-trip</em> guarantee
+     * to the {@link java.io.File} class. For a given {@code Path} <i>p</i> it
+     * is guaranteed that
+     * <blockquote><tt>
+     * {@link Paths#get(URI) Paths.get}(</tt><i>p</i><tt>.toUri()).equals(</tt><i>p</i>
+     * <tt>.{@link #toAbsolutePath() toAbsolutePath}())</tt>
+     * </blockquote>
+     * so long as the original {@code Path}, the {@code URI}, and the new {@code
+     * Path} are all created in (possibly different invocations of) the same
+     * Java virtual machine. Whether other providers make any guarantees is
+     * provider specific and therefore unspecified.
+     *
+     * <p> When a file system is constructed to access the contents of a file
+     * as a file system then it is highly implementation specific if the returned
+     * URI represents the given path in the file system or it represents a
+     * <em>compound</em> URI that encodes the URI of the enclosing file system.
+     * A format for compound URIs is not defined in this release; such a scheme
+     * may be added in a future release.
+     *
+     * @return  an absolute, hierarchical URI with a non-empty path component
+     *
+     * @throws  IOError
+     *          if an I/O error occurs obtaining the absolute path, or where a
+     *          file system is constructed to access the contents of a file as
+     *          a file system, and the URI of the enclosing file system cannot be
+     *          obtained
+     *
+     * @throws  SecurityException
+     *          In the case of the the default provider, and a security manager
+     *          is installed, the {@link #toAbsolutePath toAbsolutePath} method
+     *          throws a security exception.
+     */
+    public abstract URI toUri();
+
+    /**
+     * Returns a {@code Path} object representing the absolute path of this
+     * path.
+     *
+     * <p> If this path is already {@link Path#isAbsolute absolute} then this
+     * method simply returns this path. Otherwise, this method resolves the path
+     * in an implementation dependent manner, typically by resolving the path
+     * against a file system default directory. Depending on the implementation,
+     * this method may throw an I/O error if the file system is not accessible.
+     *
+     * @return  a {@code Path} object representing the absolute path
+     *
+     * @throws  IOError
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the the default provider, and a security manager
+     *          is installed, its {@link SecurityManager#checkPropertyAccess(String)
+     *          checkPropertyAccess} method is invoked to check access to the
+     *          system property {@code user.dir}
+     */
+    public abstract 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
+     * 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
+     * actual case. Additionally, the resulting path has redundant name
+     * elements removed.
+     *
+     * <p> If this path is relative then its absolute path is first obtained,
+     * as if by invoking the {@link #toAbsolutePath toAbsolutePath} method.
+     *
+     * <p> The {@code resolveLinks} parameter specifies if symbolic links
+     * should be resolved. This parameter is ignored when symbolic links are
+     * not supported. Where supported, and the parameter has the value {@code
+     * true} then symbolic links are resolved to their final target. Where the
+     * parameter has the value {@code false} then this method does not resolve
+     * symbolic links. Some implementations allow special names such as
+     * "{@code ..}" to refer to the parent directory. When deriving the <em>real
+     * path</em>, and a "{@code ..}" (or equivalent) is preceded by a
+     * non-"{@code ..}" name then an implementation will typically causes both
+     * names to be removed. When not resolving symbolic links and the preceding
+     * name is a symbolic link then the names are only removed if it guaranteed
+     * that the resulting path will locate the same file as this path.
+     *
+     * @return  an absolute path represent the <em>real</em> path of the file
+     *          located by this object
+     *
+     * @throws  IOException
+     *          if the file does not exist or an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the the default provider, and a security manager
+     *          is installed, its {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the file, and where
+     *          this path is not absolute, its {@link SecurityManager#checkPropertyAccess(String)
+     *          checkPropertyAccess} method is invoked to check access to the
+     *          system property {@code user.dir}
+     */
+    public abstract Path toRealPath(boolean resolveLinks) throws IOException;
+
+    /**
+     * Copy the file located by this path to a target location.
+     *
+     * <p> This method copies the file located by this {@code Path} to the
+     * target location with the {@code options} parameter specifying how the
+     * copy is performed. By default, the copy fails if the target file already
+     * exists, except if the source and target are the {@link #isSameFile same}
+     * file, in which case this method has no effect. File attributes are not
+     * required to be copied to the target file. If symbolic links are supported,
+     * and the file is a link, then the final target of the link is copied. If
+     * the file is a directory then it creates an empty directory in the target
+     * location (entries in the directory are not copied). This method can be
+     * used with the {@link Files#walkFileTree Files.walkFileTree} utility
+     * method to copy a directory and all entries in the directory, or an entire
+     * <i>file-tree</i> where required.
+     *
+     * <p> The {@code options} parameter is an array of options and may contain
+     * any of the following:
+     *
+     * <table border=1 cellpadding=5 summary="">
+     * <tr> <th>Option</th> <th>Description</th> </tr>
+     * <tr>
+     *   <td> {@link StandardCopyOption#REPLACE_EXISTING REPLACE_EXISTING} </td>
+     *   <td> If the target file exists, then the target file is replaced if it
+     *     is not a non-empty directory. If the target file exists and is a
+     *     symbolic-link then the symbolic-link is replaced (not the target of
+     *     the link. </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. </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 link is copied rather than the target of
+     *     the link. 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 link. </td>
+     * </tr>
+     * </table>
+     *
+     * <p> An implementation of this interface may support additional
+     * implementation specific options.
+     *
+     * <p> Copying a file is not an atomic operation. If an {@link IOException}
+     * is thrown then it possible that the target file is incomplete or some of
+     * its file attributes have not been copied from the source file. When the
+     * {@code REPLACE_EXISTING} option is specified and the target file exists,
+     * then the target file is replaced. The check for the existence of the file
+     * and the creation of the new file may not be atomic with respect to other
+     * file system activities.
+     *
+     * @param   target
+     *          the target location
+     * @param   options
+     *          options specifying how the copy should be done
+     *
+     * @return  the target
+     *
+     * @throws  UnsupportedOperationException
+     *          if the array contains a copy option that is not supported
+     * @throws  FileAlreadyExistsException
+     *          if the target file exists and cannot be replaced because the
+     *          {@code REPLACE_EXISTING} option is not specified, or the target
+     *          file is a non-empty directory <i>(optional specific exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the source file, the
+     *          {@link SecurityManager#checkWrite(String) checkWrite} is invoked
+     *          to check write access to the target file. If a symbolic link is
+     *          copied the security manager is invoked to check {@link
+     *          LinkPermission}{@code ("symbolic")}.
+     */
+    public abstract Path copyTo(Path target, CopyOption... options)
+        throws IOException;
+
+    /**
+     * Move or rename the file located by this path to a target location.
+     *
+     * <p> By default, this method attempts to move the file to the target
+     * location, failing if the target file exists except if the source and
+     * target are the {@link #isSameFile same} file, in which case this method
+     * has no effect. If the file is a symbolic link then the link is moved and
+     * not the target of the link. 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 is replaced and not the target of
+     *     the link. </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. The {@link Files#withDirectory Files.withDirectory} utility
+     * method is useful for cases where a task is performed on each accepted
+     * entry in a directory. This method closes the directory when iteration is
+     * complete (or an error occurs).
+     *
+     * <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  UnsupportedOperationException
+     *          if the pattern syntax is not known to the implementation
+     * @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}. The {@link DirectoryStreamFilters}
+     * class defines factory methods that create useful filters.
+     *
+     * <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. The {@link Files#withDirectory Files.withDirectory} utility
+     * method is useful for cases where a task is performed on each accepted
+     * entry in a directory. This method closes the directory when iteration is
+     * complete (or an error occurs).
+     *
+     * <p> Where the filter terminates due to an uncaught error or runtime
+     * exception then it propogated to the caller of the iterator's {@link
+     * Iterator#hasNext() hasNext} or {@link Iterator#next() next} methods.
+     *
+     * <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) {
+     *             try {
+     *                 long size = Attributes.readBasicFileAttributes(file).size();
+     *                 return (size > 8192L);
+     *             } catch (IOException e) {
+     *                 // failed to get size
+     *                 return false;
+     *             }
+     *         }
+     *     };
+     *     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.
+     */
+    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 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 extends the options defined by the {@code FileRef}
+     * interface and to the options specified by the {@link
+     * #newByteChannel(Set,FileAttribute[]) newByteChannel} method
+     * except that the options are specified by an array. In the case of the
+     * default provider, the returned seekable byte channel is a {@link
+     * FileChannel}.
+     *
+     * @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                 {@inheritDoc}
+     * @throws  SecurityException           {@inheritDoc}
+     */
+    @Override
+    public abstract SeekableByteChannel newByteChannel(OpenOption... options)
+        throws IOException;
+
+    /**
+     * Opens the file located by this path for reading, returning an input
+     * stream to read bytes 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.
+     *
+     * @return  an input stream to read bytes from the 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 the file.
+     */
+    public abstract InputStream newInputStream() throws IOException;
+
+    /**
+     * Opens or creates the file located by this path 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. If no open options are present
+     * then this method creates a new file for writing or truncates an existing
+     * file.
+     *
+     * <p> The resulting stream will not be buffered. The stream will be safe
+     * for access by multiple concurrent threads.
+     *
+     * <p> <b>Usage Example:</b>
+     * Suppose we wish to open a log file for writing so that we append to the
+     * file if it already exists, or create it when it doesn't exist.
+     * <pre>
+     *     Path logfile = ...
+     *     OutputStream out = new BufferedOutputStream(logfile.newOutputStream(CREATE, APPEND));
+     * </pre>
+     *
+     * @param   options
+     *          options specifying how the file is opened
+     *
+     * @return  a new seekable byte channel
+     *
+     * @throws  IllegalArgumentException
+     *          if {@code options} contains an invalid combination of options
+     * @throws  UnsupportedOperationException
+     *          if an unsupported open 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.
+     */
+    public abstract OutputStream newOutputStream(OpenOption... options)
+        throws IOException;
+
+    /**
+     * Opens or creates the file located by this path 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 {@code options} parameter may not contain the {@link
+     * StandardOpenOption#READ READ} option. If no open options are present
+     * then this method creates a new file for writing or truncates an existing
+     * file.
+     *
+     * <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
+     * @param   attrs
+     *          an optional list of file attributes to set atomically when
+     *          creating the file
+     *
+     * @return  a new output stream
+     *
+     * @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  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.
+     */
+    public abstract OutputStream newOutputStream(Set<? extends OpenOption> options,
+                                                 FileAttribute<?>... attrs)
+        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;
+
+    /**
+     * 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();
+
+    // -- watchable --
+
+    /**
+     * Registers the file located by this path with a watch service.
+     *
+     * <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:
+     * <ul>
+     *   <li>{@link StandardWatchEventKind#ENTRY_CREATE ENTRY_CREATE} -
+     *       entry created or moved into the directory</li>
+     *   <li>{@link StandardWatchEventKind#ENTRY_DELETE ENTRY_DELETE} -
+     *        entry deleted or moved out of the directory</li>
+     *   <li>{@link StandardWatchEventKind#ENTRY_MODIFY ENTRY_MODIFY} -
+     *        entry in directory was modified</li>
+     * </ul>
+     *
+     * <p> The {@link WatchEvent#context context} for these events is the
+     * relative path between the directory located by this path, and the path
+     * that locates the directory entry that is created, deleted, or modified.
+     *
+     * <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> 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
+     * on the existence of the link after it is registered.
+     *
+     * @param   watcher
+     *          the watch service to which this object is to be registered
+     * @param   events
+     *          the events for which this object should be registered
+     * @param   modifiers
+     *          the modifiers, if any, that modify how the object is registered
+     *
+     * @return  a key representing the registration of this object with the
+     *          given watch service
+     *
+     * @throws  UnsupportedOperationException
+     *          if unsupported events or modifiers are specified
+     * @throws  IllegalArgumentException
+     *          if an invalid combination of events or modifiers is specified
+     * @throws  ClosedWatchServiceException
+     *          if the watch service is closed
+     * @throws  NotDirectoryException
+     *          if the file is registered to watch the entries in a directory
+     *          and the file 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 file.
+     */
+    @Override
+    public abstract WatchKey register(WatchService watcher,
+                                      WatchEvent.Kind<?>[] events,
+                                      WatchEvent.Modifier... modifiers)
+        throws IOException;
+
+    /**
+     * Registers the file located by this path with a watch service.
+     *
+     * <p> An invocation of this method behaves in exactly the same way as the
+     * invocation
+     * <pre>
+     *     watchable.{@link #register(WatchService,WatchEvent.Kind[],WatchEvent.Modifier[]) register}(watcher, events, new WatchEvent.Modifier[0]);
+     * </pre>
+     *
+     * <p> <b>Usage Example:</b>
+     * Suppose we wish to register a directory for entry create, delete, and modify
+     * events:
+     * <pre>
+     *     Path dir = ...
+     *     WatchService watcher = ...
+     *
+     *     WatchKey key = dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
+     * </pre>
+     * @param   watcher
+     *          The watch service to which this object is to be registered
+     * @param   events
+     *          The events for which this object should be registered
+     *
+     * @return  A key representing the registration of this object with the
+     *          given watch service
+     *
+     * @throws  UnsupportedOperationException
+     *          If unsupported events are specified
+     * @throws  IllegalArgumentException
+     *          If an invalid combination of events is specified
+     * @throws  ClosedWatchServiceException
+     *          If the watch service is closed
+     * @throws  NotDirectoryException
+     *          If the file is registered to watch the entries in a directory
+     *          and the file 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 file.
+     */
+    @Override
+    public abstract WatchKey register(WatchService watcher,
+                                      WatchEvent.Kind<?>... events)
+        throws IOException;
+
+    // -- Iterable --
+
+    /**
+     * Returns an iterator over the name elements of this path.
+     *
+     * <p> The first element returned by the iterator represents the name
+     * element that is closest to the root in the directory hierarchy, the
+     * second element is the next closest, and so on. The last element returned
+     * is the name of the file or directory denoted by this path. The {@link
+     * #getRoot root} component, if present, is not returned by the iterator.
+     *
+     * @return  an iterator over the name elements of this path.
+     */
+    @Override
+    public abstract Iterator<Path> iterator();
+
+    // -- compareTo/equals/hashCode --
+
+    /**
+     * Compares two abstract paths lexicographically. The ordering defined by
+     * this method is provider specific, and in the case of the default
+     * provider, platform specific. This method does not access the file system
+     * and neither file is required to exist.
+     *
+     * @param   other  the path compared to this path.
+     *
+     * @return  zero if the argument is {@link #equals equal} to this path, a
+     *          value less than zero if this path is lexicographically less than
+     *          the argument, or a value greater than zero if this path is
+     *          lexicographically greater than the argument
+     */
+    @Override
+    public abstract int compareTo(Path other);
+
+    /**
+     * Tests this path for equality with the given object.
+     *
+     * <p> If the given object is not a Path, or is a Path associated with a
+     * different provider, then this method immediately returns {@code false}.
+     *
+     * <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.
+     *
+     * <p> This method satisfies the general contract of the {@link
+     * java.lang.Object#equals(Object) Object.equals} method. </p>
+     *
+     * @param   other
+     *          the object to which this object is to be compared
+     *
+     * @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);
+
+    /**
+     * Computes a hash code for this path.
+     *
+     * <p> The hash code is based upon the components of the path, and
+     * satisfies the general contract of the {@link Object#hashCode
+     * Object.hashCode} method.
+     *
+     * @return  the hash-code value for this path
+     */
+    @Override
+    public abstract int hashCode();
+
+    /**
+     * Returns the string representation of this path.
+     *
+     * <p> If this path was created by converting a path string using the
+     * {@link FileSystem#getPath getPath} method then the path string returned
+     * by this method may differ from the original String used to create the path.
+     *
+     * <p> The returned path string uses the default name {@link
+     * FileSystem#getSeparator separator} to separate names in the path.
+     *
+     * @return  the string representation of this path
+     */
+    @Override
+    public abstract String toString();
+}
diff --git a/jdk/src/share/classes/java/nio/file/PathMatcher.java b/jdk/src/share/classes/java/nio/file/PathMatcher.java
new file mode 100644
index 0000000..5a1cfee
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/PathMatcher.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+/**
+ * An interface that is implemented by objects that perform match operations on
+ * paths.
+ *
+ * @since 1.7
+ *
+ * @see FileSystem#getPathMatcher
+ * @see Path#newDirectoryStream(String)
+ */
+
+public interface PathMatcher {
+    /**
+     * Tells if given path matches this matcher's pattern.
+     *
+     * @param   path
+     *          the path to match
+     *
+     * @return  {@code true} if, and only if, the path matches this
+     *          matcher's pattern
+     */
+    boolean matches(Path path);
+}
diff --git a/jdk/src/share/classes/java/nio/file/Paths.java b/jdk/src/share/classes/java/nio/file/Paths.java
new file mode 100644
index 0000000..2cd7a09
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/Paths.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+import java.nio.file.spi.FileSystemProvider;
+import java.net.URI;
+
+/**
+ * This class consists exclusively of static methods that return a {@link Path}
+ * by converting a path string or {@link URI}.
+ *
+ * @since 1.7
+ */
+
+public class Paths {
+    private Paths() { }
+
+    /**
+     * Constructs a {@code Path} by converting the given path string.
+     *
+     * <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
+     * 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:
+     * <pre>
+     *     Path dir = ...
+     *     Path path = dir.resolve("file");
+     * </pre>
+     *
+     * @param   path
+     *          the path string to convert
+     *
+     * @return  the resulting {@code Path}
+     *
+     * @throws  InvalidPathException
+     *          if the path string cannot be converted to a {@code Path}
+     *
+     * @see FileSystem#getPath
+     */
+    public static Path get(String path) {
+        return FileSystems.getDefault().getPath(path);
+    }
+
+    /**
+     * Converts the given URI to a {@link Path} object.
+     *
+     * <p> This method iterates over the {@link FileSystemProvider#installedProviders()
+     * installed} providers to locate the provider that is identified by the
+     * URI {@link URI#getScheme scheme} of the given URI. URI schemes are
+     * compared without regard to case. If the provider is found then its {@link
+     * FileSystemProvider#getPath getPath} method is invoked to convert the
+     * URI.
+     *
+     * <p> In the case of the default provider, identified by the URI scheme
+     * "file", the given URI has a non-empty path component, and undefined query
+     * and fragment components. Whether the authority component may be present
+     * is platform specific. The returned {@code Path} is associated with the
+     * {@link FileSystems#getDefault default} file system.
+     *
+     * <p> The default provider provides a similar <em>round-trip</em> guarantee
+     * to the {@link java.io.File} class. For a given {@code Path} <i>p</i> it
+     * is guaranteed that
+     * <blockquote><tt>
+     * Paths.get(</tt><i>p</i><tt>.{@link Path#toUri() toUri}()).equals(</tt>
+     * <i>p</i><tt>.{@link Path#toAbsolutePath() toAbsolutePath}())</tt>
+     * </blockquote>
+     * so long as the original {@code Path}, the {@code URI}, and the new {@code
+     * Path} are all created in (possibly different invocations of) the same
+     * Java virtual machine. Whether other providers make any guarantees is
+     * provider specific and therefore unspecified.
+     *
+     * @param   uri
+     *          the URI to convert
+     *
+     * @return  the resulting {@code Path}
+     *
+     * @throws  IllegalArgumentException
+     *          if preconditions on the {@code uri} parameter do not hold. The
+     *          format of the URI is provider specific.
+     * @throws  FileSystemNotFoundException
+     *          if the file system identified by the URI does not exist or the
+     *          provider identified by the URI's scheme component is not installed
+     * @throws  SecurityException
+     *          if a security manager is installed and it denies an unspecified
+     *          permission to access the file system
+     */
+    public static Path get(URI uri) {
+        String scheme =  uri.getScheme();
+        if (scheme == null)
+            throw new IllegalArgumentException("Missing scheme");
+
+        // check for default provider to avoid loading of installed providers
+        if (scheme.equalsIgnoreCase("file"))
+            return FileSystems.getDefault().provider().getPath(uri);
+
+        // try to find provider
+        for (FileSystemProvider provider: FileSystemProvider.installedProviders()) {
+            if (provider.getScheme().equalsIgnoreCase(scheme)) {
+                return provider.getPath(uri);
+            }
+        }
+
+        throw new FileSystemNotFoundException("Provider \"" + scheme + "\" not installed");
+    }
+}
diff --git a/jdk/src/share/classes/java/nio/file/ProviderMismatchException.java b/jdk/src/share/classes/java/nio/file/ProviderMismatchException.java
new file mode 100644
index 0000000..7c1bbc0
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/ProviderMismatchException.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Unchecked exception thrown when an attempt is made to invoke a method on an
+ * object created by one file system provider with a parameter created by a
+ * different file system provider.
+ */
+public class ProviderMismatchException
+    extends java.lang.IllegalArgumentException
+{
+    static final long serialVersionUID = 4990847485741612530L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public ProviderMismatchException() {
+    }
+
+    /**
+     * Constructs an instance of this class.
+     *
+     * @param   msg
+     *          the detail message
+     */
+    public ProviderMismatchException(String msg) {
+        super(msg);
+    }
+}
diff --git a/jdk/src/share/classes/java/nio/file/ProviderNotFoundException.java b/jdk/src/share/classes/java/nio/file/ProviderNotFoundException.java
new file mode 100644
index 0000000..dd1fee8
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/ProviderNotFoundException.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Runtime exception thrown when a provider of the required type cannot be found.
+ */
+
+public class ProviderNotFoundException
+    extends RuntimeException
+{
+    static final long serialVersionUID = -1880012509822920354L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public ProviderNotFoundException() {
+    }
+
+    /**
+     * Constructs an instance of this class.
+     *
+     * @param   msg
+     *          the detail message
+     */
+    public ProviderNotFoundException(String msg) {
+        super(msg);
+    }
+}
diff --git a/jdk/src/share/classes/java/nio/file/ReadOnlyFileSystemException.java b/jdk/src/share/classes/java/nio/file/ReadOnlyFileSystemException.java
new file mode 100644
index 0000000..4e92efb
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/ReadOnlyFileSystemException.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Unchecked exception thrown when an attempt is made to update an object
+ * associated with a {@link FileSystem#isReadOnly() read-only} {@code FileSystem}.
+ */
+
+public class ReadOnlyFileSystemException
+    extends UnsupportedOperationException
+{
+    static final long serialVersionUID = -6822409595617487197L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public ReadOnlyFileSystemException() {
+    }
+}
diff --git a/jdk/src/share/classes/java/nio/file/SecureDirectoryStream.java b/jdk/src/share/classes/java/nio/file/SecureDirectoryStream.java
new file mode 100644
index 0000000..11df095
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/SecureDirectoryStream.java
@@ -0,0 +1,324 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classname" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package java.nio.file;
+
+import java.nio.file.attribute.*;
+import java.nio.channels.SeekableByteChannel;
+import java.util.Set;
+import java.io.IOException;
+
+/**
+ * A {@code DirectoryStream} that defines operations on files that are located
+ * relative to an open directory. A {@code SecureDirectoryStream} is intended
+ * for use by sophisticated or security sensitive applications requiring to
+ * traverse file trees or otherwise operate on directories in a race-free manner.
+ * Race conditions can arise when a sequence of file operations cannot be
+ * carried out in isolation. Each of the file operations defined by this
+ * interface specify a relative {@link Path}. All access to the file is relative
+ * to the open directory irrespective of if the directory is moved or replaced
+ * by an attacker while the directory is open. A {@code SecureDirectoryStream}
+ * may also be used as a virtual <em>working directory</em>.
+ *
+ * <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
+ * newDirectoryStream} method will be a {@code SecureDirectoryStream} and must
+ * be cast to that type in order to invoke the methods defined by this interface.
+ *
+ * <p> As specified by {@code DirectoryStream}, the iterator's {@link
+ * java.util.Iterator#remove() remove} method removes the directory entry for
+ * the last element returned by the iterator. In the case of a {@code
+ * SecureDirectoryStream} the {@code remove} method behaves as if by invoking
+ * the {@link #deleteFile deleteFile} or {@link #deleteDirectory deleteDirectory}
+ * methods defined by this interface. The {@code remove} may require to examine
+ * the file to determine if the file is a directory, and consequently, it may
+ * not be atomic with respect to other file system operations.
+ *
+ * <p> In the case of the default {@link java.nio.file.spi.FileSystemProvider
+ * provider}, and a security manager is set, then the permission checks are
+ * performed using the path obtained by resolving the given relative path
+ * against the <i>original path</i> of the directory (irrespective of if the
+ * directory is moved since it was opened).
+ *
+ * @since   1.7
+ */
+
+public abstract class SecureDirectoryStream
+    implements DirectoryStream<Path>
+{
+    /**
+     * 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
+     * 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 {@code followLinks} parameter
+     * determines if links should be followed. If this parameter is {@code
+     * false} and the file is a symbolic link then this method fails (by
+     * throwing an I/O exception).
+     *
+     * <p> The new directory stream, once created, is not dependent upon the
+     * directory stream used to create it. Closing this directory stream has no
+     * effect upon newly created directory stream.
+     *
+     * @param   path
+     *          the path to the directory to open
+     * @param   followLinks
+     *          {@code true} if the links should be followed
+     * @param   filter
+     *          the directory stream filter or {@code null}.
+     *
+     * @return  a new and open {@code SecureDirectoryStream} object
+     *
+     * @throws  ClosedDirectoryStreamException
+     *          if the directory stream is closed
+     * @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 SecureDirectoryStream newDirectoryStream(Path path,
+                                                             boolean followLinks,
+                                                             DirectoryStream.Filter<? super Path> filter)
+        throws IOException;
+
+    /**
+     * Opens or creates a file in this directory, returning a seekable byte
+     * channel to access the file.
+     *
+     * <p> This method works in exactly the manner specified by the {@link
+     * Path#newByteChannel Path.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
+     * LinkOption#NOFOLLOW_LINKS NOFOLLOW_LINKS} option may be used to
+     * ensure that this method fails if the file is a symbolic link.
+     *
+     * <p> The channel, once created, is not dependent upon the directory stream
+     * used to create it. Closing this directory stream has no effect upon the
+     * channel.
+     *
+     * @param   path
+     *          the path of the file to open open or create
+     * @param   options
+     *          options specifying how the file is opened
+     * @param   attrs
+     *          an optional list of attributes to set atomically when creating
+     *          the file
+     *
+     * @throws  ClosedDirectoryStreamException
+     *          if the directory stream is closed
+     * @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(Path path,
+                                                       Set<? extends OpenOption> options,
+                                                       FileAttribute<?>... attrs)
+        throws IOException;
+
+    /**
+     * Deletes a file.
+     *
+     * <p> Unlike the {@link FileRef#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 is
+     * deleted (not the final target of the link). When the parameter is a
+     * relative path then the file to delete is relative to this open directory.
+     *
+     * @param   path
+     *          the path of the file to delete
+     *
+     * @throws  ClosedDirectoryStreamException
+     *          if the directory stream is closed
+     * @throws  NoSuchFileException
+     *          if the file does not exist <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) checkDelete}
+     *          method is invoked to check delete access to the file
+     */
+    public abstract void deleteFile(Path path) throws IOException;
+
+    /**
+     * Deletes a directory.
+     *
+     * <p> Unlike the {@link FileRef#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
+     * directory to delete is relative to this open directory.
+     *
+     * @param   path
+     *          the path of the directory to delete
+     *
+     * @throws  ClosedDirectoryStreamException
+     *          if the directory stream is closed
+     * @throws  NoSuchFileException
+     *          if the the directory does not exist <i>(optional specific exception)</i>
+     * @throws  DirectoryNotEmptyException
+     *          if the directory could not otherwise be deleted because it 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) checkDelete}
+     *          method is invoked to check delete access to the directory
+     */
+    public abstract void deleteDirectory(Path 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}
+     * 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
+     * absolute} path then it locates the source file. If the parameter is a
+     * relative path then it is located relative to this open directory. If
+     * the {@code targetpath} parameter is absolute then it locates the target
+     * file (the {@code targetdir} parameter is ignored). If the parameter is
+     * a relative path it is located relative to the open directory identified
+     * by the {@code targetdir} parameter. In all cases, if the target file
+     * exists then it is implementation specific if it is replaced or this
+     * method fails.
+     *
+     * @param   srcpath
+     *          the name of the file to move
+     * @param   targetdir
+     *          the destination directory
+     * @param   targetpath
+     *          the name to give the file in the destination directory
+     *
+     * @throws  ClosedDirectoryStreamException
+     *          if this or the target directory stream is closed
+     * @throws  FileAlreadyExistsException
+     *          if the file already exists in the target directory and cannot
+     *          be replaced <i>(optional specific exception)</i>
+     * @throws  AtomicMoveNotSupportedException
+     *          if the file cannot be moved as an atomic file system operation
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method is invoked to check write access to both the source and
+     *          target file.
+     */
+    public abstract void move(Path srcpath, SecureDirectoryStream targetdir, Path targetpath)
+        throws IOException;
+
+    /**
+     * Returns a new file attribute view to access the file attributes of this
+     * directory.
+     *
+     * <p> The resulting file attribute view can be used to read or update the
+     * attributes of this (open) directory. The {@code type} parameter specifies
+     * the type of the attribute view and the method returns an instance of that
+     * type if supported. Invoking this method to obtain a {@link
+     * BasicFileAttributeView} always returns an instance of that class that is
+     * bound to this open directory.
+     *
+     * <p> The state of resulting file attribute view is intimately connected
+     * to this directory stream. Once the directory stream is {@link #close closed},
+     * then all methods to read or update attributes will throw {@link
+     * ClosedDirectoryStreamException ClosedDirectoryStreamException}.
+     *
+     * @param   type
+     *          the {@code Class} object corresponding to the file attribute view
+     *
+     * @return  a new file attribute view of the specified type bound to
+     *          this directory stream, or {@code null} if the attribute view
+     *          type is not available
+     */
+    public abstract <V extends FileAttributeView> V getFileAttributeView(Class<V> type);
+
+    /**
+     * Returns a new file attribute view to access the file attributes of a file
+     * in this directory.
+     *
+     * <p> The resulting file attribute view can be used to read or update the
+     * attributes of file in this directory. The {@code type} parameter specifies
+     * the type of the attribute view and the method returns an instance of that
+     * type if supported. Invoking this method to obtain a {@link
+     * BasicFileAttributeView} always returns an instance of that class that is
+     * bound to the file in the directory.
+     *
+     * <p> The state of resulting file attribute view is intimately connected
+     * to this directory stream. Once the directory stream {@link #close closed},
+     * then all methods to read or update attributes will throw {@link
+     * ClosedDirectoryStreamException ClosedDirectoryStreamException}. The
+     * file is not required to exist at the time that the file attribute view
+     * is created but methods to read or update attributes of the file will
+     * fail when invoked and the file does not exist.
+     *
+     * @param   path
+     *          the path of 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 new file attribute view of the specified type bound to a
+     *          this directory stream, or {@code null} if the attribute view
+     *          type is not available
+     *
+     */
+    public abstract <V extends FileAttributeView> V getFileAttributeView(Path path,
+                                                                         Class<V> type,
+                                                                         LinkOption... options);
+}
diff --git a/jdk/src/share/classes/java/nio/file/SimpleFileVisitor.java b/jdk/src/share/classes/java/nio/file/SimpleFileVisitor.java
new file mode 100644
index 0000000..d9557d0
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/SimpleFileVisitor.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+import java.nio.file.attribute.BasicFileAttributes;
+import java.io.IOException;
+import java.io.IOError;
+
+/**
+ * A simple visitor of files with default behavior to visit all files and to
+ * re-throw I/O errors.
+ *
+ * <p> Methods in this class may be overridden subject to their general contract.
+ *
+ * @param   <T>     The type of reference to the files
+ *
+ * @since 1.7
+ */
+
+public class SimpleFileVisitor<T extends FileRef> implements FileVisitor<T> {
+    /**
+     * Initializes a new instance of this class.
+     */
+    protected SimpleFileVisitor() {
+    }
+
+    /**
+     * Invoked for a directory before entries in the directory are visited.
+     *
+     * <p> Unless overridden, this method returns {@link FileVisitResult#CONTINUE
+     * CONTINUE}.
+     */
+    @Override
+    public FileVisitResult preVisitDirectory(T dir) {
+        return FileVisitResult.CONTINUE;
+    }
+
+    /**
+     * Invoked for a directory that could not be opened.
+     *
+     * <p> Unless overridden, this method throws {@link IOError} with the I/O
+     * exception as cause.
+     *
+     * @throws  IOError
+     *          with the I/O exception thrown when the attempt to open the
+     *          directory failed
+     */
+    @Override
+    public FileVisitResult preVisitDirectoryFailed(T dir, IOException exc) {
+        throw new IOError(exc);
+    }
+
+    /**
+     * Invoked for a file in a directory.
+     *
+     * <p> Unless overridden, this method returns {@link FileVisitResult#CONTINUE
+     * CONTINUE}.
+     */
+    @Override
+    public FileVisitResult visitFile(T file, BasicFileAttributes attrs) {
+        return FileVisitResult.CONTINUE;
+    }
+
+    /**
+     * Invoked for a file when its basic file attributes could not be read.
+     *
+     * <p> Unless overridden, this method throws {@link IOError} with the I/O
+     * exception as cause.
+     *
+     * @throws  IOError
+     *          with the I/O exception thrown when the attempt to read the file
+     *          attributes failed
+     */
+    @Override
+    public FileVisitResult visitFileFailed(T file, IOException exc) {
+        throw new IOError(exc);
+    }
+
+    /**
+     * Invoked for a directory after entries in the directory, and all of their
+     * descendants, have been visited.
+     *
+     * <p> Unless overridden, this method returns {@link FileVisitResult#CONTINUE
+     * CONTINUE} if the directory iteration completes without an I/O exception;
+     * otherwise this method throws {@link IOError} with the I/O exception as
+     * cause.
+     *
+     * @throws  IOError
+     *          if iteration of the directory completed prematurely due to an
+     *          I/O error
+     */
+    @Override
+    public FileVisitResult postVisitDirectory(T dir, IOException exc) {
+        if (exc != null)
+            throw new IOError(exc);
+        return FileVisitResult.CONTINUE;
+    }
+}
diff --git a/jdk/src/share/classes/java/nio/file/StandardCopyOption.java b/jdk/src/share/classes/java/nio/file/StandardCopyOption.java
new file mode 100644
index 0000000..32572c1
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/StandardCopyOption.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Defines the standard copy options.
+ *
+ * @since 1.7
+ */
+
+public enum StandardCopyOption implements CopyOption {
+    /**
+     * Replace an existing file if it exists.
+     */
+    REPLACE_EXISTING,
+    /**
+     * Copy attributes to the new file.
+     */
+    COPY_ATTRIBUTES,
+    /**
+     * Move the file as an atomic file system operation.
+     */
+    ATOMIC_MOVE;
+}
diff --git a/jdk/src/share/classes/java/nio/file/StandardOpenOption.java b/jdk/src/share/classes/java/nio/file/StandardOpenOption.java
new file mode 100644
index 0000000..d01763c
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/StandardOpenOption.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Defines the standard open options.
+ *
+ * @since 1.7
+ */
+
+public enum StandardOpenOption implements OpenOption {
+    /**
+     * Open for read access.
+     */
+    READ,
+
+    /**
+     * Open for write access.
+     */
+    WRITE,
+
+    /**
+     * If the file is opened for {@link #WRITE} access then bytes will be written
+     * to the end of the file rather than the beginning.
+     *
+     * <p> If the file is opened for write access by other programs, then it
+     * is file system specific if writing to the end of the file is atomic.
+     */
+    APPEND,
+
+    /**
+     * If the file already exists and it is opened for {@link #WRITE}
+     * access, then its length is truncated to 0. This option is ignored
+     * if the file is opened only for {@link #READ} access.
+     */
+    TRUNCATE_EXISTING,
+
+    /**
+     * Create a new file if it does not exist.
+     * This option is ignored if the {@link #CREATE_NEW} option is also set.
+     * 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.
+     */
+    CREATE,
+
+    /**
+     * Create a new file, failing if the file already exists.
+     * 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.
+     */
+    CREATE_NEW,
+
+    /**
+     * Delete on close. When this option is present then the implementation
+     * makes a <em>best effort</em> attempt to delete the file when closed
+     * by the appropriate {@code 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 (either normally, as
+     * defined by the Java Language Specification, or where possible, abnormally).
+     * This option is primarily intended for use with <em>work files</em> that
+     * are used solely by a single instance of the Java virtual machine. This
+     * option is not recommended for use when opening files that are open
+     * concurrently by other entities. Many of the details as to when and how
+     * the file is deleted are implementation specific and therefore not
+     * specified. In particular, an implementation may be unable to guarantee
+     * that it deletes the expected file when replaced by an attacker while the
+     * file is open. Consequently, security sensitive applications should take
+     * care when using this option.
+     *
+     * <p> For security reasons, this option may imply the {@link
+     * LinkOption#NOFOLLOW_LINKS} option. In other words, if the option is present
+     * when opening an existing file that is a symbolic link then it may fail
+     * (by throwing {@link java.io.IOException}).
+     */
+    DELETE_ON_CLOSE,
+
+    /**
+     * Sparse file. When used with the {@link #CREATE_NEW} option then this
+     * option provides a <em>hint</em> that the new file will be sparse. The
+     * option is ignored when the file system does not support the creation of
+     * sparse files.
+     */
+    SPARSE,
+
+    /**
+     * 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>
+     */
+    SYNC,
+
+    /**
+     * 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>
+     */
+    DSYNC;
+}
diff --git a/jdk/src/share/classes/java/nio/file/StandardWatchEventKind.java b/jdk/src/share/classes/java/nio/file/StandardWatchEventKind.java
new file mode 100644
index 0000000..6cc937e
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/StandardWatchEventKind.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Defines the <em>standard</em> event kinds.
+ *
+ * @since 1.7
+ */
+
+public class StandardWatchEventKind {
+    private StandardWatchEventKind() { }
+
+    /**
+     * A special event to indicate that events may have been lost or
+     * discarded.
+     *
+     * <p> The {@link WatchEvent#context context} for this event is
+     * implementation specific and may be {@code null}. The event {@link
+     * WatchEvent#count count} may be greater than {@code 1}.
+     *
+     * @see WatchService
+     */
+    public static final WatchEvent.Kind<Void> OVERFLOW =
+        new StdWatchEventKind<Void>("OVERFLOW", Void.class);
+
+    /**
+     * Directory entry created.
+     *
+     * <p> When a directory is registered for this event then the {@link WatchKey}
+     * is queued when it is observed that an entry is created in the directory
+     * or renamed into the directory. The event {@link WatchEvent#count count}
+     * for this event is always {@code 1}.
+     */
+    public static final WatchEvent.Kind<Path> ENTRY_CREATE =
+        new StdWatchEventKind<Path>("ENTRY_CREATE", Path.class);
+
+    /**
+     * Directory entry deleted.
+     *
+     * <p> When a directory is registered for this event then the {@link WatchKey}
+     * is queued when it is observed that an entry is deleted or renamed out of
+     * the directory. The event {@link WatchEvent#count count} for this event
+     * is always {@code 1}.
+     */
+    public static final WatchEvent.Kind<Path> ENTRY_DELETE =
+        new StdWatchEventKind<Path>("ENTRY_DELETE", Path.class);
+
+    /**
+     * Directory entry modified.
+     *
+     * <p> When a directory is registered for this event then the {@link WatchKey}
+     * is queued when it is observed that an entry in the directory has been
+     * modified. The event {@link WatchEvent#count count} for this event is
+     * {@code 1} or greater.
+     */
+    public static final WatchEvent.Kind<Path> ENTRY_MODIFY =
+        new StdWatchEventKind<Path>("ENTRY_MODIFY", Path.class);
+
+    private static class StdWatchEventKind<T> implements WatchEvent.Kind<T> {
+        private final String name;
+        private final Class<T> type;
+        StdWatchEventKind(String name, Class<T> type) {
+            this.name = name;
+            this.type = type;
+        }
+        @Override public String name() { return name; }
+        @Override public Class<T> type() { return type; }
+        @Override public String toString() { return name; }
+    }
+}
diff --git a/jdk/src/share/classes/java/nio/file/WatchEvent.java b/jdk/src/share/classes/java/nio/file/WatchEvent.java
new file mode 100644
index 0000000..296efd4
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/WatchEvent.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+/**
+ * An event or a repeated event for an object that is registered with a {@link
+ * WatchService}.
+ *
+ * <p> An event is classified by its {@link #kind() kind} and has a {@link
+ * #count() count} to indicate the number of times that the event has been
+ * observed. This allows for efficient representation of repeated events. The
+ * {@link #context() context} method returns any context associated with
+ * the event. In the case of a repeated event then the context is the same for
+ * all events.
+ *
+ * <p> Watch events are immutable and safe for use by multiple concurrent
+ * threads.
+ *
+ * @param   <T>     The type of the context object associated with the event
+ *
+ * @since 1.7
+ */
+
+public abstract class WatchEvent<T> {
+
+    /**
+     * An event kind, for the purposes of identification.
+     *
+     * @since 1.7
+     * @see StandardWatchEventKind
+     */
+    public static interface Kind<T> {
+        /**
+         * Returns the name of the event kind.
+         */
+        String name();
+
+        /**
+         * Returns the type of the {@link WatchEvent#context context} value.
+         */
+        Class<T> type();
+    }
+
+    /**
+     * Initializes a new instance of this class.
+     */
+    protected WatchEvent() { }
+
+    /**
+     * An event modifier that qualifies how a {@link Watchable} is registered
+     * with a {@link WatchService}.
+     *
+     * <p> This release does not define any <em>standard</em> modifiers.
+     *
+     * @since 1.7
+     * @see Watchable#register
+     */
+    public static interface Modifier {
+        /**
+         * Returns the name of the modifier.
+         */
+        String name();
+    }
+
+    /**
+     * Returns the event kind.
+     *
+     * @return  the event kind
+     */
+    public abstract Kind<T> kind();
+
+    /**
+     * Returns the event count. If the event count is greater than {@code 1}
+     * then this is a repeated event.
+     *
+     * @return  the event count
+     */
+    public abstract int count();
+
+    /**
+     * Returns the context for the event.
+     *
+     * <p> In the case of {@link StandardWatchEventKind#ENTRY_CREATE ENTRY_CREATE},
+     * {@link StandardWatchEventKind#ENTRY_DELETE ENTRY_DELETE}, and {@link
+     * StandardWatchEventKind#ENTRY_MODIFY ENTRY_MODIFY} events the context is
+     * a {@code Path} that is the {@link Path#relativize relative} path between
+     * the directory registered with the watch service, and the entry that is
+     * created, deleted, or modified.
+     *
+     * @return  the event context; may be {@code null}
+     */
+    public abstract T context();
+}
diff --git a/jdk/src/share/classes/java/nio/file/WatchKey.java b/jdk/src/share/classes/java/nio/file/WatchKey.java
new file mode 100644
index 0000000..d065585
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/WatchKey.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+import java.util.List;
+
+/**
+ * A token representing the registration of a {@link Watchable watchable} object
+ * with a {@link WatchService}.
+ *
+ * <p> A watch key is created when a watchable object is registered with a watch
+ * service. The key remains {@link #isValid valid} until:
+ * <ol>
+ *   <li> It is cancelled, explicitly, by invoking its {@link #cancel cancel}
+ *     method, or</li>
+ *   <li> Cancelled implicitly, because the object is no longer accessible,
+ *     or </li>
+ *   <li> By {@link WatchService#close closing} the watch service. </li>
+ * </ol>
+ *
+ * <p> A watch key has a state. When initially created the key is said to be
+ * <em>ready</em>. When an event is detected then the key is <em>signalled</em>
+ * and queued so that it can be retrieved by invoking the watch service's {@link
+ * WatchService#poll() poll} or {@link WatchService#take() take} methods. Once
+ * signalled, a key remains in this state until its {@link #reset reset} method
+ * is invoked to return the key to the ready state. Events detected while the
+ * key is in the signalled state are queued but do not cause the key to be
+ * re-queued for retrieval from the watch service. Events are retrieved by
+ * invoking the key's {@link #pollEvents pollEvents} method. This method
+ * retrieves and removes all events accumulated for the object. When initially
+ * created, a watch key has no pending events. Typically events are retrieved
+ * when the key is in the signalled state leading to the following idiom:
+ *
+ * <pre>
+ *     for (;;) {
+ *         // retrieve key
+ *         WatchKey key = watcher.take();
+ *
+ *         // process events
+ *         for (WatchEvent&lt;?&gt; event: key.pollEvents()) {
+ *             :
+ *         }
+ *
+ *         // reset the key
+ *         boolean valid = key.reset();
+ *         if (!valid) {
+ *             // object no longer registered
+ *         }
+ *     }
+ * </pre>
+ *
+ * <p> Watch keys are safe for use by multiple concurrent threads. Where there
+ * are several threads retrieving signalled keys from a watch service then care
+ * should be taken to ensure that the {@code reset} method is only invoked after
+ * the events for the object have been processed. This ensures that one thread
+ * is processing the events for an object at any time.
+ *
+ * @since 1.7
+ */
+
+public abstract class WatchKey {
+    /**
+     * Initializes a new instance of this class.
+     */
+    protected WatchKey() { }
+
+    /**
+     * Tells whether or not this watch key is valid.
+     *
+     * <p> A watch key is valid upon creation and remains until it is cancelled,
+     * or its watch service is closed.
+     *
+     * @return  {@code true} if, and only if, this watch key is valid
+     */
+    public abstract boolean isValid();
+
+    /**
+     * Retrieves and removes all pending events for this watch key, returning
+     * a {@code List} of the events that were retrieved.
+     *
+     * <p> Note that this method does not wait if there are no events pending.
+     *
+     * @return  the list of the events retrieved
+     */
+    public abstract List<WatchEvent<?>> pollEvents();
+
+    /**
+     * Resets this watch key.
+     *
+     * <p> If this watch key has been cancelled or this watch key is already in
+     * the ready state then invoking this method has no effect. Otherwise
+     * if there are pending events for the object then this watch key is
+     * immediately re-queued to the watch service. If there are no pending
+     * events then the watch key is put into the ready state and will remain in
+     * that state until an event is detected or the watch key is cancelled.
+     *
+     * @return  {@code true} if the watch key is valid and has been reset, and
+     *          {@code false} if the watch key could not be reset because it is
+     *          no longer {@link #isValid valid}
+     */
+    public abstract boolean reset();
+
+    /**
+     * Cancels the registration with the watch service. Upon return the watch key
+     * will be invalid. If the watch key is enqueued, waiting to be retrieved
+     * from the watch service, then it will remain in the queue until it is
+     * removed. Pending events, if any, remain pending and may be retrieved by
+     * invoking the {@link #pollEvents pollEvents} method event after the key is
+     * cancelled.
+     *
+     * <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();
+}
diff --git a/jdk/src/share/classes/java/nio/file/WatchService.java b/jdk/src/share/classes/java/nio/file/WatchService.java
new file mode 100644
index 0000000..52678df
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/WatchService.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A watch service that <em>watches</em> registered objects for changes and
+ * events. For example a file manager may use a watch service to monitor a
+ * directory for changes so that it can update its display of the list of files
+ * when files are created or deleted.
+ *
+ * <p> A {@link Watchable} object is registered with a watch service by invoking
+ * its {@link Watchable#register register} method, returning a {@link WatchKey}
+ * to represent the registration. When an event for an object is detected the
+ * key is <em>signalled</em>, and if not currently signalled, it is queued to
+ * the watch service so that it can be retrieved by consumers that invoke the
+ * {@link #poll() poll} or {@link #take() take} methods to retrieve keys
+ * and process events. Once the events have been processed the consumer
+ * invokes the key's {@link WatchKey#reset reset} method to reset the key which
+ * allows the key to be signalled and re-queued with further events.
+ *
+ * <p> Registration with a watch service is cancelled by invoking the key's
+ * {@link WatchKey#cancel cancel} method. A key that is queued at the time that
+ * it is cancelled remains in the queue until it is retrieved. Depending on the
+ * object, a key may be cancelled automatically. For example, suppose a
+ * directory is watched and the watch service detects that it has been deleted
+ * or its file system is no longer accessible. When a key is cancelled in this
+ * manner it is signalled and queued, if not currently signalled. To ensure
+ * that the consumer is notified the return value from the {@code reset}
+ * method indicates if the key is valid.
+ *
+ * <p> A watch service is safe for use by multiple concurrent consumers. To
+ * ensure that only one consumer processes the events for a particular object at
+ * any time then care should be taken to ensure that the key's {@code reset}
+ * method is only invoked after its events have been processed. The {@link
+ * #close close} method may be invoked at any time to close the service causing
+ * any threads waiting to retrieve keys, to throw {@code
+ * ClosedWatchServiceException}.
+ *
+ * <p> File systems may report events faster than they can be retrieved or
+ * processed and an implementation may impose an unspecified limit on the number
+ * of events that it may accumulate. Where an implementation <em>knowingly</em>
+ * discards events then it arranges for the key's {@link WatchKey#pollEvents
+ * pollEvents} method to return an element with an event type of {@link
+ * StandardWatchEventKind#OVERFLOW OVERFLOW}. This event can be used by the
+ * consumer as a trigger to re-examine the state of the object.
+ *
+ * <p> When an event is reported to indicate that a file in a watched directory
+ * has been modified then there is no guarantee that the program (or programs)
+ * that have modified the file have completed. Care should be taken to coordinate
+ * access with other programs that may be updating the file.
+ * The {@link java.nio.channels.FileChannel FileChannel} class defines methods
+ * to lock regions of a file against access by other programs.
+ *
+ * <h4>Platform dependencies</h4>
+ *
+ * <p> The implementation that observes events from the file system is intended
+ * to map directly on to the native file event notification facility where
+ * available, or to use a primitive mechanism, such as polling, when a native
+ * facility is not available. Consequently, many of the details on how events
+ * are detected, their timeliness, and whether their ordering is preserved are
+ * highly implementation specific. For example, when a file in a watched
+ * directory is modified then it may result in a single {@link
+ * StandardWatchEventKind#ENTRY_MODIFY ENTRY_MODIFY} event in some
+ * implementations but several events in other implementations. Short-lived
+ * files (meaning files that are deleted very quickly after they are created)
+ * may not be detected by primitive implementations that periodically poll the
+ * file system to detect changes.
+ *
+ * <p> If a watched file is not located on a local storage device then it is
+ * implementation specific if changes to the file can be detected. In particular,
+ * it is not required that changes to files carried out on remote systems be
+ * detected.
+ *
+ * @since 1.7
+ *
+ * @see FileSystem#newWatchService
+ */
+
+public abstract class WatchService
+    implements Closeable
+{
+    /**
+     * Initializes a new instance of this class.
+     */
+    protected WatchService() { }
+
+    /**
+     * Closes this watch service.
+     *
+     * <p> If a thread is currently blocked in the {@link #take take} or {@link
+     * #poll(long,TimeUnit) poll} methods waiting for a key to be queued then
+     * it immediately receives a {@link ClosedWatchServiceException}. Any
+     * valid keys associated with this watch service are {@link WatchKey#isValid
+     * invalidated}.
+     *
+     * <p> After a watch service is closed, any further attempt to invoke
+     * operations upon it will throw {@link ClosedWatchServiceException}.
+     * If this watch service is already closed then invoking this method
+     * has no effect.
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     */
+    @Override
+    public abstract void close() throws IOException;
+
+    /**
+     * Retrieves and removes the next watch key, or {@code null} if none are
+     * present.
+     *
+     * @return  the next watch key, or {@code null}
+     *
+     * @throws  ClosedWatchServiceException
+     *          if this watch service is closed
+     */
+    public abstract WatchKey poll();
+
+    /**
+     * Retrieves and removes the next watch key, waiting if necessary up to the
+     * specified wait time if none are yet present.
+     *
+     * @param   timeout
+     *          how to wait before giving up, in units of unit
+     * @param   unit
+     *          a {@code TimeUnit} determining how to interpret the timeout
+     *          parameter
+     *
+     * @return  the next watch key, or {@code null}
+     *
+     * @throws  ClosedWatchServiceException
+     *          if this watch service is closed, or it is closed while waiting
+     *          for the next key
+     * @throws  InterruptedException
+     *          if interrupted while waiting
+     */
+    public abstract WatchKey poll(long timeout, TimeUnit unit)
+        throws InterruptedException;
+
+    /**
+     * Retrieves and removes next watch key, waiting if none are yet present.
+     *
+     * @return  the next watch key
+     *
+     * @throws  ClosedWatchServiceException
+     *          if this watch service is closed, or it is closed while waiting
+     *          for the next key
+     * @throws  InterruptedException
+     *          if interrupted while waiting
+     */
+    public abstract WatchKey take() throws InterruptedException;
+}
diff --git a/jdk/src/share/classes/java/nio/file/Watchable.java b/jdk/src/share/classes/java/nio/file/Watchable.java
new file mode 100644
index 0000000..9bfa627
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/Watchable.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file;
+
+import java.io.IOException;
+
+/**
+ * An object that may be registered with a watch service so that it can be
+ * <em>watched</em> for changes and events.
+ *
+ * <p> This interface defines the {@link #register register} method to register
+ * the object with a {@link WatchService} returning a {@link WatchKey} to
+ * represent the registration. An object may be registered with more than one
+ * watch service. Registration with a watch service is cancelled by invoking the
+ * key's {@link WatchKey#cancel cancel} method.
+ *
+ * @since 1.7
+ *
+ * @see Path#register
+ */
+
+public interface Watchable {
+
+    /**
+     * Registers an object with a watch service.
+     *
+     * <p> If the file system object identified by this object is currently
+     * registered with the watch service then the watch key, representing that
+     * registration, is returned after changing the event set or modifiers to
+     * those specified by the {@code events} and {@code modifiers} parameters.
+     * Changing the event set does not cause pending events for the object to be
+     * discarded. Objects are automatically registered for the {@link
+     * StandardWatchEventKind#OVERFLOW OVERFLOW} event. This event is not
+     * required to be present in the array of events.
+     *
+     * <p> Otherwise the file system object has not yet been registered with the
+     * given watch service, so it is registered and the resulting new key is
+     * returned.
+     *
+     * <p> Implementations of this interface should specify the events they
+     * support.
+     *
+     * @param   watcher
+     *          the watch service to which this object is to be registered
+     * @param   events
+     *          the events for which this object should be registered
+     * @param   modifiers
+     *          the modifiers, if any, that modify how the object is registered
+     *
+     * @return  a key representing the registration of this object with the
+     *          given watch service
+     *
+     * @throws  UnsupportedOperationException
+     *          if unsupported events or modifiers are specified
+     * @throws  IllegalArgumentException
+     *          if an invalid of combination of events are modifiers are specified
+     * @throws  ClosedWatchServiceException
+     *          if the watch service is closed
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          if a security manager is installed and it denies an unspecified
+     *          permission required to monitor this object. Implementations of
+     *          this interface should specify the permission checks.
+     */
+    WatchKey register(WatchService watcher,
+                      WatchEvent.Kind<?>[] events,
+                      WatchEvent.Modifier... modifiers)
+        throws IOException;
+
+
+    /**
+     * Registers an object with a watch service.
+     *
+     * <p> An invocation of this method behaves in exactly the same way as the
+     * invocation
+     * <pre>
+     *     watchable.{@link #register(WatchService,WatchEvent.Kind[],WatchEvent.Modifier[]) register}(watcher, events, new WatchEvent.Modifier[0]);
+     * </pre>
+     *
+     * @param   watcher
+     *          the watch service to which this object is to be registered
+     * @param   events
+     *          the events for which this object should be registered
+     *
+     * @return  a key representing the registration of this object with the
+     *          given watch service
+     *
+     * @throws  UnsupportedOperationException
+     *          if unsupported events are specified
+     * @throws  IllegalArgumentException
+     *          if an invalid of combination of events are specified
+     * @throws  ClosedWatchServiceException
+     *          if the watch service is closed
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          if a security manager is installed and it denies an unspecified
+     *          permission required to monitor this object. Implementations of
+     *          this interface should specify the permission checks.
+     */
+    WatchKey register(WatchService watcher, WatchEvent.Kind<?>... events)
+        throws IOException;
+}
diff --git a/jdk/src/share/classes/java/nio/file/attribute/AclEntry.java b/jdk/src/share/classes/java/nio/file/attribute/AclEntry.java
new file mode 100644
index 0000000..817e1b0
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/attribute/AclEntry.java
@@ -0,0 +1,394 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file.attribute;
+
+import java.util.*;
+
+/**
+ * An entry in an access control list (ACL).
+ *
+ * <p> The ACL entry represented by this class is based on the ACL model
+ * specified in <a href="http://www.ietf.org/rfc/rfc3530.txt"><i>RFC&nbsp;3530:
+ * Network File System (NFS) version 4 Protocol</i></a>. Each entry has four
+ * components as follows:
+ *
+ * <ol>
+ *    <li><p> The {@link #type() type} component determines if the entry
+ *    grants or denies access. </p></li>
+ *
+ *    <li><p> The {@link #principal() principal} component, sometimes called the
+ *    "who" component, is a {@link UserPrincipal} corresponding to the identity
+ *    that the entry grants or denies access
+ *    </p></li>
+ *
+ *    <li><p> The {@link #permissions permissions} component is a set of
+ *    {@link AclEntryPermission permissions}
+ *    </p></li>
+ *
+ *    <li><p> The {@link #flags flags} component is a set of {@link AclEntryFlag
+ *    flags} to indicate how entries are inherited and propagated </p></li>
+ * </ol>
+ *
+ * <p> ACL entries are created using an associated {@link Builder} object by
+ * invoking its {@link Builder#build build} method.
+ *
+ * <p> ACL entries are immutable and are safe for use by multiple concurrent
+ * threads.
+ *
+ * @since 1.7
+ */
+
+public final class AclEntry {
+
+    private final AclEntryType type;
+    private final UserPrincipal who;
+    private final Set<AclEntryPermission> perms;
+    private final Set<AclEntryFlag> flags;
+
+    // cached hash code
+    private volatile int hash;
+
+    // private constructor
+    private AclEntry(AclEntryType type,
+                     UserPrincipal who,
+                     Set<AclEntryPermission> perms,
+                     Set<AclEntryFlag> flags)
+    {
+        this.type = type;
+        this.who = who;
+        this.perms = perms;
+        this.flags = flags;
+    }
+
+    /**
+     * A builder of {@link AclEntry} objects.
+     *
+     * <p> A {@code Builder} object is obtained by invoking one of the {@link
+     * AclEntry#newBuilder newBuilder} methods defined by the {@code AclEntry}
+     * class.
+     *
+     * <p> Builder objects are mutable and are not safe for use by multiple
+     * concurrent threads without appropriate synchronization.
+     *
+     * @since 1.7
+     */
+    public static final class Builder {
+        private AclEntryType type;
+        private UserPrincipal who;
+        private Set<AclEntryPermission> perms;
+        private Set<AclEntryFlag> flags;
+
+        private Builder(AclEntryType type,
+                        UserPrincipal who,
+                        Set<AclEntryPermission> perms,
+                        Set<AclEntryFlag> flags)
+        {
+            assert perms != null && flags != null;
+            this.type = type;
+            this.who = who;
+            this.perms = perms;
+            this.flags = flags;
+        }
+
+        /**
+         * Constructs an {@link AclEntry} from the components of this builder.
+         * The type and who components are required to have been set in order
+         * to construct an {@code AclEntry}.
+         *
+         * @return  a new ACL entry
+         *
+         * @throws  IllegalStateException
+         *          if the type or who component have not been set
+         */
+        public AclEntry build() {
+            if (type == null)
+                throw new IllegalStateException("Missing type component");
+            if (who == null)
+                throw new IllegalStateException("Missing who component");
+            return new AclEntry(type, who, perms, flags);
+        }
+
+        /**
+         * Sets the type component of this builder.
+         *
+         * @return  this builder
+         */
+        public Builder setType(AclEntryType type) {
+            if (type == null)
+                throw new NullPointerException();
+            this.type = type;
+            return this;
+        }
+
+        /**
+         * Sets the principal component of this builder.
+         *
+         * @return  this builder
+         */
+        public Builder setPrincipal(UserPrincipal who) {
+            if (who == null)
+                throw new NullPointerException();
+            this.who = who;
+            return this;
+        }
+
+        // check set only contains elements of the given type
+        private static void checkSet(Set<?> set, Class<?> type) {
+            for (Object e: set) {
+                if (e == null)
+                    throw new NullPointerException();
+                type.cast(e);
+            }
+        }
+
+        /**
+         * Sets the permissions component of this builder. On return, the
+         * permissions component of this builder is a copy of the given set.
+         *
+         * @return  this builder
+         *
+         * @throws  ClassCastException
+         *          if the set contains elements that are not of type {@code
+         *          AclEntryPermission}
+         */
+        public Builder setPermissions(Set<AclEntryPermission> perms) {
+            // copy and check for erroneous elements
+            perms = new HashSet<AclEntryPermission>(perms);
+            checkSet(perms, AclEntryPermission.class);
+            this.perms = perms;
+            return this;
+        }
+
+        /**
+         * Sets the permissions component of this builder. On return, the
+         * permissions component of this builder is a copy of the permissions in
+         * the given array.
+         *
+         * @return  this builder
+         */
+        public Builder setPermissions(AclEntryPermission... perms) {
+            Set<AclEntryPermission> set =
+                new HashSet<AclEntryPermission>(perms.length);
+            // copy and check for null elements
+            for (AclEntryPermission p: perms) {
+                if (p == null)
+                    throw new NullPointerException();
+                set.add(p);
+            }
+            this.perms = set;
+            return this;
+        }
+
+        /**
+         * Sets the flags component of this builder. On return, the flags
+         * component of this builder is a copy of the given set.
+         *
+         * @return  this builder
+         *
+         * @throws  ClassCastException
+         *          if the set contains elements that are not of type {@code
+         *          AclEntryFlag}
+         */
+        public Builder setFlags(Set<AclEntryFlag> flags) {
+            // copy and check for erroneous elements
+            flags = new HashSet<AclEntryFlag>(flags);
+            checkSet(flags, AclEntryFlag.class);
+            this.flags = flags;
+            return this;
+        }
+
+        /**
+         * Sets the flags component of this builder. On return, the flags
+         * component of this builder is a copy of the flags in the given
+         * array.
+         *
+         * @return  this builder
+         */
+        public Builder setFlags(AclEntryFlag... flags) {
+            Set<AclEntryFlag> set = new HashSet<AclEntryFlag>(flags.length);
+            // copy and check for null elements
+            for (AclEntryFlag f: flags) {
+                if (f == null)
+                    throw new NullPointerException();
+                set.add(f);
+            }
+            this.flags = set;
+            return this;
+        }
+    }
+
+    /**
+     * Constructs a new builder. The initial value of the type and who
+     * components is {@code null}. The initial value of the permissions and
+     * flags components is the empty set.
+     *
+     * @return  a new builder
+     */
+    public static Builder newBuilder() {
+        Set<AclEntryPermission> perms = Collections.emptySet();
+        Set<AclEntryFlag> flags = Collections.emptySet();
+        return new Builder(null, null, perms, flags);
+    }
+
+    /**
+     * Constructs a new builder with the components of an existing ACL entry.
+     *
+     * @param   entry
+     *          an ACL entry
+     *
+     * @return  a new builder
+     */
+    public static Builder newBuilder(AclEntry entry) {
+        return new Builder(entry.type, entry.who, entry.perms, entry.flags);
+    }
+
+    /**
+     * Returns the ACL entry type.
+     */
+    public AclEntryType type() {
+        return type;
+    }
+
+    /**
+     * Returns the principal component.
+     */
+    public UserPrincipal principal() {
+        return who;
+    }
+
+    /**
+     * Returns a copy of the permissions component.
+     *
+     * <p> The returned set is a modifiable copy of the permissions.
+     */
+    public Set<AclEntryPermission> permissions() {
+        return new HashSet<AclEntryPermission>(perms);
+    }
+
+    /**
+     * Returns a copy of the flags component.
+     *
+     * <p> The returned set is a modifiable copy of the flags.
+     */
+    public Set<AclEntryFlag> flags() {
+        return new HashSet<AclEntryFlag>(flags);
+    }
+
+    /**
+     * Compares the specified object with this ACL entry for equality.
+     *
+     * <p> If the given object is not an {@code AclEntry} then this method
+     * immediately returns {@code false}.
+     *
+     * <p> For two ACL entries to be considered equals requires that they are
+     * both the same type, their who components are equal, their permissions
+     * components are equal, and their flags components are equal.
+     *
+     * <p> This method satisfies the general contract of the {@link
+     * java.lang.Object#equals(Object) Object.equals} method. </p>
+     *
+     * @param   ob   the object to which this object is to be compared
+     *
+     * @return  {@code true} if, and only if, the given object is an AclEntry that
+     *          is identical to this AclEntry
+     */
+    @Override
+    public boolean equals(Object ob) {
+        if (ob == this)
+            return true;
+        if (ob == null || !(ob instanceof AclEntry))
+            return false;
+        AclEntry other = (AclEntry)ob;
+        if (this.type != other.type)
+            return false;
+        if (!this.who.equals(other.who))
+            return false;
+        if (!this.perms.equals(other.perms))
+            return false;
+        if (!this.flags.equals(other.flags))
+            return false;
+        return true;
+    }
+
+    private static int hash(int h, Object o) {
+        return h * 127 + o.hashCode();
+    }
+
+    /**
+     * Returns the hash-code value for this ACL entry.
+     *
+     * <p> This method satisfies the general contract of the {@link
+     * Object#hashCode} method.
+     */
+    @Override
+    public int hashCode() {
+        // return cached hash if available
+        if (hash != 0)
+            return hash;
+        int h = type.hashCode();
+        h = hash(h, who);
+        h = hash(h, perms);
+        h = hash(h, flags);
+        hash = h;
+        return hash;
+    }
+
+    /**
+     * Returns the string representation of this ACL entry.
+     *
+     * @return  the string representation of this entry
+     */
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+
+        // who
+        sb.append(who.getName());
+        sb.append(':');
+
+        // permissions
+        for (AclEntryPermission perm: perms) {
+            sb.append(perm.name());
+            sb.append('/');
+        }
+        sb.setLength(sb.length()-1); // drop final slash
+        sb.append(':');
+
+        // flags
+        if (!flags.isEmpty()) {
+            for (AclEntryFlag flag: flags) {
+                sb.append(flag.name());
+                sb.append('/');
+            }
+            sb.setLength(sb.length()-1);  // drop final slash
+            sb.append(':');
+        }
+
+        // type
+        sb.append(type.name());
+        return sb.toString();
+    }
+}
diff --git a/jdk/src/share/classes/java/nio/file/attribute/AclEntryFlag.java b/jdk/src/share/classes/java/nio/file/attribute/AclEntryFlag.java
new file mode 100644
index 0000000..8cad24d
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/attribute/AclEntryFlag.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file.attribute;
+
+/**
+ * Defines the flags for used by the flags component of an ACL {@link AclEntry
+ * entry}.
+ *
+ * <p> In this release, this class does not define flags related to {@link
+ * AclEntryType#AUDIT} and {@link AclEntryType#ALARM} entry types.
+ *
+ * @since 1.7
+ */
+
+public enum AclEntryFlag {
+
+    /**
+     * Can be placed on a directory and indicates that the ACL entry should be
+     * added to each new non-directory file created.
+     */
+    FILE_INHERIT,
+
+    /**
+     * Can be placed on a directory and indicates that the ACL entry should be
+     * added to each new directory created.
+     */
+    DIRECTORY_INHERIT,
+
+    /**
+     * Can be placed on a directory to indicate that the ACL entry should not
+     * be placed on the newly created directory which is inheritable by
+     * subdirectories of the created directory.
+     */
+    NO_PROPAGATE_INHERIT,
+
+    /**
+     * Can be placed on a directory but does not apply to the directory,
+     * only to newly created files/directories as specified by the
+     * {@link #FILE_INHERIT} and {@link #DIRECTORY_INHERIT} flags.
+     */
+    INHERIT_ONLY;
+}
diff --git a/jdk/src/share/classes/java/nio/file/attribute/AclEntryPermission.java b/jdk/src/share/classes/java/nio/file/attribute/AclEntryPermission.java
new file mode 100644
index 0000000..b88431c
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/attribute/AclEntryPermission.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file.attribute;
+
+/**
+ * Defines the permissions for use with the permissions component of an ACL
+ * {@link AclEntry entry}.
+ *
+ * @since 1.7
+ */
+
+public enum AclEntryPermission {
+
+    /**
+     * Permission to read the data of the file.
+     */
+    READ_DATA,
+
+    /**
+     * Permission to modify the file's data.
+     */
+    WRITE_DATA,
+
+    /**
+     * Permission to append data to a file.
+     */
+    APPEND_DATA,
+
+    /**
+     * Permission to read the named attributes of a file.
+     *
+     * <p> <a href="http://www.ietf.org/rfc/rfc3530.txt">RFC&nbsp;3530: Network
+     * File System (NFS) version 4 Protocol</a> defines <em>named attributes</em>
+     * as opaque files associated with a file in the file system.
+     */
+    READ_NAMED_ATTRS,
+
+    /**
+     * Permission to write the named attributes of a file.
+     *
+     * <p> <a href="http://www.ietf.org/rfc/rfc3530.txt">RFC&nbsp;3530: Network
+     * File System (NFS) version 4 Protocol</a> defines <em>named attributes</em>
+     * as opaque files associated with a file in the file system.
+     */
+    WRITE_NAMED_ATTRS,
+
+    /**
+     * Permission to execute a file.
+     */
+    EXECUTE,
+
+    /**
+     * Permission to delete a file or directory within a directory.
+     */
+    DELETE_CHILD,
+
+    /**
+     * The ability to read (non-acl) file attributes.
+     */
+    READ_ATTRIBUTES,
+
+    /**
+     * The ability to write (non-acl) file attributes.
+     */
+    WRITE_ATTRIBUTES,
+
+    /**
+     * Permission to delete the file.
+     */
+    DELETE,
+
+    /**
+     * Permission to read the ACL attribute.
+     */
+    READ_ACL,
+
+    /**
+     * Permission to write the ACL attribute.
+     */
+    WRITE_ACL,
+
+    /**
+     * Permission to change the owner.
+     */
+    WRITE_OWNER,
+
+    /**
+     * Permission to access file locally at the server with synchronous reads
+     * and writes.
+     */
+    SYNCHRONIZE;
+
+    /**
+     * Permission to list the entries of a directory (equal to {@link #READ_DATA})
+     */
+    public static final AclEntryPermission LIST_DIRECTORY = READ_DATA;
+
+    /**
+     * Permission to add a new file to a directory (equal to {@link #WRITE_DATA})
+     */
+    public static final AclEntryPermission ADD_FILE = WRITE_DATA;
+
+    /**
+     * Permission to create a subdirectory to a directory (equal to {@link #APPEND_DATA})
+     */
+    public static final AclEntryPermission ADD_SUBDIRECTORY = APPEND_DATA;
+}
diff --git a/jdk/src/share/classes/java/nio/file/attribute/AclEntryType.java b/jdk/src/share/classes/java/nio/file/attribute/AclEntryType.java
new file mode 100644
index 0000000..c0051c0
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/attribute/AclEntryType.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file.attribute;
+
+/**
+ * A typesafe enumeration of the access control entry types.
+ *
+ * @since 1.7
+ */
+
+public enum AclEntryType {
+    /**
+     * Explicitly grants access to a file or directory.
+     */
+    ALLOW,
+
+    /**
+     * Explicitly denies access to a file or directory.
+     */
+    DENY,
+
+    /**
+     * Log, in a system dependent way, the access specified in the
+     * permissions component of the ACL entry.
+     */
+    AUDIT,
+
+    /**
+     * Generate an alarm, in a system dependent way, the access specified in the
+     * permissions component of the ACL entry.
+     */
+    ALARM
+}
diff --git a/jdk/src/share/classes/java/nio/file/attribute/AclFileAttributeView.java b/jdk/src/share/classes/java/nio/file/attribute/AclFileAttributeView.java
new file mode 100644
index 0000000..c3d28c9
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/attribute/AclFileAttributeView.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file.attribute;
+
+import java.nio.file.*;
+import java.util.List;
+import java.io.IOException;
+
+/**
+ * A file attribute view that supports reading or updating a file's Access
+ * Control Lists (ACL) or file owner attributes.
+ *
+ * <p> ACLs are used to specify access rights to file system objects. An ACL is
+ * an ordered list of {@link AclEntry access-control-entries}, each specifying a
+ * {@link UserPrincipal} and the level of access for that user principal. This
+ * file attribute view defines the {@link #getAcl() getAcl}, and {@link
+ * #setAcl(List) setAcl} methods to read and write ACLs based on the ACL
+ * model specified in <a href="http://www.ietf.org/rfc/rfc3530.txt"><i>RFC&nbsp;3530:
+ * Network File System (NFS) version 4 Protocol</i></a>. This file attribute view
+ * is intended for file system implementations that support the NFSv4 ACL model
+ * or have a <em>well-defined</em> mapping between the NFSv4 ACL model and the ACL
+ * model used by the file system. The details of such mapping are implementation
+ * dependent and are therefore unspecified.
+ *
+ * <p> This class also extends {@code FileOwnerAttributeView} so as to define
+ * methods to get and set the file owner.
+ *
+ * <p> When a file system provides access to a set of {@link FileStore
+ * file-systems} that are not homogeneous then only some of the file systems may
+ * support ACLs. The {@link FileStore#supportsFileAttributeView
+ * supportsFileAttributeView} method can be used to test if a file system
+ * supports ACLs.
+ *
+ * <a name="interop"><h4>Interoperability</h4></a>
+ *
+ * RFC&nbsp;3530 allows for special user identities to be used on platforms that
+ * support the POSIX defined access permissions. The special user identities
+ * are "{@code OWNER@}", "{@code GROUP@}", and "{@code EVERYONE@}". When both
+ * the {@code AclFileAttributeView} and the {@link PosixFileAttributeView}
+ * are supported then these special user identities may be included in ACL {@link
+ * AclEntry entries} that are read or written. The file system's {@link
+ * UserPrincipalLookupService} may be used to obtain a {@link UserPrincipal}
+ * to represent these special identities by invoking the {@link
+ * UserPrincipalLookupService#lookupPrincipalByName lookupPrincipalByName}
+ * method.
+ *
+ * <p> <b>Usage Example:</b>
+ * Suppose we wish to add an entry to an existing ACL to grant "joe" access:
+ * <pre>
+ *     // lookup "joe"
+ *     UserPrincipal joe = file.getFileSystem().getUserPrincipalLookupService()
+ *         .lookupPrincipalByName("joe");
+ *
+ *     // get view
+ *     AclFileAttributeView view = file.newFileAttributeView(AclFileAttributeView.class);
+ *
+ *     // create ACE to give "joe" read access
+ *     AclEntry entry = AclEntry.newBuilder()
+ *         .setType(AclEntryType.ALLOW)
+ *         .setPrincipal(joe)
+ *         .setPermissions(AclEntryPermission.READ_DATA, AclEntryPermission.READ_ATTRIBUTES)
+ *         .build();
+ *
+ *     // read ACL, insert ACE, re-write ACL
+ *     List&lt;AclEntry&gt acl = view.getAcl();
+ *     acl.add(0, entry);   // insert before any DENY entries
+ *     view.setAcl(acl);
+ * </pre>
+ *
+ * <h4> Dynamic Access </h4>
+ * <p> Where dynamic access to file attributes is required, the attributes
+ * supported by this attribute view are as follows:
+ * <blockquote>
+ * <table border="1" cellpadding="8">
+ *   <tr>
+ *     <th> Name </th>
+ *     <th> Type </th>
+ *   </tr>
+ *   <tr>
+ *     <td> "acl" </td>
+ *     <td> {@link List}&lt;{@link AclEntry}&gt; </td>
+ *   </tr>
+ *   <tr>
+ *     <td> "owner" </td>
+ *     <td> {@link UserPrincipal} </td>
+ *   </tr>
+ * </table>
+ * </blockquote>
+ *
+ * <p> The {@link #getAttribute getAttribute} or {@link #readAttributes
+ * readAttributes} methods 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 #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.
+ *
+ * <h4> Setting the ACL when creating a file </h4>
+ *
+ * <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
+ * FileAttribute#name name} {@code "acl:acl"} and a {@link FileAttribute#value
+ * value} that is the list of {@code AclEntry} objects.
+ *
+ * <p> Where an implementation supports an ACL model that differs from the NFSv4
+ * defined ACL model then setting the initial ACL when creating the file must
+ * translate the ACL to the model supported by the file system. Methods that
+ * create a file should reject (by throwing {@link IOException IOException})
+ * any attempt to create a file that would be less secure as a result of the
+ * translation.
+ *
+ * @since 1.7
+ * @see Attributes#getAcl
+ * @see Attributes#setAcl
+ */
+
+public interface AclFileAttributeView
+    extends FileOwnerAttributeView
+{
+    /**
+     * Returns the name of the attribute view. Attribute views of this type
+     * have the name {@code "acl"}.
+     */
+    @Override
+    String name();
+
+    /**
+     * Reads the access control list.
+     *
+     * <p> When the file system uses an ACL model that differs from the NFSv4
+     * defined ACL model, then this method returns an ACL that is the translation
+     * of the ACL to the NFSv4 ACL model.
+     *
+     * <p> The returned list is modifiable so as to facilitate changes to the
+     * existing ACL. The {@link #setAcl setAcl} method is used to update
+     * the file's ACL attribute.
+     *
+     * @return  an ordered list of {@link AclEntry entries} representing the
+     *          ACL
+     *
+     * @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.
+     */
+    List<AclEntry> getAcl() throws IOException;
+
+    /**
+     * Updates (replace) the access control list.
+     *
+     * <p> Where the file system supports Access Control Lists, and it uses an
+     * ACL model that differs from the NFSv4 defined ACL model, then this method
+     * must translate the ACL to the model supported by the file system. This
+     * method should reject (by throwing {@link IOException IOException}) any
+     * attempt to write an ACL that would appear to make the file more secure
+     * than would be the case if the ACL were updated. Where an implementation
+     * does not support a mapping of {@link AclEntryType#AUDIT} or {@link
+     * AclEntryType#ALARM} entries, then this method ignores these entries when
+     * writing the ACL.
+     *
+     * <p> If an ACL entry contains a {@link AclEntry#principal user-principal}
+     * that is not associated with the same provider as this attribute view then
+     * {@link ProviderMismatchException} is thrown. Additional validation, if
+     * any, is implementation dependent.
+     *
+     * <p> If the file system supports other security related file attributes
+     * (such as a file {@link PosixFileAttributes#permissions
+     * access-permissions} for example), the updating the access control list
+     * may also cause these security related attributes to be updated.
+     *
+     * @param   acl
+     *          the new access control list
+     *
+     * @throws  IOException
+     *          if an I/O error occurs or the ACL is invalid
+     * @throws  SecurityException
+     *          In the case of the default provider, 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.
+     */
+    void setAcl(List<AclEntry> acl) throws IOException;
+}
diff --git a/jdk/src/share/classes/java/nio/file/attribute/AttributeView.java b/jdk/src/share/classes/java/nio/file/attribute/AttributeView.java
new file mode 100644
index 0000000..6b0934e
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/attribute/AttributeView.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file.attribute;
+
+import java.util.*;
+import java.io.IOException;
+
+/**
+ * An object that provides a read-only or updatable <em>view</em> of non-opaque
+ * values associated with an object in a filesystem. This interface is extended
+ * or implemented by specific attribute views that define the attributes
+ * supported by the view. A specific attribute view will typically define
+ * type-safe methods to read or update the attributes that it supports. It also
+ * provides <em>dynamic access</em> where the {@link #readAttributes
+ * readAttributes}, {@link #getAttribute getAttribute} and {@link #setAttribute
+ * setAttributs} methods are used to access the attributes by names defined
+ * by the attribute view. Implementations must ensure that the attribute names
+ * do not contain the colon (':') or comma (',') characters.
+ *
+ * @since 1.7
+ */
+
+public interface AttributeView {
+    /**
+     * Returns the name of the attribute view.
+     */
+    String name();
+
+    /**
+     * Reads the value of an attribute.
+     *
+     * @param   attribute
+     *          the attribute name (case sensitive)
+     *
+     * @return  the value of the attribute, or {@code null} if the attribute is
+     *          not supported
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          if a security manager is set and it denies access
+     */
+    Object getAttribute(String attribute) throws IOException;
+
+    /**
+     * Sets/updates the value of an attribute.
+     *
+     * @param   attribute
+     *          the attribute name (case sensitive)
+     * @param   value
+     *          the attribute value
+     *
+     * @throws  UnsupportedOperationException
+     *          if the attribute is not supported or this attribute view does
+     *          not support updating the value of 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
+     *          if a security manager is set and it denies access
+     */
+    void setAttribute(String attribute, Object value) throws IOException;
+
+    /**
+     * Reads all, or a subset, of the attributes supported by this file attribute
+     * view.
+     *
+     * <p> The {@code first} and {@code rest} parameters are the names of the
+     * attributes to read. If any of the parameters has 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.
+     *
+     * @param   first
+     *          the name of an attribute to read (case sensitive)
+     * @param   rest
+     *          the names of other attributes to read (case sensitive)
+     *
+     * @return  an unmodifiable map of the attributes; may be empty. Its keys are
+     *          the attribute names, its values are the attribute values
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          if a security manager is set and it denies access
+     */
+    Map<String,?> readAttributes(String first, String... rest) throws IOException;
+}
diff --git a/jdk/src/share/classes/java/nio/file/attribute/Attributes.java b/jdk/src/share/classes/java/nio/file/attribute/Attributes.java
new file mode 100644
index 0000000..b3fe130
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/attribute/Attributes.java
@@ -0,0 +1,703 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file.attribute;
+
+import java.nio.file.*;
+import java.io.IOException;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * This class consists exclusively of static methods that operate on or return
+ * the attributes of files or file stores. These methods provide for convenient
+ * use of the {@link AttributeView attribute-views} defined in this package.
+ *
+ * @since 1.7
+ */
+
+public final class Attributes {
+    private Attributes() {
+    }
+
+    /**
+     * Splits the given attribute name into the name of an attribute view and
+     * the attribute. If the attribute view is not identified then it assumed
+     * to be "basic".
+     */
+    private static String[] split(String attribute) {
+        String[] s = new String[2];
+        int pos = attribute.indexOf(':');
+        if (pos == -1) {
+            s[0] = "basic";
+            s[1] = attribute;
+        } else {
+            s[0] = attribute.substring(0, pos++);
+            s[1] = (pos == attribute.length()) ? "" : attribute.substring(pos);
+        }
+        return s;
+    }
+
+    /**
+     * 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>
+     *    Attributes.setAttribute(file, "dos:hidden", true);
+     * </pre>
+     *
+     * @param   file
+     *          A file reference that locates the file
+     * @param   attribute
+     *          The attribute to set
+     * @param   value
+     *          The attribute value
+     *
+     * @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 void setAttribute(FileRef file, String attribute, Object value)
+        throws IOException
+    {
+        String[] s = split(attribute);
+        FileAttributeView view = file.getFileAttributeView(s[0]);
+        if (view == null)
+            throw new UnsupportedOperationException("View '" + s[0] + "' not available");
+        view.setAttribute(s[1], value);
+    }
+
+    /**
+     * 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)Attributes.getAttribute(file, "unix:uid");
+     * </pre>
+     *
+     * @param   file
+     *          A file reference that locates 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(FileRef file,
+                                      String attribute,
+                                      LinkOption... options)
+        throws IOException
+    {
+        String[] s = split(attribute);
+        FileAttributeView view = file.getFileAttributeView(s[0], options);
+        if (view != null)
+            return view.getAttribute(s[1]);
+        // view not available
+        return null;
+    }
+
+    /**
+     * 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 attributes of the final target
+     * of the link are read. If the option {@link LinkOption#NOFOLLOW_LINKS
+     * NOFOLLOW_LINKS} is present then symbolic links are not followed and so
+     * the method returns the file attributes of the symbolic link.
+     *
+     * @param   file
+     *          A file reference that locates 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,?> readAttributes(FileRef file,
+                                               String attributes,
+                                               LinkOption... options)
+        throws IOException
+    {
+        String[] s = split(attributes);
+        FileAttributeView view = file.getFileAttributeView(s[0], options);
+        if (view != null) {
+            // further split attributes into the first and rest.
+            String[] names = s[1].split(",");
+            int rem = names.length-1;
+            String first = names[0];
+            String[] rest = new String[rem];
+            if (rem > 0) System.arraycopy(names, 1, rest, 0, rem);
+
+            return view.readAttributes(first, rest);
+        }
+        // view not available
+        return Collections.emptyMap();
+    }
+
+    /**
+     * Reads the basic file attributes of a file.
+     *
+     * <p> The {@code options} array may be used to indicate how symbolic links
+     * are handled for the case that the file is a symbolic link. By default,
+     * symbolic links are followed and the file attributes of the final target
+     * of the link are read. If the option {@link LinkOption#NOFOLLOW_LINKS
+     * NOFOLLOW_LINKS} is present then symbolic links are not followed and so
+     * the method returns the file attributes of the symbolic link. This option
+     * should be used where there is a need to determine if a file is a
+     * symbolic link:
+     * <pre>
+     *    boolean isSymbolicLink = Attributes.readBasicFileAttributes(file, NOFOLLOW_LINKS).isSymbolicLink();
+     * </pre>
+     *
+     * <p> It is implementation specific if all file attributes are read as an
+     * atomic operation with respect to other file system operations.
+     *
+     * @param   file
+     *          A file reference that locates the file
+     * @param   options
+     *          Options indicating how symbolic links are handled
+     *
+     * @return  The basic file attributes
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, the security manager's {@link
+     *          SecurityManager#checkRead(String) checkRead} method is invoked
+     *          to check read access to file
+     *
+     * @see BasicFileAttributeView#readAttributes
+     */
+    public static BasicFileAttributes readBasicFileAttributes(FileRef file,
+                                                              LinkOption... options)
+        throws IOException
+    {
+        return file.getFileAttributeView(BasicFileAttributeView.class, options)
+            .readAttributes();
+    }
+
+    /**
+     * Reads the POSIX file attributes of a file.
+     *
+     * <p> The {@code file} parameter locates a file that supports the {@link
+     * PosixFileAttributeView}. This file attribute view provides access to a
+     * subset of the file attributes commonly associated with files on file
+     * systems used by operating systems that implement the Portable Operating
+     * System Interface (POSIX) family of standards. It is implementation
+     * specific if all file attributes are read as an atomic operation with
+     * respect to other file system operations.
+     *
+     * <p> The {@code options} array may be used to indicate how symbolic links
+     * are handled for the case that the file is a symbolic link. By default,
+     * symbolic links are followed and the file attributes of the final target
+     * of the link are read. If the option {@link LinkOption#NOFOLLOW_LINKS
+     * NOFOLLOW_LINKS} is present then symbolic links are not followed and so
+     * the method returns the file attributes of the symbolic link.
+     *
+     * @param   file
+     *          A file reference that locates the file
+     * @param   options
+     *          Options indicating how symbolic links are handled
+     *
+     * @return  The POSIX file attributes
+     *
+     * @throws  UnsupportedOperationException
+     *          If the {@code PosixFileAttributeView} is not available
+     * @throws  IOException
+     *          If an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
+     *          or its {@link SecurityManager#checkRead(String) checkRead} method
+     *          denies read access to the file.
+     *
+     * @see PosixFileAttributeView#readAttributes
+     */
+    public static PosixFileAttributes readPosixFileAttributes(FileRef file,
+                                                              LinkOption... options)
+        throws IOException
+    {
+        PosixFileAttributeView view =
+            file.getFileAttributeView(PosixFileAttributeView.class, options);
+        if (view == null)
+            throw new UnsupportedOperationException();
+        return view.readAttributes();
+    }
+
+    /**
+     * Reads the DOS file attributes of a file.
+     *
+     * <p> The {@code file} parameter locates a file that supports the {@link
+     * DosFileAttributeView}. This file attribute view provides access to
+     * legacy "DOS" attributes supported by the file systems such as File
+     * Allocation Table (FAT), commonly used in <em>consumer devices</em>. It is
+     * implementation specific if all file attributes are read as an atomic
+     * operation with respect to other file system operations.
+     *
+     * <p> The {@code options} array may be used to indicate how symbolic links
+     * are handled for the case that the file is a symbolic link. By default,
+     * symbolic links are followed and the file attributes of the final target
+     * of the link are read. If the option {@link LinkOption#NOFOLLOW_LINKS
+     * NOFOLLOW_LINKS} is present then symbolic links are not followed and so
+     * the method returns the file attributes of the symbolic link.
+     *
+     * @param   file
+     *          A file reference that locates the file
+     * @param   options
+     *          Options indicating how symbolic links are handled
+     *
+     * @return  The DOS file attributes
+     *
+     * @throws  UnsupportedOperationException
+     *          If the {@code DosFileAttributeView} is not available
+     * @throws  IOException
+     *          If an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, the security manager's {@link
+     *          SecurityManager#checkRead(String) checkRead} method is invoked
+     *          to check read access to file
+     *
+     * @see DosFileAttributeView#readAttributes
+     */
+    public static DosFileAttributes readDosFileAttributes(FileRef file,
+                                                          LinkOption... options)
+        throws IOException
+    {
+        DosFileAttributeView view =
+            file.getFileAttributeView(DosFileAttributeView.class, options);
+        if (view == null)
+            throw new UnsupportedOperationException();
+        return view.readAttributes();
+    }
+
+    /**
+     * Returns the owner of a file.
+     *
+     * <p> The {@code file} parameter locates a file that supports the {@link
+     * FileOwnerAttributeView}. This file attribute view provides access to
+     * a file attribute that is the owner of the file.
+     *
+     * @param   file
+     *          A file reference that locates the file
+     *
+     * @return  A user principal representing the owner of the file
+     *
+     * @throws  UnsupportedOperationException
+     *          If the {@code FileOwnerAttributeView} is not available
+     * @throws  IOException
+     *          If an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
+     *          or its {@link SecurityManager#checkRead(String) checkRead} method
+     *          denies read access to the file.
+     *
+     * @see FileOwnerAttributeView#getOwner
+     */
+    public static UserPrincipal getOwner(FileRef file) throws IOException {
+        FileOwnerAttributeView view =
+            file.getFileAttributeView(FileOwnerAttributeView.class);
+        if (view == null)
+            throw new UnsupportedOperationException();
+        return view.getOwner();
+    }
+
+    /**
+     * Updates the file owner.
+     *
+     * <p> The {@code file} parameter locates a file that supports the {@link
+     * FileOwnerAttributeView}. This file attribute view provides access to
+     * a file attribute that is the owner of the file.
+     *
+     * @param   file
+     *          A file reference that locates the file
+     * @param   owner
+     *          The new file owner
+     *
+     * @throws  UnsupportedOperationException
+     *          If the {@code FileOwnerAttributeView} is not available
+     * @throws  IOException
+     *          If an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
+     *          or its {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method denies write access to the file.
+     *
+     * @see FileOwnerAttributeView#setOwner
+     */
+    public static void setOwner(FileRef file, UserPrincipal owner)
+            throws IOException
+    {
+        FileOwnerAttributeView view =
+            file.getFileAttributeView(FileOwnerAttributeView.class);
+        if (view == null)
+            throw new UnsupportedOperationException();
+        view.setOwner(owner);
+    }
+
+    /**
+     * Reads a file's Access Control List (ACL).
+     *
+     * <p> The {@code file} parameter locates a file that supports the {@link
+     * AclFileAttributeView}. This file attribute view provides access to ACLs
+     * based on the ACL model specified in
+     *  <a href="http://www.ietf.org/rfc/rfc3530.txt"><i>RFC&nbsp;3530</i></a>.
+     *
+     * @param   file
+     *          A file reference that locates the file
+     *
+     * @return  An ordered list of {@link AclEntry entries} representing the
+     *          ACL. The returned list is modifiable.
+     *
+     * @throws  UnsupportedOperationException
+     *          If the {@code AclAttributeView} is not available
+     * @throws  IOException
+     *          If an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
+     *          or its {@link SecurityManager#checkRead(String) checkRead} method
+     *          denies read access to the file.
+     *
+     * @see AclFileAttributeView#getAcl
+     */
+    public static List<AclEntry> getAcl(FileRef file) throws IOException {
+        AclFileAttributeView view =
+            file.getFileAttributeView(AclFileAttributeView.class);
+        if (view == null)
+            throw new UnsupportedOperationException();
+        return view.getAcl();
+    }
+
+    /**
+     * Updates a file's Access Control List (ACL).
+     *
+     * <p> The {@code file} parameter locates a file that supports the {@link
+     * AclFileAttributeView}. This file attribute view provides access to ACLs
+     * based on the ACL model specified in
+     *  <a href="http://www.ietf.org/rfc/rfc3530.txt"><i>RFC&nbsp;3530</i></a>.
+     *
+     * @param   file
+     *          A file reference that locates the file
+     * @param   acl
+     *          The new file ACL
+     *
+     * @throws  UnsupportedOperationException
+     *          If the {@code AclFileAttributeView} is not available
+     * @throws  IOException
+     *          If an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
+     *          or its {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method denies write access to the file.
+     *
+     * @see AclFileAttributeView#setAcl
+     */
+    public static void setAcl(FileRef file, List<AclEntry> acl)
+        throws IOException
+    {
+        AclFileAttributeView view =
+            file.getFileAttributeView(AclFileAttributeView.class);
+        if (view == null)
+            throw new UnsupportedOperationException();
+        view.setAcl(acl);
+    }
+
+    /**
+     * Updates the value of a file's last modified time attribute.
+     *
+     * <p> The time value is measured since the epoch
+     * (00:00:00 GMT, January 1, 1970) and is converted to the precision supported
+     * by the file system. Converting from finer to coarser granularities result
+     * in precision loss.
+     *
+     * <p> If the file system does not support a last modified time attribute then
+     * this method has no effect.
+     *
+     * @param   file
+     *          A file reference that locates the file
+     *
+     * @param   lastModifiedTime
+     *          The new last modified time, or {@code -1L} to update it to
+     *          the current time
+     * @param   unit
+     *          A {@code TimeUnit} determining how to interpret the
+     *          {@code lastModifiedTime} parameter
+     *
+     * @throws  IllegalArgumentException
+     *          If the {@code lastModifiedime} parameter is a negative value other
+     *          than {@code -1L}
+     * @throws  IOException
+     *          If an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, the security manager's {@link
+     *          SecurityManager#checkWrite(String) checkWrite} method is invoked
+     *          to check write access to file
+     *
+     * @see BasicFileAttributeView#setTimes
+     */
+    public static void setLastModifiedTime(FileRef file,
+                                           long lastModifiedTime,
+                                           TimeUnit unit)
+        throws IOException
+    {
+        file.getFileAttributeView(BasicFileAttributeView.class)
+            .setTimes(lastModifiedTime, null, null, unit);
+    }
+
+    /**
+     * Updates the value of a file's last access time attribute.
+     *
+     * <p> The time value is measured since the epoch
+     * (00:00:00 GMT, January 1, 1970) and is converted to the precision supported
+     * by the file system. Converting from finer to coarser granularities result
+     * in precision loss.
+     *
+     * <p> If the file system does not support a last access time attribute then
+     * this method has no effect.
+     *
+     * @param   lastAccessTime
+     *          The new last access time, or {@code -1L} to update it to
+     *          the current time
+     * @param   unit
+     *          A {@code TimeUnit} determining how to interpret the
+     *          {@code lastModifiedTime} parameter
+     *
+     * @throws  IllegalArgumentException
+     *          If the {@code lastAccessTime} parameter is a negative value other
+     *          than {@code -1L}
+     * @throws  IOException
+     *          If an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, the security manager's {@link
+     *          SecurityManager#checkWrite(String) checkWrite} method is invoked
+     *          to check write access to file
+     *
+     * @see BasicFileAttributeView#setTimes
+     */
+    public static void setLastAccessTime(FileRef file,
+                                         long lastAccessTime,
+                                         TimeUnit unit)
+        throws IOException
+    {
+        file.getFileAttributeView(BasicFileAttributeView.class)
+            .setTimes(null, lastAccessTime, null, unit);
+    }
+
+    /**
+     * Sets a file's POSIX permissions.
+     *
+     * <p> The {@code file} parameter is a reference to an existing file. It
+     * supports the {@link PosixFileAttributeView} that provides access to file
+     * attributes commonly associated with files on file systems used by
+     * operating systems that implement the Portable Operating System Interface
+     * (POSIX) family of standards.
+     *
+     * @param   file
+     *          A file reference that locates the file
+     * @param   perms
+     *          The new set of permissions
+     *
+     * @throws  UnsupportedOperationException
+     *          If {@code PosixFileAttributeView} is not available
+     * @throws  ClassCastException
+     *          If the sets contains elements that are not of type {@code
+     *          PosixFilePermission}
+     * @throws  IOException
+     *          If an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
+     *          or its {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method denies write access to the file.
+     *
+     * @see PosixFileAttributeView#setPermissions
+     */
+    public static void setPosixFilePermissions(FileRef file,
+                                               Set<PosixFilePermission> perms)
+        throws IOException
+    {
+        PosixFileAttributeView view =
+            file.getFileAttributeView(PosixFileAttributeView.class);
+        if (view == null)
+            throw new UnsupportedOperationException();
+        view.setPermissions(perms);
+    }
+
+    /**
+     * Reads the space attributes of a file store.
+     *
+     * <p> The {@code store} parameter is a file store that supports the
+     * {@link FileStoreSpaceAttributeView} providing access to the space related
+     * attributes of the file store. It is implementation specific if all attributes
+     * are read as an atomic operation with respect to other file system operations.
+     *
+     * @param   store
+     *          The file store
+     *
+     * @return  The file store space attributes
+     *
+     * @throws  UnsupportedOperationException
+     *          If the file store space attribute view is not supported
+     * @throws  IOException
+     *          If an I/O error occurs
+     *
+     * @see FileStoreSpaceAttributeView#readAttributes()
+     */
+    public static FileStoreSpaceAttributes readFileStoreSpaceAttributes(FileStore store)
+        throws IOException
+    {
+        FileStoreSpaceAttributeView view =
+            store.getFileStoreAttributeView(FileStoreSpaceAttributeView.class);
+        if (view == null)
+            throw new UnsupportedOperationException();
+        return view.readAttributes();
+    }
+}
diff --git a/jdk/src/share/classes/java/nio/file/attribute/BasicFileAttributeView.java b/jdk/src/share/classes/java/nio/file/attribute/BasicFileAttributeView.java
new file mode 100644
index 0000000..7010083
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/attribute/BasicFileAttributeView.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file.attribute;
+
+import java.util.concurrent.TimeUnit;
+import java.io.IOException;
+
+/**
+ * A file attribute view that provides a view of a <em>basic set</em> of file
+ * attributes common to many file systems. The basic set of file attributes
+ * consist of <em>mandatory</em> and <em>optional</em> file attributes as
+ * defined by the {@link BasicFileAttributes} interface.
+
+ * <p> The file attributes are retrieved from the file system as a <em>bulk
+ * operation</em> by invoking the {@link #readAttributes() readAttributes} method.
+ * This class also defines the {@link #setTimes setTimes} method to update the
+ * file's time attributes.
+ *
+ * <p> Where dynamic access to file attributes is required, the attributes
+ * supported by this attribute view have the following names and types:
+ * <blockquote>
+ *  <table border="1" cellpadding="8">
+ *   <tr>
+ *     <th> Name </th>
+ *     <th> Type </th>
+ *   </tr>
+ *  <tr>
+ *     <td> "lastModifiedTime" </td>
+ *     <td> {@link Long} </td>
+ *   </tr>
+ *   <tr>
+ *     <td> "lastAccessTime" </td>
+ *     <td> {@link Long} </td>
+ *   </tr>
+ *   <tr>
+ *     <td> "creationTime" </td>
+ *     <td> {@link Long} </td>
+ *   </tr>
+ *  <tr>
+ *     <td> "resolution" </td>
+ *     <td> {@link java.util.concurrent.TimeUnit} </td>
+ *   </tr>
+ *   <tr>
+ *     <td> "size" </td>
+ *     <td> {@link Long} </td>
+ *   </tr>
+ *   <tr>
+ *     <td> "isRegularFile" </td>
+ *     <td> {@link Boolean} </td>
+ *   </tr>
+ *   <tr>
+ *     <td> "isDirectory" </td>
+ *     <td> {@link Boolean} </td>
+ *   </tr>
+ *   <tr>
+ *     <td> "isSymbolicLink" </td>
+ *     <td> {@link Boolean} </td>
+ *   </tr>
+ *   <tr>
+ *     <td> "isOther" </td>
+ *     <td> {@link Boolean} </td>
+ *   </tr>
+ *   <tr>
+ *     <td> "linkCount" </td>
+ *     <td> {@link Integer} </td>
+ *   </tr>
+ *   <tr>
+ *     <td> "fileKey" </td>
+ *     <td> {@link Object} </td>
+ *   </tr>
+ * </table>
+ * </blockquote>
+ *
+ * <p> The {@link #getAttribute getAttribute} or {@link
+ * #readAttributes(String,String[]) readAttributes(String,String[])} methods may
+ * be used to read any of these attributes as if by invoking the {@link
+ * #readAttributes() readAttributes()} method.
+ *
+ * <p> The {@link #setAttribute setAttribute} method may be used to update the
+ * file's last modified time, last access time or create time attributes as if
+ * by invoking the {@link #setTimes setTimes} method. In that case, the time
+ * value is interpreted in {@link TimeUnit#MILLISECONDS milliseconds} and
+ * converted to the precision supported by the file system.
+ *
+ * @since 1.7
+ * @see Attributes
+ */
+
+public interface BasicFileAttributeView
+    extends FileAttributeView
+{
+    /**
+     * Returns the name of the attribute view. Attribute views of this type
+     * have the name {@code "basic"}.
+     */
+    @Override
+    String name();
+
+    /**
+     * Reads the basic file attributes as a bulk operation.
+     *
+     * <p> It is implementation specific if all file attributes are read as an
+     * atomic operation with respect to other file system operations.
+     *
+     * @return  the file attributes
+     *
+     * @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
+     */
+    BasicFileAttributes readAttributes() throws IOException;
+
+    /**
+     * Updates any or all of the file's last modified time, last access time,
+     * and create time attributes.
+     *
+     * <p> This method updates the file's timestamp attributes. The values are
+     * measured since the epoch (00:00:00 GMT, January 1, 1970) and converted to
+     * the precision supported by the file system. Converting from finer to
+     * coarser granularities result in precision loss. If a value is larger
+     * than the maximum supported by the file system then the corresponding
+     * timestamp is set to its maximum value.
+     *
+     * <p> If any of the {@code lastModifiedTime}, {@code lastAccessTime},
+     * or {@code createTime} parameters has the value {@code null} then the
+     * corresponding timestamp is not changed. An implementation may require to
+     * read the existing values of the file attributes when only some, but not
+     * all, of the timestamp attributes are updated. Consequently, this method
+     * may not be an atomic operation with respect to other file system
+     * operations. If all of the {@code lastModifiedTime}, {@code
+     * lastAccessTime} and {@code createTime} parameters are {@code null} then
+     * this method has no effect.
+     *
+     * @param   lastModifiedTime
+     *          the new last modified time, or {@code -1L} to update it to
+     *          the current time, or {@code null} to not change the attribute
+     * @param   lastAccessTime
+     *          the last access time, or {@code -1L} to update it to
+     *          the current time, or {@code null} to not change the attribute.
+     * @param   createTime
+     *          the file's create time, or {@code -1L} to update it to
+     *          the current time, or {@code null} to not change the attribute
+     * @param   unit
+     *          a {@code TimeUnit} determining how to interpret the time values
+     *
+     * @throws  IllegalArgumentException
+     *          if any of the parameters is a negative value other than {@code
+     *          -1L}
+     * @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#checkWrite(String) checkWrite}
+     *          method is invoked to check write access to the file
+     */
+    void setTimes(Long lastModifiedTime,
+                  Long lastAccessTime,
+                  Long createTime,
+                  TimeUnit unit) throws IOException;
+}
diff --git a/jdk/src/share/classes/java/nio/file/attribute/BasicFileAttributes.java b/jdk/src/share/classes/java/nio/file/attribute/BasicFileAttributes.java
new file mode 100644
index 0000000..64c163b
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/attribute/BasicFileAttributes.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file.attribute;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Basic attributes associated with a file in a file system.
+ *
+ * <p> Basic file attributes are attributes that are common to many file systems
+ * and consist of mandatory and optional file attributes as defined by this
+ * interface.
+ *
+ * <p> <b>Usage Example:</b>
+ * <pre>
+ *    FileRef file = ...
+ *    BasicFileAttributes attrs = Attributes.readBasicFileAttributes(file);
+ * </pre>
+ *
+ * @since 1.7
+ *
+ * @see BasicFileAttributeView
+ */
+
+public interface BasicFileAttributes {
+
+    /**
+     * Returns the time of last modification.
+     *
+     * <p> The {@link #resolution() resolution} method returns the {@link TimeUnit}
+     * to interpret the return value of this method.
+     *
+     * @return  a <code>long</code> value representing the time the file was
+     *          last modified since the epoch (00:00:00 GMT, January 1, 1970),
+     *          or {@code -1L} if the attribute is not supported.
+     */
+    long lastModifiedTime();
+
+    /**
+     * Returns the time of last access if supported.
+     *
+     * <p> The {@link #resolution() resolution} method returns the {@link TimeUnit}
+     * to interpret the return value of this method.
+     *
+     * @return  a <code>long</code> value representing the time of last access
+     *          since the epoch (00:00:00 GMT, January 1, 1970), or {@code -1L}
+     *          if the attribute is not supported.
+     */
+    long lastAccessTime();
+
+    /**
+     * Returns the creation time if supported. The creation time is the time
+     * that the file was created.
+     *
+     * <p> The {@link #resolution() resolution} method returns the {@link TimeUnit}
+     * to interpret the return value of this method.
+     *
+     * @return  a <code>long</code> value representing the time the file was
+     *          created since the epoch (00:00:00 GMT, January 1, 1970), or
+     *          {@code -1L} if the attribute is not supported.
+     */
+    long creationTime();
+
+    /**
+     * Returns the {@link TimeUnit} required to interpret the time of last
+     * modification, time of last access, and creation time.
+     *
+     * @return  the {@code TimeUnit} required to interpret the file time stamps
+     */
+    TimeUnit resolution();
+
+    /**
+     * Tells whether the file is a regular file with opaque content.
+     */
+    boolean isRegularFile();
+
+    /**
+     * Tells whether the file is a directory.
+     */
+    boolean isDirectory();
+
+    /**
+     * Tells whether the file is a symbolic-link.
+     */
+    boolean isSymbolicLink();
+
+    /**
+     * Tells whether the file is something other than a regular file, directory,
+     * or link.
+     */
+    boolean isOther();
+
+    /**
+     * Returns the size of the 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.
+     *
+     * @return  the file size, in bytes
+     */
+    long size();
+
+    /**
+     * Returns the number of <em>links</em> to this file.
+     *
+     * <p> On file systems where the same file may be in several directories then
+     * the link count is the number of directory entries for the file. The return
+     * value is {@code 1} on file systems that only allow a file to have a
+     * single name in a single directory.
+     *
+     * @see java.nio.file.Path#createLink
+     */
+    int linkCount();
+
+    /**
+     * Returns an object that uniquely identifies the given file, or {@code
+     * null} if a file key is not available. On some platforms or file systems
+     * it is possible to use an identifier, or a combination of identifiers to
+     * uniquely identify a file. Such identifiers are important for operations
+     * such as file tree traversal in file systems that support <a
+     * href="../package-summary.html#links">symbolic links</a> or file systems
+     * that allow a file to be an entry in more than one directory. On UNIX file
+     * systems, for example, the <em>device ID</em> and <em>inode</em> are
+     * commonly used for such purposes.
+     *
+     * <p> The file key returned by this method can only be guaranteed to be
+     * unique if the file system and files remain static. Whether a file system
+     * re-uses identifiers after a file is deleted is implementation dependent and
+     * therefore unspecified.
+     *
+     * <p> File keys returned by this method can be compared for equality and are
+     * suitable for use in collections. If the file system and files remain static,
+     * and two files are the {@link java.nio.file.FileRef#isSameFile same} with
+     * non-{@code null} file keys, then their file keys are equal.
+     *
+     * @see java.nio.file.Files#walkFileTree
+     */
+    Object fileKey();
+}
diff --git a/jdk/src/share/classes/java/nio/file/attribute/DosFileAttributeView.java b/jdk/src/share/classes/java/nio/file/attribute/DosFileAttributeView.java
new file mode 100644
index 0000000..c576839
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/attribute/DosFileAttributeView.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file.attribute;
+
+import java.io.IOException;
+
+/**
+ * A file attribute view that provides a view of the legacy "DOS" file attributes.
+ * These attributes are supported by file systems such as the File Allocation
+ * Table (FAT) format commonly used in <em>consumer devices</em>.
+ *
+ * <p> A {@code DosFileAttributeView} is a {@link BasicFileAttributeView} that
+ * additionally supports access to the set of DOS attribute flags that are used
+ * to indicate if the file is read-only, hidden, a system file, or archived.
+ *
+ * <p> Where dynamic access to file attributes is required, the attributes
+ * supported by this attribute view are as defined by {@code
+ * BasicFileAttributeView}, and in addition, the following attributes are
+ * supported:
+ * <blockquote>
+ * <table border="1" cellpadding="8">
+ *   <tr>
+ *     <th> Name </th>
+ *     <th> Type </th>
+ *   </tr>
+ *   <tr>
+ *     <td> readonly </td>
+ *     <td> {@link Boolean} </td>
+ *   </tr>
+ *   <tr>
+ *     <td> hidden </td>
+ *     <td> {@link Boolean} </td>
+ *   </tr>
+ *   <tr>
+ *     <td> system </td>
+ *     <td> {@link Boolean} </td>
+ *   </tr>
+ *   <tr>
+ *     <td> archive </td>
+ *     <td> {@link Boolean} </td>
+ *   </tr>
+ * </table>
+ * </blockquote>
+ *
+ * <p> The {@link #getAttribute getAttribute} or {@link #readAttributes(String,String[])
+ * readAttributes(String,String[])} methods may be used to read any of these
+ * attributes, or any of the attributes defined by {@link BasicFileAttributeView}
+ * as if by invoking the {@link #readAttributes readAttributes()} method.
+ *
+ * <p> The {@link #setAttribute setAttribute} method may be used to update the
+ * file's last modified time, last access time or create time attributes as
+ * defined by {@link BasicFileAttributeView}. It may also be used to update
+ * the DOS attributes as if by invoking the {@link #setReadOnly setReadOnly},
+ * {@link #setHidden setHidden}, {@link #setSystem setSystem}, and {@link
+ * #setArchive setArchive} methods respectively.
+ *
+ * @since 1.7
+ */
+
+public interface DosFileAttributeView
+    extends BasicFileAttributeView
+{
+    /**
+     * Returns the name of the attribute view. Attribute views of this type
+     * have the name {@code "dos"}.
+     */
+    @Override
+    String name();
+
+    /**
+     * @throws  IOException                             {@inheritDoc}
+     * @throws  SecurityException                       {@inheritDoc}
+     */
+    @Override
+    DosFileAttributes readAttributes() throws IOException;
+
+    /**
+     * Updates the value of the read-only attribute.
+     *
+     * <p> It is implementation specific if the attribute can be updated as an
+     * atomic operation with respect to other file system operations. An
+     * implementation may, for example, require to read the existing value of
+     * the DOS attribute in order to update this attribute.
+     *
+     * @param   value
+     *          the new value of the attribute
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default, and a security manager is installed,
+     *          its  {@link SecurityManager#checkWrite(String) checkWrite} method
+     *          is invoked to check write access to the file
+     */
+    void setReadOnly(boolean value) throws IOException;
+
+    /**
+     * Updates the value of the hidden attribute.
+     *
+     * <p> It is implementation specific if the attribute can be updated as an
+     * atomic operation with respect to other file system operations. An
+     * implementation may, for example, require to read the existing value of
+     * the DOS attribute in order to update this attribute.
+     *
+     * @param   value
+     *          the new value of the attribute
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default, and a security manager is installed,
+     *          its  {@link SecurityManager#checkWrite(String) checkWrite} method
+     *          is invoked to check write access to the file
+     */
+    void setHidden(boolean value) throws IOException;
+
+    /**
+     * Updates the value of the system attribute.
+     *
+     * <p> It is implementation specific if the attribute can be updated as an
+     * atomic operation with respect to other file system operations. An
+     * implementation may, for example, require to read the existing value of
+     * the DOS attribute in order to update this attribute.
+     *
+     * @param   value
+     *          the new value of the attribute
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default, and a security manager is installed,
+     *          its  {@link SecurityManager#checkWrite(String) checkWrite} method
+     *          is invoked to check write access to the file
+     */
+    void setSystem(boolean value) throws IOException;
+
+    /**
+     * Updates the value of the archive attribute.
+     *
+     * <p> It is implementation specific if the attribute can be updated as an
+     * atomic operation with respect to other file system operations. An
+     * implementation may, for example, require to read the existing value of
+     * the DOS attribute in order to update this attribute.
+     *
+     * @param   value
+     *          the new value of the attribute
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default, and a security manager is installed,
+     *          its  {@link SecurityManager#checkWrite(String) checkWrite} method
+     *          is invoked to check write access to the file
+     */
+    void setArchive(boolean value) throws IOException;
+}
diff --git a/jdk/src/share/classes/java/nio/file/attribute/DosFileAttributes.java b/jdk/src/share/classes/java/nio/file/attribute/DosFileAttributes.java
new file mode 100644
index 0000000..53e63d5
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/attribute/DosFileAttributes.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file.attribute;
+
+/**
+ * File attributes associated with a file in a file system that supports
+ * legacy "DOS" attributes.
+ *
+ * <p> The DOS attributes of a file are retrieved using a {@link
+ * DosFileAttributeView} by invoking its {@link DosFileAttributeView#readAttributes
+ * readAttributes} method.
+ *
+ * @since 1.7
+ *
+ * @see Attributes#readDosFileAttributes
+ */
+
+public interface DosFileAttributes
+    extends BasicFileAttributes
+{
+    /**
+     * Returns the value of the read-only attribute.
+     *
+     * <p> This attribute is often used as a simple access control mechanism
+     * to prevent files from being deleted or updated. Whether the file system
+     * or platform does any enforcement to prevent <em>read-only</em> files
+     * from being updated is implementation specific.
+     *
+     * @return  the value of the read-only attribute
+     */
+    boolean isReadOnly();
+
+    /**
+     * Returns the value of the hidden attribute.
+     *
+     * <p> This attribute is often used to indicate if the file is visible to
+     * users.
+     *
+     * @return  the value of the hidden attribute
+     */
+    boolean isHidden();
+
+    /**
+     * Returns the value of the archive attribute.
+     *
+     * <p> This attribute is typically used by backup programs.
+     *
+     * @return  the value of the archive attribute
+     */
+    boolean isArchive();
+
+    /**
+     * Returns the value of the system attribute.
+     *
+     * <p> This attribute is often used to indicate that the file is a component
+     * of the operating system.
+     *
+     * @return  the value of the system attribute
+     */
+    boolean isSystem();
+}
diff --git a/jdk/src/share/classes/java/nio/file/attribute/FileAttribute.java b/jdk/src/share/classes/java/nio/file/attribute/FileAttribute.java
new file mode 100644
index 0000000..ed0d731
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/attribute/FileAttribute.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file.attribute;
+
+/**
+ * An object that encapsulates the value of a file attribute that can be set
+ * atomically when creating a new file or directory by invoking the {@link
+ * java.nio.file.Path#createFile createFile} or {@link
+ * java.nio.file.Path#createDirectory createDirectory} methods.
+ *
+ * @param <T> The type of the file attribute value
+ *
+ * @since 1.7
+ * @see PosixFilePermissions#asFileAttribute
+ */
+
+public interface FileAttribute<T> {
+    /**
+     * Returns the attribute name.
+     */
+    String name();
+
+    /**
+     * Returns the attribute value.
+     */
+    T value();
+}
diff --git a/jdk/src/share/classes/java/nio/file/attribute/FileAttributeView.java b/jdk/src/share/classes/java/nio/file/attribute/FileAttributeView.java
new file mode 100644
index 0000000..78a67b4
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/attribute/FileAttributeView.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file.attribute;
+
+/**
+ * An attribute view that is a read-only or updatable view of non-opaque
+ * values associated with a file in a filesystem. This interface is extended or
+ * implemented by specific file attribute views that define methods to read
+ * and/or update the attributes of a file.
+ *
+ * @since 1.7
+ *
+ * @see java.nio.file.FileRef#getFileAttributeView(Class,java.nio.file.LinkOption[])
+ * @see java.nio.file.FileRef#getFileAttributeView(String,java.nio.file.LinkOption[])
+ */
+
+public interface FileAttributeView
+    extends AttributeView
+{
+}
diff --git a/jdk/src/share/classes/java/nio/file/attribute/FileOwnerAttributeView.java b/jdk/src/share/classes/java/nio/file/attribute/FileOwnerAttributeView.java
new file mode 100644
index 0000000..0afc19e
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/attribute/FileOwnerAttributeView.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file.attribute;
+
+import java.io.IOException;
+
+/**
+ * A file attribute view that supports reading or updating the owner of a file.
+ * This file attribute view is intended for file system implementations that
+ * support a file attribute that represents an identity that is the owner of
+ * the file. Often the owner of a file is the identity of the entity that
+ * created the file.
+ *
+ * <p> The {@link #getOwner getOwner} or {@link #setOwner setOwner} methods may
+ * be used to read or update the owner of the file.
+ *
+ * <p> Where dynamic access to file attributes is required, the owner attribute
+ * is identified by the name {@code "owner"}, and the value of the attribute is
+ * a {@link UserPrincipal}. The {@link #readAttributes readAttributes}, {@link
+ * #getAttribute getAttribute} and {@link #setAttribute setAttributes} methods
+ * may be used to read or update the file owner.
+ *
+ * @since 1.7
+ */
+
+public interface FileOwnerAttributeView
+    extends FileAttributeView
+{
+    /**
+     * Returns the name of the attribute view. Attribute views of this type
+     * have the name {@code "owner"}.
+     */
+    @Override
+    String name();
+
+    /**
+     * Read the file owner.
+     *
+     * <p> It it implementation specific if the file owner can be a {@link
+     * GroupPrincipal group}.
+     *
+     * @return  the file owner
+     *
+     * @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.
+     */
+    UserPrincipal getOwner() throws IOException;
+
+    /**
+     * Updates the file owner.
+     *
+     * <p> It it implementation specific if the file owner can be a {@link
+     * GroupPrincipal group}. To ensure consistent and correct behavior
+     * across platforms it is recommended that this method should only be used
+     * to set the file owner to a user principal that is not a group.
+     *
+     * @param   owner
+     *          the new file owner
+     *
+     * @throws  IOException
+     *          if an I/O error occurs, or the {@code owner} parameter is a
+     *          group and this implementation does not support setting the owner
+     *          to a group
+     * @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#checkWrite(String) checkWrite} method
+     *          denies write access to the file.
+     */
+    void setOwner(UserPrincipal owner) throws IOException;
+}
diff --git a/jdk/src/share/classes/java/nio/file/attribute/FileStoreAttributeView.java b/jdk/src/share/classes/java/nio/file/attribute/FileStoreAttributeView.java
new file mode 100644
index 0000000..6dfb3ff
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/attribute/FileStoreAttributeView.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file.attribute;
+
+/**
+ * An attribute view that is a read-only or updatable view of the attributes of
+ * a {@link java.nio.file.FileStore}.
+ *
+ * @since 1.7
+ */
+
+public interface FileStoreAttributeView
+    extends AttributeView
+{
+}
diff --git a/jdk/src/share/classes/java/nio/file/attribute/FileStoreSpaceAttributeView.java b/jdk/src/share/classes/java/nio/file/attribute/FileStoreSpaceAttributeView.java
new file mode 100644
index 0000000..22d3861
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/attribute/FileStoreSpaceAttributeView.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file.attribute;
+
+import java.io.IOException;
+
+/**
+ * A file store attribute view that supports reading of space attributes.
+ *
+ * <p> Where dynamic access to file attributes is required, the attributes
+ * supported by this attribute view have the following names and types:
+ * <blockquote>
+ * <table border="1" cellpadding="8">
+ *   <tr>
+ *     <th> Name </th>
+ *     <th> Type </th>
+ *   </tr>
+ *  <tr>
+ *     <td> "totalSpace" </td>
+ *     <td> {@link Long} </td>
+ *   </tr>
+ *  <tr>
+ *     <td> "usableSpace" </td>
+ *     <td> {@link Long} </td>
+ *   </tr>
+ *  <tr>
+ *     <td> "unallocatedSpace" </td>
+ *     <td> {@link Long} </td>
+ *   </tr>
+ * </table>
+ * </blockquote>
+ * <p> The {@link #getAttribute getAttribute} or {@link #readAttributes
+ * readAttributes(String,String[])} methods may be used to read any of these
+ * attributes as if by invoking the {@link #readAttributes readAttributes()}
+ * method.
+ *
+ * @since 1.7
+ */
+
+public interface FileStoreSpaceAttributeView
+    extends FileStoreAttributeView
+{
+    /**
+     * Returns the name of the attribute view. Attribute views of this type
+     * have the name {@code "space"}.
+     */
+    @Override
+    String name();
+
+    /**
+     * Reads the disk space attributes as a bulk operation.
+     *
+     * <p> It is file system specific if all attributes are read as an
+     * atomic operation with respect to other file system operations.
+     *
+     * @return  The disk space attributes
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    FileStoreSpaceAttributes readAttributes() throws IOException;
+}
diff --git a/jdk/src/share/classes/java/nio/file/attribute/FileStoreSpaceAttributes.java b/jdk/src/share/classes/java/nio/file/attribute/FileStoreSpaceAttributes.java
new file mode 100644
index 0000000..6f12d71
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/attribute/FileStoreSpaceAttributes.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file.attribute;
+
+/**
+ * Space related attributes of a file store.
+ *
+ * @since 1.7
+ *
+ * @see Attributes#readFileStoreSpaceAttributes
+ */
+
+public interface FileStoreSpaceAttributes {
+    /**
+     * Returns the size, in bytes, of the file store.
+     */
+    long totalSpace();
+
+    /**
+     * Returns the number of bytes available to this Java virtual machine on the
+     * file store.
+     *
+     * <p> The returned number of available bytes is a hint, but not a
+     * guarantee, that it is possible to use most or any of these bytes.  The
+     * number of usable bytes is most likely to be accurate immediately
+     * after the space attributes are obtained. It is likely to be made inaccurate
+     * by any external I/O operations including those made on the system outside
+     * of this Java virtual machine.
+     */
+    long usableSpace();
+
+    /**
+     * Returns the number of unallocated bytes in the file store.
+     *
+     * <p> The returned number of unallocated bytes is a hint, but not a
+     * guarantee, that it is possible to use most or any of these bytes.  The
+     * number of unallocated bytes is most likely to be accurate immediately
+     * after the space attributes are obtained. It is likely to be
+     * made inaccurate by any external I/O operations including those made on
+     * the system outside of this virtual machine.
+     */
+    long unallocatedSpace();
+}
diff --git a/jdk/src/share/classes/java/nio/file/attribute/GroupPrincipal.java b/jdk/src/share/classes/java/nio/file/attribute/GroupPrincipal.java
new file mode 100644
index 0000000..db09d48
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/attribute/GroupPrincipal.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file.attribute;
+
+/**
+ * A {@code UserPrincipal} representing a <em>group identity</em>, used to
+ * determine access rights to objects in a file system. The exact definition of
+ * a group is implementation specific, but typically, it represents an identity
+ * created for administrative purposes so as to determine the access rights for
+ * the members of the group. Whether an entity can be a member of multiple
+ * groups, and whether groups can be nested, are implementation specified and
+ * therefore not specified.
+ *
+ * @since 1.7
+ *
+ * @see UserPrincipalLookupService#lookupPrincipalByGroupName
+ */
+
+public interface GroupPrincipal extends UserPrincipal { }
diff --git a/jdk/src/share/classes/java/nio/file/attribute/PosixFileAttributeView.java b/jdk/src/share/classes/java/nio/file/attribute/PosixFileAttributeView.java
new file mode 100644
index 0000000..285b8bb
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/attribute/PosixFileAttributeView.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file.attribute;
+
+import java.nio.file.*;
+import java.util.Set;
+import java.io.IOException;
+
+/**
+ * A file attribute view that provides a view of the file attributes commonly
+ * associated with files on file systems used by operating systems that implement
+ * the Portable Operating System Interface (POSIX) family of standards.
+ *
+ * <p> Operating systems that implement the <a href="http://www.opengroup.org">
+ * POSIX</a> family of standards commonly use file systems that have a
+ * file <em>owner</em>, <em>group-owner</em>, and related <em>access
+ * permissions</em>. This file attribute view provides read and write access
+ * to these attributes.
+ *
+ * <p> The {@link #readAttributes() readAttributes} method is used to read the
+ * file's attributes. The file {@link PosixFileAttributes#owner() owner} is
+ * represented by a {@link UserPrincipal} that is the identity of the file owner
+ * for the purposes of access control. The {@link PosixFileAttributes#group()
+ * group-owner}, represented by a {@link GroupPrincipal}, is the identity of the
+ * group owner, where a group is an identity created for administrative purposes
+ * so as to determine the access rights for the members of the group.
+ *
+ * <p> The {@link PosixFileAttributes#permissions() permissions} attribute is a
+ * set of access permissions. This file attribute view provides access to the nine
+ * permission defined by the {@link PosixFilePermission} class.
+ * These nine permission bits determine the <em>read</em>, <em>write</em>, and
+ * <em>execute</em> access for the file owner, group, and others (others
+ * meaning identities other than the owner and members of the group). Some
+ * operating systems and file systems may provide additional permission bits
+ * but access to these other bits is not defined by this class in this release.
+ *
+ * <p> <b>Usage Example:</b>
+ * Suppose we need to print out the owner and access permissions of a file:
+ * <pre>
+ *     FileRef file = ...
+ *     PosixFileAttributes attrs = file.newFileAttributeView(PosixFileAttributeView.class)
+ *         .readAttributes();
+ *     System.out.format("%s %s%n",
+ *         attrs.owner().getName(),
+ *         PosixFilePermissions.toString(attrs.permissions()));
+ * </pre>
+ *
+ * <h4> Dynamic Access </h4>
+ * <p> Where dynamic access to file attributes is required, the attributes
+ * supported by this attribute view are as defined by {@link
+ * BasicFileAttributeView} and {@link FileOwnerAttributeView}, and in addition,
+ * the following attributes are supported:
+ * <blockquote>
+ * <table border="1" cellpadding="8">
+ *   <tr>
+ *     <th> Name </th>
+ *     <th> Type </th>
+ *   </tr>
+ *  <tr>
+ *     <td> "permissions" </td>
+ *     <td> {@link Set}&lt;{@link PosixFilePermission}&gt; </td>
+ *   </tr>
+ *   <tr>
+ *     <td> "group" </td>
+ *     <td> {@link GroupPrincipal} </td>
+ *   </tr>
+ * </table>
+ * </blockquote>
+ *
+ * <p> The {@link #getAttribute getAttribute} or {@link
+ * #readAttributes(String,String[]) readAttributes(String,String[])} methods may
+ * be used to read any of these attributes, or any of the attributes defined by
+ * {@link BasicFileAttributeView} as if by invoking the {@link #readAttributes
+ * readAttributes()} method.
+ *
+ * <p> The {@link #setAttribute setAttribute} method may be used to update the
+ * file's last modified time, last access time or create time attributes as
+ * defined by {@link BasicFileAttributeView}. It may also be used to update
+ * the permissions, owner, or group-owner as if by invoking the {@link
+ * #setPermissions setPermissions}, {@link #setOwner setOwner}, and {@link
+ * #setGroup setGroup} methods respectively.
+ *
+ * <h4> Setting Initial Permissions </h4>
+ * <p> Implementations supporting this attribute view may also support setting
+ * the initial permissions when creating a file or directory. The
+ * initial permissions are provided to the  {@link Path#createFile createFile}
+ * or {@link Path#createDirectory createDirectory} methods as a {@link
+ * FileAttribute} with {@link FileAttribute#name name} {@code "posix:permissions"}
+ * and a {@link FileAttribute#value value} that is the set of permissions. The
+ * following example uses the {@link PosixFilePermissions#asFileAttribute
+ * asFileAttribute} method to construct a {@code FileAttribute} when creating a
+ * file:
+ *
+ * <pre>
+ *     Path path = ...
+ *     Set&lt;PosixFilePermission&gt; perms =
+ *         EnumSet.of(OWNER_READ, OWNER_WRITE, OWNER_EXECUTE, GROUP_READ);
+ *     path.createFile(PosixFilePermissions.asFileAttribute(perms));
+ * </pre>
+ *
+ * <p> When the access permissions are set at file creation time then the actual
+ * value of the permissions may differ that the value of the attribute object.
+ * The reasons for this are implementation specific. On UNIX systems, for
+ * example, a process has a <em>umask</em> that impacts the permission bits
+ * of newly created files. Where an implementation supports the setting of
+ * the access permissions, and the underlying file system supports access
+ * permissions, then it is required that the value of the actual access
+ * permissions will be equal or less than the value of the attribute
+ * provided to the {@link java.nio.file.Path#createFile createFile} or
+ * {@link java.nio.file.Path#createDirectory createDirectory} methods. In
+ * other words, the file may be more secure than requested.
+ *
+ * @since 1.7
+ *
+ * @see Attributes#readPosixFileAttributes
+ */
+
+public interface PosixFileAttributeView
+    extends BasicFileAttributeView, FileOwnerAttributeView
+{
+    /**
+     * Returns the name of the attribute view. Attribute views of this type
+     * have the name {@code "posix"}.
+     */
+    @Override
+    String name();
+
+    /**
+     * @throws  IOException                {@inheritDoc}
+     * @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.
+     */
+    @Override
+    PosixFileAttributes readAttributes() throws IOException;
+
+    /**
+     * Updates the file permissions.
+     *
+     * @param   perms
+     *          the new set of permissions
+     *
+     * @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, a security manager is
+     *          installed, and it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
+     *          or its {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method denies write access to the file.
+     */
+    void setPermissions(Set<PosixFilePermission> perms) throws IOException;
+
+    /**
+     * Updates the file group-owner.
+     *
+     * @param   group
+     *          the new file group-owner
+     *
+     * @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.
+     */
+    void setGroup(GroupPrincipal group) throws IOException;
+}
diff --git a/jdk/src/share/classes/java/nio/file/attribute/PosixFileAttributes.java b/jdk/src/share/classes/java/nio/file/attribute/PosixFileAttributes.java
new file mode 100644
index 0000000..c09aa9d
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/attribute/PosixFileAttributes.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file.attribute;
+
+import java.util.Set;
+
+/**
+ * File attributes associated with files on file systems used by operating systems
+ * that implement the Portable Operating System Interface (POSIX) family of
+ * standards.
+ *
+ * <p> The POSIX attributes of a file are retrieved using a {@link
+ * PosixFileAttributeView} by invoking its {@link
+ * PosixFileAttributeView#readAttributes readAttributes} method.
+ *
+ * @since 1.7
+ *
+ * @see Attributes#readPosixFileAttributes
+ */
+
+public interface PosixFileAttributes
+    extends BasicFileAttributes
+{
+    /**
+     * Returns the owner of the file.
+     *
+     * @return  the file owner
+     *
+     * @see PosixFileAttributeView#setOwner
+     */
+    UserPrincipal owner();
+
+    /**
+     * Returns the group owner of the file.
+     *
+     * @return  the file group owner
+     *
+     * @see PosixFileAttributeView#setGroup
+     */
+    GroupPrincipal group();
+
+    /**
+     * Returns the permissions of the file. The file permissions are returned
+     * as a set of {@link PosixFilePermission} elements. The returned set is a
+     * copy of the file permissions and is modifiable. This allows the result
+     * to be modified and passed to the {@link PosixFileAttributeView#setPermissions
+     * setPermissions} method to update the file's permissions.
+     *
+     * @return  the file permissions
+     *
+     * @see PosixFileAttributeView#setPermissions
+     */
+    Set<PosixFilePermission> permissions();
+}
diff --git a/jdk/src/share/classes/java/nio/file/attribute/PosixFilePermission.java b/jdk/src/share/classes/java/nio/file/attribute/PosixFilePermission.java
new file mode 100644
index 0000000..795f509
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/attribute/PosixFilePermission.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file.attribute;
+
+import java.util.*;
+
+/**
+ * Defines the bits for use with the {@link PosixFileAttributes#permissions()
+ * permissions} attribute.
+ *
+ * <p> The {@link PosixFileAttributes} class defines method methods for
+ * manipulating {@link Set sets} of permissions.
+ *
+ * @since 1.7
+ */
+
+public enum PosixFilePermission {
+
+    /**
+     * Read permission, owner.
+     */
+    OWNER_READ,
+
+    /**
+     * Write permission, owner.
+     */
+    OWNER_WRITE,
+
+    /**
+     * Execute/search permission, owner.
+     */
+    OWNER_EXECUTE,
+
+    /**
+     * Read permission, group.
+     */
+    GROUP_READ,
+
+    /**
+     * Write permission, group.
+     */
+    GROUP_WRITE,
+
+    /**
+     * Execute/search permission, group.
+     */
+    GROUP_EXECUTE,
+
+    /**
+     * Read permission, others.
+     */
+    OTHERS_READ,
+
+    /**
+     * Write permission, others.
+     */
+    OTHERS_WRITE,
+
+    /**
+     * Execute/search permission, others.
+     */
+    OTHERS_EXECUTE;
+}
diff --git a/jdk/src/share/classes/java/nio/file/attribute/PosixFilePermissions.java b/jdk/src/share/classes/java/nio/file/attribute/PosixFilePermissions.java
new file mode 100644
index 0000000..97d322c
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/attribute/PosixFilePermissions.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file.attribute;
+
+import static java.nio.file.attribute.PosixFilePermission.*;
+import java.util.*;
+
+/**
+ * This class consists exclusively of static methods that operate on sets of
+ * {@link PosixFilePermission} objects.
+ *
+ * @since 1.7
+ */
+
+public class PosixFilePermissions {
+    private PosixFilePermissions() { }
+
+    // Write string representation of permission bits to {@code sb}.
+    private static void writeBits(StringBuilder sb, boolean r, boolean w, boolean x) {
+        if (r) {
+            sb.append('r');
+        } else {
+            sb.append('-');
+        }
+        if (w) {
+            sb.append('w');
+        } else {
+            sb.append('-');
+        }
+        if (x) {
+            sb.append('x');
+        } else {
+            sb.append('-');
+        }
+    }
+
+    /**
+     * Returns the {@code String} representation of a set of permissions.
+     *
+     * <p> If the set contains {@code null} or elements that are not of type
+     * {@code PosixFilePermission} then these elements are ignored.
+     *
+     * @param   perms
+     *          the set of permissions
+     *
+     * @return  the string representation of the permission set
+     *
+     * @see #fromString
+     */
+    public static String toString(Set<PosixFilePermission> perms) {
+        StringBuilder sb = new StringBuilder(9);
+        writeBits(sb, perms.contains(OWNER_READ), perms.contains(OWNER_WRITE),
+          perms.contains(OWNER_EXECUTE));
+        writeBits(sb, perms.contains(GROUP_READ), perms.contains(GROUP_WRITE),
+          perms.contains(GROUP_EXECUTE));
+        writeBits(sb, perms.contains(OTHERS_READ), perms.contains(OTHERS_WRITE),
+          perms.contains(OTHERS_EXECUTE));
+        return sb.toString();
+    }
+
+    private static boolean isSet(char c, char setValue) {
+        if (c == setValue)
+            return true;
+        if (c == '-')
+            return false;
+        throw new IllegalArgumentException("Invalid mode");
+    }
+    private static boolean isR(char c) { return isSet(c, 'r'); }
+    private static boolean isW(char c) { return isSet(c, 'w'); }
+    private static boolean isX(char c) { return isSet(c, 'x'); }
+
+    /**
+     * Returns the set of permissions corresponding to a given {@code String}
+     * representation.
+     *
+     * <p> The {@code perms} parameter is a {@code String} representing the
+     * permissions. It has 9 characters that are interpreted as three sets of
+     * three. The first set refers to the owner's permissions; the next to the
+     * group permissions and the last to others. Within each set, the first
+     * character is {@code 'r'} to indicate permission to read, the second
+     * character is {@code 'w'} to indicate permission to write, and the third
+     * character is {@code 'x'} for execute permission. Where a permission is
+     * not set then the corresponding character is set to {@code '-'}.
+     *
+     * <p> <b>Usage Example:</b>
+     * Suppose we require the set of permissions that indicate the owner has read,
+     * write, and execute permissions, the group has read and execute permissions
+     * and others have none.
+     * <pre>
+     *   Set&lt;PosixFilePermission&gt; perms = PosixFilePermissions.fromString("rwxr-x---");
+     * </pre>
+     *
+     * @param   perms
+     *          string representing a set of permissions
+     *
+     * @return  the resulting set of permissions
+     *
+     * @throws  IllegalArgumentException
+     *          if the string cannot be converted to a set of permissions
+     *
+     * @see #toString(Set)
+     */
+    public static Set<PosixFilePermission> fromString(String perms) {
+        if (perms.length() != 9)
+            throw new IllegalArgumentException("Invalid mode");
+        Set<PosixFilePermission> result = new HashSet<PosixFilePermission>();
+        if (isR(perms.charAt(0))) result.add(OWNER_READ);
+        if (isW(perms.charAt(1))) result.add(OWNER_WRITE);
+        if (isX(perms.charAt(2))) result.add(OWNER_EXECUTE);
+        if (isR(perms.charAt(3))) result.add(GROUP_READ);
+        if (isW(perms.charAt(4))) result.add(GROUP_WRITE);
+        if (isX(perms.charAt(5))) result.add(GROUP_EXECUTE);
+        if (isR(perms.charAt(6))) result.add(OTHERS_READ);
+        if (isW(perms.charAt(7))) result.add(OTHERS_WRITE);
+        if (isX(perms.charAt(8))) result.add(OTHERS_EXECUTE);
+        return result;
+    }
+
+    /**
+     * Creates a {@link FileAttribute}, encapsulating a copy of the given file
+     * permissions, suitable for passing to the {@link java.nio.file.Path#createFile
+     * createFile} or {@link java.nio.file.Path#createDirectory createDirectory}
+     * methods.
+     *
+     * @param   perms
+     *          the set of permissions
+     *
+     * @return  an attribute encapsulating the given file permissions with
+     *          {@link FileAttribute#name name} {@code "posix:permissions"}
+     *
+     * @throws  ClassCastException
+     *          if the set contains elements that are not of type {@code
+     *          PosixFilePermission}
+     */
+    public static FileAttribute<Set<PosixFilePermission>>
+        asFileAttribute(Set<PosixFilePermission> perms)
+    {
+        // copy set and check for nulls (CCE will be thrown if an element is not
+        // a PosixFilePermission)
+        perms = new HashSet<PosixFilePermission>(perms);
+        for (PosixFilePermission p: perms) {
+            if (p == null)
+                throw new NullPointerException();
+        }
+        final Set<PosixFilePermission> value = perms;
+        return new FileAttribute<Set<PosixFilePermission>>() {
+            @Override
+            public String name() {
+                return "posix:permissions";
+            }
+            @Override
+            public Set<PosixFilePermission> value() {
+                return Collections.unmodifiableSet(value);
+            }
+        };
+    }
+}
diff --git a/jdk/src/share/classes/java/nio/file/attribute/UserDefinedFileAttributeView.java b/jdk/src/share/classes/java/nio/file/attribute/UserDefinedFileAttributeView.java
new file mode 100644
index 0000000..c0b6896
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/attribute/UserDefinedFileAttributeView.java
@@ -0,0 +1,232 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file.attribute;
+
+import java.nio.ByteBuffer;
+import java.util.List;
+import java.io.IOException;
+
+/**
+ * A file attribute view that provides a view of a file's user-defined
+ * attributes, sometimes known as <em>extended attributes</em>. User-defined
+ * file attributes are used to store metadata with a file that is not meaningful
+ * to the file system. It is primarily intended for file system implementations
+ * that support such a capability directly but may be emulated. The details of
+ * such emulation are highly implementation specific and therefore not specified.
+ *
+ * <p> This {@code FileAttributeView} provides a view of a file's user-defined
+ * attributes as a set of name/value pairs, where the attribute name is
+ * represented by a {@code String}. An implementation may require to encode and
+ * decode from the platform or file system representation when accessing the
+ * attribute. The value has opaque content. This attribute view defines the
+ * {@link #read read} and {@link #write write} methods to read the value into
+ * or write from a {@link ByteBuffer}. This {@code FileAttributeView} is not
+ * intended for use where the size of an attribute value is larger than {@link
+ * Integer#MAX_VALUE}.
+ *
+ * <p> User-defined attributes may be used in some implementations to store
+ * security related attributes so consequently, in the case of the default
+ * provider at least, all methods that access user-defined attributes require the
+ * {@code RuntimePermission("accessUserDefinedAttributes")} permission when a
+ * security manager is installed.
+ *
+ * <p> The {@link java.nio.file.FileStore#supportsFileAttributeView
+ * supportsFileAttributeView} method may be used to test if a specific {@link
+ * java.nio.file.FileStore FileStore} supports the storage of user-defined
+ * attributes.
+ *
+ * <p> Where dynamic access to file attributes is required, the {@link
+ * #getAttribute getAttribute} or {@link #readAttributes(String,String[])
+ * readAttributes(String,String[])} methods may be used to read the attribute
+ * value. The attribute value is returned as a byte array (byte[]). The {@link
+ * #setAttribute setAttribute} method may be used to write the value of a
+ * user-defined attribute from a buffer (as if by invoking the {@link #write
+ * write} method), or byte array (byte[]).
+ *
+ * @since 1.7
+ */
+
+public interface UserDefinedFileAttributeView
+    extends FileAttributeView
+{
+    /**
+     * Returns the name of this attribute view. Attribute views of this type
+     * have the name {@code "xattr"}.
+     */
+    @Override
+    String name();
+
+    /**
+     * Returns a list containing the names of the user-defined attributes.
+     *
+     * @return  An unmodifiable list continaing the names of the file's
+     *          user-defined
+     *
+     * @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>("accessUserDefinedAttributes")</tt>
+     *          or its {@link SecurityManager#checkRead(String) checkRead} method
+     *          denies read access to the file.
+     */
+    List<String> list() throws IOException;
+
+    /**
+     * Returns the size of the value of a user-defined attribute.
+     *
+     * @param   name
+     *          The attribute name
+     *
+     * @return  The size of the attribute value, in bytes.
+     *
+     * @throws  ArithmeticException
+     *          If the size of the attribute is larger than {@link Integer#MAX_VALUE}
+     * @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>("accessUserDefinedAttributes")</tt>
+     *          or its {@link SecurityManager#checkRead(String) checkRead} method
+     *          denies read access to the file.
+     */
+    int size(String name) throws IOException;
+
+    /**
+     * Read the value of a user-defined attribute into a buffer.
+     *
+     * <p> This method reads the value of the attribute into the given buffer
+     * as a sequence of bytes, failing if the number of bytes remaining in
+     * the buffer is insufficient to read the complete attribute value. The
+     * number of bytes transferred into the buffer is {@code n}, where {@code n}
+     * is the size of the attribute value. The first byte in the sequence is at
+     * index {@code p} and the last byte is at index {@code p + n - 1}, where
+     * {@code p} is the buffer's position. Upon return the buffer's position
+     * will be equal to {@code p + n}; its limit will not have changed.
+     *
+     * <p> <b>Usage Example:</b>
+     * Suppose we want to read a file's MIME type that is stored as a user-defined
+     * attribute with the name "{@code user.mimetype}".
+     * <pre>
+     *    UserDefinedFileAttributeView view = file
+     *        .getFileAttributeView(UserDefinedFileAttributeView.class);
+     *    String name = "user.mimetype";
+     *    ByteBuffer buf = ByteBuffer.allocate(view.size(name));
+     *    view.read(name, buf);
+     *    buf.flip();
+     *    String value = Charset.defaultCharset().decode(buf).toString();
+     * </pre>
+     *
+     * @param   name
+     *          The attribute name
+     * @param   dst
+     *          The destination buffer
+     *
+     * @return  The number of bytes read, possibly zero
+     *
+     * @throws  IllegalArgumentException
+     *          If the destination buffer is read-only
+     * @throws  IOException
+     *          If an I/O error occurs or there is insufficient space in the
+     *          destination buffer for the attribute value
+     * @throws  SecurityException
+     *          In the case of the default provider, a security manager is
+     *          installed, and it denies {@link
+     *          RuntimePermission}<tt>("accessUserDefinedAttributes")</tt>
+     *          or its {@link SecurityManager#checkRead(String) checkRead} method
+     *          denies read access to the file.
+     *
+     * @see #size
+     */
+    int read(String name, ByteBuffer dst) throws IOException;
+
+    /**
+     * Writes the value of a user-defined attribute from a buffer.
+     *
+     * <p> This method writes the value of the attribute from a given buffer as
+     * a sequence of bytes. The size of the value to transfer is {@code r},
+     * where {@code r} is the number of bytes remaining in the buffer, that is
+     * {@code src.remaining()}. The sequence of bytes is transferred from the
+     * buffer starting at index {@code p}, where {@code p} is the buffer's
+     * position. Upon return, the buffer's position will be equal to {@code
+     * p + n}, where {@code n} is the number of bytes transferred; its limit
+     * will not have changed.
+     *
+     * <p> If an attribute of the given name already exists then its value is
+     * replaced. If the attribute does not exist then it is created. If it
+     * implementation specific if a test to check for the existence of the
+     * attribute and the creation of attribute are atomic with repect to other
+     * file system activities.
+     *
+     * <p> Where there is insufficient space to store the attribute, or the
+     * attribute name or value exceed an implementation specific maximum size
+     * then an {@code IOException} is thrown.
+     *
+     * <p> <b>Usage Example:</b>
+     * Suppose we want to write a file's MIME type as a user-defined attribute:
+     * <pre>
+     *    UserDefinedFileAttributeView view = file
+     *        .getFileAttributeView(UserDefinedFileAttributeView.class);
+     *    view.write("user.mimetype", Charset.defaultCharset().encode("text/html"));
+     * </pre>
+     *
+     * @param   name
+     *          The attribute name
+     * @param   src
+     *          The buffer containing the attribute value
+     *
+     * @return  The number of bytes written, possibly zero
+     *
+     * @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>("accessUserDefinedAttributes")</tt>
+     *          or its {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method denies write access to the file.
+     */
+    int write(String name, ByteBuffer src) throws IOException;
+
+    /**
+     * Deletes a user-defined attribute.
+     *
+     * @param   name
+     *          The attribute name
+     *
+     * @throws  IOException
+     *          If an I/O error occurs or the attribute does not exist
+     * @throws  SecurityException
+     *          In the case of the default provider, a security manager is
+     *          installed, and it denies {@link
+     *          RuntimePermission}<tt>("accessUserDefinedAttributes")</tt>
+     *          or its {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method denies write access to the file.
+     */
+    void delete(String name) throws IOException;
+}
diff --git a/jdk/src/share/classes/java/nio/file/attribute/UserPrincipal.java b/jdk/src/share/classes/java/nio/file/attribute/UserPrincipal.java
new file mode 100644
index 0000000..edb04fc
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/attribute/UserPrincipal.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file.attribute;
+
+import java.security.Principal;
+
+/**
+ * A {@code Principal} representing an identity used to determine access rights
+ * to objects in a file system.
+ *
+ * <p> On many platforms and file systems an entity requires appropriate access
+ * rights or permissions in order to access objects in a file system. The
+ * access rights are generally performed by checking the identity of the entity.
+ * For example, on implementations that use Access Control Lists (ACLs) to
+ * enforce privilege separation then a file in the file system may have an
+ * associated ACL that determines the access rights of identities specified in
+ * the ACL.
+ *
+ * <p> A {@code UserPrincipal} object is an abstract representation of an
+ * identity. It has a {@link #getName() name} that is typically the username or
+ * account name that it represents. User principal objects may be obtained using
+ * a {@link UserPrincipalLookupService}, or returned by {@link
+ * FileAttributeView} implementations that provide access to identity related
+ * attributes. For example, the {@link AclFileAttributeView} and {@link
+ * PosixFileAttributeView} provide access to a file's {@link
+ * PosixFileAttributes#owner owner}.
+ *
+ * @since 1.7
+ */
+
+public interface UserPrincipal extends Principal { }
diff --git a/jdk/src/share/classes/java/nio/file/attribute/UserPrincipalLookupService.java b/jdk/src/share/classes/java/nio/file/attribute/UserPrincipalLookupService.java
new file mode 100644
index 0000000..ba74882
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/attribute/UserPrincipalLookupService.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file.attribute;
+
+import java.io.IOException;
+
+/**
+ * An object to lookup user and group principals by name. A {@link UserPrincipal}
+ * represents an identity that may be used to determine access rights to objects
+ * in a file system. A {@link GroupPrincipal} represents a <em>group identity</em>.
+ * A {@code UserPrincipalLookupService} defines methods to lookup identities by
+ * name or group name (which are typically user or account names). Whether names
+ * and group names are case sensitive or not depends on the implementation.
+ * The exact definition of a group is implementation specific but typically a
+ * group represents an identity created for administrative purposes so as to
+ * determine the access rights for the members of the group. In particular it is
+ * implementation specific if the <em>namespace</em> for names and groups is the
+ * same or is distinct. To ensure consistent and correct behavior across
+ * platforms it is recommended that this API be used as if the namespaces are
+ * distinct. In other words, the {@link #lookupPrincipalByName
+ * lookupPrincipalByName} should be used to lookup users, and {@link
+ * #lookupPrincipalByGroupName lookupPrincipalByGroupName} should be used to
+ * lookup groups.
+ *
+ * @since 1.7
+ *
+ * @see java.nio.file.FileSystem#getUserPrincipalLookupService
+ */
+
+public abstract class UserPrincipalLookupService {
+
+    /**
+     * Initializes a new instance of this class.
+     */
+    protected UserPrincipalLookupService() {
+    }
+
+    /**
+     * Lookup a user principal by name.
+     *
+     * @param   name
+     *          the string representation of the user principal to lookup
+     *
+     * @return  a user principal
+     *
+     * @throws  UserPrincipalNotFoundException
+     *          the principal does not exist
+     * @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 {@link RuntimePermission}<tt>("lookupUserInformation")</tt>
+     */
+    public abstract UserPrincipal lookupPrincipalByName(String name)
+        throws IOException;
+
+    /**
+     * Lookup a group principal by group name.
+     *
+     * <p> Where an implementation does not support any notion of group then
+     * this method always throws {@link UserPrincipalNotFoundException}. Where
+     * the namespace for user accounts and groups is the same, then this method
+     * is identical to invoking {@link #lookupPrincipalByName
+     * lookupPrincipalByName}.
+     *
+     * @param   group
+     *          the string representation of the group to lookup
+     *
+     * @return  a user principal
+     *
+     * @throws  UserPrincipalNotFoundException
+     *          the principal does not exist or is not a group
+     * @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 {@link RuntimePermission}<tt>("lookupUserInformation")</tt>
+     */
+    public abstract GroupPrincipal lookupPrincipalByGroupName(String group)
+        throws IOException;
+}
diff --git a/jdk/src/share/classes/java/nio/file/attribute/UserPrincipalNotFoundException.java b/jdk/src/share/classes/java/nio/file/attribute/UserPrincipalNotFoundException.java
new file mode 100644
index 0000000..94cc88b
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/attribute/UserPrincipalNotFoundException.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file.attribute;
+
+import java.io.IOException;
+
+/**
+ * Checked exception thrown when a lookup of {@link UserPrincipal} fails because
+ * the principal does not exist.
+ *
+ * @since 1.7
+ */
+
+public class UserPrincipalNotFoundException
+    extends IOException
+{
+    static final long serialVersionUID = -5369283889045833024L;
+
+    private final String name;
+
+    /**
+     * Constructs an instance of this class.
+     *
+     * @param   name
+     *          the principal name; may be {@code null}
+     */
+    public UserPrincipalNotFoundException(String name) {
+        super();
+        this.name = name;
+    }
+
+    /**
+     * Returns the user principal name if this exception was created with the
+     * user principal name that was not found, otherwise <tt>null</tt>.
+     *
+     * @return  the user principal name or {@code null}
+     */
+    public String getName() {
+        return name;
+    }
+}
diff --git a/jdk/src/share/classes/java/nio/file/attribute/package-info.java b/jdk/src/share/classes/java/nio/file/attribute/package-info.java
new file mode 100644
index 0000000..c5301b1
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/attribute/package-info.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * Interfaces and classes providing access to file and file system attributes.
+ *
+ * <blockquote><table cellspacing=1 cellpadding=0 summary="Attribute views">
+ * <tr><th><p align="left">Attribute views</p></th><th><p align="left">Description</p></th></tr>
+ * <tr><td valign=top><tt><i>{@link java.nio.file.attribute.AttributeView}</i></tt></td>
+ *     <td>Can read or update non-opaque values associated with objects in a file system</td></tr>
+ * <tr><td valign=top><tt>&nbsp;&nbsp;<i>{@link java.nio.file.attribute.FileAttributeView}</i></tt></td>
+ *     <td>Can read or update file attributes</td></tr>
+ * <tr><td valign=top><tt>&nbsp;&nbsp;&nbsp;&nbsp;<i>{@link java.nio.file.attribute.BasicFileAttributeView}&nbsp;&nbsp;</i></tt></td>
+ *     <td>Can read or update a basic set of file attributes</td></tr>
+ * <tr><td valign=top><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<i>{@link java.nio.file.attribute.PosixFileAttributeView}&nbsp;&nbsp;</i></tt></td>
+ *     <td>Can read or update POSIX defined file attributes</td></tr>
+ * <tr><td valign=top><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<i>{@link java.nio.file.attribute.DosFileAttributeView}&nbsp;&nbsp;</i></tt></td>
+ *     <td>Can read or update FAT file attributes</td></tr>
+ * <tr><td valign=top><tt>&nbsp;&nbsp;&nbsp;&nbsp<i>{@link java.nio.file.attribute.FileOwnerAttributeView}&nbsp;&nbsp;</i></tt></td>
+ *     <td>Can read or update the owner of a file</td></tr>
+ * <tr><td valign=top><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<i>{@link java.nio.file.attribute.AclFileAttributeView}&nbsp;&nbsp;</i></tt></td>
+ *     <td>Can read or update Access Control Lists</td></tr>
+ * <tr><td valign=top><tt>&nbsp;&nbsp;&nbsp;&nbsp;<i>{@link java.nio.file.attribute.UserDefinedFileAttributeView}&nbsp;&nbsp;</i></tt></td>
+ *     <td>Can read or update user-defined file attributes</td></tr>
+ * <tr><td valign=top><tt>&nbsp;&nbsp;<i>{@link java.nio.file.attribute.FileStoreAttributeView}</i></tt></td>
+ *     <td>Can read or update file system attributes</td></tr>
+ * <tr><td valign=top><tt>&nbsp;&nbsp;&nbsp;&nbsp;<i>{@link java.nio.file.attribute.FileStoreSpaceAttributeView}&nbsp;&nbsp;</i></tt></td>
+ *     <td>Can read file system <em>space usage</em> related attributes</td></tr>
+ * </table></blockquote>
+ *
+ * <p> An attribute view provides a read-only or updatable view of the non-opaque
+ * values, or <em>metadata</em>, associated with objects in a file system.
+ * The {@link java.nio.file.attribute.FileAttributeView} interface is
+ * extended by several other interfaces that that views to specific sets of file
+ * attributes. {@code FileAttributeViews} are selected by invoking the {@link
+ * java.nio.file.FileRef#getFileAttributeView} method with a
+ * <em>type-token</em> to identify the required view. Views can also be identified
+ * by name. The {@link java.nio.file.attribute.FileStoreAttributeView} interface
+ * provides access to file store attributes. A {@code FileStoreAttributeView} of
+ * a given type is obtained by invoking the {@link
+ * java.nio.file.FileStore#getFileStoreAttributeView} method.
+ *
+ * <p> The {@link java.nio.file.attribute.BasicFileAttributeView}
+ * class defines methods to read and update a <em>basic</em> set of file
+ * attributes that are common to many file systems.
+ *
+ * <p> The {@link java.nio.file.attribute.PosixFileAttributeView}
+ * interface extends {@code BasicFileAttributeView} by defining methods
+ * to access the file attributes commonly used by file systems and operating systems
+ * that implement the Portable Operating System Interface (POSIX) family of
+ * standards.
+ *
+ * <p> The {@link java.nio.file.attribute.DosFileAttributeView}
+ * class extends {@code BasicFileAttributeView} by defining methods to
+ * access the legacy "DOS" file attributes supported on file systems such as File
+ * Allocation Tabl (FAT), commonly used in consumer devices.
+ *
+ * <p> The {@link java.nio.file.attribute.AclFileAttributeView}
+ * class defines methods to read and write the Access Control List (ACL)
+ * file attribute. The ACL model used by this file attribute view is based
+ * on the model defined by <a href="http://www.ietf.org/rfc/rfc3530.txt">
+ * <i>RFC&nbsp;3530: Network File System (NFS) version 4 Protocol</i></a>.
+ *
+ * <p> The {@link java.nio.file.attribute.FileStoreSpaceAttributeView} class
+ * defines methods to read file system space usage related attributes of a file system.
+ *
+ * <p> The {@link java.nio.file.attribute.Attributes} utility class defines
+ * static methods to access file or file system attribute using the above
+ * attribute views.
+ *
+ * <p> In addition to attribute views, this package also defines classes and
+ * interfaces that are used when accessing attributes:
+ *
+ * <ul>
+ *
+ *   <p><li> The {@link java.nio.file.attribute.UserPrincipal} and
+ *   {@link java.nio.file.attribute.GroupPrincipal} interfaces represent an
+ *   identity or group identity. </li>
+ *
+ *   <p><li> The {@link java.nio.file.attribute.UserPrincipalLookupService}
+ *   interface defines methods to lookup user or group principals. </li>
+ *
+ *   <p><li> The {@link java.nio.file.attribute.Attribute} interface
+ *   represents the value of an attribute for cases where the attribute value is
+ *   require to be set atomically when creating an object in the file system. </li>
+ *
+ * </ul>
+ *
+ *
+ * <p> Unless otherwise noted, passing a <tt>null</tt> argument to a constructor
+ * or method in any class or interface in this package will cause a {@link
+ * java.lang.NullPointerException NullPointerException} to be thrown.
+ *
+ * @since 1.7
+ */
+
+package java.nio.file.attribute;
diff --git a/jdk/src/share/classes/java/nio/file/package-info.java b/jdk/src/share/classes/java/nio/file/package-info.java
new file mode 100644
index 0000000..3623ebe
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/package-info.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * Defines interfaces and classes for the Java virtual machine to access files,
+ * file attributes, and file systems.
+ *
+ * <p> The java.nio.file package defines classes to access files and file
+ * systems. The API to access file and file system attributes is defined in the
+ * {@link java.nio.file.attribute} package. The {@link java.nio.file.spi}
+ * package is used by service provider implementors wishing to extend the
+ * platform default provider, or to construct other provider implementations.
+ *
+ * <a name="links"><h3>Symbolic Links</h3></a>
+ * Many operating systems and file systems support for <em>symbolic links</em>.
+ * A symbolic link is a special file that serves as a reference to another file.
+ * For the most part, symbolic links are transparent to applications and
+ * operations on symbolic links are automatically redirected to the <em>target</em>
+ * of the link. Exceptions to this are when a symbolic link is deleted or
+ * renamed/moved in which case the link is deleted or removed rather than the
+ * target of the link. This package includes support for symbolic links where
+ * implementations provide these semantics. File systems may support other types
+ * that are semantically close but support for these other types of links is
+ * not included in this package.
+ *
+ * <a name="interop"><h3>Interoperability</h3></a>
+ * The {@link java.io.File} class defines the {@link java.io.File#toPath
+ * toPath} method to construct a {@link java.nio.file.Path} by converting
+ * the abstract path represented by the {@code java.io.File} object. The resulting
+ * {@code Path} can be used to operate on the same file as the {@code File}
+ * object. The {@code Path} specification provides further information
+ * on the <a href="Path.html#interop">interoperability</a> between {@code Path}
+ * and {@code java.io.File} objects.
+ *
+ * <h3>Visibility</h3>
+ * The view of the files and file system provided by classes in this package are
+ * guaranteed to be consistent with other views provided by other instances in the
+ * same Java virtual machine.  The view may or may not, however, be consistent with
+ * the view of the file system as seen by other concurrently running programs due
+ * to caching performed by the underlying operating system and delays induced by
+ * network-filesystem protocols. This is true regardless of the language in which
+ * these other programs are written, and whether they are running on the same machine
+ * or on some other machine.  The exact nature of any such inconsistencies are
+ * system-dependent and are therefore unspecified.
+ *
+ * <a name="integrity"><h3>Synchronized I/O File Integrity</h3></a>
+ * The {@link java.nio.file.StandardOpenOption#SYNC SYNC} and {@link
+ * java.nio.file.StandardOpenOption#DSYNC DSYNC} options are used when opening a file
+ * to require that updates to the file are written synchronously to the underlying
+ * storage device. In the case of the default provider, and the file resides on
+ * a local storage device, and the {@link java.nio.channels.SeekableByteChannel
+ * seekable} channel is connected to a file that was opened with one of these
+ * options, then an invocation of the {@link
+ * java.nio.channels.WritableByteChannel#write(java.nio.ByteBuffer) write}
+ * method is only guaranteed to return when all changes made to the file
+ * by that invocation have been written to the device. These options are useful
+ * for ensuring that critical information is not lost in the event of a system
+ * crash. If the file does not reside on a local device then no such guarantee
+ * is made. Whether this guarantee is possible with other {@link
+ * java.nio.file.spi.FileSystemProvider provider} implementations is provider
+ * specific.
+ *
+ * <h3>General Exceptions</h3>
+ * Unless otherwise noted, passing a {@code null} argument to a constructor
+ * or method of any class or interface in this package will cause a {@link
+ * java.lang.NullPointerException NullPointerException} to be thrown. Additionally,
+ * invoking a method with a collection containing a {@code null} element will
+ * cause a {@code NullPointerException}, unless otherwise specified.
+ *
+ * <p> Unless otherwise noted, methods that attempt to access the file system
+ * will throw {@link java.nio.file.ClosedFileSystemException} when invoked on
+ * objects associated with a {@link java.nio.file.FileSystem} that has been
+ * {@link java.nio.file.FileSystem#close closed}. Additionally, any methods
+ * that attempt write access to a file system will throw {@link
+ * java.nio.file.ReadOnlyFileSystemException} when invoked on an object associated
+ * with a {@link java.nio.file.FileSystem} that only provides read-only access.
+ *
+ * <p> Unless otherwise noted, invoking a method of any class or interface in
+ * this package created by one {@link java.nio.file.spi.FileSystemProvider
+ * provider} with a parameter that is an object created by another provider,
+ * will throw {@link java.nio.file.ProviderMismatchException}.
+ *
+ * <h3>Optional Specific Exceptions</h3>
+ * Most of the methods defined by classes in this package that access the
+ * file system specify that {@link java.io.IOException} be thrown when an I/O
+ * error occurs. In some cases, these methods define specific I/O exceptions
+ * for common cases. These exceptions, noted as <i>optional specific exceptions</i>,
+ * are thrown by the implementation where it can detect the specific error.
+ * Where the specific error cannot be detected then the more general {@code
+ * IOException} is thrown.
+ *
+ * @since 1.7
+ */
+package java.nio.file;
diff --git a/jdk/src/share/classes/java/nio/file/spi/AbstractPath.java b/jdk/src/share/classes/java/nio/file/spi/AbstractPath.java
new file mode 100644
index 0000000..133411e
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/spi/AbstractPath.java
@@ -0,0 +1,568 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file.spi;
+
+import java.nio.file.*;
+import static java.nio.file.StandardOpenOption.*;
+import java.nio.file.attribute.*;
+import java.nio.channels.*;
+import java.nio.ByteBuffer;
+import java.io.*;
+import java.util.*;
+
+/**
+ * Base implementation class for a {@code Path}.
+ *
+ * <p> This class is intended to be extended by provider implementors. It
+ * implements, or provides default implementations for several of the methods
+ * defined by the {@code Path} class. It implements the {@link #copyTo copyTo}
+ * and {@link #moveTo moveTo} methods for the case that the source and target
+ * are not associated with the same provider.
+ *
+ * @since 1.7
+ */
+
+public abstract class AbstractPath extends Path {
+
+    /**
+     * Initializes a new instance of this class.
+     */
+    protected AbstractPath() { }
+
+    /**
+     * Deletes the file referenced by this object.
+     *
+     * <p> This method invokes the {@link #delete(boolean) delete(boolean)}
+     * method with a parameter of {@code true}. It may be overridden where
+     * required.
+     *
+     * @throws  NoSuchFileException             {@inheritDoc}
+     * @throws  DirectoryNotEmptyException      {@inheritDoc}
+     * @throws  IOException                     {@inheritDoc}
+     * @throws  SecurityException               {@inheritDoc}
+     */
+    @Override
+    public void delete() throws IOException {
+        delete(true);
+    }
+
+    /**
+     * Creates a new and empty file, failing if the file already exists.
+     *
+     * <p> This method invokes the {@link #newByteChannel(Set,FileAttribute[])
+     * newByteChannel(Set,FileAttribute...)} method to create the file. It may be
+     * overridden where required.
+     *
+     * @throws  IllegalArgumentException        {@inheritDoc}
+     * @throws  FileAlreadyExistsException      {@inheritDoc}
+     * @throws  IOException                     {@inheritDoc}
+     * @throws  SecurityException               {@inheritDoc}
+     */
+    @Override
+    public Path createFile(FileAttribute<?>... attrs)
+        throws IOException
+    {
+        EnumSet<StandardOpenOption> options = EnumSet.of(CREATE_NEW, WRITE);
+        SeekableByteChannel sbc = newByteChannel(options, attrs);
+        try {
+            sbc.close();
+        } catch (IOException x) {
+            // ignore
+        }
+        return this;
+    }
+
+    /**
+     * Opens or creates a file, returning a seekable byte channel to access the
+     * file.
+     *
+     * <p> This method invokes the {@link #newByteChannel(Set,FileAttribute[])
+     * newByteChannel(Set,FileAttribute...)} method to open or create the file.
+     * It may be overridden where required.
+     *
+     * @throws  IllegalArgumentException        {@inheritDoc}
+     * @throws  FileAlreadyExistsException      {@inheritDoc}
+     * @throws  IOException                     {@inheritDoc}
+     * @throws  SecurityException               {@inheritDoc}
+     */
+    @Override
+    public SeekableByteChannel newByteChannel(OpenOption... options)
+        throws IOException
+    {
+        Set<OpenOption> set = new HashSet<OpenOption>(options.length);
+        Collections.addAll(set, options);
+        return newByteChannel(set);
+    }
+
+    /**
+     * Opens the file located by this path for reading, returning an input
+     * stream to read bytes from the file.
+     *
+     * <p> This method returns an {@code InputStream} that is constructed by
+     * invoking the {@link java.nio.channels.Channels#newInputStream
+     * Channels.newInputStream} method. It may be overridden where a more
+     * efficient implementation is available.
+     *
+     * @throws  IOException                     {@inheritDoc}
+     * @throws  SecurityException               {@inheritDoc}
+     */
+    @Override
+    public InputStream newInputStream() throws IOException {
+        return Channels.newInputStream(newByteChannel());
+    }
+
+    // opts must be modifiable
+    private OutputStream implNewOutputStream(Set<OpenOption> opts,
+                                             FileAttribute<?>... attrs)
+        throws IOException
+    {
+        if (opts.isEmpty()) {
+            opts.add(CREATE);
+            opts.add(TRUNCATE_EXISTING);
+        } else {
+            if (opts.contains(READ))
+                throw new IllegalArgumentException("READ not allowed");
+        }
+        opts.add(WRITE);
+        return Channels.newOutputStream(newByteChannel(opts, attrs));
+    }
+
+    /**
+     * Opens or creates the file located by this path for writing, returning an
+     * output stream to write bytes to the file.
+     *
+     * <p> This method returns an {@code OutputStream} that is constructed by
+     * invoking the {@link java.nio.channels.Channels#newOutputStream
+     * Channels.newOutputStream} method. It may be overridden where a more
+     * efficient implementation is available.
+     *
+     * @throws  IllegalArgumentException        {@inheritDoc}
+     * @throws  IOException                     {@inheritDoc}
+     * @throws  SecurityException               {@inheritDoc}
+     */
+    @Override
+    public OutputStream newOutputStream(OpenOption... options) throws IOException {
+        int len = options.length;
+        Set<OpenOption> opts = new HashSet<OpenOption>(len + 3);
+        if (len > 0) {
+            for (OpenOption opt: options) {
+                opts.add(opt);
+            }
+        }
+        return implNewOutputStream(opts);
+    }
+
+    /**
+     * Opens or creates the file located by this path for writing, returning an
+     * output stream to write bytes to the file.
+     *
+     * <p> This method returns an {@code OutputStream} that is constructed by
+     * invoking the {@link java.nio.channels.Channels#newOutputStream
+     * Channels.newOutputStream} method. It may be overridden where a more
+     * efficient implementation is available.
+     *
+     * @throws  IllegalArgumentException        {@inheritDoc}
+     * @throws  IOException                     {@inheritDoc}
+     * @throws  SecurityException               {@inheritDoc}
+     */
+    @Override
+    public OutputStream newOutputStream(Set<? extends OpenOption> options,
+                                        FileAttribute<?>... attrs)
+        throws IOException
+    {
+        Set<OpenOption> opts = new HashSet<OpenOption>(options);
+        return implNewOutputStream(opts, attrs);
+    }
+
+    /**
+     * Opens the directory referenced by this object, returning a {@code
+     * DirectoryStream} to iterate over all entries in the directory.
+     *
+     * <p> This method invokes the {@link
+     * #newDirectoryStream(java.nio.file.DirectoryStream.Filter)
+     * newDirectoryStream(Filter)} method with a filter that accept all entries.
+     * It may be overridden where required.
+     *
+     * @throws  NotDirectoryException           {@inheritDoc}
+     * @throws  IOException                     {@inheritDoc}
+     * @throws  SecurityException               {@inheritDoc}
+     */
+    @Override
+    public DirectoryStream<Path> newDirectoryStream() throws IOException {
+        return newDirectoryStream(acceptAllFilter);
+    }
+    private static final DirectoryStream.Filter<Path> acceptAllFilter =
+        new DirectoryStream.Filter<Path>() {
+            @Override public boolean accept(Path entry) { return true; }
+        };
+
+    /**
+     * Opens the directory referenced by this object, returning a {@code
+     * DirectoryStream} to iterate over the entries in the directory. The
+     * entries are filtered by matching the {@code String} representation of
+     * their file names against a given pattern.
+     *
+     * <p> This method constructs a {@link PathMatcher} by invoking the
+     * file system's {@link java.nio.file.FileSystem#getPathMatcher
+     * getPathMatcher} method. This method may be overridden where a more
+     * efficient implementation is available.
+     *
+     * @throws  java.util.regex.PatternSyntaxException  {@inheritDoc}
+     * @throws  UnsupportedOperationException   {@inheritDoc}
+     * @throws  NotDirectoryException           {@inheritDoc}
+     * @throws  IOException                     {@inheritDoc}
+     * @throws  SecurityException               {@inheritDoc}
+     */
+    @Override
+    public DirectoryStream<Path> newDirectoryStream(String glob)
+        throws IOException
+    {
+        // avoid creating a matcher if all entries are required.
+        if (glob.equals("*"))
+            return newDirectoryStream();
+
+        // create a matcher and return a filter that uses it.
+        final PathMatcher matcher = getFileSystem().getPathMatcher("glob:" + glob);
+        DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
+            @Override
+            public boolean accept(Path entry)  {
+                return matcher.matches(entry.getName());
+            }
+        };
+        return newDirectoryStream(filter);
+    }
+
+    /**
+     * Tests whether the file located by this path exists.
+     *
+     * <p> This method invokes the {@link #checkAccess checkAccess} method to
+     * check if the file exists. It may be  overridden where a more efficient
+     * implementation is available.
+     */
+    @Override
+    public boolean exists() {
+        try {
+            checkAccess();
+            return true;
+        } catch (IOException x) {
+            // unable to determine if file exists
+        }
+        return false;
+    }
+
+    /**
+     * Tests whether the file located by this path does not exist.
+     *
+     * <p> This method invokes the {@link #checkAccess checkAccess} method to
+     * check if the file exists. It may be  overridden where a more efficient
+     * implementation is available.
+     */
+    @Override
+    public boolean notExists() {
+        try {
+            checkAccess();
+            return false;
+        } catch (NoSuchFileException x) {
+            // file confirmed not to exist
+            return true;
+        } catch (IOException x) {
+            return false;
+        }
+    }
+
+    /**
+     * Registers the file located by this path with a watch service.
+     *
+     * <p> This method invokes the {@link #register(WatchService,WatchEvent.Kind[],WatchEvent.Modifier[])
+     * register(WatchService,WatchEvent.Kind[],WatchEvent.Modifier...)}
+     * method to register the file. It may be  overridden where required.
+     */
+    @Override
+    public WatchKey register(WatchService watcher, WatchEvent.Kind<?>... events)
+        throws IOException
+    {
+        return register(watcher, events, NO_MODIFIERS);
+    }
+    private static final WatchEvent.Modifier[] NO_MODIFIERS = new WatchEvent.Modifier[0];
+
+    /**
+     * Copy the file located by this path to a target location.
+     *
+     * <p> This method is invoked by the {@link #copyTo copyTo} method for
+     * the case that this {@code Path} and the target {@code Path} are
+     * associated with the same provider.
+     *
+     * @param   target
+     *          The target location
+     * @param   options
+     *          Options specifying how the copy should be done
+     *
+     * @throws  IllegalArgumentException
+     *          If an invalid option is specified
+     * @throws  FileAlreadyExistsException
+     *          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")}.
+     */
+    protected abstract void implCopyTo(Path target, CopyOption... options)
+        throws IOException;
+
+    /**
+     * Move the file located by this path to a target location.
+     *
+     * <p> This method is invoked by the {@link #moveTo moveTo} method for
+     * the case that this {@code Path} and the target {@code Path} are
+     * associated with the same provider.
+     *
+     * @param   target
+     *          The target location
+     * @param   options
+     *          Options specifying how the move should be done
+     *
+     * @throws  IllegalArgumentException
+     *          If an invalid option is specified
+     * @throws  FileAlreadyExistsException
+     *          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
+     *          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.
+     */
+    protected abstract void implMoveTo(Path target, CopyOption... options)
+        throws IOException;
+
+    /**
+     * Copy the file located by this path to a target location.
+     *
+     * <p> If this path is associated with the same {@link FileSystemProvider
+     * provider} as the {@code target} then the {@link #implCopyTo implCopyTo}
+     * method is invoked to copy the file. Otherwise, this method attempts to
+     * copy the file to the target location in a manner that may be less
+     * efficient than would be the case that target is associated with the same
+     * provider as this path.
+     *
+     * @throws  IllegalArgumentException            {@inheritDoc}
+     * @throws  FileAlreadyExistsException          {@inheritDoc}
+     * @throws  IOException                         {@inheritDoc}
+     * @throws  SecurityException                   {@inheritDoc}
+     */
+    @Override
+    public final Path copyTo(Path target, CopyOption... options)
+        throws IOException
+    {
+        if ((getFileSystem().provider() == target.getFileSystem().provider())) {
+            implCopyTo(target, options);
+        } else {
+            xProviderCopyTo(target, options);
+        }
+        return target;
+    }
+
+    /**
+     * Move or rename the file located by this path to a target location.
+     *
+     * <p> If this path is associated with the same {@link FileSystemProvider
+     * provider} as the {@code target} then the {@link #implCopyTo implMoveTo}
+     * method is invoked to move the file. Otherwise, this method attempts to
+     * copy the file to the target location and delete the source file. This
+     * implementation may be less efficient than would be the case that
+     * target is associated with the same provider as this path.
+     *
+     * @throws  IllegalArgumentException            {@inheritDoc}
+     * @throws  FileAlreadyExistsException          {@inheritDoc}
+     * @throws  IOException                         {@inheritDoc}
+     * @throws  SecurityException                   {@inheritDoc}
+     */
+    @Override
+    public final Path moveTo(Path target, CopyOption... options)
+        throws IOException
+    {
+        if ((getFileSystem().provider() == target.getFileSystem().provider())) {
+            implMoveTo(target, options);
+        } else {
+            // different providers so copy + delete
+            xProviderCopyTo(target, convertMoveToCopyOptions(options));
+            delete(false);
+        }
+        return target;
+    }
+
+    /**
+     * Converts the given array of options for moving a file to options suitable
+     * for copying the file when a move is implemented as copy + delete.
+     */
+    private static CopyOption[] convertMoveToCopyOptions(CopyOption... options)
+        throws AtomicMoveNotSupportedException
+    {
+        int len = options.length;
+        CopyOption[] newOptions = new CopyOption[len+2];
+        for (int i=0; i<len; i++) {
+            CopyOption option = options[i];
+            if (option == StandardCopyOption.ATOMIC_MOVE) {
+                throw new AtomicMoveNotSupportedException(null, null,
+                    "Atomic move between providers is not supported");
+            }
+            newOptions[i] = option;
+        }
+        newOptions[len] = LinkOption.NOFOLLOW_LINKS;
+        newOptions[len+1] = StandardCopyOption.COPY_ATTRIBUTES;
+        return newOptions;
+    }
+
+    /**
+     * Parses the arguments for a file copy operation.
+     */
+    private static class CopyOptions {
+        boolean replaceExisting = false;
+        boolean copyAttributes = false;
+        boolean followLinks = true;
+
+        private CopyOptions() { }
+
+        static CopyOptions parse(CopyOption... options) {
+            CopyOptions result = new CopyOptions();
+            for (CopyOption option: options) {
+                if (option == StandardCopyOption.REPLACE_EXISTING) {
+                    result.replaceExisting = true;
+                    continue;
+                }
+                if (option == LinkOption.NOFOLLOW_LINKS) {
+                    result.followLinks = false;
+                    continue;
+                }
+                if (option == StandardCopyOption.COPY_ATTRIBUTES) {
+                    result.copyAttributes = true;
+                    continue;
+                }
+                if (option == null)
+                    throw new NullPointerException();
+                throw new IllegalArgumentException("'" + option +
+                    "' is not a valid copy option");
+            }
+            return result;
+        }
+    }
+
+    /**
+     * Simple cross-provider copy where the target is a Path.
+     */
+    private void xProviderCopyTo(Path target, CopyOption... options)
+        throws IOException
+    {
+        CopyOptions opts = CopyOptions.parse(options);
+        LinkOption[] linkOptions = (opts.followLinks) ? new LinkOption[0] :
+            new LinkOption[] { LinkOption.NOFOLLOW_LINKS };
+
+        // attributes of source file
+        BasicFileAttributes attrs = Attributes
+            .readBasicFileAttributes(this, linkOptions);
+        if (attrs.isSymbolicLink())
+            throw new IOException("Copying of symbolic links not supported");
+
+        // delete target file
+        if (opts.replaceExisting)
+            target.delete(false);
+
+        // create directory or file
+        if (attrs.isDirectory()) {
+            target.createDirectory();
+        } else {
+            xProviderCopyRegularFileTo(target);
+        }
+
+        // copy basic attributes to target
+        if (opts.copyAttributes) {
+            BasicFileAttributeView view = target
+                .getFileAttributeView(BasicFileAttributeView.class, linkOptions);
+            try {
+                view.setTimes(attrs.lastModifiedTime(),
+                              attrs.lastAccessTime(),
+                              attrs.creationTime(),
+                              attrs.resolution());
+            } catch (IOException x) {
+                // rollback
+                try {
+                    target.delete(false);
+                } catch (IOException ignore) { }
+                throw x;
+            }
+        }
+    }
+
+
+   /**
+     * Simple copy of regular file to a target file that exists.
+     */
+    private void xProviderCopyRegularFileTo(FileRef target)
+        throws IOException
+    {
+        ReadableByteChannel rbc = newByteChannel();
+        try {
+            // open target file for writing
+            SeekableByteChannel sbc = target.newByteChannel(CREATE, WRITE);
+
+            // simple copy loop
+            try {
+                ByteBuffer buf = ByteBuffer.wrap(new byte[8192]);
+                int n = 0;
+                for (;;) {
+                    n = rbc.read(buf);
+                    if (n < 0)
+                        break;
+                    assert n > 0;
+                    buf.flip();
+                    while (buf.hasRemaining()) {
+                        sbc.write(buf);
+                    }
+                    buf.rewind();
+                }
+
+            } finally {
+                sbc.close();
+            }
+        } finally {
+            rbc.close();
+        }
+    }
+}
diff --git a/jdk/src/share/classes/java/nio/file/spi/FileSystemProvider.java b/jdk/src/share/classes/java/nio/file/spi/FileSystemProvider.java
new file mode 100644
index 0000000..6b79381
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/spi/FileSystemProvider.java
@@ -0,0 +1,434 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file.spi;
+
+import java.nio.file.*;
+import java.nio.file.attribute.FileAttribute;
+import java.nio.channels.*;
+import java.net.URI;
+import java.util.*;
+import java.util.concurrent.ExecutorService;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.io.IOException;
+
+/**
+ * Service-provider class for file systems.
+ *
+ * <p> A file system provider is a concrete implementation of this class that
+ * implements the abstract methods defined by this class. A provider is
+ * identified by a {@code URI} {@link #getScheme() scheme}. The default provider
+ * is identified by the URI scheme "file". It creates the {@link FileSystem} that
+ * provides access to the file systems accessible to the Java virtual machine.
+ * The {@link FileSystems} class defines how file system providers are located
+ * and loaded. The default provider is typically a system-default provider but
+ * may be overridden if the system property {@code
+ * java.nio.file.spi.DefaultFileSystemProvider} is set. In that case, the
+ * provider has a one argument constructor whose formal parameter type is {@code
+ * FileSystemProvider}. All other providers have a zero argument constructor
+ * that initializes the provider.
+ *
+ * <p> A provider is a factory for one or more {@link FileSystem} instances. Each
+ * file system is identified by a {@code URI} where the URI's scheme matches
+ * the provider's {@link #getScheme scheme}. The default file system, for example,
+ * is identified by the URI {@code "file:///"}. A memory-based file system,
+ * for example, may be identified by a URI such as {@code "memory:///?name=logfs"}.
+ * The {@link #newFileSystem newFileSystem} method may be used to create a file
+ * system, and the {@link #getFileSystem getFileSystem} method may be used to
+ * obtain a reference to an existing file system created by the provider. Where
+ * a provider is the factory for a single file system then it is provider dependent
+ * if the file system is created when the provider is initialized, or later when
+ * the {@code newFileSystem} method is invoked. In the case of the default
+ * provider, the {@code FileSystem} is created when the provider is initialized.
+ *
+ * <p> In addition to file systems, a provider is also a factory for {@link
+ * FileChannel} and {@link AsynchronousFileChannel} channels. The {@link
+ * #newFileChannel newFileChannel} and {@link #newAsynchronousFileChannel
+ * AsynchronousFileChannel} methods are defined to open or create files, returning
+ * a channel to access the file. These methods are invoked by static factory
+ * methods defined in the {@link java.nio.channels} package.
+ *
+ * <p> All of the methods in this class are safe for use by multiple concurrent
+ * threads.
+ *
+ * @since 1.7
+ */
+
+public abstract class FileSystemProvider {
+    // lock using when loading providers
+    private static final Object lock = new Object();
+
+    // installed providers
+    private static volatile List<FileSystemProvider> installedProviders;
+
+    // used to avoid recursive loading of instaled providers
+    private static boolean loadingProviders  = false;
+
+    private static Void checkPermission() {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null)
+            sm.checkPermission(new RuntimePermission("fileSystemProvider"));
+        return null;
+    }
+    private FileSystemProvider(Void ignore) { }
+
+    /**
+     * Initializes a new instance of this class.
+     *
+     * <p> During construction a provider may safely access files associated
+     * with the default provider but care needs to be taken to avoid circular
+     * loading of other installed providers. If circular loading of installed
+     * providers is detected then an unspecified error is thrown.
+     *
+     * @throws  SecurityException
+     *          If a security manager has been installed and it denies
+     *          {@link RuntimePermission}<tt>("fileSystemProvider")</tt>
+     */
+    protected FileSystemProvider() {
+        this(checkPermission());
+    }
+
+    // loads all installed providers
+    private static List<FileSystemProvider> loadInstalledProviders() {
+        List<FileSystemProvider> list = new ArrayList<FileSystemProvider>();
+
+        ServiceLoader<FileSystemProvider> sl = ServiceLoader
+            .load(FileSystemProvider.class, ClassLoader.getSystemClassLoader());
+
+        // ServiceConfigurationError may be throw here
+        for (FileSystemProvider provider: sl) {
+            String scheme = provider.getScheme();
+
+            // add to list if the provider is not "file" and isn't a duplicate
+            if (!scheme.equalsIgnoreCase("file")) {
+                boolean found = false;
+                for (FileSystemProvider p: list) {
+                    if (p.getScheme().equalsIgnoreCase(scheme)) {
+                        found = true;
+                        break;
+                    }
+                }
+                if (!found) {
+                    list.add(provider);
+                }
+            }
+        }
+        return list;
+    }
+
+    /**
+     * Returns a list of the installed file system providers.
+     *
+     * <p> The first invocation of this method causes the default provider to be
+     * initialized (if not already initialized) and loads any other installed
+     * providers as described by the {@link FileSystems} class.
+     *
+     * @return  An unmodifiable list of the installed file system providers. The
+     *          list contains at least one element, that is the default file
+     *          system provider
+     *
+     * @throws  ServiceConfigurationError
+     *          When an error occurs while loading a service provider
+     */
+    public static List<FileSystemProvider> installedProviders() {
+        if (installedProviders == null) {
+            // ensure default provider is initialized
+            FileSystemProvider defaultProvider = FileSystems.getDefault().provider();
+
+            synchronized (lock) {
+                if (installedProviders == null) {
+                    if (loadingProviders) {
+                        throw new Error("Circular loading of installed providers detected");
+                    }
+                    loadingProviders = true;
+
+                    List<FileSystemProvider> list = AccessController
+                        .doPrivileged(new PrivilegedAction<List<FileSystemProvider>>() {
+                            @Override
+                            public List<FileSystemProvider> run() {
+                                return loadInstalledProviders();
+                        }});
+
+                    // insert the default provider at the start of the list
+                    list.add(0, defaultProvider);
+
+                    installedProviders = Collections.unmodifiableList(list);
+                }
+            }
+        }
+        return installedProviders;
+    }
+
+    /**
+     * Returns the URI scheme that identifies this provider.
+     *
+     * @return  The URI scheme
+     */
+    public abstract String getScheme();
+
+    /**
+     * Constructs a new {@code FileSystem} object identified by a URI. This
+     * method is invoked by the {@link FileSystems#newFileSystem(URI,Map)}
+     * method to open a new file system identified by a URI.
+     *
+     * <p> The {@code uri} parameter is an absolute, hierarchical URI, with a
+     * scheme equal (without regard to case) to the scheme supported by this
+     * provider. The exact form of the URI is highly provider dependent. The
+     * {@code env} parameter is a map of provider specific properties to configure
+     * the file system.
+     *
+     * <p> This method throws {@link FileSystemAlreadyExistsException} if the
+     * file system already exists because it was previously created by an
+     * invocation of this method. Once a file system is {@link FileSystem#close
+     * closed} it is provider-dependent if the provider allows a new file system
+     * to be created with the same URI as a file system it previously created.
+     *
+     * @param   uri
+     *          URI reference
+     * @param   env
+     *          A map of provider specific properties to configure the file system;
+     *          may be empty
+     *
+     * @return  A new file system
+     *
+     * @throws  IllegalArgumentException
+     *          If the pre-conditions for the {@code uri} parameter aren't met,
+     *          or the {@code env} parameter does not contain properties required
+     *          by the provider, or a property value is invalid
+     * @throws  IOException
+     *          An I/O error occurs creating the file system
+     * @throws  SecurityException
+     *          If a security manager is installed and it denies an unspecified
+     *          permission required by the file system provider implementation
+     * @throws  FileSystemAlreadyExistsException
+     *          If the file system has already been created
+     */
+    public abstract FileSystem newFileSystem(URI uri, Map<String,?> env)
+        throws IOException;
+
+    /**
+     * Returns an existing {@code FileSystem} created by this provider.
+     *
+     * <p> This method returns a reference to a {@code FileSystem} that was
+     * created by invoking the {@link #newFileSystem(URI,Map) newFileSystem(URI,Map)}
+     * method. File systems created the {@link #newFileSystem(FileRef,Map)
+     * newFileSystem(FileRef,Map)} method are not returned by this method.
+     * The file system is identified by its {@code URI}. Its exact form
+     * is highly provider dependent. In the case of the default provider the URI's
+     * path component is {@code "/"} and the authority, query and fragment components
+     * are undefined (Undefined components are represented by {@code null}).
+     *
+     * <p> Once a file system created by this provider is {@link FileSystem#close
+     * closed} it is provider-dependent if this method returns a reference to
+     * the closed file system or throws {@link FileSystemNotFoundException}.
+     * If the provider allows a new file system to be created with the same URI
+     * as a file system it previously created then this method throws the
+     * exception if invoked after the file system is closed (and before a new
+     * instance is created by the {@link #newFileSystem newFileSystem} method).
+     *
+     * <p> If a security manager is installed then a provider implementation
+     * may require to check a permission before returning a reference to an
+     * existing file system. In the case of the {@link FileSystems#getDefault
+     * default} file system, no permission check is required.
+     *
+     * @param   uri
+     *          URI reference
+     *
+     * @return  The file system
+     *
+     * @throws  IllegalArgumentException
+     *          If the pre-conditions for the {@code uri} parameter aren't met
+     * @throws  FileSystemNotFoundException
+     *          If the file system does not exist
+     * @throws  SecurityException
+     *          If a security manager is installed and it denies an unspecified
+     *          permission.
+     */
+    public abstract FileSystem getFileSystem(URI uri);
+
+    /**
+     * Return a {@code Path} object by converting the given {@link URI}.
+     *
+     * <p> The exact form of the URI is file system provider dependent. In the
+     * case of the default provider, the URI scheme is {@code "file"} and the
+     * given URI has a non-empty path component, and undefined query, and
+     * fragment components. The resulting {@code Path} is associated with the
+     * default {@link FileSystems#getDefault default} {@code FileSystem}.
+     *
+     * <p> If a security manager is installed then a provider implementation
+     * may require to check a permission. In the case of the {@link
+     * FileSystems#getDefault default} file system, no permission check is
+     * required.
+     *
+     * @param   uri
+     *          The URI to convert
+     *
+     * @throws  IllegalArgumentException
+     *          If the URI scheme does not identify this provider or other
+     *          preconditions on the uri parameter do not hold
+     * @throws  FileSystemNotFoundException
+     *          The file system, identified by the URI, does not exist
+     * @throws  SecurityException
+     *          If a security manager is installed and it denies an unspecified
+     *          permission.
+     */
+    public abstract Path getPath(URI uri);
+
+    /**
+     * Constructs a new {@code FileSystem} to access the contents of a file as a
+     * file system.
+     *
+     * <p> This method is intended for specialized providers of pseudo file
+     * systems where the contents of one or more files is treated as a file
+     * system. The {@code file} parameter is a reference to an existing file
+     * and the {@code env} parameter is a map of provider specific properties to
+     * configure the file system.
+     *
+     * <p> If this provider does not support the creation of such file systems
+     * or if the provider does not recognize the file type of the given file then
+     * it throws {@code UnsupportedOperationException}. The default implementation
+     * of this method throws {@code UnsupportedOperationException}.
+     *
+     * @param   file
+     *          The file
+     * @param   env
+     *          A map of provider specific properties to configure the file system;
+     *          may be empty
+     *
+     * @return  A new file system
+     *
+     * @throws  UnsupportedOperationException
+     *          If this provider does not support access to the contents as a
+     *          file system or it does not recognize the file type of the
+     *          given file
+     * @throws  IllegalArgumentException
+     *          If the {@code env} parameter does not contain properties required
+     *          by the provider, or a property value is invalid
+     * @throws  IOException
+     *          If an I/O error occurs
+     * @throws  SecurityException
+     *          If a security manager is installed and it denies an unspecified
+     *          permission.
+     */
+    public FileSystem newFileSystem(FileRef file, Map<String,?> env)
+        throws IOException
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Opens or creates a file for reading and/or writing, returning a file
+     * channel to access the file.
+     *
+     * <p> This method is invoked by the {@link FileChannel#open(Path,Set,FileAttribute[])
+     * FileChannel.open} method to open a file channel. A provider that does not
+     * support all the features required to construct a file channel throws
+     * {@code UnsupportedOperationException}. The default provider is required
+     * to support the creation of file channels. When not overridden, the
+     * default implementation throws {@code UnsupportedOperationException}.
+     *
+     * @param   path
+     *          The path of the file to open or create
+     * @param   options
+     *          Options specifying how the file is opened
+     * @param   attrs
+     *          An optional list of file attributes to set atomically when
+     *          creating the file
+     *
+     * @return  A new file channel
+     *
+     * @throws  IllegalArgumentException
+     *          If the set contains an invalid combination of options
+     * @throws  UnsupportedOperationException
+     *          If this provider that does not support creating file channels,
+     *          or an unsupported open option or file attribute is specified
+     * @throws  IOException
+     *          If an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default file system, the {@link
+     *          SecurityManager#checkRead(String)} method is invoked to check
+     *          read access if the file is opened for reading. The {@link
+     *          SecurityManager#checkWrite(String)} method is invoked to check
+     *          write access if the file is opened for writing
+     */
+    public FileChannel newFileChannel(Path path,
+                                      Set<? extends OpenOption> options,
+                                      FileAttribute<?>... attrs)
+        throws IOException
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Opens or creates a file for reading and/or writing, returning an
+     * asynchronous file channel to access the file.
+     *
+     * <p> This method is invoked by the {@link
+     * AsynchronousFileChannel#open(Path,Set,ExecutorService,FileAttribute[])
+     * AsynchronousFileChannel.open} method to open an asynchronous file channel.
+     * A provider that does not support all the features required to construct
+     * an asynchronous file channel throws {@code UnsupportedOperationException}.
+     * The default provider is required to support the creation of asynchronous
+     * file channels. When not overridden, the default implementation of this
+     * method throws {@code UnsupportedOperationException}.
+     *
+     * @param   path
+     *          The path of the file to open or create
+     * @param   options
+     *          Options specifying how the file is opened
+     * @param   executor
+     *          The thread pool or {@code null} to associate the channel with
+     *          the default thread pool
+     * @param   attrs
+     *          An optional list of file attributes to set atomically when
+     *          creating the file
+     *
+     * @return  A new asynchronous file channel
+     *
+     * @throws  IllegalArgumentException
+     *          If the set contains an invalid combination of options
+     * @throws  UnsupportedOperationException
+     *          If this provider that does not support creating asynchronous file
+     *          channels, or an unsupported open option or file attribute is
+     *          specified
+     * @throws  IOException
+     *          If an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default file system, the {@link
+     *          SecurityManager#checkRead(String)} method is invoked to check
+     *          read access if the file is opened for reading. The {@link
+     *          SecurityManager#checkWrite(String)} method is invoked to check
+     *          write access if the file is opened for writing
+     */
+    public AsynchronousFileChannel newAsynchronousFileChannel(Path path,
+                                                              Set<? extends OpenOption> options,
+                                                              ExecutorService executor,
+                                                              FileAttribute<?>... attrs)
+        throws IOException
+    {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/jdk/src/share/classes/java/nio/file/spi/FileTypeDetector.java b/jdk/src/share/classes/java/nio/file/spi/FileTypeDetector.java
new file mode 100644
index 0000000..65e3c49
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/spi/FileTypeDetector.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file.spi;
+
+import java.nio.file.FileRef;
+import java.io.IOException;
+
+/**
+ * A file type detector for probing a file to guess its file type.
+ *
+ * <p> A file type detector is a concrete implementation of this class, has a
+ * zero-argument constructor, and implements the abstract methods specified
+ * below.
+ *
+ * <p> The means by which a file type detector determines the file type is
+ * highly implementation specific. A simple implementation might examine the
+ * <em>file extension</em> (a convention used in some platforms) and map it to
+ * a file type. In other cases, the file type may be stored as a file <a
+ * href="../attribute/package-summary.html"> attribute</a> or the bytes in a
+ * file may be examined to guess its file type.
+ *
+ * @see java.nio.file.Files#probeContentType(FileRef)
+ *
+ * @since 1.7
+ */
+
+public abstract class FileTypeDetector {
+
+    private static Void checkPermission() {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null)
+            sm.checkPermission(new RuntimePermission("fileTypeDetector"));
+        return null;
+    }
+    private FileTypeDetector(Void ignore) { }
+
+    /**
+     * Initializes a new instance of this class.
+     *
+     * @throws  SecurityException
+     *          If a security manager has been installed and it denies
+     *          {@link RuntimePermission}<tt>("fileTypeDetector")</tt>
+     */
+    protected FileTypeDetector() {
+        this(checkPermission());
+    }
+
+    /**
+     * Probes the given file to guess its content type.
+     *
+     * <p> The means by which this method determines the file type is highly
+     * implementation specific. It may simply examine the file name, it may use
+     * a file <a href="../attribute/package-summary.html">attribute</a>,
+     * or it may examines bytes in the file.
+     *
+     * <p> The probe result is the string form of the value of a
+     * Multipurpose Internet Mail Extension (MIME) content type as
+     * defined by <a href="http://www.ietf.org/rfc/rfc2045.txt"><i>RFC&nbsp;2045:
+     * Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet
+     * Message Bodies</i></a>. The string must be parsable according to the
+     * grammar in the RFC 2045.
+     *
+     * @param   file
+     *          The file to probe
+     *
+     * @return  The content type or {@code null} if the file type is not
+     *          recognized
+     *
+     * @throws  IOException
+     *          An I/O error occurs
+     * @throws  SecurityException
+     *          If the implementation requires to access the file, and a
+     *          security manager is installed, and it denies an unspecified
+     *          permission required by a file system provider implementation.
+     *          If the file reference is associated with the default file system
+     *          provider then the {@link SecurityManager#checkRead(String)} method
+     *          is invoked to check read access to the file.
+     *
+     * @see java.nio.file.Files#probeContentType
+     */
+    public abstract String probeContentType(FileRef file)
+        throws IOException;
+}
diff --git a/jdk/src/share/classes/java/nio/file/spi/package-info.java b/jdk/src/share/classes/java/nio/file/spi/package-info.java
new file mode 100644
index 0000000..88149b7
--- /dev/null
+++ b/jdk/src/share/classes/java/nio/file/spi/package-info.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * Service-provider classes for the <tt>{@link java.nio.file}</tt> package.
+ *
+ * <p> Only developers who are defining new file system providers or file type
+ * detectors should need to make direct use of this package.  </p>
+ *
+ * <p> Unless otherwise noted, passing a <tt>null</tt> argument to a constructor
+ * or method in any class or interface in this package will cause a {@link
+ * java.lang.NullPointerException NullPointerException} to be thrown.
+ *
+ * @since 1.7
+ */
+
+package java.nio.file.spi;
diff --git a/jdk/src/share/classes/java/util/Scanner.java b/jdk/src/share/classes/java/util/Scanner.java
index 8fd828f..3e3806d 100644
--- a/jdk/src/share/classes/java/util/Scanner.java
+++ b/jdk/src/share/classes/java/util/Scanner.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-2009 Sun Microsystems, Inc.  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
@@ -25,6 +25,7 @@
 
 package java.util;
 
+import java.nio.file.FileRef;
 import java.util.regex.*;
 import java.io.*;
 import java.math.*;
@@ -673,6 +674,49 @@
     }
 
     /**
+     * {@note new}
+     * Constructs a new <code>Scanner</code> that produces values scanned
+     * from the specified file. Bytes from the file are converted into
+     * characters using the underlying platform's
+     * {@linkplain java.nio.charset.Charset#defaultCharset() default charset}.
+     *
+     * @param   source
+     *          A file to be scanned
+     * @throws  IOException
+     *          if an I/O error occurs opening source
+     *
+     * @since   1.7
+     */
+    public Scanner(FileRef source)
+        throws IOException
+    {
+        this(source.newByteChannel());
+    }
+
+    /**
+     * {@note new}
+     * Constructs a new <code>Scanner</code> that produces values scanned
+     * from the specified file. Bytes from the file are converted into
+     * characters using the specified charset.
+     *
+     * @param   source
+     *          A file to be scanned
+     * @param   charsetName
+     *          The encoding type used to convert bytes from the file
+     *          into characters to be scanned
+     * @throws  IOException
+     *          if an I/O error occurs opening source
+     * @throws  IllegalArgumentException
+     *          if the specified encoding is not found
+     * @since   1.7
+     */
+    public Scanner(FileRef source, String charsetName)
+        throws IOException
+    {
+        this(source.newByteChannel(), charsetName);
+    }
+
+    /**
      * Constructs a new <code>Scanner</code> that produces values scanned
      * from the specified string.
      *
diff --git a/jdk/src/share/classes/java/util/regex/Matcher.java b/jdk/src/share/classes/java/util/regex/Matcher.java
index ee79316..61b75eb 100644
--- a/jdk/src/share/classes/java/util/regex/Matcher.java
+++ b/jdk/src/share/classes/java/util/regex/Matcher.java
@@ -491,6 +491,45 @@
     }
 
     /**
+     * Returns the input subsequence captured by the given
+     * <a href="Pattern.html#groupname">named-capturing group</a> during the previous
+     * match operation.
+     *
+     * <p> If the match was successful but the group specified failed to match
+     * any part of the input sequence, then <tt>null</tt> is returned. Note
+     * that some groups, for example <tt>(a*)</tt>, match the empty string.
+     * This method will return the empty string when such a group successfully
+     * matches the empty string in the input.  </p>
+     *
+     * @param  name
+     *         The name of a named-capturing group in this matcher's pattern
+     *
+     * @return  The (possibly empty) subsequence captured by the named group
+     *          during the previous match, or <tt>null</tt> if the group
+     *          failed to match part of the input
+     *
+     * @throws  IllegalStateException
+     *          If no match has yet been attempted,
+     *          or if the previous match operation failed
+     *
+     * @throws  IllegalArgumentException
+     *          If there is no capturing group in the pattern
+     *          with the given name
+     */
+    public String group(String name) {
+        if (name == null)
+            throw new NullPointerException("Null group name");
+        if (first < 0)
+            throw new IllegalStateException("No match found");
+        if (!parentPattern.namedGroups().containsKey(name))
+            throw new IllegalArgumentException("No group with name <" + name + ">");
+        int group = parentPattern.namedGroups().get(name);
+        if ((groups[group*2] == -1) || (groups[group*2+1] == -1))
+            return null;
+        return getSubSequence(groups[group * 2], groups[group * 2 + 1]).toString();
+    }
+
+    /**
      * Returns the number of capturing groups in this matcher's pattern.
      *
      * <p> Group zero denotes the entire pattern by convention. It is not
@@ -649,9 +688,11 @@
      *
      * <p> The replacement string may contain references to subsequences
      * captured during the previous match: Each occurrence of
-     * <tt>$</tt><i>g</i><tt></tt> will be replaced by the result of
-     * evaluating {@link #group(int) group}<tt>(</tt><i>g</i><tt>)</tt>.
-     * The first number after the <tt>$</tt> is always treated as part of
+     * <tt>$</tt>&lt;<i>name</i>&gt; or <tt>$</tt><i>g</i>
+     * will be replaced by the result of evaluating the corresponding
+     * {@link #group(String) group(name)} or {@link #group(int) group(g)</tt>}
+     * respectively. For  <tt>$</tt><i>g</i><tt></tt>,
+     * the first number after the <tt>$</tt> is always treated as part of
      * the group reference. Subsequent numbers are incorporated into g if
      * they would form a legal group reference. Only the numerals '0'
      * through '9' are considered as potential components of the group
@@ -695,6 +736,10 @@
      *          If no match has yet been attempted,
      *          or if the previous match operation failed
      *
+     * @throws  IllegalArgumentException
+     *          If the replacement string refers to a named-capturing
+     *          group that does not exist in the pattern
+     *
      * @throws  IndexOutOfBoundsException
      *          If the replacement string refers to a capturing group
      *          that does not exist in the pattern
@@ -719,29 +764,62 @@
             } else if (nextChar == '$') {
                 // Skip past $
                 cursor++;
-                // The first number is always a group
-                int refNum = (int)replacement.charAt(cursor) - '0';
-                if ((refNum < 0)||(refNum > 9))
-                    throw new IllegalArgumentException(
-                        "Illegal group reference");
-                cursor++;
-
-                // Capture the largest legal group string
-                boolean done = false;
-                while (!done) {
-                    if (cursor >= replacement.length()) {
-                        break;
+                // A StringIndexOutOfBoundsException is thrown if
+                // this "$" is the last character in replacement
+                // string in current implementation, a IAE might be
+                // more appropriate.
+                nextChar = replacement.charAt(cursor);
+                int refNum = -1;
+                if (nextChar == '<') {
+                    cursor++;
+                    StringBuilder gsb = new StringBuilder();
+                    while (cursor < replacement.length()) {
+                        nextChar = replacement.charAt(cursor);
+                        if (ASCII.isLower(nextChar) ||
+                            ASCII.isUpper(nextChar) ||
+                            ASCII.isDigit(nextChar)) {
+                            gsb.append(nextChar);
+                            cursor++;
+                        } else {
+                            break;
+                        }
                     }
-                    int nextDigit = replacement.charAt(cursor) - '0';
-                    if ((nextDigit < 0)||(nextDigit > 9)) { // not a number
-                        break;
-                    }
-                    int newRefNum = (refNum * 10) + nextDigit;
-                    if (groupCount() < newRefNum) {
-                        done = true;
-                    } else {
-                        refNum = newRefNum;
-                        cursor++;
+                    if (gsb.length() == 0)
+                        throw new IllegalArgumentException(
+                            "named capturing group has 0 length name");
+                    if (nextChar != '>')
+                        throw new IllegalArgumentException(
+                            "named capturing group is missing trailing '>'");
+                    String gname = gsb.toString();
+                    if (!parentPattern.namedGroups().containsKey(gname))
+                        throw new IllegalArgumentException(
+                            "No group with name <" + gname + ">");
+                    refNum = parentPattern.namedGroups().get(gname);
+                    cursor++;
+                } else {
+                    // The first number is always a group
+                    refNum = (int)nextChar - '0';
+                    if ((refNum < 0)||(refNum > 9))
+                        throw new IllegalArgumentException(
+                            "Illegal group reference");
+                    cursor++;
+                    // Capture the largest legal group string
+                    boolean done = false;
+                    while (!done) {
+                        if (cursor >= replacement.length()) {
+                            break;
+                        }
+                        int nextDigit = replacement.charAt(cursor) - '0';
+                        if ((nextDigit < 0)||(nextDigit > 9)) { // not a number
+                            break;
+                        }
+                        int newRefNum = (refNum * 10) + nextDigit;
+                        if (groupCount() < newRefNum) {
+                            done = true;
+                        } else {
+                            refNum = newRefNum;
+                            cursor++;
+                        }
                     }
                 }
                 // Append group
diff --git a/jdk/src/share/classes/java/util/regex/Pattern.java b/jdk/src/share/classes/java/util/regex/Pattern.java
index 2458a85..919c1bf 100644
--- a/jdk/src/share/classes/java/util/regex/Pattern.java
+++ b/jdk/src/share/classes/java/util/regex/Pattern.java
@@ -29,6 +29,7 @@
 import java.security.PrivilegedAction;
 import java.text.CharacterIterator;
 import java.text.Normalizer;
+import java.util.Map;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Arrays;
@@ -298,6 +299,10 @@
  *     <td valign="bottom" headers="matches">Whatever the <i>n</i><sup>th</sup>
  *     <a href="#cg">capturing group</a> matched</td></tr>
  *
+ * <tr><td valign="bottom" headers="construct backref"><tt>\</tt><i>k</i>&lt;<i>name</i>&gt;</td>
+ *     <td valign="bottom" headers="matches">Whatever the
+ *     <a href="#groupname">named-capturing group</a> "name" matched</td></tr>
+ *
  * <tr><th>&nbsp;</th></tr>
  * <tr align="left"><th colspan="2" id="quot">Quotation</th></tr>
  *
@@ -310,8 +315,10 @@
  *     <!-- Metachars: !$()*+.<>?[\]^{|} -->
  *
  * <tr><th>&nbsp;</th></tr>
- * <tr align="left"><th colspan="2" id="special">Special constructs (non-capturing)</th></tr>
+ * <tr align="left"><th colspan="2" id="special">Special constructs (named-capturing and non-capturing)</th></tr>
  *
+ * <tr><td valign="top" headers="construct special"><tt>(?&lt;<a href="#groupname">name</a>&gt;</tt><i>X</i><tt>)</tt></td>
+ *     <td headers="matches"><i>X</i>, as a named-capturing group</td></tr>
  * <tr><td valign="top" headers="construct special"><tt>(?:</tt><i>X</i><tt>)</tt></td>
  *     <td headers="matches"><i>X</i>, as a non-capturing group</td></tr>
  * <tr><td valign="top" headers="construct special"><tt>(?idmsux-idmsux)&nbsp;</tt></td>
@@ -449,6 +456,8 @@
  * <a name="cg">
  * <h4> Groups and capturing </h4>
  *
+ * <a name="gnumber">
+ * <h5> Group number </h5>
  * <p> Capturing groups are numbered by counting their opening parentheses from
  * left to right.  In the expression <tt>((A)(B(C)))</tt>, for example, there
  * are four such groups: </p>
@@ -471,6 +480,24 @@
  * subsequence may be used later in the expression, via a back reference, and
  * may also be retrieved from the matcher once the match operation is complete.
  *
+ * <a name="groupname">
+ * <h5> Group name </h5>
+ * <p>A capturing group can also be assigned a "name", a <tt>named-capturing group</tt>,
+ * and then be back-referenced later by the "name". Group names are composed of
+ * the following characters:
+ *
+ * <ul>
+ *   <li> The uppercase letters <tt>'A'</tt> through <tt>'Z'</tt>
+ *        (<tt>'&#92;u0041'</tt>&nbsp;through&nbsp;<tt>'&#92;u005a'</tt>),
+ *   <li> The lowercase letters <tt>'a'</tt> through <tt>'z'</tt>
+ *        (<tt>'&#92;u0061'</tt>&nbsp;through&nbsp;<tt>'&#92;u007a'</tt>),
+ *   <li> The digits <tt>'0'</tt> through <tt>'9'</tt>
+ *        (<tt>'&#92;u0030'</tt>&nbsp;through&nbsp;<tt>'&#92;u0039'</tt>),
+ * </ul>
+ *
+ * <p> A <tt>named-capturing group</tt> is still numbered as described in
+ * <a href="#gnumber">Group number</a>.
+ *
  * <p> The captured input associated with a group is always the subsequence
  * that the group most recently matched.  If a group is evaluated a second time
  * because of quantification then its previously-captured value, if any, will
@@ -479,9 +506,9 @@
  * group two set to <tt>"b"</tt>.  All captured input is discarded at the
  * beginning of each match.
  *
- * <p> Groups beginning with <tt>(?</tt> are pure, <i>non-capturing</i> groups
- * that do not capture text and do not count towards the group total.
- *
+ * <p> Groups beginning with <tt>(?</tt> are either pure, <i>non-capturing</i> groups
+ * that do not capture text and do not count towards the group total, or
+ * <i>named-capturing</i> group.
  *
  * <h4> Unicode support </h4>
  *
@@ -795,6 +822,12 @@
     transient int[] buffer;
 
     /**
+     * Map the "name" of the "named capturing group" to its group id
+     * node.
+     */
+    transient volatile Map<String, Integer> namedGroups;
+
+    /**
      * Temporary storage used while parsing group references.
      */
     transient GroupHead[] groupNodes;
@@ -1467,6 +1500,7 @@
         // Allocate all temporary objects here.
         buffer = new int[32];
         groupNodes = new GroupHead[10];
+        namedGroups = null;
 
         if (has(LITERAL)) {
             // Literal pattern handling
@@ -1505,6 +1539,12 @@
         compiled = true;
     }
 
+    Map<String, Integer> namedGroups() {
+        if (namedGroups == null)
+            namedGroups = new HashMap<String, Integer>(2);
+        return namedGroups;
+    }
+
     /**
      * Used to print out a subtree of the Pattern to help with debugging.
      */
@@ -2156,7 +2196,22 @@
         case 'h':
         case 'i':
         case 'j':
+            break;
         case 'k':
+            if (inclass)
+                break;
+            if (read() != '<')
+                throw error("\\k is not followed by '<' for named capturing group");
+            String name = groupname(read());
+            if (!namedGroups().containsKey(name))
+                throw error("(named capturing group <"+ name+"> does not exit");
+            if (create) {
+                if (has(CASE_INSENSITIVE))
+                    root = new CIBackRef(namedGroups().get(name), has(UNICODE_CASE));
+                else
+                    root = new BackRef(namedGroups().get(name));
+            }
+            return -1;
         case 'l':
         case 'm':
             break;
@@ -2456,6 +2511,24 @@
     }
 
     /**
+     * Parses and returns the name of a "named capturing group", the trailing
+     * ">" is consumed after parsing.
+     */
+    private String groupname(int ch) {
+        StringBuilder sb = new StringBuilder();
+        sb.append(Character.toChars(ch));
+        while (ASCII.isLower(ch=read()) || ASCII.isUpper(ch) ||
+               ASCII.isDigit(ch)) {
+            sb.append(Character.toChars(ch));
+        }
+        if (sb.length() == 0)
+            throw error("named capturing group has 0 length name");
+        if (ch != '>')
+            throw error("named capturing group is missing trailing '>'");
+        return sb.toString();
+    }
+
+    /**
      * Parses a group and returns the head node of a set of nodes that process
      * the group. Sometimes a double return system is used where the tail is
      * returned in root.
@@ -2494,6 +2567,18 @@
                 break;
             case '<':   // (?<xxx)  look behind
                 ch = read();
+                if (Character.isLetter(ch)) {     // named captured group
+                    String name = groupname(ch);
+                    if (namedGroups().containsKey(name))
+                        throw error("Named capturing group <" + name
+                                    + "> is already defined");
+                    capturingGroup = true;
+                    head = createGroup(false);
+                    tail = root;
+                    namedGroups().put(name, capturingGroupCount-1);
+                    head.next = expr(tail);
+                    break;
+                }
                 int start = cursor;
                 head = createGroup(true);
                 tail = root;
diff --git a/jdk/src/share/classes/sun/nio/ch/AbstractFuture.java b/jdk/src/share/classes/sun/nio/ch/AbstractFuture.java
new file mode 100644
index 0000000..f79dc7a
--- /dev/null
+++ b/jdk/src/share/classes/sun/nio/ch/AbstractFuture.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.ch;
+
+import java.nio.channels.AsynchronousChannel;
+import java.util.concurrent.Future;
+
+/**
+ * Base implementation of Future used for asynchronous I/O
+ */
+
+abstract class AbstractFuture<V,A>
+    implements Future<V>
+{
+    private final AsynchronousChannel channel;
+    private final A attachment;
+
+    protected AbstractFuture(AsynchronousChannel channel, A attachment) {
+        this.channel = channel;
+        this.attachment = attachment;
+    }
+
+    final AsynchronousChannel channel() {
+        return channel;
+    }
+
+    final A attachment() {
+        return attachment;
+    }
+
+    /**
+     * Returns the result of the operation if it has completed successfully.
+     */
+    abstract V value();
+
+    /**
+     * Returns the exception if the operation has failed.
+     */
+    abstract Throwable exception();
+}
diff --git a/jdk/src/share/classes/sun/nio/ch/AsynchronousChannelGroupImpl.java b/jdk/src/share/classes/sun/nio/ch/AsynchronousChannelGroupImpl.java
new file mode 100644
index 0000000..14e33ff
--- /dev/null
+++ b/jdk/src/share/classes/sun/nio/ch/AsynchronousChannelGroupImpl.java
@@ -0,0 +1,341 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.ch;
+
+import java.nio.channels.Channel;
+import java.nio.channels.AsynchronousChannelGroup;
+import java.nio.channels.spi.AsynchronousChannelProvider;
+import java.io.IOException;
+import java.io.FileDescriptor;
+import java.util.Queue;
+import java.util.concurrent.*;
+import java.util.concurrent.locks.*;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.security.PrivilegedAction;
+import java.security.AccessController;
+import java.security.AccessControlContext;
+import sun.security.action.GetIntegerAction;
+
+/**
+ * Base implementation of AsynchronousChannelGroup
+ */
+
+abstract class AsynchronousChannelGroupImpl
+    extends AsynchronousChannelGroup implements Executor
+{
+    // number of internal threads handling I/O events when using an unbounded
+    // thread pool. Internal threads do not dispatch to completion handlers.
+    private static final int internalThreadCount = AccessController.doPrivileged(
+        new GetIntegerAction("sun.nio.ch.internalThreadPoolSize", 1));
+
+    // associated thread pool
+    private final ThreadPool pool;
+
+    // number of tasks running (including internal)
+    private final AtomicInteger threadCount = new AtomicInteger();
+
+    // associated Executor for timeouts
+    private ScheduledThreadPoolExecutor timeoutExecutor;
+
+    // task queue for when using a fixed thread pool. In that case, thread
+    // waiting on I/O events must be awokon to poll tasks from this queue.
+    private final Queue<Runnable> taskQueue;
+
+    // group shutdown
+    // shutdownLock is RW lock so as to allow for concurrent queuing of tasks
+    // when using a fixed thread pool.
+    private final ReadWriteLock shutdownLock = new ReentrantReadWriteLock();
+    private final Object shutdownNowLock = new Object();
+    private volatile boolean shutdown;
+    private volatile boolean terminateInitiated;
+
+    AsynchronousChannelGroupImpl(AsynchronousChannelProvider provider,
+                                 ThreadPool pool)
+    {
+        super(provider);
+        this.pool = pool;
+
+        if (pool.isFixedThreadPool()) {
+            taskQueue = new ConcurrentLinkedQueue<Runnable>();
+        } else {
+            taskQueue = null;   // not used
+        }
+
+        // use default thread factory as thread should not be visible to
+        // application (it doesn't execute completion handlers).
+        this.timeoutExecutor = (ScheduledThreadPoolExecutor)
+            Executors.newScheduledThreadPool(1, ThreadPool.defaultThreadFactory());
+        this.timeoutExecutor.setRemoveOnCancelPolicy(true);
+    }
+
+    final ExecutorService executor() {
+        return pool.executor();
+    }
+
+    final boolean isFixedThreadPool() {
+        return pool.isFixedThreadPool();
+    }
+
+    final int fixedThreadCount() {
+        if (isFixedThreadPool()) {
+            return pool.poolSize();
+        } else {
+            return pool.poolSize() + internalThreadCount;
+        }
+    }
+
+    private Runnable bindToGroup(final Runnable task) {
+        final AsynchronousChannelGroupImpl thisGroup = this;
+        return new Runnable() {
+            public void run() {
+                Invoker.bindToGroup(thisGroup);
+                task.run();
+            }
+        };
+    }
+
+    private void startInternalThread(final Runnable task) {
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+            @Override
+            public Void run() {
+                // internal threads should not be visible to application so
+                // cannot use user-supplied thread factory
+                ThreadPool.defaultThreadFactory().newThread(task).start();
+                return null;
+            }
+         });
+    }
+
+    protected final void startThreads(Runnable task) {
+        if (!isFixedThreadPool()) {
+            for (int i=0; i<internalThreadCount; i++) {
+                startInternalThread(task);
+                threadCount.incrementAndGet();
+            }
+        }
+        if (pool.poolSize() > 0) {
+            task = bindToGroup(task);
+            try {
+                for (int i=0; i<pool.poolSize(); i++) {
+                    pool.executor().execute(task);
+                    threadCount.incrementAndGet();
+                }
+            } catch (RejectedExecutionException  x) {
+                // nothing we can do
+            }
+        }
+    }
+
+    final int threadCount() {
+        return threadCount.get();
+    }
+
+    /**
+     * Invoked by tasks as they terminate
+     */
+    final int threadExit(Runnable task, boolean replaceMe) {
+        if (replaceMe) {
+            try {
+                if (Invoker.isBoundToAnyGroup()) {
+                    // submit new task to replace this thread
+                    pool.executor().execute(bindToGroup(task));
+                } else {
+                    // replace internal thread
+                    startInternalThread(task);
+                }
+                return threadCount.get();
+            } catch (RejectedExecutionException x) {
+                // unable to replace
+            }
+        }
+        return threadCount.decrementAndGet();
+    }
+
+    /**
+     * Wakes up a thread waiting for I/O events to execute the given task.
+     */
+    abstract void executeOnHandlerTask(Runnable task);
+
+    /**
+     * For a fixed thread pool the task is queued to a thread waiting on I/O
+     * events. For other thread pools we simply submit the task to the thread
+     * pool.
+     */
+    final void executeOnPooledThread(Runnable task) {
+        if (isFixedThreadPool()) {
+            executeOnHandlerTask(task);
+        } else {
+            pool.executor().execute(bindToGroup(task));
+        }
+    }
+
+    final void offerTask(Runnable task) {
+        taskQueue.offer(task);
+    }
+
+    final Runnable pollTask() {
+        return (taskQueue == null) ? null : taskQueue.poll();
+    }
+
+    final Future<?> schedule(Runnable task, long timeout, TimeUnit unit) {
+        try {
+            return timeoutExecutor.schedule(task, timeout, unit);
+        } catch (RejectedExecutionException rej) {
+            if (terminateInitiated) {
+                // no timeout scheduled as group is terminating
+                return null;
+            }
+            throw new AssertionError(rej);
+        }
+    }
+
+    @Override
+    public final boolean isShutdown() {
+        return shutdown;
+    }
+
+    @Override
+    public final boolean isTerminated()  {
+        return pool.executor().isTerminated();
+    }
+
+    /**
+     * Returns true if there are no channels in the group
+     */
+    abstract boolean isEmpty();
+
+    /**
+     * Attaches a foreign channel to this group.
+     */
+    abstract Object attachForeignChannel(Channel channel, FileDescriptor fdo)
+        throws IOException;
+
+    /**
+     * Detaches a foreign channel from this group.
+     */
+    abstract void detachForeignChannel(Object key);
+
+    /**
+     * Closes all channels in the group
+     */
+    abstract void closeAllChannels() throws IOException;
+
+    /**
+     * Shutdown all tasks waiting for I/O events.
+     */
+    abstract void shutdownHandlerTasks();
+
+    private void shutdownExecutors() {
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+            public Void run() {
+                pool.executor().shutdown();
+                timeoutExecutor.shutdown();
+                return null;
+            }
+        });
+    }
+
+    @Override
+    public final void shutdown() {
+        shutdownLock.writeLock().lock();
+        try {
+            if (shutdown) {
+                // already shutdown
+                return;
+            }
+            shutdown = true;
+        } finally {
+            shutdownLock.writeLock().unlock();
+        }
+
+        // if there are channels in the group then shutdown will continue
+        // when the last channel is closed
+        if (!isEmpty()) {
+            return;
+        }
+        // initiate termination (acquire shutdownNowLock to ensure that other
+        // threads invoking shutdownNow will block).
+        synchronized (shutdownNowLock) {
+            if (!terminateInitiated) {
+                terminateInitiated = true;
+                shutdownHandlerTasks();
+                shutdownExecutors();
+            }
+        }
+    }
+
+    @Override
+    public final void shutdownNow() throws IOException {
+        shutdownLock.writeLock().lock();
+        try {
+            shutdown = true;
+        } finally {
+            shutdownLock.writeLock().unlock();
+        }
+        synchronized (shutdownNowLock) {
+            if (!terminateInitiated) {
+                terminateInitiated = true;
+                closeAllChannels();
+                shutdownHandlerTasks();
+                shutdownExecutors();
+            }
+        }
+    }
+
+    @Override
+    public final boolean awaitTermination(long timeout, TimeUnit unit)
+        throws InterruptedException
+    {
+        return pool.executor().awaitTermination(timeout, unit);
+    }
+
+    /**
+     * Executes the given command on one of the channel group's pooled threads.
+     */
+    @Override
+    public final void execute(Runnable task) {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            // when a security manager is installed then the user's task
+            // must be run with the current calling context
+            final AccessControlContext acc = AccessController.getContext();
+            final Runnable delegate = task;
+            task = new Runnable() {
+                @Override
+                public void run() {
+                    AccessController.doPrivileged(new PrivilegedAction<Void>() {
+                        @Override
+                        public Void run() {
+                            delegate.run();
+                            return null;
+                        }
+                    }, acc);
+                }
+            };
+        }
+        executeOnPooledThread(task);
+    }
+}
diff --git a/jdk/src/share/classes/sun/nio/ch/AsynchronousFileChannelImpl.java b/jdk/src/share/classes/sun/nio/ch/AsynchronousFileChannelImpl.java
new file mode 100644
index 0000000..2735a5a
--- /dev/null
+++ b/jdk/src/share/classes/sun/nio/ch/AsynchronousFileChannelImpl.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.ch;
+
+import java.nio.channels.*;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.locks.*;
+import java.io.FileDescriptor;
+import java.io.IOException;
+
+/**
+ * Base implementation of AsynchronousFileChannel.
+ */
+
+abstract class AsynchronousFileChannelImpl
+    extends AsynchronousFileChannel
+{
+    // close support
+    protected final ReadWriteLock closeLock = new ReentrantReadWriteLock();
+    protected volatile boolean closed;
+
+    // file descriptor
+    protected final FileDescriptor fdObj;
+
+    // indicates if open for reading/writing
+    protected final boolean reading;
+    protected final boolean writing;
+
+    // associated Executor
+    protected final ExecutorService executor;
+
+    protected AsynchronousFileChannelImpl(FileDescriptor fdObj,
+                                          boolean reading,
+                                          boolean writing,
+                                          ExecutorService executor)
+    {
+        this.fdObj = fdObj;
+        this.reading = reading;
+        this.writing = writing;
+        this.executor = executor;
+    }
+
+    final ExecutorService executor() {
+        return executor;
+    }
+
+    @Override
+    public final boolean isOpen() {
+        return !closed;
+    }
+
+    /**
+     * Marks the beginning of an I/O operation.
+     *
+     * @throws  ClosedChannelException  If channel is closed
+     */
+    protected final void begin() throws IOException {
+        closeLock.readLock().lock();
+        if (closed)
+            throw new ClosedChannelException();
+    }
+
+    /**
+     * Marks the end of an I/O operation.
+     */
+    protected final void end() {
+        closeLock.readLock().unlock();
+    }
+
+    /**
+     * Marks end of I/O operation
+     */
+    protected final void end(boolean completed) throws IOException {
+        end();
+        if (!completed && !isOpen())
+            throw new AsynchronousCloseException();
+    }
+
+    // -- file locking --
+
+    private volatile FileLockTable fileLockTable;
+
+    final void ensureFileLockTableInitialized() throws IOException {
+        if (fileLockTable == null) {
+            synchronized (this) {
+                if (fileLockTable == null) {
+                    fileLockTable = FileLockTable.newSharedFileLockTable(this, fdObj);
+                }
+            }
+        }
+    }
+
+    final void invalidateAllLocks() {
+        if (fileLockTable != null) {
+            try {
+                fileLockTable.removeAll( new FileLockTable.Releaser() {
+                    public void release(FileLock fl) {
+                        ((FileLockImpl)fl).invalidate();
+                    }
+                });
+            } catch (IOException e) {
+                throw new AssertionError(e);
+            }
+        }
+    }
+
+    /**
+     * Adds region to lock table
+     */
+    protected final FileLockImpl addToFileLockTable(long position, long size, boolean shared) {
+        final FileLockImpl fli;
+        try {
+            // like begin() but returns null instead of exception
+            closeLock.readLock().lock();
+            if (closed)
+                return null;
+
+            try {
+                ensureFileLockTableInitialized();
+            } catch (IOException x) {
+                // should not happen
+                throw new AssertionError(x);
+            }
+            fli = new FileLockImpl(this, position, size, shared);
+            // may throw OverlappedFileLockException
+            fileLockTable.add(fli);
+        } finally {
+            end();
+        }
+        return fli;
+    }
+
+    protected final void removeFromFileLockTable(FileLockImpl fli) {
+        fileLockTable.remove(fli);
+    }
+
+    /**
+     * Invoked by FileLockImpl to release lock acquired by this channel.
+     */
+    abstract void release(FileLockImpl fli) throws IOException;
+}
diff --git a/jdk/src/share/classes/sun/nio/ch/AsynchronousServerSocketChannelImpl.java b/jdk/src/share/classes/sun/nio/ch/AsynchronousServerSocketChannelImpl.java
new file mode 100644
index 0000000..b4fcb9c
--- /dev/null
+++ b/jdk/src/share/classes/sun/nio/ch/AsynchronousServerSocketChannelImpl.java
@@ -0,0 +1,219 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.ch;
+
+import java.nio.channels.*;
+import java.net.SocketAddress;
+import java.net.SocketOption;
+import java.net.StandardSocketOption;
+import java.net.InetSocketAddress;
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Collections;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+/**
+ * Base implementation of AsynchronousServerSocketChannel.
+ */
+
+abstract class AsynchronousServerSocketChannelImpl
+    extends AsynchronousServerSocketChannel
+    implements Cancellable, Groupable
+{
+    protected final FileDescriptor fd;
+
+    // the local address to which the channel's socket is bound
+    protected volatile SocketAddress localAddress = null;
+
+    // need this lock to set local address
+    private final Object stateLock = new Object();
+
+    // close support
+    private ReadWriteLock closeLock = new ReentrantReadWriteLock();
+    private volatile boolean open = true;
+
+    // set true when accept operation is cancelled
+    private volatile boolean acceptKilled;
+
+
+    AsynchronousServerSocketChannelImpl(AsynchronousChannelGroupImpl group) {
+        super(group.provider());
+        this.fd = Net.serverSocket(true);
+    }
+
+    @Override
+    public final boolean isOpen() {
+        return open;
+    }
+
+    /**
+     * Marks beginning of access to file descriptor/handle
+     */
+    final void begin() throws IOException {
+        closeLock.readLock().lock();
+        if (!isOpen())
+            throw new ClosedChannelException();
+    }
+
+    /**
+     * Marks end of access to file descriptor/handle
+     */
+    final void end() {
+        closeLock.readLock().unlock();
+    }
+
+    /**
+     * Invoked to close file descriptor/handle.
+     */
+    abstract void implClose() throws IOException;
+
+    @Override
+    public final void close() throws IOException {
+        // synchronize with any threads using file descriptor/handle
+        closeLock.writeLock().lock();
+        try {
+            if (!open)
+                return;     // already closed
+            open = false;
+        } finally {
+            closeLock.writeLock().unlock();
+        }
+        implClose();
+    }
+
+    final boolean isAcceptKilled() {
+        return acceptKilled;
+    }
+
+    @Override
+    public final void onCancel(PendingFuture<?,?> task) {
+        acceptKilled = true;
+    }
+
+    @Override
+    public final AsynchronousServerSocketChannel bind(SocketAddress local, int backlog)
+        throws IOException
+    {
+        InetSocketAddress isa = (local == null) ? new InetSocketAddress(0) :
+            Net.checkAddress(local);
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null)
+            sm.checkListen(isa.getPort());
+
+        try {
+            begin();
+            synchronized (stateLock) {
+                if (localAddress != null)
+                    throw new AlreadyBoundException();
+                Net.bind(fd, isa.getAddress(), isa.getPort());
+                Net.listen(fd, backlog < 1 ? 50 : backlog);
+                localAddress = Net.localAddress(fd);
+            }
+        } finally {
+            end();
+        }
+        return this;
+    }
+
+    @Override
+    public final SocketAddress getLocalAddress() throws IOException {
+        if (!isOpen())
+            throw new ClosedChannelException();
+        return localAddress;
+    }
+
+    @Override
+    public final <T> AsynchronousServerSocketChannel setOption(SocketOption<T> name,
+                                                               T value)
+        throws IOException
+    {
+        if (name == null)
+            throw new NullPointerException();
+        if (!supportedOptions().contains(name))
+            throw new UnsupportedOperationException("'" + name + "' not supported");
+
+        try {
+            begin();
+            Net.setSocketOption(fd, Net.UNSPEC, name, value);
+            return this;
+        } finally {
+            end();
+        }
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public final <T> T getOption(SocketOption<T> name) throws IOException {
+        if (name == null)
+            throw new NullPointerException();
+        if (!supportedOptions().contains(name))
+            throw new UnsupportedOperationException("'" + name + "' not supported");
+
+        try {
+            begin();
+            return (T) Net.getSocketOption(fd, Net.UNSPEC, name);
+        } finally {
+            end();
+        }
+    }
+
+    private static class DefaultOptionsHolder {
+        static final Set<SocketOption<?>> defaultOptions = defaultOptions();
+
+        private static Set<SocketOption<?>> defaultOptions() {
+            HashSet<SocketOption<?>> set = new HashSet<SocketOption<?>>(2);
+            set.add(StandardSocketOption.SO_RCVBUF);
+            set.add(StandardSocketOption.SO_REUSEADDR);
+            return Collections.unmodifiableSet(set);
+        }
+    }
+
+    @Override
+    public final Set<SocketOption<?>> supportedOptions() {
+        return DefaultOptionsHolder.defaultOptions;
+    }
+
+    @Override
+    public final String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(this.getClass().getName());
+        sb.append('[');
+        if (!isOpen())
+            sb.append("closed");
+        else {
+            if (localAddress == null) {
+                sb.append("unbound");
+            } else {
+                sb.append(localAddress.toString());
+            }
+        }
+        sb.append(']');
+        return sb.toString();
+    }
+}
diff --git a/jdk/src/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java b/jdk/src/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java
new file mode 100644
index 0000000..09637fb
--- /dev/null
+++ b/jdk/src/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java
@@ -0,0 +1,542 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.ch;
+
+import java.nio.ByteBuffer;
+import java.nio.channels.*;
+import java.net.SocketOption;
+import java.net.StandardSocketOption;
+import java.net.SocketAddress;
+import java.net.InetSocketAddress;
+import java.io.IOException;
+import java.io.FileDescriptor;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Collections;
+import java.util.concurrent.*;
+import java.util.concurrent.locks.*;
+
+/**
+ * Base implementation of AsynchronousSocketChannel
+ */
+
+abstract class AsynchronousSocketChannelImpl
+    extends AsynchronousSocketChannel
+    implements Cancellable, Groupable
+{
+    protected final FileDescriptor fd;
+
+    // protects state, localAddress, and remoteAddress
+    protected final Object stateLock = new Object();
+
+    protected volatile SocketAddress localAddress = null;
+    protected volatile SocketAddress remoteAddress = null;
+
+    // State, increases monotonically
+    static final int ST_UNINITIALIZED = -1;
+    static final int ST_UNCONNECTED = 0;
+    static final int ST_PENDING = 1;
+    static final int ST_CONNECTED = 2;
+    protected volatile int state = ST_UNINITIALIZED;
+
+    // reading state
+    private final Object readLock = new Object();
+    private boolean reading;
+    private boolean readShutdown;
+    private boolean readKilled;     // further reading disallowed due to timeout
+
+    // writing state
+    private final Object writeLock = new Object();
+    private boolean writing;
+    private boolean writeShutdown;
+    private boolean writeKilled;    // further writing disallowed due to timeout
+
+    // close support
+    private final ReadWriteLock closeLock = new ReentrantReadWriteLock();
+    private volatile boolean open = true;
+
+    AsynchronousSocketChannelImpl(AsynchronousChannelGroupImpl group)
+        throws IOException
+    {
+        super(group.provider());
+        this.fd = Net.socket(true);
+        this.state = ST_UNCONNECTED;
+    }
+
+    // Constructor for sockets obtained from AsynchronousServerSocketChannelImpl
+    AsynchronousSocketChannelImpl(AsynchronousChannelGroupImpl group,
+                                  FileDescriptor fd,
+                                  InetSocketAddress remote)
+        throws IOException
+    {
+        super(group.provider());
+        this.fd = fd;
+        this.state = ST_CONNECTED;
+        this.localAddress = Net.localAddress(fd);
+        this.remoteAddress = remote;
+    }
+
+    @Override
+    public final boolean isOpen() {
+        return open;
+    }
+
+    /**
+     * Marks beginning of access to file descriptor/handle
+     */
+    final void begin() throws IOException {
+        closeLock.readLock().lock();
+        if (!isOpen())
+            throw new ClosedChannelException();
+    }
+
+    /**
+     * Marks end of access to file descriptor/handle
+     */
+    final void end() {
+        closeLock.readLock().unlock();
+    }
+
+    /**
+     * Invoked to close socket and release other resources.
+     */
+    abstract void implClose() throws IOException;
+
+    @Override
+    public final void close() throws IOException {
+        // synchronize with any threads initiating asynchronous operations
+        closeLock.writeLock().lock();
+        try {
+            if (!open)
+                return;     // already closed
+            open = false;
+        } finally {
+            closeLock.writeLock().unlock();
+        }
+        implClose();
+    }
+
+    final void enableReading(boolean killed) {
+        synchronized (readLock) {
+            reading = false;
+            if (killed)
+                readKilled = true;
+        }
+    }
+
+    final void enableReading() {
+        enableReading(false);
+    }
+
+    final void enableWriting(boolean killed) {
+        synchronized (writeLock) {
+            writing = false;
+            if (killed)
+                writeKilled = true;
+        }
+    }
+
+    final void enableWriting() {
+        enableWriting(false);
+    }
+
+    final void killReading() {
+        synchronized (readLock) {
+            readKilled = true;
+        }
+    }
+
+    final void killWriting() {
+        synchronized (writeLock) {
+            writeKilled = true;
+        }
+    }
+
+    final void killConnect() {
+        // when a connect is cancelled then the connection may have been
+        // established so prevent reading or writing.
+        killReading();
+        killWriting();
+    }
+
+    /**
+     * Invoked by read to initiate the I/O operation.
+     */
+    abstract <V extends Number,A> Future<V> readImpl(ByteBuffer[] dsts,
+                                                     boolean isScatteringRead,
+                                                     long timeout,
+                                                     TimeUnit unit,
+                                                     A attachment,
+                                                     CompletionHandler<V,? super A> handler);
+
+    @SuppressWarnings("unchecked")
+    private <V extends Number,A> Future<V> read(ByteBuffer[] dsts,
+                                                boolean isScatteringRead,
+                                                long timeout,
+                                                TimeUnit unit,
+                                                A attachment,
+                                                CompletionHandler<V,? super A> handler)
+    {
+        if (!isOpen()) {
+            CompletedFuture<V,A> result = CompletedFuture
+                .withFailure(this, new ClosedChannelException(), attachment);
+            Invoker.invoke(handler, result);
+            return result;
+        }
+
+        if (remoteAddress == null)
+            throw new NotYetConnectedException();
+        if (timeout < 0L)
+            throw new IllegalArgumentException("Negative timeout");
+
+        boolean hasSpaceToRead = isScatteringRead || dsts[0].hasRemaining();
+        boolean shutdown = false;
+
+        // check and update state
+        synchronized (readLock) {
+            if (readKilled)
+                throw new RuntimeException("Reading not allowed due to timeout or cancellation");
+            if (reading)
+                throw new ReadPendingException();
+            if (readShutdown) {
+                shutdown = true;
+            } else {
+                if (hasSpaceToRead) {
+                    reading = true;
+                }
+            }
+        }
+
+        // immediately complete with -1 if shutdown for read
+        // immediately complete with 0 if no space remaining
+        if (shutdown || !hasSpaceToRead) {
+            CompletedFuture<V,A> result;
+            if (isScatteringRead) {
+                Long value = (shutdown) ? Long.valueOf(-1L) : Long.valueOf(0L);
+                result = (CompletedFuture<V,A>)CompletedFuture.withResult(this, value, attachment);
+            } else {
+                int value = (shutdown) ? -1 : 0;
+                result = (CompletedFuture<V,A>)CompletedFuture.withResult(this, value, attachment);
+            }
+            Invoker.invoke(handler, result);
+            return result;
+        }
+
+        return readImpl(dsts, isScatteringRead, timeout, unit, attachment, handler);
+    }
+
+    @Override
+    public final <A> Future<Integer> read(ByteBuffer dst,
+                                          long timeout,
+                                          TimeUnit unit,
+                                          A attachment,
+                                          CompletionHandler<Integer,? super A> handler)
+    {
+        if (dst.isReadOnly())
+            throw new IllegalArgumentException("Read-only buffer");
+        ByteBuffer[] bufs = new ByteBuffer[1];
+        bufs[0] = dst;
+        return read(bufs, false, timeout, unit, attachment, handler);
+    }
+
+    @Override
+    public final <A> Future<Long> read(ByteBuffer[] dsts,
+                                       int offset,
+                                       int length,
+                                       long timeout,
+                                       TimeUnit unit,
+                                       A attachment,
+                                       CompletionHandler<Long,? super A> handler)
+    {
+        if ((offset < 0) || (length < 0) || (offset > dsts.length - length))
+            throw new IndexOutOfBoundsException();
+        ByteBuffer[] bufs = Util.subsequence(dsts, offset, length);
+        for (int i=0; i<bufs.length; i++) {
+            if (bufs[i].isReadOnly())
+                throw new IllegalArgumentException("Read-only buffer");
+        }
+        return read(bufs, true, timeout, unit, attachment, handler);
+    }
+
+    /**
+     * Invoked by write to initiate the I/O operation.
+     */
+    abstract <V extends Number,A> Future<V> writeImpl(ByteBuffer[] srcs,
+                                                      boolean isGatheringWrite,
+                                                      long timeout,
+                                                      TimeUnit unit,
+                                                      A attachment,
+                                                      CompletionHandler<V,? super A> handler);
+
+    @SuppressWarnings("unchecked")
+    private <V extends Number,A> Future<V> write(ByteBuffer[] srcs,
+                                                 boolean isGatheringWrite,
+                                                 long timeout,
+                                                 TimeUnit unit,
+                                                 A attachment,
+                                                 CompletionHandler<V,? super A> handler)
+    {
+        boolean hasDataToWrite = isGatheringWrite || srcs[0].hasRemaining();
+
+        boolean closed = false;
+        if (isOpen()) {
+            if (remoteAddress == null)
+                throw new NotYetConnectedException();
+            if (timeout < 0L)
+                throw new IllegalArgumentException("Negative timeout");
+            // check and update state
+            synchronized (writeLock) {
+                if (writeKilled)
+                    throw new RuntimeException("Writing not allowed due to timeout or cancellation");
+                if (writing)
+                    throw new WritePendingException();
+                if (writeShutdown) {
+                    closed = true;
+                } else {
+                    if (hasDataToWrite)
+                        writing = true;
+                }
+            }
+        } else {
+            closed = true;
+        }
+
+        // channel is closed or shutdown for write
+        if (closed) {
+            CompletedFuture<V,A> result = CompletedFuture
+                .withFailure(this, new ClosedChannelException(), attachment);
+            Invoker.invoke(handler, result);
+            return result;
+        }
+
+        // nothing to write so complete immediately
+        if (!hasDataToWrite) {
+            CompletedFuture<V,A> result;
+            if (isGatheringWrite) {
+                result = (CompletedFuture<V,A>)CompletedFuture.withResult(this, 0L, attachment);
+            } else {
+                result = (CompletedFuture<V,A>)CompletedFuture.withResult(this, 0, attachment);
+            }
+            Invoker.invoke(handler, result);
+            return result;
+        }
+
+        return writeImpl(srcs, isGatheringWrite, timeout, unit, attachment, handler);
+    }
+
+    @Override
+    public final <A> Future<Integer> write(ByteBuffer src,
+                                           long timeout,
+                                           TimeUnit unit,
+                                           A attachment,
+                                           CompletionHandler<Integer,? super A> handler)
+    {
+        ByteBuffer[] bufs = new ByteBuffer[1];
+        bufs[0] = src;
+        return write(bufs, false, timeout, unit, attachment, handler);
+    }
+
+    @Override
+    public final <A> Future<Long> write(ByteBuffer[] srcs,
+                                        int offset,
+                                        int length,
+                                        long timeout,
+                                        TimeUnit unit,
+                                        A attachment,
+                                        CompletionHandler<Long,? super A> handler)
+    {
+        if ((offset < 0) || (length < 0) || (offset > srcs.length - length))
+            throw new IndexOutOfBoundsException();
+        srcs = Util.subsequence(srcs, offset, length);
+        return write(srcs, true, timeout, unit, attachment, handler);
+    }
+
+    @Override
+    public final AsynchronousSocketChannel bind(SocketAddress local)
+        throws IOException
+    {
+        try {
+            begin();
+            synchronized (stateLock) {
+                if (state == ST_PENDING)
+                    throw new ConnectionPendingException();
+                if (localAddress != null)
+                    throw new AlreadyBoundException();
+                InetSocketAddress isa = (local == null) ?
+                    new InetSocketAddress(0) : Net.checkAddress(local);
+                Net.bind(fd, isa.getAddress(), isa.getPort());
+                localAddress = Net.localAddress(fd);
+            }
+        } finally {
+            end();
+        }
+        return this;
+    }
+
+    @Override
+    public final SocketAddress getLocalAddress() throws IOException {
+        if (!isOpen())
+            throw new ClosedChannelException();
+        return localAddress;
+    }
+
+    @Override
+    public final <T> AsynchronousSocketChannel setOption(SocketOption<T> name, T value)
+        throws IOException
+    {
+        if (name == null)
+            throw new NullPointerException();
+        if (!supportedOptions().contains(name))
+            throw new UnsupportedOperationException("'" + name + "' not supported");
+
+        try {
+            begin();
+            if (writeShutdown)
+                throw new IOException("Connection has been shutdown for writing");
+            Net.setSocketOption(fd, Net.UNSPEC, name, value);
+            return this;
+        } finally {
+            end();
+        }
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public final <T> T getOption(SocketOption<T> name) throws IOException {
+        if (name == null)
+            throw new NullPointerException();
+        if (!supportedOptions().contains(name))
+            throw new UnsupportedOperationException("'" + name + "' not supported");
+
+        try {
+            begin();
+            return (T) Net.getSocketOption(fd, Net.UNSPEC, name);
+        } finally {
+            end();
+        }
+    }
+
+    private static class DefaultOptionsHolder {
+        static final Set<SocketOption<?>> defaultOptions = defaultOptions();
+
+        private static Set<SocketOption<?>> defaultOptions() {
+            HashSet<SocketOption<?>> set = new HashSet<SocketOption<?>>(5);
+            set.add(StandardSocketOption.SO_SNDBUF);
+            set.add(StandardSocketOption.SO_RCVBUF);
+            set.add(StandardSocketOption.SO_KEEPALIVE);
+            set.add(StandardSocketOption.SO_REUSEADDR);
+            set.add(StandardSocketOption.TCP_NODELAY);
+            return Collections.unmodifiableSet(set);
+        }
+    }
+
+    @Override
+    public final Set<SocketOption<?>> supportedOptions() {
+        return DefaultOptionsHolder.defaultOptions;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public final SocketAddress getRemoteAddress() throws IOException {
+        if (!isOpen())
+            throw new ClosedChannelException();
+        return remoteAddress;
+    }
+
+    @Override
+    public final AsynchronousSocketChannel shutdownInput() throws IOException {
+        try {
+            begin();
+            if (remoteAddress == null)
+                throw new NotYetConnectedException();
+            synchronized (readLock) {
+                if (!readShutdown) {
+                    Net.shutdown(fd, Net.SHUT_RD);
+                    readShutdown = true;
+                }
+            }
+        } finally {
+            end();
+        }
+        return this;
+    }
+
+    @Override
+    public final AsynchronousSocketChannel shutdownOutput() throws IOException {
+        try {
+            begin();
+            if (remoteAddress == null)
+                throw new NotYetConnectedException();
+            synchronized (writeLock) {
+                if (!writeShutdown) {
+                    Net.shutdown(fd, Net.SHUT_WR);
+                    writeShutdown = true;
+                }
+            }
+        } finally {
+            end();
+        }
+        return this;
+    }
+
+    @Override
+    public final String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(this.getClass().getName());
+        sb.append('[');
+        synchronized (stateLock) {
+            if (!isOpen()) {
+                sb.append("closed");
+            } else {
+                switch (state) {
+                case ST_UNCONNECTED:
+                    sb.append("unconnected");
+                    break;
+                case ST_PENDING:
+                    sb.append("connection-pending");
+                    break;
+                case ST_CONNECTED:
+                    sb.append("connected");
+                    if (readShutdown)
+                        sb.append(" ishut");
+                    if (writeShutdown)
+                        sb.append(" oshut");
+                    break;
+                }
+                if (localAddress != null) {
+                    sb.append(" local=");
+                    sb.append(localAddress.toString());
+                }
+                if (remoteAddress != null) {
+                    sb.append(" remote=");
+                    sb.append(remoteAddress.toString());
+                }
+            }
+        }
+        sb.append(']');
+        return sb.toString();
+    }
+}
diff --git a/jdk/src/share/classes/sun/nio/ch/Cancellable.java b/jdk/src/share/classes/sun/nio/ch/Cancellable.java
new file mode 100644
index 0000000..ae08ed9
--- /dev/null
+++ b/jdk/src/share/classes/sun/nio/ch/Cancellable.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.ch;
+
+/**
+ * Implemented by asynchronous channels that require notification when an I/O
+ * operation is cancelled.
+ */
+
+interface Cancellable {
+    /**
+     * Invoked to notify channel that cancel has been invoked while holding
+     * the Future's lock.
+     */
+    void onCancel(PendingFuture<?,?> task);
+}
diff --git a/jdk/src/share/classes/sun/nio/ch/CompletedFuture.java b/jdk/src/share/classes/sun/nio/ch/CompletedFuture.java
new file mode 100644
index 0000000..221b9f8
--- /dev/null
+++ b/jdk/src/share/classes/sun/nio/ch/CompletedFuture.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.ch;
+
+import java.nio.channels.AsynchronousChannel;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.ExecutionException;
+import java.io.IOException;
+
+/**
+ * A Future representing the result of an I/O operation that has already
+ * completed.
+ */
+
+final class CompletedFuture<V,A>
+    extends AbstractFuture<V,A>
+{
+    private final V result;
+    private final Throwable exc;
+
+    private CompletedFuture(AsynchronousChannel channel,
+                            V result,
+                            Throwable exc,
+                            A attachment)
+    {
+        super(channel, attachment);
+        this.result = result;
+        this.exc = exc;
+    }
+
+    @SuppressWarnings("unchecked")
+    static <V,A> CompletedFuture<V,A> withResult(AsynchronousChannel channel,
+                                                 V result,
+                                                 A attachment)
+    {
+        return new CompletedFuture<V,A>(channel, result, null, attachment);
+    }
+
+    @SuppressWarnings("unchecked")
+    static <V,A> CompletedFuture<V,A> withFailure(AsynchronousChannel channel,
+                                                  Throwable exc,
+                                                  A attachment)
+    {
+        // exception must be IOException or SecurityException
+        if (!(exc instanceof IOException) && !(exc instanceof SecurityException))
+            exc = new IOException(exc);
+        return new CompletedFuture(channel, null, exc, attachment);
+    }
+
+    @Override
+    public V get() throws ExecutionException {
+        if (exc != null)
+            throw new ExecutionException(exc);
+        return result;
+    }
+
+    @Override
+    public V get(long timeout, TimeUnit unit) throws ExecutionException {
+        if (unit == null)
+            throw new NullPointerException();
+        if (exc != null)
+            throw new ExecutionException(exc);
+        return result;
+    }
+
+    @Override
+    public boolean isCancelled() {
+        return false;
+    }
+
+    @Override
+    public boolean isDone() {
+        return true;
+    }
+
+    @Override
+    public boolean cancel(boolean mayInterruptIfRunning) {
+        return false;
+    }
+
+    @Override
+    Throwable exception() {
+        return exc;
+    }
+
+    @Override
+    V value() {
+        return result;
+    }
+}
diff --git a/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java b/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java
index 54cbfba..e5ec5e0 100644
--- a/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java
+++ b/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2001-2009 Sun Microsystems, Inc.  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
@@ -111,8 +111,12 @@
     public DatagramChannelImpl(SelectorProvider sp, ProtocolFamily family) {
         super(sp);
         if ((family != StandardProtocolFamily.INET) &&
-            (family != StandardProtocolFamily.INET6)) {
-            throw new UnsupportedOperationException("Protocol family not supported");
+            (family != StandardProtocolFamily.INET6))
+        {
+            if (family == null)
+                throw new NullPointerException("'family' is null");
+            else
+                throw new UnsupportedOperationException("Protocol family not supported");
         }
         if (family == StandardProtocolFamily.INET6) {
             if (!Net.isIPv6Available()) {
@@ -149,28 +153,28 @@
     public SocketAddress getLocalAddress() throws IOException {
         synchronized (stateLock) {
             if (!isOpen())
-                return null;
+                throw new ClosedChannelException();
             return localAddress;
         }
     }
 
     @Override
-    public SocketAddress getConnectedAddress() throws IOException {
+    public SocketAddress getRemoteAddress() throws IOException {
         synchronized (stateLock) {
             if (!isOpen())
-                return null;
+                throw new ClosedChannelException();
             return remoteAddress;
         }
     }
 
     @Override
-    public DatagramChannel setOption(SocketOption name, Object value)
+    public <T> DatagramChannel setOption(SocketOption<T> name, T value)
         throws IOException
     {
         if (name == null)
             throw new NullPointerException();
-        if (!options().contains(name))
-            throw new IllegalArgumentException("Invalid option name");
+        if (!supportedOptions().contains(name))
+            throw new UnsupportedOperationException("'" + name + "' not supported");
 
         synchronized (stateLock) {
             ensureOpen();
@@ -224,8 +228,8 @@
     {
         if (name == null)
             throw new NullPointerException();
-        if (!options().contains(name))
-            throw new IllegalArgumentException("Invalid option name");
+        if (!supportedOptions().contains(name))
+            throw new UnsupportedOperationException("'" + name + "' not supported");
 
         synchronized (stateLock) {
             ensureOpen();
@@ -273,7 +277,7 @@
         }
     }
 
-    private static class LazyInitialization {
+    private static class DefaultOptionsHolder {
         static final Set<SocketOption<?>> defaultOptions = defaultOptions();
 
         private static Set<SocketOption<?>> defaultOptions() {
@@ -291,8 +295,8 @@
     }
 
     @Override
-    public final Set<SocketOption<?>> options() {
-        return LazyInitialization.defaultOptions;
+    public final Set<SocketOption<?>> supportedOptions() {
+        return DefaultOptionsHolder.defaultOptions;
     }
 
     private void ensureOpen() throws ClosedChannelException {
@@ -864,23 +868,26 @@
     }
 
     // package-private
-    void drop(MembershipKeyImpl key)
-        throws IOException
-    {
-        assert key.getChannel() == this;
+    void drop(MembershipKeyImpl key) {
+        assert key.channel() == this;
 
         synchronized (stateLock) {
             if (!key.isValid())
                 return;
 
-            if (family == StandardProtocolFamily.INET6) {
-                MembershipKeyImpl.Type6 key6 =
-                    (MembershipKeyImpl.Type6)key;
-                Net.drop6(fd, key6.group(), key6.index(), key6.source());
-            } else {
-                MembershipKeyImpl.Type4 key4 =
-                    (MembershipKeyImpl.Type4)key;
-                Net.drop4(fd, key4.group(), key4.interfaceAddress(), key4.source());
+            try {
+                if (family == StandardProtocolFamily.INET6) {
+                    MembershipKeyImpl.Type6 key6 =
+                        (MembershipKeyImpl.Type6)key;
+                    Net.drop6(fd, key6.groupAddress(), key6.index(), key6.source());
+                } else {
+                    MembershipKeyImpl.Type4 key4 = (MembershipKeyImpl.Type4)key;
+                    Net.drop4(fd, key4.groupAddress(), key4.interfaceAddress(),
+                        key4.source());
+                }
+            } catch (IOException ioe) {
+                // should not happen
+                throw new AssertionError(ioe);
             }
 
             key.invalidate();
@@ -895,8 +902,8 @@
     void block(MembershipKeyImpl key, InetAddress source)
         throws IOException
     {
-        assert key.getChannel() == this;
-        assert key.getSourceAddress() == null;
+        assert key.channel() == this;
+        assert key.sourceAddress() == null;
 
         synchronized (stateLock) {
             if (!key.isValid())
@@ -905,19 +912,19 @@
                 throw new IllegalArgumentException("Source address is a wildcard address");
             if (source.isMulticastAddress())
                 throw new IllegalArgumentException("Source address is multicast address");
-            if (source.getClass() != key.getGroup().getClass())
+            if (source.getClass() != key.group().getClass())
                 throw new IllegalArgumentException("Source address is different type to group");
 
             int n;
             if (family == StandardProtocolFamily.INET6) {
                  MembershipKeyImpl.Type6 key6 =
                     (MembershipKeyImpl.Type6)key;
-                n = Net.block6(fd, key6.group(), key6.index(),
+                n = Net.block6(fd, key6.groupAddress(), key6.index(),
                                Net.inet6AsByteArray(source));
             } else {
                 MembershipKeyImpl.Type4 key4 =
                     (MembershipKeyImpl.Type4)key;
-                n = Net.block4(fd, key4.group(), key4.interfaceAddress(),
+                n = Net.block4(fd, key4.groupAddress(), key4.interfaceAddress(),
                                Net.inet4AsInt(source));
             }
             if (n == IOStatus.UNAVAILABLE) {
@@ -930,26 +937,29 @@
     /**
      * Unblock given source.
      */
-    void unblock(MembershipKeyImpl key, InetAddress source)
-        throws IOException
-    {
-        assert key.getChannel() == this;
-        assert key.getSourceAddress() == null;
+    void unblock(MembershipKeyImpl key, InetAddress source) {
+        assert key.channel() == this;
+        assert key.sourceAddress() == null;
 
         synchronized (stateLock) {
             if (!key.isValid())
                 throw new IllegalStateException("key is no longer valid");
 
-            if (family == StandardProtocolFamily.INET6) {
-                MembershipKeyImpl.Type6 key6 =
-                    (MembershipKeyImpl.Type6)key;
-                Net.unblock6(fd, key6.group(), key6.index(),
-                             Net.inet6AsByteArray(source));
-            } else {
-                MembershipKeyImpl.Type4 key4 =
-                    (MembershipKeyImpl.Type4)key;
-                Net.unblock4(fd, key4.group(), key4.interfaceAddress(),
-                             Net.inet4AsInt(source));
+            try {
+                if (family == StandardProtocolFamily.INET6) {
+                    MembershipKeyImpl.Type6 key6 =
+                        (MembershipKeyImpl.Type6)key;
+                    Net.unblock6(fd, key6.groupAddress(), key6.index(),
+                                 Net.inet6AsByteArray(source));
+                } else {
+                    MembershipKeyImpl.Type4 key4 =
+                        (MembershipKeyImpl.Type4)key;
+                    Net.unblock4(fd, key4.groupAddress(), key4.interfaceAddress(),
+                                 Net.inet4AsInt(source));
+                }
+            } catch (IOException ioe) {
+                // should not happen
+                throw new AssertionError(ioe);
             }
         }
     }
diff --git a/jdk/src/share/classes/sun/nio/ch/ExtendedSocketOption.java b/jdk/src/share/classes/sun/nio/ch/ExtendedSocketOption.java
index 86e787e..d695fd2 100644
--- a/jdk/src/share/classes/sun/nio/ch/ExtendedSocketOption.java
+++ b/jdk/src/share/classes/sun/nio/ch/ExtendedSocketOption.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2008 Sun Microsystems, Inc.  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
diff --git a/jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java b/jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java
index 4d0543e..1e622e1 100644
--- a/jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java
+++ b/jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2009 Sun Microsystems, Inc.  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
@@ -26,27 +26,18 @@
 package sun.nio.ch;
 
 import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.RandomAccessFile;
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.MappedByteBuffer;
 import java.nio.BufferPoolMXBean;
 import java.nio.channels.*;
-import java.nio.channels.spi.*;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Iterator;
-import java.util.concurrent.ConcurrentHashMap;
-import java.lang.ref.WeakReference;
-import java.lang.ref.ReferenceQueue;
 import java.lang.reflect.Field;
 import java.security.AccessController;
-import java.security.PrivilegedAction;
 import javax.management.ObjectName;
 import javax.management.MalformedObjectNameException;
-
 import sun.misc.Cleaner;
 import sun.security.action.GetPropertyAction;
 
@@ -55,7 +46,7 @@
 {
 
     // Used to make native read and write calls
-    private static final NativeDispatcher nd;
+    private static final FileDispatcher nd;
 
     // Memory allocation size for mapping buffers
     private static final long allocationGranularity;
@@ -104,20 +95,19 @@
     // -- Standard channel operations --
 
     protected void implCloseChannel() throws IOException {
-
-        nd.preClose(fd);
-        threads.signal();
-
         // Invalidate and release any locks that we still hold
         if (fileLockTable != null) {
             fileLockTable.removeAll( new FileLockTable.Releaser() {
                 public void release(FileLock fl) throws IOException {
                     ((FileLockImpl)fl).invalidate();
-                    release0(fd, fl.position(), fl.size());
+                    nd.release(fd, fl.position(), fl.size());
                 }
             });
         }
 
+        nd.preClose(fd);
+        threads.signalAndWait();
+
         if (parent != null) {
 
             // Close the fd via the parent stream's close method.  The parent
@@ -138,12 +128,11 @@
             throw new NonReadableChannelException();
         synchronized (positionLock) {
             int n = 0;
-            int ti = -1;
+            int ti = threads.add();
             try {
                 begin();
                 if (!isOpen())
                     return 0;
-                ti = threads.add();
                 do {
                     n = IOUtil.read(fd, dst, -1, nd, positionLock);
                 } while ((n == IOStatus.INTERRUPTED) && isOpen());
@@ -162,12 +151,11 @@
             throw new NonReadableChannelException();
         synchronized (positionLock) {
             long n = 0;
-            int ti = -1;
+            int ti = threads.add();
             try {
                 begin();
                 if (!isOpen())
                     return 0;
-                ti = threads.add();
                 do {
                     n = IOUtil.read(fd, dsts, nd);
                 } while ((n == IOStatus.INTERRUPTED) && isOpen());
@@ -195,12 +183,11 @@
             throw new NonWritableChannelException();
         synchronized (positionLock) {
             int n = 0;
-            int ti = -1;
+            int ti = threads.add();
             try {
                 begin();
                 if (!isOpen())
                     return 0;
-                ti = threads.add();
                 do {
                     n = IOUtil.write(fd, src, -1, nd, positionLock);
                 } while ((n == IOStatus.INTERRUPTED) && isOpen());
@@ -219,12 +206,11 @@
             throw new NonWritableChannelException();
         synchronized (positionLock) {
             long n = 0;
-            int ti = -1;
+            int ti = threads.add();
             try {
                 begin();
                 if (!isOpen())
                     return 0;
-                ti = threads.add();
                 do {
                     n = IOUtil.write(fd, srcs, nd);
                 } while ((n == IOStatus.INTERRUPTED) && isOpen());
@@ -253,12 +239,11 @@
         ensureOpen();
         synchronized (positionLock) {
             long p = -1;
-            int ti = -1;
+            int ti = threads.add();
             try {
                 begin();
                 if (!isOpen())
                     return 0;
-                ti = threads.add();
                 do {
                     p = position0(fd, -1);
                 } while ((p == IOStatus.INTERRUPTED) && isOpen());
@@ -277,12 +262,11 @@
             throw new IllegalArgumentException();
         synchronized (positionLock) {
             long p = -1;
-            int ti = -1;
+            int ti = threads.add();
             try {
                 begin();
                 if (!isOpen())
                     return null;
-                ti = threads.add();
                 do {
                     p  = position0(fd, newPosition);
                 } while ((p == IOStatus.INTERRUPTED) && isOpen());
@@ -299,14 +283,13 @@
         ensureOpen();
         synchronized (positionLock) {
             long s = -1;
-            int ti = -1;
+            int ti = threads.add();
             try {
                 begin();
                 if (!isOpen())
                     return -1;
-                ti = threads.add();
                 do {
-                    s = size0(fd);
+                    s = nd.size(fd);
                 } while ((s == IOStatus.INTERRUPTED) && isOpen());
                 return IOStatus.normalize(s);
             } finally {
@@ -328,12 +311,11 @@
         synchronized (positionLock) {
             int rv = -1;
             long p = -1;
-            int ti = -1;
+            int ti = threads.add();
             try {
                 begin();
                 if (!isOpen())
                     return null;
-                ti = threads.add();
 
                 // get current position
                 do {
@@ -345,7 +327,7 @@
 
                 // truncate file
                 do {
-                    rv = truncate0(fd, size);
+                    rv = nd.truncate(fd, size);
                 } while ((rv == IOStatus.INTERRUPTED) && isOpen());
                 if (!isOpen())
                     return null;
@@ -368,14 +350,13 @@
     public void force(boolean metaData) throws IOException {
         ensureOpen();
         int rv = -1;
-        int ti = -1;
+        int ti = threads.add();
         try {
             begin();
             if (!isOpen())
                 return;
-            ti = threads.add();
             do {
-                rv = force0(fd, metaData);
+                rv = nd.force(fd, metaData);
             } while ((rv == IOStatus.INTERRUPTED) && isOpen());
         } finally {
             threads.remove(ti);
@@ -425,12 +406,11 @@
             return IOStatus.UNSUPPORTED;
 
         long n = -1;
-        int ti = -1;
+        int ti = threads.add();
         try {
             begin();
             if (!isOpen())
                 return -1;
-            ti = threads.add();
             do {
                 n = transferTo0(thisFDVal, position, icount, targetFDVal);
             } while ((n == IOStatus.INTERRUPTED) && isOpen());
@@ -632,12 +612,11 @@
             throw new NonReadableChannelException();
         ensureOpen();
         int n = 0;
-        int ti = -1;
+        int ti = threads.add();
         try {
             begin();
             if (!isOpen())
                 return -1;
-            ti = threads.add();
             do {
                 n = IOUtil.read(fd, dst, position, nd, positionLock);
             } while ((n == IOStatus.INTERRUPTED) && isOpen());
@@ -658,12 +637,11 @@
             throw new NonWritableChannelException();
         ensureOpen();
         int n = 0;
-        int ti = -1;
+        int ti = threads.add();
         try {
             begin();
             if (!isOpen())
                 return -1;
-            ti = threads.add();
             do {
                 n = IOUtil.write(fd, src, position, nd, positionLock);
             } while ((n == IOStatus.INTERRUPTED) && isOpen());
@@ -753,12 +731,11 @@
             throw new NonReadableChannelException();
 
         long addr = -1;
-        int ti = -1;
+        int ti = threads.add();
         try {
             begin();
             if (!isOpen())
                 return null;
-            ti = threads.add();
             if (size() < position + size) { // Extend file size
                 if (!writable) {
                     throw new IOException("Channel not open for writing " +
@@ -766,7 +743,7 @@
                 }
                 int rv;
                 do {
-                    rv = truncate0(fd, position + size);
+                    rv = nd.truncate(fd, position + size);
                 } while ((rv == IOStatus.INTERRUPTED) && isOpen());
             }
             if (size == 0) {
@@ -860,10 +837,7 @@
 
     // -- Locks --
 
-    public static final int NO_LOCK = -1;       // Failed to lock
-    public static final int LOCKED = 0;         // Obtained requested lock
-    public static final int RET_EX_LOCK = 1;    // Obtained exclusive lock
-    public static final int INTERRUPTED = 2;    // Request interrupted
+
 
     // keeps track of locks on this file
     private volatile FileLockTable fileLockTable;
@@ -893,12 +867,21 @@
         return isSharedFileLockTable;
     }
 
-    private FileLockTable fileLockTable() {
+    private FileLockTable fileLockTable() throws IOException {
         if (fileLockTable == null) {
             synchronized (this) {
                 if (fileLockTable == null) {
-                    fileLockTable = isSharedFileLockTable() ?
-                        new SharedFileLockTable(this) : new SimpleFileLockTable();
+                    if (isSharedFileLockTable()) {
+                        int ti = threads.add();
+                        try {
+                            ensureOpen();
+                            fileLockTable = FileLockTable.newSharedFileLockTable(this, fd);
+                        } finally {
+                            threads.remove(ti);
+                        }
+                    } else {
+                        fileLockTable = new SimpleFileLockTable();
+                    }
                 }
             }
         }
@@ -917,21 +900,20 @@
         FileLockTable flt = fileLockTable();
         flt.add(fli);
         boolean i = true;
-        int ti = -1;
+        int ti = threads.add();
         try {
             begin();
             if (!isOpen())
                 return null;
-            ti = threads.add();
-            int result = lock0(fd, true, position, size, shared);
-            if (result == RET_EX_LOCK) {
+            int result = nd.lock(fd, true, position, size, shared);
+            if (result == FileDispatcher.RET_EX_LOCK) {
                 assert shared;
                 FileLockImpl fli2 = new FileLockImpl(this, position, size,
                                                      false);
                 flt.replace(fli, fli2);
                 return fli2;
             }
-            if (result == INTERRUPTED || result == NO_LOCK) {
+            if (result == FileDispatcher.INTERRUPTED || result == FileDispatcher.NO_LOCK) {
                 flt.remove(fli);
                 i = false;
             }
@@ -960,77 +942,54 @@
         FileLockImpl fli = new FileLockImpl(this, position, size, shared);
         FileLockTable flt = fileLockTable();
         flt.add(fli);
-        int result = lock0(fd, false, position, size, shared);
-        if (result == NO_LOCK) {
-            flt.remove(fli);
-            return null;
+        int result;
+
+        int ti = threads.add();
+        try {
+            try {
+                ensureOpen();
+                result = nd.lock(fd, false, position, size, shared);
+            } catch (IOException e) {
+                flt.remove(fli);
+                throw e;
+            }
+            if (result == FileDispatcher.NO_LOCK) {
+                flt.remove(fli);
+                return null;
+            }
+            if (result == FileDispatcher.RET_EX_LOCK) {
+                assert shared;
+                FileLockImpl fli2 = new FileLockImpl(this, position, size,
+                                                     false);
+                flt.replace(fli, fli2);
+                return fli2;
+            }
+            return fli;
+        } finally {
+            threads.remove(ti);
         }
-        if (result == RET_EX_LOCK) {
-            assert shared;
-            FileLockImpl fli2 = new FileLockImpl(this, position, size,
-                                                 false);
-            flt.replace(fli, fli2);
-            return fli2;
-        }
-        return fli;
     }
 
     void release(FileLockImpl fli) throws IOException {
         ensureOpen();
-        release0(fd, fli.position(), fli.size());
+        int ti = threads.add();
+        try {
+            ensureOpen();
+            nd.release(fd, fli.position(), fli.size());
+        } finally {
+            threads.remove(ti);
+        }
         assert fileLockTable != null;
         fileLockTable.remove(fli);
     }
 
-
-    // -- File lock support  --
-
-    /**
-     * A table of FileLocks.
-     */
-    private interface FileLockTable {
-        /**
-         * Adds a file lock to the table.
-         *
-         * @throws OverlappingFileLockException if the file lock overlaps
-         *         with an existing file lock in the table
-         */
-        void add(FileLock fl) throws OverlappingFileLockException;
-
-        /**
-         * Remove an existing file lock from the table.
-         */
-        void remove(FileLock fl);
-
-        /**
-         * An implementation of this interface releases a given file lock.
-         * Used with removeAll.
-         */
-        interface Releaser {
-            void release(FileLock fl) throws IOException;
-        }
-
-        /**
-         * Removes all file locks from the table.
-         * <p>
-         * The Releaser#release method is invoked for each file lock before
-         * it is removed.
-         *
-         * @throws IOException if the release method throws IOException
-         */
-        void removeAll(Releaser r) throws IOException;
-
-        /**
-         * Replaces an existing file lock in the table.
-         */
-        void replace(FileLock fl1, FileLock fl2);
-    }
+    // -- File lock support --
 
     /**
      * A simple file lock table that maintains a list of FileLocks obtained by a
      * FileChannel. Use to get 1.4/5.0 behaviour.
      */
-    private static class SimpleFileLockTable implements FileLockTable {
+    private static class SimpleFileLockTable extends FileLockTable {
         // synchronize on list for access
         private List<FileLock> lockList = new ArrayList<FileLock>(2);
 
@@ -1080,207 +1039,8 @@
         }
     }
 
-    /**
-     * A weak reference to a FileLock.
-     * <p>
-     * SharedFileLockTable uses a list of file lock references to avoid keeping the
-     * FileLock (and FileChannel) alive.
-     */
-    private static class FileLockReference extends WeakReference<FileLock> {
-        private FileKey fileKey;
-
-        FileLockReference(FileLock referent,
-                          ReferenceQueue<FileLock> queue,
-                          FileKey key) {
-            super(referent, queue);
-            this.fileKey = key;
-        }
-
-        private FileKey fileKey() {
-            return fileKey;
-        }
-    }
-
-    /**
-     * A file lock table that is over a system-wide map of all file locks.
-     */
-    private static class SharedFileLockTable implements FileLockTable {
-        // The system-wide map is a ConcurrentHashMap that is keyed on the FileKey.
-        // The map value is a list of file locks represented by FileLockReferences.
-        // All access to the list must be synchronized on the list.
-        private static ConcurrentHashMap<FileKey, ArrayList<FileLockReference>> lockMap =
-            new ConcurrentHashMap<FileKey, ArrayList<FileLockReference>>();
-
-        // reference queue for cleared refs
-        private static ReferenceQueue<FileLock> queue = new ReferenceQueue<FileLock>();
-
-        // the enclosing file channel
-        private FileChannelImpl fci;
-
-        // File key for the file that this channel is connected to
-        private FileKey fileKey;
-
-        public SharedFileLockTable(FileChannelImpl fci) {
-            this.fci = fci;
-            this.fileKey = FileKey.create(fci.fd);
-        }
-
-        public void add(FileLock fl) throws OverlappingFileLockException {
-            ArrayList<FileLockReference> list = lockMap.get(fileKey);
-
-            for (;;) {
-
-                // The key isn't in the map so we try to create it atomically
-                if (list == null) {
-                    list = new ArrayList<FileLockReference>(2);
-                    ArrayList<FileLockReference> prev;
-                    synchronized (list) {
-                        prev = lockMap.putIfAbsent(fileKey, list);
-                        if (prev == null) {
-                            // we successfully created the key so we add the file lock
-                            list.add(new FileLockReference(fl, queue, fileKey));
-                            break;
-                        }
-                    }
-                    // someone else got there first
-                    list = prev;
-                }
-
-                // There is already a key. It is possible that some other thread
-                // is removing it so we re-fetch the value from the map. If it
-                // hasn't changed then we check the list for overlapping locks
-                // and add the new lock to the list.
-                synchronized (list) {
-                    ArrayList<FileLockReference> current = lockMap.get(fileKey);
-                    if (list == current) {
-                        checkList(list, fl.position(), fl.size());
-                        list.add(new FileLockReference(fl, queue, fileKey));
-                        break;
-                    }
-                    list = current;
-                }
-
-            }
-
-            // process any stale entries pending in the reference queue
-            removeStaleEntries();
-        }
-
-        private void removeKeyIfEmpty(FileKey fk, ArrayList<FileLockReference> list) {
-            assert Thread.holdsLock(list);
-            assert lockMap.get(fk) == list;
-            if (list.isEmpty()) {
-                lockMap.remove(fk);
-            }
-        }
-
-        public void remove(FileLock fl) {
-            assert fl != null;
-
-            // the lock must exist so the list of locks must be present
-            ArrayList<FileLockReference> list = lockMap.get(fileKey);
-            assert list != null;
-
-            synchronized (list) {
-                int index = 0;
-                while (index < list.size()) {
-                    FileLockReference ref = list.get(index);
-                    FileLock lock = ref.get();
-                    if (lock == fl) {
-                        assert (lock != null) && (lock.channel() == fci);
-                        ref.clear();
-                        list.remove(index);
-                        break;
-                    }
-                    index++;
-                }
-            }
-        }
-
-        public void removeAll(Releaser releaser) throws IOException {
-            ArrayList<FileLockReference> list = lockMap.get(fileKey);
-            if (list != null) {
-                synchronized (list) {
-                    int index = 0;
-                    while (index < list.size()) {
-                        FileLockReference ref = list.get(index);
-                        FileLock lock = ref.get();
-
-                        // remove locks obtained by this channel
-                        if (lock != null && lock.channel() == fci) {
-                            // invoke the releaser to invalidate/release the lock
-                            releaser.release(lock);
-
-                            // remove the lock from the list
-                            ref.clear();
-                            list.remove(index);
-                        } else {
-                            index++;
-                        }
-                    }
-
-                    // once the lock list is empty we remove it from the map
-                    removeKeyIfEmpty(fileKey, list);
-                }
-            }
-        }
-
-        public void replace(FileLock fromLock, FileLock toLock) {
-            // the lock must exist so there must be a list
-            ArrayList<FileLockReference> list = lockMap.get(fileKey);
-            assert list != null;
-
-            synchronized (list) {
-                for (int index=0; index<list.size(); index++) {
-                    FileLockReference ref = list.get(index);
-                    FileLock lock = ref.get();
-                    if (lock == fromLock) {
-                        ref.clear();
-                        list.set(index, new FileLockReference(toLock, queue, fileKey));
-                        break;
-                    }
-                }
-            }
-        }
-
-        // Check for overlapping file locks
-        private void checkList(List<FileLockReference> list, long position, long size)
-            throws OverlappingFileLockException
-        {
-            assert Thread.holdsLock(list);
-            for (FileLockReference ref: list) {
-                FileLock fl = ref.get();
-                if (fl != null && fl.overlaps(position, size))
-                    throw new OverlappingFileLockException();
-            }
-        }
-
-        // Process the reference queue
-        private void removeStaleEntries() {
-            FileLockReference ref;
-            while ((ref = (FileLockReference)queue.poll()) != null) {
-                FileKey fk = ref.fileKey();
-                ArrayList<FileLockReference> list = lockMap.get(fk);
-                if (list != null) {
-                    synchronized (list) {
-                        list.remove(ref);
-                        removeKeyIfEmpty(fk, list);
-                    }
-                }
-            }
-        }
-    }
-
     // -- Native methods --
 
-    // Grabs a file lock
-    native int lock0(FileDescriptor fd, boolean blocking, long pos, long size,
-                     boolean shared) throws IOException;
-
-    // Releases a file lock
-    native void release0(FileDescriptor fd, long pos, long size)
-        throws IOException;
-
     // Creates a new mapping
     private native long map0(int prot, long position, long length)
         throws IOException;
@@ -1288,12 +1048,6 @@
     // Removes an existing mapping
     private static native int unmap0(long address, long length);
 
-    // Forces output to device
-    private native int force0(FileDescriptor fd, boolean metaData);
-
-    // Truncates a file
-    private native int truncate0(FileDescriptor fd, long size);
-
     // Transfers from src to dst, or returns -2 if kernel can't do that
     private native long transferTo0(int src, long position, long count, int dst);
 
@@ -1302,16 +1056,13 @@
     // otherwise the position is set to offset
     private native long position0(FileDescriptor fd, long offset);
 
-    // Reports this file's size
-    private native long size0(FileDescriptor fd);
-
     // Caches fieldIDs
     private static native long initIDs();
 
     static {
         Util.load();
         allocationGranularity = initIDs();
-        nd = new FileDispatcher();
+        nd = new FileDispatcherImpl();
     }
 
 }
diff --git a/jdk/src/share/classes/sun/nio/ch/FileDispatcher.java b/jdk/src/share/classes/sun/nio/ch/FileDispatcher.java
new file mode 100644
index 0000000..9f8a0f7
--- /dev/null
+++ b/jdk/src/share/classes/sun/nio/ch/FileDispatcher.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.ch;
+
+import java.io.*;
+
+abstract class FileDispatcher extends NativeDispatcher {
+
+    public static final int NO_LOCK = -1;       // Failed to lock
+    public static final int LOCKED = 0;         // Obtained requested lock
+    public static final int RET_EX_LOCK = 1;    // Obtained exclusive lock
+    public static final int INTERRUPTED = 2;    // Request interrupted
+
+    abstract int force(FileDescriptor fd, boolean metaData) throws IOException;
+
+    abstract int truncate(FileDescriptor fd, long size) throws IOException;
+
+    abstract long size(FileDescriptor fd) throws IOException;
+
+    abstract int lock(FileDescriptor fd, boolean blocking, long pos, long size,
+                       boolean shared) throws IOException;
+
+    abstract void release(FileDescriptor fd, long pos, long size)
+        throws IOException;
+}
diff --git a/jdk/src/share/classes/sun/nio/ch/FileLockImpl.java b/jdk/src/share/classes/sun/nio/ch/FileLockImpl.java
index 721faf1..9efd153 100644
--- a/jdk/src/share/classes/sun/nio/ch/FileLockImpl.java
+++ b/jdk/src/share/classes/sun/nio/ch/FileLockImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2003 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2001-2009 Sun Microsystems, Inc.  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
@@ -26,9 +26,7 @@
 package sun.nio.ch;
 
 import java.io.IOException;
-import java.nio.channels.ClosedChannelException;
-import java.nio.channels.FileLock;
-import java.nio.channels.FileChannel;
+import java.nio.channels.*;
 
 public class FileLockImpl
     extends FileLock
@@ -41,6 +39,12 @@
         this.valid = true;
     }
 
+    FileLockImpl(AsynchronousFileChannel channel, long position, long size, boolean shared)
+    {
+        super(channel, position, size, shared);
+        this.valid = true;
+    }
+
     public synchronized boolean isValid() {
         return valid;
     }
@@ -50,10 +54,15 @@
     }
 
     public synchronized void release() throws IOException {
-        if (!channel().isOpen())
+        Channel ch = acquiredBy();
+        if (!ch.isOpen())
             throw new ClosedChannelException();
         if (valid) {
-            ((FileChannelImpl)channel()).release(this);
+            if (ch instanceof FileChannelImpl)
+                ((FileChannelImpl)ch).release(this);
+            else if (ch instanceof AsynchronousFileChannelImpl)
+                ((AsynchronousFileChannelImpl)ch).release(this);
+            else throw new AssertionError();
             valid = false;
         }
     }
diff --git a/jdk/src/share/classes/sun/nio/ch/FileLockTable.java b/jdk/src/share/classes/sun/nio/ch/FileLockTable.java
new file mode 100644
index 0000000..137ab88
--- /dev/null
+++ b/jdk/src/share/classes/sun/nio/ch/FileLockTable.java
@@ -0,0 +1,282 @@
+/*
+ * Copyright 2005-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.ch;
+
+import java.nio.channels.*;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.lang.ref.*;
+import java.io.FileDescriptor;
+import java.io.IOException;
+
+abstract class FileLockTable {
+    protected FileLockTable() {
+    }
+
+    /**
+     * Creates and returns a file lock table for a channel that is connected to
+     * the a system-wide map of all file locks for the Java virtual machine.
+     */
+    public static FileLockTable newSharedFileLockTable(Channel channel,
+                                                       FileDescriptor fd)
+        throws IOException
+    {
+        return new SharedFileLockTable(channel, fd);
+    }
+
+    /**
+     * Adds a file lock to the table.
+     *
+     * @throws OverlappingFileLockException if the file lock overlaps
+     *         with an existing file lock in the table
+     */
+    public abstract void add(FileLock fl) throws OverlappingFileLockException;
+
+    /**
+     * Remove an existing file lock from the table.
+     */
+    public abstract void remove(FileLock fl);
+
+    /**
+     * An implementation of this interface releases a given file lock.
+     * Used with removeAll.
+     */
+    public abstract interface Releaser {
+        void release(FileLock fl) throws IOException;
+    }
+
+    /**
+     * Removes all file locks from the table.
+     * <p>
+     * The Releaser#release method is invoked for each file lock before
+     * it is removed.
+     *
+     * @throws IOException if the release method throws IOException
+     */
+    public abstract void removeAll(Releaser r) throws IOException;
+
+    /**
+     * Replaces an existing file lock in the table.
+     */
+    public abstract void replace(FileLock fl1, FileLock fl2);
+}
+
+
+/**
+ * A file lock table that is over a system-wide map of all file locks.
+ */
+class SharedFileLockTable extends FileLockTable {
+
+    /**
+     * A weak reference to a FileLock.
+     * <p>
+     * SharedFileLockTable uses a list of file lock references to avoid keeping the
+     * FileLock (and FileChannel) alive.
+     */
+    private static class FileLockReference extends WeakReference<FileLock> {
+        private FileKey fileKey;
+
+        FileLockReference(FileLock referent,
+                          ReferenceQueue<FileLock> queue,
+                          FileKey key) {
+            super(referent, queue);
+            this.fileKey = key;
+        }
+
+        FileKey fileKey() {
+            return fileKey;
+        }
+    }
+
+    // The system-wide map is a ConcurrentHashMap that is keyed on the FileKey.
+    // The map value is a list of file locks represented by FileLockReferences.
+    // All access to the list must be synchronized on the list.
+    private static ConcurrentHashMap<FileKey, List<FileLockReference>> lockMap =
+        new ConcurrentHashMap<FileKey, List<FileLockReference>>();
+
+    // reference queue for cleared refs
+    private static ReferenceQueue<FileLock> queue = new ReferenceQueue<FileLock>();
+
+    // The connection to which this table is connected
+    private final Channel channel;
+
+    // File key for the file that this channel is connected to
+    private final FileKey fileKey;
+
+    SharedFileLockTable(Channel channel, FileDescriptor fd) throws IOException {
+        this.channel = channel;
+        this.fileKey = FileKey.create(fd);
+    }
+
+    @Override
+    public void add(FileLock fl) throws OverlappingFileLockException {
+        List<FileLockReference> list = lockMap.get(fileKey);
+
+        for (;;) {
+
+            // The key isn't in the map so we try to create it atomically
+            if (list == null) {
+                list = new ArrayList<FileLockReference>(2);
+                List<FileLockReference> prev;
+                synchronized (list) {
+                    prev = lockMap.putIfAbsent(fileKey, list);
+                    if (prev == null) {
+                        // we successfully created the key so we add the file lock
+                        list.add(new FileLockReference(fl, queue, fileKey));
+                        break;
+                    }
+                }
+                // someone else got there first
+                list = prev;
+            }
+
+            // There is already a key. It is possible that some other thread
+            // is removing it so we re-fetch the value from the map. If it
+            // hasn't changed then we check the list for overlapping locks
+            // and add the new lock to the list.
+            synchronized (list) {
+                List<FileLockReference> current = lockMap.get(fileKey);
+                if (list == current) {
+                    checkList(list, fl.position(), fl.size());
+                    list.add(new FileLockReference(fl, queue, fileKey));
+                    break;
+                }
+                list = current;
+            }
+
+        }
+
+        // process any stale entries pending in the reference queue
+        removeStaleEntries();
+    }
+
+    private void removeKeyIfEmpty(FileKey fk, List<FileLockReference> list) {
+        assert Thread.holdsLock(list);
+        assert lockMap.get(fk) == list;
+        if (list.isEmpty()) {
+            lockMap.remove(fk);
+        }
+    }
+
+    @Override
+    public void remove(FileLock fl) {
+        assert fl != null;
+
+        // the lock must exist so the list of locks must be present
+        List<FileLockReference> list = lockMap.get(fileKey);
+        if (list == null) return;
+
+        synchronized (list) {
+            int index = 0;
+            while (index < list.size()) {
+                FileLockReference ref = list.get(index);
+                FileLock lock = ref.get();
+                if (lock == fl) {
+                    assert (lock != null) && (lock.channel() == channel);
+                    ref.clear();
+                    list.remove(index);
+                    break;
+                }
+                index++;
+            }
+        }
+    }
+
+    @Override
+    public void removeAll(Releaser releaser) throws IOException {
+        List<FileLockReference> list = lockMap.get(fileKey);
+        if (list != null) {
+            synchronized (list) {
+                int index = 0;
+                while (index < list.size()) {
+                    FileLockReference ref = list.get(index);
+                    FileLock lock = ref.get();
+
+                    // remove locks obtained by this channel
+                    if (lock != null && lock.channel() == channel) {
+                        // invoke the releaser to invalidate/release the lock
+                        releaser.release(lock);
+
+                        // remove the lock from the list
+                        ref.clear();
+                        list.remove(index);
+                    } else {
+                        index++;
+                    }
+                }
+
+                // once the lock list is empty we remove it from the map
+                removeKeyIfEmpty(fileKey, list);
+            }
+        }
+    }
+
+    @Override
+    public void replace(FileLock fromLock, FileLock toLock) {
+        // the lock must exist so there must be a list
+        List<FileLockReference> list = lockMap.get(fileKey);
+        assert list != null;
+
+        synchronized (list) {
+            for (int index=0; index<list.size(); index++) {
+                FileLockReference ref = list.get(index);
+                FileLock lock = ref.get();
+                if (lock == fromLock) {
+                    ref.clear();
+                    list.set(index, new FileLockReference(toLock, queue, fileKey));
+                    break;
+                }
+            }
+        }
+    }
+
+    // Check for overlapping file locks
+    private void checkList(List<FileLockReference> list, long position, long size)
+        throws OverlappingFileLockException
+    {
+        assert Thread.holdsLock(list);
+        for (FileLockReference ref: list) {
+            FileLock fl = ref.get();
+            if (fl != null && fl.overlaps(position, size))
+                throw new OverlappingFileLockException();
+        }
+    }
+
+    // Process the reference queue
+    private void removeStaleEntries() {
+        FileLockReference ref;
+        while ((ref = (FileLockReference)queue.poll()) != null) {
+            FileKey fk = ref.fileKey();
+            List<FileLockReference> list = lockMap.get(fk);
+            if (list != null) {
+                synchronized (list) {
+                    list.remove(ref);
+                    removeKeyIfEmpty(fk, list);
+                }
+            }
+        }
+    }
+}
diff --git a/jdk/src/share/classes/sun/nio/ch/Groupable.java b/jdk/src/share/classes/sun/nio/ch/Groupable.java
new file mode 100644
index 0000000..b176015
--- /dev/null
+++ b/jdk/src/share/classes/sun/nio/ch/Groupable.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.ch;
+
+/**
+ * Implemented by asynchronous channels that can be associated with an
+ * asynchronous channel group.
+ */
+
+interface Groupable {
+    AsynchronousChannelGroupImpl group();
+}
diff --git a/jdk/src/share/classes/sun/nio/ch/IOUtil.java b/jdk/src/share/classes/sun/nio/ch/IOUtil.java
index f57b724..8d5bb13 100644
--- a/jdk/src/share/classes/sun/nio/ch/IOUtil.java
+++ b/jdk/src/share/classes/sun/nio/ch/IOUtil.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2002 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2009 Sun Microsystems, Inc.  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
@@ -27,10 +27,7 @@
 
 import java.io.FileDescriptor;
 import java.io.IOException;
-import java.net.*;
 import java.nio.ByteBuffer;
-import java.nio.channels.*;
-import java.nio.channels.spi.*;
 
 
 /**
@@ -47,7 +44,6 @@
      */
     private static int remaining(ByteBuffer[] bufs) {
         int numBufs = bufs.length;
-        boolean remaining = false;
         for (int i=0; i<numBufs; i++) {
             if (bufs[i].hasRemaining()) {
                 return i;
@@ -138,74 +134,82 @@
             bufs = skipBufs(bufs, nextWithRemaining);
 
         int numBufs = bufs.length;
-        int bytesReadyToWrite = 0;
 
         // Create shadow to ensure DirectByteBuffers are used
         ByteBuffer[] shadow = new ByteBuffer[numBufs];
-        for (int i=0; i<numBufs; i++) {
-            if (!(bufs[i] instanceof DirectBuffer)) {
-                int pos = bufs[i].position();
-                int lim = bufs[i].limit();
-                assert (pos <= lim);
-                int rem = (pos <= lim ? lim - pos : 0);
-
-                ByteBuffer bb = ByteBuffer.allocateDirect(rem);
-                shadow[i] = bb;
-                // Leave slow buffer position untouched; it will be updated
-                // after we see how many bytes were really written out
-                bb.put(bufs[i]);
-                bufs[i].position(pos);
-                bb.flip();
-            } else {
-                shadow[i] = bufs[i];
-            }
-        }
-
-        IOVecWrapper vec = null;
-        long bytesWritten = 0;
         try {
-            // Create a native iovec array
-            vec= new IOVecWrapper(numBufs);
-
-            // Fill in the iovec array with appropriate data
             for (int i=0; i<numBufs; i++) {
-                ByteBuffer nextBuffer = shadow[i];
-                // put in the buffer addresses
-                long pos = nextBuffer.position();
-                long len = nextBuffer.limit() - pos;
-                bytesReadyToWrite += len;
-                vec.putBase(i, ((DirectBuffer)nextBuffer).address() + pos);
-                vec.putLen(i, len);
-            }
+                if (!(bufs[i] instanceof DirectBuffer)) {
+                    int pos = bufs[i].position();
+                    int lim = bufs[i].limit();
+                    assert (pos <= lim);
+                    int rem = (pos <= lim ? lim - pos : 0);
 
-            // Invoke native call to fill the buffers
-            bytesWritten = nd.writev(fd, vec.address, numBufs);
-        } finally {
-            vec.free();
-        }
-        long returnVal = bytesWritten;
-
-        // Notify the buffers how many bytes were taken
-        for (int i=0; i<numBufs; i++) {
-            ByteBuffer nextBuffer = bufs[i];
-            int pos = nextBuffer.position();
-            int lim = nextBuffer.limit();
-            assert (pos <= lim);
-            int len = (pos <= lim ? lim - pos : lim);
-            if (bytesWritten >= len) {
-                bytesWritten -= len;
-                int newPosition = pos + len;
-                nextBuffer.position(newPosition);
-            } else { // Buffers not completely filled
-                if (bytesWritten > 0) {
-                    assert(pos + bytesWritten < (long)Integer.MAX_VALUE);
-                    int newPosition = (int)(pos + bytesWritten);
-                    nextBuffer.position(newPosition);
+                    ByteBuffer bb = Util.getTemporaryDirectBuffer(rem);
+                    shadow[i] = bb;
+                    // Leave slow buffer position untouched; it will be updated
+                    // after we see how many bytes were really written out
+                    bb.put(bufs[i]);
+                    bufs[i].position(pos);
+                    bb.flip();
+                } else {
+                    shadow[i] = bufs[i];
                 }
-                break;
+            }
+
+            IOVecWrapper vec = null;
+            long bytesWritten = 0;
+            try {
+                // Create a native iovec array
+                vec= new IOVecWrapper(numBufs);
+
+                // Fill in the iovec array with appropriate data
+                for (int i=0; i<numBufs; i++) {
+                    ByteBuffer nextBuffer = shadow[i];
+                    // put in the buffer addresses
+                    long pos = nextBuffer.position();
+                    long len = nextBuffer.limit() - pos;
+                    vec.putBase(i, ((DirectBuffer)nextBuffer).address() + pos);
+                    vec.putLen(i, len);
+                }
+
+                // Invoke native call to fill the buffers
+                bytesWritten = nd.writev(fd, vec.address, numBufs);
+            } finally {
+                vec.free();
+            }
+            long returnVal = bytesWritten;
+
+            // Notify the buffers how many bytes were taken
+            for (int i=0; i<numBufs; i++) {
+                ByteBuffer nextBuffer = bufs[i];
+                int pos = nextBuffer.position();
+                int lim = nextBuffer.limit();
+                assert (pos <= lim);
+                int len = (pos <= lim ? lim - pos : lim);
+                if (bytesWritten >= len) {
+                    bytesWritten -= len;
+                    int newPosition = pos + len;
+                    nextBuffer.position(newPosition);
+                } else { // Buffers not completely filled
+                    if (bytesWritten > 0) {
+                        assert(pos + bytesWritten < (long)Integer.MAX_VALUE);
+                        int newPosition = (int)(pos + bytesWritten);
+                        nextBuffer.position(newPosition);
+                    }
+                    break;
+                }
+            }
+            return returnVal;
+        } finally {
+            // return any substituted buffers to cache
+            for (int i=0; i<numBufs; i++) {
+                ByteBuffer bb = shadow[i];
+                if (bb != null && bb != bufs[i]) {
+                    Util.releaseTemporaryDirectBuffer(bb);
+                }
             }
         }
-        return returnVal;
     }
 
     static int read(FileDescriptor fd, ByteBuffer dst, long position,
@@ -270,68 +274,83 @@
 
         // Read into the shadow to ensure DirectByteBuffers are used
         ByteBuffer[] shadow = new ByteBuffer[numBufs];
-        for (int i=0; i<numBufs; i++) {
-            if (bufs[i].isReadOnly())
-                throw new IllegalArgumentException("Read-only buffer");
-            if (!(bufs[i] instanceof DirectBuffer)) {
-                shadow[i] = ByteBuffer.allocateDirect(bufs[i].remaining());
-            } else {
-                shadow[i] = bufs[i];
-            }
-        }
-
-        IOVecWrapper vec = null;
-        long bytesRead = 0;
+        boolean usingSlowBuffers = false;
         try {
-            // Create a native iovec array
-            vec = new IOVecWrapper(numBufs);
+            for (int i=0; i<numBufs; i++) {
+                if (bufs[i].isReadOnly())
+                    throw new IllegalArgumentException("Read-only buffer");
+                if (!(bufs[i] instanceof DirectBuffer)) {
+                    shadow[i] = Util.getTemporaryDirectBuffer(bufs[i].remaining());
+                    usingSlowBuffers = true;
+                } else {
+                    shadow[i] = bufs[i];
+                }
+            }
 
-            // Fill in the iovec array with appropriate data
+            IOVecWrapper vec = null;
+            long bytesRead = 0;
+            try {
+                // Create a native iovec array
+                vec = new IOVecWrapper(numBufs);
+
+                // Fill in the iovec array with appropriate data
+                for (int i=0; i<numBufs; i++) {
+                    ByteBuffer nextBuffer = shadow[i];
+                    // put in the buffer addresses
+                    long pos = nextBuffer.position();
+                    long len = nextBuffer.remaining();
+                    vec.putBase(i, ((DirectBuffer)nextBuffer).address() + pos);
+                    vec.putLen(i, len);
+                }
+
+                // Invoke native call to fill the buffers
+                bytesRead = nd.readv(fd, vec.address, numBufs);
+            } finally {
+                vec.free();
+            }
+            long returnVal = bytesRead;
+
+            // Notify the buffers how many bytes were read
             for (int i=0; i<numBufs; i++) {
                 ByteBuffer nextBuffer = shadow[i];
-                // put in the buffer addresses
-                long pos = nextBuffer.position();
-                long len = nextBuffer.remaining();
-                vec.putBase(i, ((DirectBuffer)nextBuffer).address() + pos);
-                vec.putLen(i, len);
-            }
-
-            // Invoke native call to fill the buffers
-            bytesRead = nd.readv(fd, vec.address, numBufs);
-        } finally {
-            vec.free();
-        }
-        long returnVal = bytesRead;
-
-        // Notify the buffers how many bytes were read
-        for (int i=0; i<numBufs; i++) {
-            ByteBuffer nextBuffer = shadow[i];
-            // Note: should this have been cached from above?
-            int pos = nextBuffer.position();
-            int len = nextBuffer.remaining();
-            if (bytesRead >= len) {
-                bytesRead -= len;
-                int newPosition = pos + len;
-                nextBuffer.position(newPosition);
-            } else { // Buffers not completely filled
-                if (bytesRead > 0) {
-                    assert(pos + bytesRead < (long)Integer.MAX_VALUE);
-                    int newPosition = (int)(pos + bytesRead);
+                // Note: should this have been cached from above?
+                int pos = nextBuffer.position();
+                int len = nextBuffer.remaining();
+                if (bytesRead >= len) {
+                    bytesRead -= len;
+                    int newPosition = pos + len;
                     nextBuffer.position(newPosition);
+                } else { // Buffers not completely filled
+                    if (bytesRead > 0) {
+                        assert(pos + bytesRead < (long)Integer.MAX_VALUE);
+                        int newPosition = (int)(pos + bytesRead);
+                        nextBuffer.position(newPosition);
+                    }
+                    break;
                 }
-                break;
+            }
+
+            // Put results from shadow into the slow buffers
+            if (usingSlowBuffers) {
+                for (int i=0; i<numBufs; i++) {
+                    if (!(bufs[i] instanceof DirectBuffer)) {
+                        shadow[i].flip();
+                        bufs[i].put(shadow[i]);
+                    }
+                }
+            }
+            return returnVal;
+        } finally {
+            // return any substituted buffers to cache
+            if (usingSlowBuffers) {
+                for (int i=0; i<numBufs; i++) {
+                    ByteBuffer bb = shadow[i];
+                    if (bb != null && bb != bufs[i]) {
+                        Util.releaseTemporaryDirectBuffer(bb);
+                    }
+                }
             }
         }
-
-        // Put results from shadow into the slow buffers
-        for (int i=0; i<numBufs; i++) {
-            if (!(bufs[i] instanceof DirectBuffer)) {
-                shadow[i].flip();
-                bufs[i].put(shadow[i]);
-            }
-        }
-
-        return returnVal;
     }
 
     static FileDescriptor newFD(int i) {
diff --git a/jdk/src/share/classes/sun/nio/ch/Invoker.java b/jdk/src/share/classes/sun/nio/ch/Invoker.java
new file mode 100644
index 0000000..182f798
--- /dev/null
+++ b/jdk/src/share/classes/sun/nio/ch/Invoker.java
@@ -0,0 +1,261 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.ch;
+
+import java.nio.channels.*;
+import java.util.concurrent.*;
+import java.security.AccessController;
+import sun.security.action.GetIntegerAction;
+
+/**
+ * Defines static methods to invoke a completion handler or arbitrary task.
+ */
+
+class Invoker {
+    private Invoker() { }
+
+    // maximum number of completion handlers that may be invoked on the current
+    // thread before it re-directs invocations to the thread pool. This helps
+    // avoid stack overflow and lessens the risk of starvation.
+    private static final int maxHandlerInvokeCount = AccessController.doPrivileged(
+        new GetIntegerAction("sun.nio.ch.maxCompletionHandlersOnStack", 16));
+
+    // Per-thread object with reference to channel group and a counter for
+    // the number of completion handlers invoked. This should be reset to 0
+    // when all completion handlers have completed.
+    static class GroupAndInvokeCount {
+        private final AsynchronousChannelGroupImpl group;
+        private int handlerInvokeCount;
+        GroupAndInvokeCount(AsynchronousChannelGroupImpl group) {
+            this.group = group;
+        }
+        AsynchronousChannelGroupImpl group() {
+            return group;
+        }
+        int invokeCount() {
+            return handlerInvokeCount;
+        }
+        void setInvokeCount(int value) {
+            handlerInvokeCount = value;
+        }
+        void resetInvokeCount() {
+            handlerInvokeCount = 0;
+        }
+        void incrementInvokeCount() {
+            handlerInvokeCount++;
+        }
+    }
+    private static final ThreadLocal<GroupAndInvokeCount> myGroupAndInvokeCount =
+        new ThreadLocal<GroupAndInvokeCount>() {
+            @Override protected GroupAndInvokeCount initialValue() {
+                return null;
+            }
+        };
+
+    /**
+     * Binds this thread to the given group
+     */
+    static void bindToGroup(AsynchronousChannelGroupImpl group) {
+        myGroupAndInvokeCount.set(new GroupAndInvokeCount(group));
+    }
+
+    /**
+     * Returns the GroupAndInvokeCount object for this thread.
+     */
+    static GroupAndInvokeCount getGroupAndInvokeCount() {
+        return myGroupAndInvokeCount.get();
+    }
+
+    /**
+     * Returns true if the current thread is in a channel group's thread pool
+     */
+    static boolean isBoundToAnyGroup() {
+        return myGroupAndInvokeCount.get() != null;
+    }
+
+    /**
+     * Returns true if the current thread is in the given channel's thread
+     * pool and we haven't exceeded the maximum number of handler frames on
+     * the stack.
+     */
+    static boolean mayInvokeDirect(GroupAndInvokeCount myGroupAndInvokeCount,
+                                   AsynchronousChannelGroupImpl group)
+    {
+        if ((myGroupAndInvokeCount != null) &&
+            (myGroupAndInvokeCount.group() == group) &&
+            (myGroupAndInvokeCount.invokeCount() < maxHandlerInvokeCount))
+        {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Invoke handler without checking the thread identity or number of handlers
+     * on the thread stack.
+     */
+    @SuppressWarnings("unchecked")
+    static <V,A> void invokeUnchecked(CompletionHandler<V,? super A> handler,
+                                      AbstractFuture<V,A> result)
+    {
+        if (handler != null && !result.isCancelled()) {
+            Throwable exc = result.exception();
+            if (exc == null) {
+                handler.completed(result.value(), result.attachment());
+            } else {
+                handler.failed(exc, result.attachment());
+            }
+
+            // clear interrupt
+            Thread.interrupted();
+        }
+    }
+
+
+    /**
+     * Invoke handler after incrementing the invoke count.
+     */
+    static <V,A> void invokeDirect(GroupAndInvokeCount myGroupAndInvokeCount,
+                                   CompletionHandler<V,? super A> handler,
+                                   AbstractFuture<V,A> result)
+    {
+        myGroupAndInvokeCount.incrementInvokeCount();
+        invokeUnchecked(handler, result);
+    }
+
+    /**
+     * Invokes the handler. If the current thread is in the channel group's
+     * thread pool then the handler is invoked directly, otherwise it is
+     * invoked indirectly.
+     */
+    static <V,A> void invoke(CompletionHandler<V,? super A> handler,
+                             AbstractFuture<V,A> result)
+    {
+        if (handler != null) {
+            boolean invokeDirect = false;
+            boolean identityOkay = false;
+            GroupAndInvokeCount thisGroupAndInvokeCount = myGroupAndInvokeCount.get();
+            if (thisGroupAndInvokeCount != null) {
+                AsynchronousChannel channel = result.channel();
+                if ((thisGroupAndInvokeCount.group() == ((Groupable)channel).group()))
+                    identityOkay = true;
+                if (identityOkay &&
+                    (thisGroupAndInvokeCount.invokeCount() < maxHandlerInvokeCount))
+                {
+                    // group match
+                    invokeDirect = true;
+                }
+            }
+            if (invokeDirect) {
+                thisGroupAndInvokeCount.incrementInvokeCount();
+                invokeUnchecked(handler, result);
+            } else {
+                try {
+                    invokeIndirectly(handler, result);
+                } catch (RejectedExecutionException ree) {
+                    // channel group shutdown; fallback to invoking directly
+                    // if the current thread has the right identity.
+                    if (identityOkay) {
+                        invokeUnchecked(handler, result);
+                    } else {
+                        throw new ShutdownChannelGroupException();
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Invokes the handler "indirectly" in the channel group's thread pool.
+     */
+    static <V,A> void invokeIndirectly(final CompletionHandler<V,? super A> handler,
+                                       final AbstractFuture<V,A> result)
+    {
+        if (handler != null) {
+            AsynchronousChannel channel = result.channel();
+            try {
+                ((Groupable)channel).group().executeOnPooledThread(new Runnable() {
+                    public void run() {
+                        GroupAndInvokeCount thisGroupAndInvokeCount =
+                            myGroupAndInvokeCount.get();
+                        if (thisGroupAndInvokeCount != null)
+                            thisGroupAndInvokeCount.setInvokeCount(1);
+                        invokeUnchecked(handler, result);
+                    }
+                });
+            } catch (RejectedExecutionException ree) {
+                throw new ShutdownChannelGroupException();
+            }
+        }
+    }
+
+    /**
+     * Invokes the handler "indirectly" in the given Executor
+     */
+    static <V,A> void invokeIndirectly(final CompletionHandler<V,? super A> handler,
+                                       final AbstractFuture<V,A> result,
+                                       Executor executor)
+    {
+        if (handler != null) {
+            try {
+                executor.execute(new Runnable() {
+                    public void run() {
+                        invokeUnchecked(handler, result);
+                    }
+                });
+            } catch (RejectedExecutionException ree) {
+                throw new ShutdownChannelGroupException();
+            }
+        }
+    }
+
+    /**
+     * Invokes the given task on the thread pool associated with the given
+     * channel. If the current thread is in the thread pool then the task is
+     * invoked directly.
+     */
+    static void invokeOnThreadInThreadPool(Groupable channel,
+                                           Runnable task)
+    {
+        boolean invokeDirect;
+        GroupAndInvokeCount thisGroupAndInvokeCount = myGroupAndInvokeCount.get();
+        AsynchronousChannelGroupImpl targetGroup = channel.group();
+        if (thisGroupAndInvokeCount == null) {
+            invokeDirect = false;
+        } else {
+            invokeDirect = (thisGroupAndInvokeCount.group == targetGroup);
+        }
+        try {
+            if (invokeDirect) {
+                task.run();
+            } else {
+                targetGroup.executeOnPooledThread(task);
+            }
+        } catch (RejectedExecutionException ree) {
+            throw new ShutdownChannelGroupException();
+        }
+    }
+}
diff --git a/jdk/src/share/classes/sun/nio/ch/MembershipKeyImpl.java b/jdk/src/share/classes/sun/nio/ch/MembershipKeyImpl.java
index 687f79c..0089ffd 100644
--- a/jdk/src/share/classes/sun/nio/ch/MembershipKeyImpl.java
+++ b/jdk/src/share/classes/sun/nio/ch/MembershipKeyImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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
@@ -85,7 +85,7 @@
             this.sourceAddress = sourceAddress;
         }
 
-        int group() {
+        int groupAddress() {
             return groupAddress;
         }
 
@@ -120,7 +120,7 @@
             this.sourceAddress = sourceAddress;
         }
 
-        byte[] group() {
+        byte[] groupAddress() {
             return groupAddress;
         }
 
@@ -142,28 +142,28 @@
         valid = false;
     }
 
-    public void drop() throws IOException {
+    public void drop() {
         // delegate to channel
         ((DatagramChannelImpl)ch).drop(this);
     }
 
     @Override
-    public MulticastChannel getChannel() {
+    public MulticastChannel channel() {
         return ch;
     }
 
     @Override
-    public InetAddress getGroup() {
+    public InetAddress group() {
         return group;
     }
 
     @Override
-    public NetworkInterface getNetworkInterface() {
+    public NetworkInterface networkInterface() {
         return interf;
     }
 
     @Override
-    public InetAddress getSourceAddress() {
+    public InetAddress sourceAddress() {
         return source;
     }
 
@@ -191,9 +191,7 @@
     }
 
     @Override
-    public MembershipKey unblock(InetAddress toUnblock)
-        throws IOException
-    {
+    public MembershipKey unblock(InetAddress toUnblock) {
         synchronized (stateLock) {
             if ((blockedSet == null) || !blockedSet.contains(toUnblock))
                 throw new IllegalStateException("not blocked");
diff --git a/jdk/src/share/classes/sun/nio/ch/MembershipRegistry.java b/jdk/src/share/classes/sun/nio/ch/MembershipRegistry.java
index 5a2a8ef..fc90be3 100644
--- a/jdk/src/share/classes/sun/nio/ch/MembershipRegistry.java
+++ b/jdk/src/share/classes/sun/nio/ch/MembershipRegistry.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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
@@ -55,20 +55,20 @@
             List<MembershipKeyImpl> keys = groups.get(group);
             if (keys != null) {
                 for (MembershipKeyImpl key: keys) {
-                    if (key.getNetworkInterface().equals(interf)) {
+                    if (key.networkInterface().equals(interf)) {
                         // already a member to receive all packets so return
                         // existing key or detect conflict
                         if (source == null) {
-                            if (key.getSourceAddress() == null)
+                            if (key.sourceAddress() == null)
                                 return key;
                             throw new IllegalStateException("Already a member to receive all packets");
                         }
 
                         // already have source-specific membership so return key
                         // or detect conflict
-                        if (key.getSourceAddress() == null)
+                        if (key.sourceAddress() == null)
                             throw new IllegalStateException("Already have source-specific membership");
-                        if (source.equals(key.getSourceAddress()))
+                        if (source.equals(key.sourceAddress()))
                             return key;
                     }
                 }
@@ -81,7 +81,7 @@
      * Add membership to the registry, returning a new membership key.
      */
     void add(MembershipKeyImpl key) {
-        InetAddress group = key.getGroup();
+        InetAddress group = key.group();
         List<MembershipKeyImpl> keys;
         if (groups == null) {
             groups = new HashMap<InetAddress,List<MembershipKeyImpl>>();
@@ -100,7 +100,7 @@
      * Remove a key from the registry
      */
     void remove(MembershipKeyImpl key) {
-        InetAddress group = key.getGroup();
+        InetAddress group = key.group();
         List<MembershipKeyImpl> keys = groups.get(group);
         if (keys != null) {
             Iterator<MembershipKeyImpl> i = keys.iterator();
@@ -120,9 +120,11 @@
      * Invalidate all keys in the registry
      */
     void invalidateAll() {
-        for (InetAddress group: groups.keySet()) {
-            for (MembershipKeyImpl key: groups.get(group)) {
-                key.invalidate();
+        if (groups != null) {
+            for (InetAddress group: groups.keySet()) {
+                for (MembershipKeyImpl key: groups.get(group)) {
+                    key.invalidate();
+                }
             }
         }
     }
diff --git a/jdk/src/share/classes/sun/nio/ch/NativeThreadSet.java b/jdk/src/share/classes/sun/nio/ch/NativeThreadSet.java
index 612befc..a009541 100644
--- a/jdk/src/share/classes/sun/nio/ch/NativeThreadSet.java
+++ b/jdk/src/share/classes/sun/nio/ch/NativeThreadSet.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2002-2009 Sun Microsystems, Inc.  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
@@ -33,6 +33,7 @@
 
     private long[] elts;
     private int used = 0;
+    private boolean waitingToEmpty;
 
     NativeThreadSet(int n) {
         elts = new long[n];
@@ -75,12 +76,14 @@
         synchronized (this) {
             elts[i] = 0;
             used--;
+            if (used == 0 && waitingToEmpty)
+                notifyAll();
         }
     }
 
     // Signals all threads in this set.
     //
-    void signal() {
+    void signalAndWait() {
         synchronized (this) {
             int u = used;
             int n = elts.length;
@@ -92,7 +95,12 @@
                 if (--u == 0)
                     break;
             }
+            waitingToEmpty = true;
+            while (used > 0) {
+                try {
+                    wait();
+                } catch (InterruptedException ignore) { }
+            }
         }
     }
-
 }
diff --git a/jdk/src/share/classes/sun/nio/ch/Net.java b/jdk/src/share/classes/sun/nio/ch/Net.java
index ba0ba0b..f910c5d 100644
--- a/jdk/src/share/classes/sun/nio/ch/Net.java
+++ b/jdk/src/share/classes/sun/nio/ch/Net.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2009 Sun Microsystems, Inc.  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
@@ -207,7 +207,7 @@
     // -- Socket options
 
     static void setSocketOption(FileDescriptor fd, ProtocolFamily family,
-                                SocketOption name, Object value)
+                                SocketOption<?> name, Object value)
         throws IOException
     {
         if (value == null)
@@ -262,7 +262,7 @@
     }
 
     static Object getSocketOption(FileDescriptor fd, ProtocolFamily family,
-                                  SocketOption name)
+                                  SocketOption<?> name)
         throws IOException
     {
         Class<?> type = name.type();
diff --git a/jdk/src/share/classes/sun/nio/ch/OptionKey.java b/jdk/src/share/classes/sun/nio/ch/OptionKey.java
index 70ba8a6..8847453 100644
--- a/jdk/src/share/classes/sun/nio/ch/OptionKey.java
+++ b/jdk/src/share/classes/sun/nio/ch/OptionKey.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2008 Sun Microsystems, Inc.  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
diff --git a/jdk/src/share/classes/sun/nio/ch/PendingFuture.java b/jdk/src/share/classes/sun/nio/ch/PendingFuture.java
new file mode 100644
index 0000000..d88cf23
--- /dev/null
+++ b/jdk/src/share/classes/sun/nio/ch/PendingFuture.java
@@ -0,0 +1,257 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.ch;
+
+import java.nio.channels.*;
+import java.util.concurrent.*;
+import java.io.IOException;
+
+/**
+ * A Future for a pending I/O operation. A PendingFuture allows for the
+ * attachment of an additional arbitrary context object and a timer task.
+ */
+
+final class PendingFuture<V,A>
+    extends AbstractFuture<V,A>
+{
+    private static final CancellationException CANCELLED =
+        new CancellationException();
+
+    private final CompletionHandler<V,? super A> handler;
+
+    // true if result (or exception) is available
+    private volatile boolean haveResult;
+    private volatile V result;
+    private volatile Throwable exc;
+
+    // latch for waiting (created lazily if needed)
+    private CountDownLatch latch;
+
+    // optional timer task that is cancelled when result becomes available
+    private Future<?> timeoutTask;
+
+    // optional context object
+    private volatile Object context;
+
+
+    PendingFuture(AsynchronousChannel channel,
+                  CompletionHandler<V,? super A> handler,
+                  A attachment,
+                  Object context)
+    {
+        super(channel, attachment);
+        this.handler = handler;
+        this.context = context;
+    }
+
+    PendingFuture(AsynchronousChannel channel,
+                  CompletionHandler<V,? super A> handler,
+                  A attachment)
+    {
+        super(channel, attachment);
+        this.handler = handler;
+    }
+
+    CompletionHandler<V,? super A> handler() {
+        return handler;
+    }
+
+    void setContext(Object context) {
+        this.context = context;
+    }
+
+    Object getContext() {
+        return context;
+    }
+
+    void setTimeoutTask(Future<?> task) {
+        synchronized (this) {
+            if (haveResult) {
+                task.cancel(false);
+            } else {
+                this.timeoutTask = task;
+            }
+        }
+    }
+
+    // creates latch if required; return true if caller needs to wait
+    private boolean prepareForWait() {
+        synchronized (this) {
+            if (haveResult) {
+                return false;
+            } else {
+                if (latch == null)
+                    latch = new CountDownLatch(1);
+                return true;
+            }
+        }
+    }
+
+    /**
+     * Sets the result, or a no-op if the result or exception is already set.
+     */
+    boolean setResult(V res) {
+        synchronized (this) {
+            if (haveResult)
+                return false;
+            result = res;
+            haveResult = true;
+            if (timeoutTask != null)
+                timeoutTask.cancel(false);
+            if (latch != null)
+                latch.countDown();
+            return true;
+        }
+    }
+
+    /**
+     * Sets the result, or a no-op if the result or exception is already set.
+     */
+    boolean setFailure(Throwable x) {
+        if (!(x instanceof IOException) && !(x instanceof SecurityException))
+            x = new IOException(x);
+        synchronized (this) {
+            if (haveResult)
+                return false;
+            exc = x;
+            haveResult = true;
+            if (timeoutTask != null)
+                timeoutTask.cancel(false);
+            if (latch != null)
+                latch.countDown();
+            return true;
+        }
+    }
+
+    @Override
+    public V get() throws ExecutionException, InterruptedException {
+        if (!haveResult) {
+            boolean needToWait = prepareForWait();
+            if (needToWait)
+                latch.await();
+        }
+        if (exc != null) {
+            if (exc == CANCELLED)
+                throw new CancellationException();
+            throw new ExecutionException(exc);
+        }
+        return result;
+    }
+
+    @Override
+    public V get(long timeout, TimeUnit unit)
+        throws ExecutionException, InterruptedException, TimeoutException
+    {
+        if (!haveResult) {
+            boolean needToWait = prepareForWait();
+            if (needToWait)
+                if (!latch.await(timeout, unit)) throw new TimeoutException();
+        }
+        if (exc != null) {
+            if (exc == CANCELLED)
+                throw new CancellationException();
+            throw new ExecutionException(exc);
+        }
+        return result;
+    }
+
+    @Override
+    Throwable exception() {
+        return (exc != CANCELLED) ? exc : null;
+    }
+
+    @Override
+    V value() {
+        return result;
+    }
+
+    @Override
+    public boolean isCancelled() {
+        return (exc == CANCELLED);
+    }
+
+    @Override
+    public boolean isDone() {
+        return haveResult;
+    }
+
+    @Override
+    public boolean cancel(boolean mayInterruptIfRunning) {
+        synchronized (this) {
+            if (haveResult)
+                return false;    // already completed
+
+            // A shutdown of the channel group will close all channels and
+            // shutdown the executor. To ensure that the completion handler
+            // is executed we queue the task while holding the lock.
+            if (handler != null) {
+                prepareForWait();
+                Runnable cancelTask = new Runnable() {
+                    public void run() {
+                        while (!haveResult) {
+                            try {
+                                latch.await();
+                            } catch (InterruptedException ignore) { }
+                        }
+                        handler.cancelled(attachment());
+                    }
+                };
+                AsynchronousChannel ch = channel();
+                if (ch instanceof Groupable) {
+                    ((Groupable)ch).group().executeOnPooledThread(cancelTask);
+                } else {
+                    if (ch instanceof AsynchronousFileChannelImpl) {
+                        ((AsynchronousFileChannelImpl)ch).executor().execute(cancelTask);
+                    } else {
+                        throw new AssertionError("Should not get here");
+                    }
+                }
+            }
+
+            // notify channel
+            if (channel() instanceof Cancellable)
+                ((Cancellable)channel()).onCancel(this);
+
+            // set result and cancel timer
+            exc = CANCELLED;
+            haveResult = true;
+            if (timeoutTask != null)
+                timeoutTask.cancel(false);
+        }
+
+        // close channel if forceful cancel
+        if (mayInterruptIfRunning) {
+            try {
+                channel().close();
+            } catch (IOException ignore) { }
+        }
+
+        // release waiters (this also releases the invoker)
+        if (latch != null)
+            latch.countDown();
+        return true;
+    }
+}
diff --git a/jdk/src/share/classes/sun/nio/ch/Reflect.java b/jdk/src/share/classes/sun/nio/ch/Reflect.java
index 913357f..cc4716e 100644
--- a/jdk/src/share/classes/sun/nio/ch/Reflect.java
+++ b/jdk/src/share/classes/sun/nio/ch/Reflect.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2009 Sun Microsystems, Inc.  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
@@ -55,7 +55,7 @@
     {
         try {
             Class<?> cl = Class.forName(className);
-            Constructor c = cl.getDeclaredConstructor(paramTypes);
+            Constructor<?> c = cl.getDeclaredConstructor(paramTypes);
             setAccessible(c);
             return c;
         } catch (ClassNotFoundException x) {
@@ -79,7 +79,7 @@
 
     static Method lookupMethod(String className,
                                String methodName,
-                               Class[] paramTypes)
+                               Class... paramTypes)
     {
         try {
             Class<?> cl = Class.forName(className);
diff --git a/jdk/src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java b/jdk/src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java
index fd53298..d509198 100644
--- a/jdk/src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java
+++ b/jdk/src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2009 Sun Microsystems, Inc.  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
@@ -27,12 +27,9 @@
 
 import java.io.FileDescriptor;
 import java.io.IOException;
-import java.lang.reflect.*;
 import java.net.*;
 import java.nio.channels.*;
 import java.nio.channels.spi.*;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
 import java.util.*;
 
 
@@ -111,19 +108,19 @@
     public SocketAddress getLocalAddress() throws IOException {
         synchronized (stateLock) {
             if (!isOpen())
-                return null;
+                throw new ClosedChannelException();
             return localAddress;
         }
     }
 
     @Override
-    public ServerSocketChannel setOption(SocketOption name, Object value)
+    public <T> ServerSocketChannel setOption(SocketOption<T> name, T value)
         throws IOException
     {
         if (name == null)
             throw new NullPointerException();
-        if (!options().contains(name))
-            throw new IllegalArgumentException("invalid option name");
+        if (!supportedOptions().contains(name))
+            throw new UnsupportedOperationException("'" + name + "' not supported");
 
         synchronized (stateLock) {
             if (!isOpen())
@@ -142,8 +139,8 @@
     {
         if (name == null)
             throw new NullPointerException();
-        if (!options().contains(name))
-            throw new IllegalArgumentException("invalid option name");
+        if (!supportedOptions().contains(name))
+            throw new UnsupportedOperationException("'" + name + "' not supported");
 
         synchronized (stateLock) {
             if (!isOpen())
@@ -154,7 +151,7 @@
         }
     }
 
-    private static class LazyInitialization {
+    private static class DefaultOptionsHolder {
         static final Set<SocketOption<?>> defaultOptions = defaultOptions();
 
         private static Set<SocketOption<?>> defaultOptions() {
@@ -166,8 +163,8 @@
     }
 
     @Override
-    public final Set<SocketOption<?>> options() {
-        return LazyInitialization.defaultOptions;
+    public final Set<SocketOption<?>> supportedOptions() {
+        return DefaultOptionsHolder.defaultOptions;
     }
 
     public boolean isBound() {
diff --git a/jdk/src/share/classes/sun/nio/ch/SimpleAsynchronousDatagramChannelImpl.java b/jdk/src/share/classes/sun/nio/ch/SimpleAsynchronousDatagramChannelImpl.java
new file mode 100644
index 0000000..47c3b2a
--- /dev/null
+++ b/jdk/src/share/classes/sun/nio/ch/SimpleAsynchronousDatagramChannelImpl.java
@@ -0,0 +1,612 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.ch;
+
+import java.nio.ByteBuffer;
+import java.nio.channels.*;
+import java.net.*;
+import java.io.IOException;
+import java.util.*;
+import java.util.concurrent.*;
+import java.security.AccessController;
+import java.security.AccessControlContext;
+import java.security.PrivilegedExceptionAction;
+import java.security.PrivilegedActionException;
+
+/**
+ * A prototype implementation of AsynchronousDatagramChannel, used to aid
+ * test and spec development.
+ */
+
+class SimpleAsynchronousDatagramChannelImpl
+    extends AsynchronousDatagramChannel implements Groupable, Cancellable
+{
+    private final DatagramChannel dc;
+    private final AsynchronousChannelGroupImpl group;
+    private final Object attachKey;
+    private boolean closed;
+
+    // used to coordinate timed and blocking reads
+    private final Object readLock = new Object();
+
+    // channel blocking mode (requires readLock)
+    private boolean isBlocking = true;
+
+    // number of blocking readers (requires readLock)
+    private int blockingReaderCount;
+
+    // true if timed read attempted while blocking read in progress (requires readLock)
+    private boolean transitionToNonBlocking;
+
+    // true if a blocking read is cancelled (requires readLock)
+    private boolean blockingReadKilledByCancel;
+
+    // temporary Selectors used by timed reads (requires readLock)
+    private Selector firstReader;
+    private Set<Selector> otherReaders;
+
+    SimpleAsynchronousDatagramChannelImpl(ProtocolFamily family,
+                                          AsynchronousChannelGroupImpl group)
+        throws IOException
+    {
+        super(group.provider());
+        this.dc = (family == null) ?
+            DatagramChannel.open() : DatagramChannel.open(family);
+        this.group = group;
+
+        // attach this channel to the group as foreign channel
+        boolean registered = false;
+        try {
+            if (!(dc instanceof DatagramChannelImpl))
+                throw new UnsupportedOperationException();
+            attachKey = group
+                .attachForeignChannel(this, ((DatagramChannelImpl)dc).getFD());
+            registered = true;
+        } finally {
+            if (!registered)
+                dc.close();
+        }
+    }
+
+    // throws RuntimeException if blocking read has been cancelled
+    private void ensureBlockingReadNotKilled() {
+        assert Thread.holdsLock(readLock);
+        if (blockingReadKilledByCancel)
+            throw new RuntimeException("Reading not allowed due to cancellation");
+    }
+
+    // invoke prior to non-timed read/receive
+    private void beginNoTimeoutRead() {
+        synchronized (readLock) {
+            ensureBlockingReadNotKilled();
+            if (isBlocking)
+                blockingReaderCount++;
+        }
+    }
+
+    // invoke after non-timed read/receive has completed
+    private void endNoTimeoutRead() {
+        synchronized (readLock) {
+            if (isBlocking) {
+                if (--blockingReaderCount == 0 && transitionToNonBlocking) {
+                    // notify any threads waiting to make channel non-blocking
+                    readLock.notifyAll();
+                }
+            }
+        }
+    }
+
+    // invoke prior to timed read
+    // returns the timeout remaining
+    private long prepareForTimedRead(PendingFuture<?,?> result, long timeout)
+        throws IOException
+    {
+        synchronized (readLock) {
+            ensureBlockingReadNotKilled();
+            if (isBlocking) {
+                transitionToNonBlocking = true;
+                while (blockingReaderCount > 0 &&
+                       timeout > 0L &&
+                       !result.isCancelled())
+                {
+                    long st = System.currentTimeMillis();
+                    try {
+                        readLock.wait(timeout);
+                    } catch (InterruptedException e) { }
+                    timeout -= System.currentTimeMillis() - st;
+                }
+                if (blockingReaderCount == 0) {
+                    // re-check that blocked read wasn't cancelled
+                    ensureBlockingReadNotKilled();
+                    // no blocking reads so change channel to non-blocking
+                    dc.configureBlocking(false);
+                    isBlocking = false;
+                }
+            }
+            return timeout;
+        }
+    }
+
+    // returns a temporary Selector
+    private Selector getSelector() throws IOException {
+        Selector sel = Util.getTemporarySelector(dc);
+        synchronized (readLock) {
+            if (firstReader == null) {
+                firstReader = sel;
+            } else {
+                if (otherReaders == null)
+                    otherReaders = new HashSet<Selector>();
+                otherReaders.add(sel);
+            }
+        }
+        return sel;
+    }
+
+    // releases a temporary Selector
+    private void releaseSelector(Selector sel) throws IOException {
+        synchronized (readLock) {
+            if (firstReader == sel) {
+                firstReader = null;
+            } else {
+                otherReaders.remove(sel);
+            }
+        }
+        Util.releaseTemporarySelector(sel);
+    }
+
+    // wakeup all Selectors currently in use
+    private void wakeupSelectors() {
+        synchronized (readLock) {
+            if (firstReader != null)
+                firstReader.wakeup();
+            if (otherReaders != null) {
+                for (Selector sel: otherReaders) {
+                    sel.wakeup();
+                }
+            }
+        }
+    }
+
+    @Override
+    public AsynchronousChannelGroupImpl group() {
+        return group;
+    }
+
+    @Override
+    public boolean isOpen() {
+        return dc.isOpen();
+    }
+
+    @Override
+    public void onCancel(PendingFuture<?,?> task) {
+        synchronized (readLock) {
+            if (blockingReaderCount > 0) {
+                blockingReadKilledByCancel = true;
+                readLock.notifyAll();
+                return;
+            }
+        }
+        wakeupSelectors();
+    }
+
+    @Override
+    public void close() throws IOException {
+        synchronized (dc) {
+            if (closed)
+                return;
+            closed = true;
+        }
+        // detach from group and close underlying channel
+        group.detachForeignChannel(attachKey);
+        dc.close();
+
+        // wakeup any threads blocked in timed read/receives
+        wakeupSelectors();
+    }
+
+    @Override
+    public AsynchronousDatagramChannel connect(SocketAddress remote)
+        throws IOException
+    {
+        dc.connect(remote);
+        return this;
+    }
+
+    @Override
+    public AsynchronousDatagramChannel disconnect() throws IOException {
+        dc.disconnect();
+        return this;
+    }
+
+    private static class WrappedMembershipKey extends MembershipKey {
+        private final MulticastChannel channel;
+        private final MembershipKey key;
+
+        WrappedMembershipKey(MulticastChannel channel, MembershipKey key) {
+            this.channel = channel;
+            this.key = key;
+        }
+
+        @Override
+        public boolean isValid() {
+            return key.isValid();
+        }
+
+        @Override
+        public void drop() {
+            key.drop();
+        }
+
+        @Override
+        public MulticastChannel channel() {
+            return channel;
+        }
+
+        @Override
+        public InetAddress group() {
+            return key.group();
+        }
+
+        @Override
+        public NetworkInterface networkInterface() {
+            return key.networkInterface();
+        }
+
+        @Override
+        public InetAddress sourceAddress() {
+            return key.sourceAddress();
+        }
+
+        @Override
+        public MembershipKey block(InetAddress toBlock) throws IOException {
+            key.block(toBlock);
+            return this;
+        }
+
+        @Override
+        public MembershipKey unblock(InetAddress toUnblock) {
+            key.unblock(toUnblock);
+            return this;
+        }
+
+        @Override
+        public String toString() {
+            return key.toString();
+        }
+    }
+
+    @Override
+    public MembershipKey join(InetAddress group,
+                              NetworkInterface interf)
+        throws IOException
+    {
+        MembershipKey key = ((MulticastChannel)dc).join(group, interf);
+        return new WrappedMembershipKey(this, key);
+    }
+
+    @Override
+    public MembershipKey join(InetAddress group,
+                              NetworkInterface interf,
+                              InetAddress source)
+        throws IOException
+    {
+        MembershipKey key = ((MulticastChannel)dc).join(group, interf, source);
+        return new WrappedMembershipKey(this, key);
+    }
+
+    @Override
+    public <A> Future<Integer> send(ByteBuffer src,
+                                    SocketAddress target,
+                                    long timeout,
+                                    TimeUnit unit,
+                                    A attachment,
+                                    CompletionHandler<Integer,? super A> handler)
+    {
+        if (timeout < 0L)
+            throw new IllegalArgumentException("Negative timeout");
+        if (unit == null)
+            throw new NullPointerException();
+
+        CompletedFuture<Integer,A> result;
+        try {
+            int n = dc.send(src, target);
+            result = CompletedFuture.withResult(this, n, attachment);
+        } catch (IOException ioe) {
+            result = CompletedFuture.withFailure(this, ioe, attachment);
+        }
+        Invoker.invoke(handler, result);
+        return result;
+    }
+
+    @Override
+    public <A> Future<Integer> write(ByteBuffer src,
+                                     long timeout,
+                                     TimeUnit unit,
+                                     A attachment,
+                                     CompletionHandler<Integer,? super A> handler)
+    {
+        if (timeout < 0L)
+            throw new IllegalArgumentException("Negative timeout");
+        if (unit == null)
+            throw new NullPointerException();
+
+        CompletedFuture<Integer,A> result;
+        try {
+            int n = dc.write(src);
+            result = CompletedFuture.withResult(this, n, attachment);
+        } catch (IOException ioe) {
+            result = CompletedFuture.withFailure(this, ioe, attachment);
+        }
+        Invoker.invoke(handler, result);
+        return result;
+    }
+
+    /**
+     * Receive into the given buffer with privileges enabled and restricted by
+     * the given AccessControlContext (can be null).
+     */
+    private SocketAddress doRestrictedReceive(final ByteBuffer dst,
+                                              AccessControlContext acc)
+        throws IOException
+    {
+        if (acc == null) {
+            return dc.receive(dst);
+        } else {
+            try {
+                return AccessController.doPrivileged(
+                    new PrivilegedExceptionAction<SocketAddress>() {
+                        public SocketAddress run() throws IOException {
+                            return dc.receive(dst);
+                        }}, acc);
+            } catch (PrivilegedActionException pae) {
+                Exception cause = pae.getException();
+                if (cause instanceof SecurityException)
+                    throw (SecurityException)cause;
+                throw (IOException)cause;
+            }
+        }
+    }
+
+    @Override
+    public <A> Future<SocketAddress> receive(final ByteBuffer dst,
+                                             final long timeout,
+                                             final TimeUnit unit,
+                                             A attachment,
+                                             final CompletionHandler<SocketAddress,? super A> handler)
+    {
+        if (dst.isReadOnly())
+            throw new IllegalArgumentException("Read-only buffer");
+        if (timeout < 0L)
+            throw new IllegalArgumentException("Negative timeout");
+        if (unit == null)
+            throw new NullPointerException();
+
+        // complete immediately if channel closed
+        if (!isOpen()) {
+            CompletedFuture<SocketAddress,A> result = CompletedFuture.withFailure(this,
+                new ClosedChannelException(), attachment);
+            Invoker.invoke(handler, result);
+            return result;
+        }
+
+        final AccessControlContext acc = (System.getSecurityManager() == null) ?
+            null : AccessController.getContext();
+        final PendingFuture<SocketAddress,A> result =
+            new PendingFuture<SocketAddress,A>(this, handler, attachment);
+        Runnable task = new Runnable() {
+            public void run() {
+                try {
+                    SocketAddress remote = null;
+                    long to;
+                    if (timeout == 0L) {
+                        beginNoTimeoutRead();
+                        try {
+                            remote = doRestrictedReceive(dst, acc);
+                        } finally {
+                            endNoTimeoutRead();
+                        }
+                        to = 0L;
+                    } else {
+                        to = prepareForTimedRead(result, unit.toMillis(timeout));
+                        if (to <= 0L)
+                            throw new InterruptedByTimeoutException();
+                        remote = doRestrictedReceive(dst, acc);
+                    }
+                    if (remote == null) {
+                        Selector sel = getSelector();
+                        SelectionKey sk = null;
+                        try {
+                            sk = dc.register(sel, SelectionKey.OP_READ);
+                            for (;;) {
+                                if (!dc.isOpen())
+                                    throw new AsynchronousCloseException();
+                                if (result.isCancelled())
+                                    break;
+                                long st = System.currentTimeMillis();
+                                int ns = sel.select(to);
+                                if (ns > 0) {
+                                    remote = doRestrictedReceive(dst, acc);
+                                    if (remote != null)
+                                        break;
+                                }
+                                sel.selectedKeys().remove(sk);
+                                if (timeout != 0L) {
+                                    to -= System.currentTimeMillis() - st;
+                                    if (to <= 0)
+                                        throw new InterruptedByTimeoutException();
+                                }
+                            }
+                        } finally {
+                            if (sk != null)
+                                sk.cancel();
+                            releaseSelector(sel);
+                        }
+                    }
+                    result.setResult(remote);
+                } catch (Throwable x) {
+                    if (x instanceof ClosedChannelException)
+                        x = new AsynchronousCloseException();
+                    result.setFailure(x);
+                }
+                Invoker.invokeUnchecked(handler, result);
+            }
+        };
+        try {
+            group.executeOnPooledThread(task);
+        } catch (RejectedExecutionException ree) {
+            throw new ShutdownChannelGroupException();
+        }
+        return result;
+    }
+
+    @Override
+    public <A> Future<Integer> read(final ByteBuffer dst,
+                                    final long timeout,
+                                    final TimeUnit unit,
+                                    A attachment,
+                                    final CompletionHandler<Integer,? super A> handler)
+    {
+        if (dst.isReadOnly())
+            throw new IllegalArgumentException("Read-only buffer");
+        if (timeout < 0L)
+            throw new IllegalArgumentException("Negative timeout");
+        if (unit == null)
+            throw new NullPointerException();
+        // another thread may disconnect before read is initiated
+        if (!dc.isConnected())
+            throw new NotYetConnectedException();
+
+        // complete immediately if channel closed
+        if (!isOpen()) {
+            CompletedFuture<Integer,A> result = CompletedFuture.withFailure(this,
+                new ClosedChannelException(), attachment);
+            Invoker.invoke(handler, result);
+            return result;
+        }
+
+        final PendingFuture<Integer,A> result =
+            new PendingFuture<Integer,A>(this, handler, attachment);
+        Runnable task = new Runnable() {
+            public void run() {
+                try {
+                    int n = 0;
+                    long to;
+                    if (timeout == 0L) {
+                        beginNoTimeoutRead();
+                        try {
+                            n = dc.read(dst);
+                        } finally {
+                            endNoTimeoutRead();
+                        }
+                        to = 0L;
+                    } else {
+                        to = prepareForTimedRead(result, unit.toMillis(timeout));
+                        if (to <= 0L)
+                            throw new InterruptedByTimeoutException();
+                        n = dc.read(dst);
+                    }
+                    if (n == 0) {
+                        Selector sel = getSelector();
+                        SelectionKey sk = null;
+                        try {
+                            sk = dc.register(sel, SelectionKey.OP_READ);
+                            for (;;) {
+                                if (!dc.isOpen())
+                                    throw new AsynchronousCloseException();
+                                if (result.isCancelled())
+                                    break;
+                                long st = System.currentTimeMillis();
+                                int ns = sel.select(to);
+                                if (ns > 0) {
+                                    if ((n = dc.read(dst)) != 0)
+                                        break;
+                                }
+                                sel.selectedKeys().remove(sk);
+                                if (timeout != 0L) {
+                                    to -= System.currentTimeMillis() - st;
+                                    if (to <= 0)
+                                        throw new InterruptedByTimeoutException();
+                                }
+                            }
+                        } finally {
+                            if (sk != null)
+                                sk.cancel();
+                            releaseSelector(sel);
+                        }
+                    }
+                    result.setResult(n);
+                } catch (Throwable x) {
+                    if (x instanceof ClosedChannelException)
+                        x = new AsynchronousCloseException();
+                    result.setFailure(x);
+                }
+                Invoker.invokeUnchecked(handler, result);
+            }
+        };
+        try {
+            group.executeOnPooledThread(task);
+        } catch (RejectedExecutionException ree) {
+            throw new ShutdownChannelGroupException();
+        }
+        return result;
+    }
+
+    @Override
+    public  AsynchronousDatagramChannel bind(SocketAddress local)
+        throws IOException
+    {
+        dc.bind(local);
+        return this;
+    }
+
+    @Override
+    public SocketAddress getLocalAddress() throws IOException {
+        return dc.getLocalAddress();
+    }
+
+    @Override
+    public <T> AsynchronousDatagramChannel setOption(SocketOption<T> name, T value)
+        throws IOException
+    {
+        dc.setOption(name, value);
+        return this;
+    }
+
+    @Override
+    public  <T> T getOption(SocketOption<T> name) throws IOException {
+        return dc.getOption(name);
+    }
+
+    @Override
+    public Set<SocketOption<?>> supportedOptions() {
+        return dc.supportedOptions();
+    }
+
+    @Override
+    public SocketAddress getRemoteAddress() throws IOException {
+        return dc.getRemoteAddress();
+    }
+}
diff --git a/jdk/src/share/classes/sun/nio/ch/SimpleAsynchronousFileChannelImpl.java b/jdk/src/share/classes/sun/nio/ch/SimpleAsynchronousFileChannelImpl.java
new file mode 100644
index 0000000..52fe5a2
--- /dev/null
+++ b/jdk/src/share/classes/sun/nio/ch/SimpleAsynchronousFileChannelImpl.java
@@ -0,0 +1,426 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.ch;
+
+import java.nio.channels.*;
+import java.util.concurrent.*;
+import java.nio.ByteBuffer;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.io.FileDescriptor;
+import java.io.IOException;
+
+/**
+ * "Portable" implementation of AsynchronousFileChannel for use on operating
+ * systems that don't support asynchronous file I/O.
+ */
+
+public class SimpleAsynchronousFileChannelImpl
+    extends AsynchronousFileChannelImpl
+{
+    // lazy initialization of default thread pool for file I/O
+    private static class DefaultExecutorHolder {
+        static final ExecutorService defaultExecutor =
+            ThreadPool.createDefault().executor();
+    }
+
+    // Used to make native read and write calls
+    private static final FileDispatcher nd = new FileDispatcherImpl();
+
+    // indicates if the associated thread pool is the default thread pool
+    private final boolean isDefaultExecutor;
+
+    // Thread-safe set of IDs of native threads, for signalling
+    private final NativeThreadSet threads = new NativeThreadSet(2);
+
+
+    SimpleAsynchronousFileChannelImpl(FileDescriptor fdObj,
+                                      boolean reading,
+                                      boolean writing,
+                                      ExecutorService executor,
+                                      boolean isDefaultexecutor)
+    {
+        super(fdObj, reading, writing, executor);
+        this.isDefaultExecutor = isDefaultexecutor;
+    }
+
+    public static AsynchronousFileChannel open(FileDescriptor fdo,
+                                               boolean reading,
+                                               boolean writing,
+                                               ThreadPool pool)
+    {
+        // Executor is either default or based on pool parameters
+        ExecutorService executor;
+        boolean isDefaultexecutor;
+        if (pool == null) {
+            executor = DefaultExecutorHolder.defaultExecutor;
+            isDefaultexecutor = true;
+        } else {
+            executor = pool.executor();
+            isDefaultexecutor = false;
+        }
+        return new SimpleAsynchronousFileChannelImpl(fdo,
+            reading, writing, executor, isDefaultexecutor);
+    }
+
+    @Override
+    public void close() throws IOException {
+        // mark channel as closed
+        synchronized (fdObj) {
+            if (closed)
+                return;     // already closed
+            closed = true;
+            // from this point on, if another thread invokes the begin() method
+            // then it will throw ClosedChannelException
+        }
+
+        // signal any threads blocked on this channel
+        nd.preClose(fdObj);
+        threads.signalAndWait();
+
+        // wait until all async I/O operations have completely gracefully
+        closeLock.writeLock().lock();
+        try {
+            // do nothing
+        } finally {
+            closeLock.writeLock().unlock();
+        }
+
+        // Invalidate and release any locks that we still hold
+        invalidateAllLocks();
+
+        // close file
+        nd.close(fdObj);
+
+        // shutdown executor if specific to this channel
+        if (!isDefaultExecutor) {
+            AccessController.doPrivileged(new PrivilegedAction<Void>() {
+                public Void run() {
+                    executor.shutdown();
+                    return null;
+                }
+            });
+        }
+    }
+
+    @Override
+    public long size() throws IOException {
+        int ti = threads.add();
+        try {
+            long n = 0L;
+            try {
+                begin();
+                do {
+                    n = nd.size(fdObj);
+                } while ((n == IOStatus.INTERRUPTED) && isOpen());
+                return n;
+            } finally {
+                end(n >= 0L);
+            }
+        } finally {
+            threads.remove(ti);
+        }
+    }
+
+    @Override
+    public AsynchronousFileChannel truncate(long size) throws IOException {
+        if (size < 0L)
+            throw new IllegalArgumentException("Negative size");
+        if (!writing)
+            throw new NonWritableChannelException();
+        int ti = threads.add();
+        try {
+            long n = 0L;
+            try {
+                begin();
+                do {
+                    n = nd.size(fdObj);
+                } while ((n == IOStatus.INTERRUPTED) && isOpen());
+
+                // truncate file if 'size' less than current size
+                if (size < n && isOpen()) {
+                    do {
+                        n = nd.truncate(fdObj, size);
+                    } while ((n == IOStatus.INTERRUPTED) && isOpen());
+                }
+                return this;
+            } finally {
+                end(n > 0);
+            }
+        } finally {
+            threads.remove(ti);
+        }
+    }
+
+    @Override
+    public void force(boolean metaData) throws IOException {
+        int ti = threads.add();
+        try {
+            int n = 0;
+            try {
+                begin();
+                do {
+                    n = nd.force(fdObj, metaData);
+                } while ((n == IOStatus.INTERRUPTED) && isOpen());
+            } finally {
+                end(n >= 0);
+            }
+        } finally {
+            threads.remove(ti);
+        }
+    }
+
+    @Override
+    public <A> Future<FileLock> lock(final long position,
+                                     final long size,
+                                     final boolean shared,
+                                     A attachment,
+                                     final CompletionHandler<FileLock,? super A> handler)
+    {
+        if (shared && !reading)
+            throw new NonReadableChannelException();
+        if (!shared && !writing)
+            throw new NonWritableChannelException();
+
+        // add to lock table
+        final FileLockImpl fli = addToFileLockTable(position, size, shared);
+        if (fli == null) {
+            CompletedFuture<FileLock,A> result = CompletedFuture
+                .withFailure(this, new ClosedChannelException(), attachment);
+            Invoker.invokeIndirectly(handler, result, executor);
+            return result;
+        }
+
+        final PendingFuture<FileLock,A> result =
+            new PendingFuture<FileLock,A>(this, handler, attachment);
+        Runnable task = new Runnable() {
+            public void run() {
+                int ti = threads.add();
+                try {
+                    int n;
+                    try {
+                        begin();
+                        do {
+                            n = nd.lock(fdObj, true, position, size, shared);
+                        } while ((n == FileDispatcher.INTERRUPTED) && isOpen());
+                        if (n == FileDispatcher.LOCKED) {
+                            result.setResult(fli);
+                        } else {
+                            if (n != FileDispatcher.INTERRUPTED)
+                                throw new AssertionError();
+                            throw new AsynchronousCloseException();
+                        }
+                    } catch (IOException x) {
+                        removeFromFileLockTable(fli);
+                        if (!isOpen())
+                            x = new AsynchronousCloseException();
+                        result.setFailure(x);
+                    } finally {
+                        end();
+                    }
+                } finally {
+                    threads.remove(ti);
+                }
+                Invoker.invokeUnchecked(handler, result);
+            }
+        };
+        try {
+            executor.execute(task);
+        } catch (RejectedExecutionException ree) {
+            // rollback
+            removeFromFileLockTable(fli);
+            throw new ShutdownChannelGroupException();
+        }
+        return result;
+    }
+
+    @Override
+    public FileLock tryLock(long position, long size, boolean shared)
+        throws IOException
+    {
+        if (shared && !reading)
+            throw new NonReadableChannelException();
+        if (!shared && !writing)
+            throw new NonWritableChannelException();
+
+        // add to lock table
+        FileLockImpl fli = addToFileLockTable(position, size, shared);
+        if (fli == null)
+            throw new ClosedChannelException();
+
+        int ti = threads.add();
+        boolean gotLock = false;
+        try {
+            begin();
+            int n;
+            do {
+                n = nd.lock(fdObj, false, position, size, shared);
+            } while ((n == FileDispatcher.INTERRUPTED) && isOpen());
+            if (n != FileDispatcher.LOCKED) {
+                if (n == FileDispatcher.NO_LOCK)
+                    return null;    // locked by someone else
+                if (n == FileDispatcher.INTERRUPTED)
+                    throw new AsynchronousCloseException();
+                // should not get here
+                throw new AssertionError();
+            }
+            gotLock = true;
+            return fli;
+        } finally {
+            if (!gotLock)
+                removeFromFileLockTable(fli);
+            end();
+            threads.remove(ti);
+        }
+    }
+
+    @Override
+    void release(FileLockImpl fli) throws IOException {
+        try {
+            begin();
+            nd.release(fdObj, fli.position(), fli.size());
+            removeFromFileLockTable(fli);
+        } finally {
+            end();
+        }
+    }
+
+    @Override
+    public <A> Future<Integer> read(final ByteBuffer dst,
+                                    final long position,
+                                    A attachment,
+                                    final CompletionHandler<Integer,? super A> handler)
+    {
+        if (position < 0)
+            throw new IllegalArgumentException("Negative position");
+        if (!reading)
+            throw new NonReadableChannelException();
+        if (dst.isReadOnly())
+            throw new IllegalArgumentException("Read-only buffer");
+
+        // complete immediately if channel closed or no space remaining
+        if (!isOpen() || (dst.remaining() == 0)) {
+            CompletedFuture<Integer,A> result;
+            if (isOpen()) {
+                result = CompletedFuture.withResult(this, 0, attachment);
+            } else {
+                result = CompletedFuture.withFailure(this,
+                    new ClosedChannelException(), attachment);
+            }
+            Invoker.invokeIndirectly(handler, result, executor);
+            return result;
+        }
+
+        final PendingFuture<Integer,A> result =
+            new PendingFuture<Integer,A>(this, handler, attachment);
+        Runnable task = new Runnable() {
+            public void run() {
+                int ti = threads.add();
+                try {
+                    begin();
+                    int n;
+                    do {
+                        n = IOUtil.read(fdObj, dst, position, nd, null);
+                    } while ((n == IOStatus.INTERRUPTED) && isOpen());
+                    if (n < 0 && !isOpen())
+                        throw new AsynchronousCloseException();
+                    result.setResult(n);
+                } catch (IOException x) {
+                    if (!isOpen())
+                        x = new AsynchronousCloseException();
+                    result.setFailure(x);
+                } finally {
+                    end();
+                    threads.remove(ti);
+                }
+                Invoker.invokeUnchecked(handler, result);
+            }
+        };
+        try {
+            executor.execute(task);
+        } catch (RejectedExecutionException ree) {
+            throw new ShutdownChannelGroupException();
+        }
+        return result;
+    }
+
+    @Override
+    public <A> Future<Integer> write(final ByteBuffer src,
+                                     final long position,
+                                     A attachment,
+                                     final CompletionHandler<Integer,? super A> handler)
+    {
+        if (position < 0)
+            throw new IllegalArgumentException("Negative position");
+        if (!writing)
+            throw new NonWritableChannelException();
+
+        // complete immediately if channel is closed or no bytes remaining
+        if (!isOpen() || (src.remaining() == 0)) {
+            CompletedFuture<Integer,A> result;
+            if (isOpen()) {
+                result = CompletedFuture.withResult(this, 0, attachment);
+            } else {
+                result = CompletedFuture.withFailure(this,
+                    new ClosedChannelException(), attachment);
+            }
+            Invoker.invokeIndirectly(handler, result, executor);
+            return result;
+        }
+
+        final PendingFuture<Integer,A> result =
+            new PendingFuture<Integer,A>(this, handler, attachment);
+        Runnable task = new Runnable() {
+            public void run() {
+                int ti = threads.add();
+                try {
+                    begin();
+                    int n;
+                    do {
+                        n = IOUtil.write(fdObj, src, position, nd, null);
+                    } while ((n == IOStatus.INTERRUPTED) && isOpen());
+                    if (n < 0 && !isOpen())
+                        throw new AsynchronousCloseException();
+                    result.setResult(n);
+                } catch (IOException x) {
+                    if (!isOpen())
+                        x = new AsynchronousCloseException();
+                    result.setFailure(x);
+                } finally {
+                    end();
+                    threads.remove(ti);
+                }
+                Invoker.invokeUnchecked(handler, result);
+            }
+        };
+        try {
+            executor.execute(task);
+        } catch (RejectedExecutionException ree) {
+            throw new ShutdownChannelGroupException();
+        }
+        return result;
+    }
+}
diff --git a/jdk/src/share/classes/sun/nio/ch/SocketChannelImpl.java b/jdk/src/share/classes/sun/nio/ch/SocketChannelImpl.java
index 11567ba..2094477 100644
--- a/jdk/src/share/classes/sun/nio/ch/SocketChannelImpl.java
+++ b/jdk/src/share/classes/sun/nio/ch/SocketChannelImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2009 Sun Microsystems, Inc.  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
@@ -128,28 +128,28 @@
     public SocketAddress getLocalAddress() throws IOException {
         synchronized (stateLock) {
             if (!isOpen())
-                return null;
+                throw new ClosedChannelException();
             return localAddress;
         }
     }
 
     @Override
-    public SocketAddress getConnectedAddress() throws IOException {
+    public SocketAddress getRemoteAddress() throws IOException {
         synchronized (stateLock) {
             if (!isOpen())
-                return null;
+                throw new ClosedChannelException();
             return remoteAddress;
         }
     }
 
     @Override
-    public SocketChannel setOption(SocketOption name, Object value)
+    public <T> SocketChannel setOption(SocketOption<T> name, T value)
         throws IOException
     {
         if (name == null)
             throw new NullPointerException();
-        if (!options().contains(name))
-            throw new IllegalArgumentException("Invalid option name");
+        if (!supportedOptions().contains(name))
+            throw new UnsupportedOperationException("'" + name + "' not supported");
 
         synchronized (stateLock) {
             if (!isOpen())
@@ -175,8 +175,8 @@
     {
         if (name == null)
             throw new NullPointerException();
-        if (!options().contains(name))
-            throw new IllegalArgumentException("Invalid option name");
+        if (!supportedOptions().contains(name))
+            throw new UnsupportedOperationException("'" + name + "' not supported");
 
         synchronized (stateLock) {
             if (!isOpen())
@@ -193,7 +193,7 @@
         }
     }
 
-    private static class LazyInitialization {
+    private static class DefaultOptionsHolder {
         static final Set<SocketOption<?>> defaultOptions = defaultOptions();
 
         private static Set<SocketOption<?>> defaultOptions() {
@@ -212,8 +212,8 @@
     }
 
     @Override
-    public final Set<SocketOption<?>> options() {
-        return LazyInitialization.defaultOptions;
+    public final Set<SocketOption<?>> supportedOptions() {
+        return DefaultOptionsHolder.defaultOptions;
     }
 
     private boolean ensureReadOpen() throws ClosedChannelException {
diff --git a/jdk/src/share/classes/sun/nio/ch/ThreadPool.java b/jdk/src/share/classes/sun/nio/ch/ThreadPool.java
new file mode 100644
index 0000000..37e6a80
--- /dev/null
+++ b/jdk/src/share/classes/sun/nio/ch/ThreadPool.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.ch;
+
+import java.util.concurrent.*;
+import java.security.AccessController;
+import sun.security.action.GetPropertyAction;
+import sun.security.action.GetIntegerAction;
+
+/**
+ * Encapsulates a thread pool associated with a channel group.
+ */
+
+public class ThreadPool {
+    private static final String DEFAULT_THREAD_POOL_THREAD_FACTORY =
+        "java.nio.channels.DefaultThreadPool.threadFactory";
+    private static final String DEFAULT_THREAD_POOL_INITIAL_SIZE =
+        "java.nio.channels.DefaultThreadPool.initialSize";
+    private static final ThreadFactory defaultThreadFactory = new ThreadFactory() {
+         @Override
+         public Thread newThread(Runnable r) {
+             Thread t = new Thread(r);
+             t.setDaemon(true);
+             return t;
+        }
+     };
+
+    private final ExecutorService executor;
+
+    // indicates if thread pool is fixed size
+    private final boolean isFixed;
+
+    // indicates the pool size (for a fixed thread pool configuratin this is
+    // the maximum pool size; for other thread pools it is the initial size)
+    private final int poolSize;
+
+    private ThreadPool(ExecutorService executor,
+                       boolean isFixed,
+                       int poolSize)
+    {
+        this.executor = executor;
+        this.isFixed = isFixed;
+        this.poolSize = poolSize;
+    }
+
+    ExecutorService executor() {
+        return executor;
+    }
+
+    boolean isFixedThreadPool() {
+        return isFixed;
+    }
+
+    int poolSize() {
+        return poolSize;
+    }
+
+    static ThreadFactory defaultThreadFactory() {
+        return defaultThreadFactory;
+    }
+
+    private static class DefaultThreadPoolHolder {
+        final static ThreadPool defaultThreadPool = createDefault();
+    }
+
+    // return the default (system-wide) thread pool
+    static ThreadPool getDefault() {
+        return DefaultThreadPoolHolder.defaultThreadPool;
+    }
+
+    // create thread using default settings (configured by system properties)
+    static ThreadPool createDefault() {
+        // default the number of fixed threads to the hardware core count
+        int initialSize = getDefaultThreadPoolInitialSize();
+        if (initialSize < 0)
+            initialSize = Runtime.getRuntime().availableProcessors();
+        // default to thread factory that creates daemon threads
+        ThreadFactory threadFactory = getDefaultThreadPoolThreadFactory();
+        if (threadFactory == null)
+            threadFactory = defaultThreadFactory;
+        // create thread pool
+        ExecutorService executor =
+            new ThreadPoolExecutor(0, Integer.MAX_VALUE,
+                                   Long.MAX_VALUE, TimeUnit.MILLISECONDS,
+                                   new SynchronousQueue<Runnable>(),
+                                   threadFactory);
+        return new ThreadPool(executor, false, initialSize);
+    }
+
+    // create using given parameters
+    static ThreadPool create(int nThreads, ThreadFactory factory) {
+        if (nThreads <= 0)
+            throw new IllegalArgumentException("'nThreads' must be > 0");
+        ExecutorService executor = Executors.newFixedThreadPool(nThreads, factory);
+        return new ThreadPool(executor, true, nThreads);
+    }
+
+    // wrap a user-supplied executor
+    public static ThreadPool wrap(ExecutorService executor, int initialSize) {
+        if (executor == null)
+            throw new NullPointerException("'executor' is null");
+        // attempt to check if cached thread pool
+        if (executor instanceof ThreadPoolExecutor) {
+            int max = ((ThreadPoolExecutor)executor).getMaximumPoolSize();
+            if (max == Integer.MAX_VALUE) {
+                if (initialSize < 0) {
+                    initialSize = Runtime.getRuntime().availableProcessors();
+                } else {
+                   // not a cached thread pool so ignore initial size
+                    initialSize = 0;
+                }
+            }
+        } else {
+            // some other type of thread pool
+            if (initialSize < 0)
+                initialSize = 0;
+        }
+        return new ThreadPool(executor, false, initialSize);
+    }
+
+    private static int getDefaultThreadPoolInitialSize() {
+        String propValue = AccessController.doPrivileged(new
+            GetPropertyAction(DEFAULT_THREAD_POOL_INITIAL_SIZE));
+        if (propValue != null) {
+            try {
+                return Integer.parseInt(propValue);
+            } catch (NumberFormatException x) {
+                throw new Error("Value of property '" + DEFAULT_THREAD_POOL_INITIAL_SIZE +
+                    "' is invalid: " + x);
+            }
+        }
+        return -1;
+    }
+
+    private static ThreadFactory getDefaultThreadPoolThreadFactory() {
+        String propValue = AccessController.doPrivileged(new
+            GetPropertyAction(DEFAULT_THREAD_POOL_THREAD_FACTORY));
+        if (propValue != null) {
+            try {
+                Class<?> c = Class
+                    .forName(propValue, true, ClassLoader.getSystemClassLoader());
+                return ((ThreadFactory)c.newInstance());
+            } catch (ClassNotFoundException x) {
+                throw new Error(x);
+            } catch (InstantiationException x) {
+                throw new Error(x);
+            } catch (IllegalAccessException x) {
+                throw new Error(x);
+            }
+        }
+        return null;
+    }
+}
diff --git a/jdk/src/share/classes/sun/nio/ch/Util.java b/jdk/src/share/classes/sun/nio/ch/Util.java
index 534548f..efdce4a 100644
--- a/jdk/src/share/classes/sun/nio/ch/Util.java
+++ b/jdk/src/share/classes/sun/nio/ch/Util.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2009 Sun Microsystems, Inc.  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
@@ -31,7 +31,6 @@
 import java.nio.ByteBuffer;
 import java.nio.MappedByteBuffer;
 import java.nio.channels.*;
-import java.nio.channels.spi.*;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.*;
@@ -100,6 +99,9 @@
                 return;
             }
         }
+
+        // release memory
+       ((DirectBuffer)buf).cleaner().clean();
     }
 
     private static class SelectorWrapper {
diff --git a/jdk/src/share/classes/sun/nio/fs/AbstractAclFileAttributeView.java b/jdk/src/share/classes/sun/nio/fs/AbstractAclFileAttributeView.java
new file mode 100644
index 0000000..053e3dc
--- /dev/null
+++ b/jdk/src/share/classes/sun/nio/fs/AbstractAclFileAttributeView.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.attribute.*;
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * Base implementation of AclFileAttributeView
+ */
+
+abstract class AbstractAclFileAttributeView
+    implements AclFileAttributeView
+{
+    private static final String OWNER_NAME = "owner";
+    private static final String ACL_NAME = "acl";
+
+    @Override
+    public final String name() {
+        return "acl";
+    }
+
+    @Override
+    public final Object getAttribute(String attribute) throws IOException {
+        if (attribute.equals(OWNER_NAME))
+            return getOwner();
+        if (attribute.equals(ACL_NAME))
+            return getAcl();
+        return null;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public final void setAttribute(String attribute, Object value)
+        throws IOException
+    {
+        if (attribute.equals(OWNER_NAME)) {
+            setOwner((UserPrincipal)value);
+            return;
+        }
+        if (attribute.equals(ACL_NAME)) {
+            setAcl((List<AclEntry>)value);
+            return;
+        }
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public final Map<String,?> readAttributes(String first, String[] rest)
+        throws IOException
+    {
+        boolean acl = false;
+        boolean owner = false;
+
+        if (first.equals(ACL_NAME)) acl = true;
+        else if (first.equals(OWNER_NAME)) owner = true;
+        else if (first.equals("*")) {
+            owner = true;
+            acl = true;
+        }
+
+        if (!acl || !owner) {
+            for (String attribute: rest) {
+                if (attribute.equals("*")) {
+                    owner = true;
+                    acl = true;
+                    break;
+                }
+                if (attribute.equals(ACL_NAME)) {
+                    acl = true;
+                    continue;
+                }
+                if (attribute.equals(OWNER_NAME)) {
+                    owner = true;
+                    continue;
+                }
+            }
+        }
+        Map<String,Object> result = new HashMap<String,Object>(2);
+        if (acl)
+            result.put(ACL_NAME, getAcl());
+        if (owner)
+            result.put(OWNER_NAME, getOwner());
+        return Collections.unmodifiableMap(result);
+    }
+}
diff --git a/jdk/src/share/classes/sun/nio/fs/AbstractBasicFileAttributeView.java b/jdk/src/share/classes/sun/nio/fs/AbstractBasicFileAttributeView.java
new file mode 100644
index 0000000..18cf00d
--- /dev/null
+++ b/jdk/src/share/classes/sun/nio/fs/AbstractBasicFileAttributeView.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.attribute.*;
+import java.io.IOException;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Base implementation of BasicFileAttributeView
+ */
+
+abstract class AbstractBasicFileAttributeView
+    implements BasicFileAttributeView
+{
+    private static final String SIZE_NAME = "size";
+    private static final String CREATION_TIME_NAME = "creationTime";
+    private static final String LAST_ACCESS_TIME_NAME = "lastAccessTime";
+    private static final String LAST_MODIFIED_TIME_NAME = "lastModifiedTime";
+    private static final String RESOLUTION_NAME = "resolution";
+    private static final String FILE_KEY_NAME = "fileKey";
+    private static final String LINK_COUNT_NAME = "linkCount";
+    private static final String IS_DIRECTORY_NAME = "isDirectory";
+    private static final String IS_REGULAR_FILE_NAME = "isRegularFile";
+    private static final String IS_SYMBOLIC_LINK_NAME = "isSymbolicLink";
+    private static final String IS_OTHER_NAME = "isOther";
+
+    protected AbstractBasicFileAttributeView() { }
+
+    @Override
+    public String name() {
+        return "basic";
+    }
+
+    @Override
+    public Object getAttribute(String attribute) throws IOException {
+        BasicFileAttributes attrs = readAttributes();
+        if (attribute.equals(SIZE_NAME))
+            return attrs.size();
+        if (attribute.equals(CREATION_TIME_NAME))
+            return attrs.creationTime();
+        if (attribute.equals(LAST_ACCESS_TIME_NAME))
+            return attrs.lastAccessTime();
+        if (attribute.equals(LAST_MODIFIED_TIME_NAME))
+            return attrs.lastModifiedTime();
+        if (attribute.equals(RESOLUTION_NAME))
+            return attrs.resolution();
+        if (attribute.equals(FILE_KEY_NAME))
+            return attrs.fileKey();
+        if (attribute.equals(LINK_COUNT_NAME))
+            return attrs.linkCount();
+        if (attribute.equals(IS_DIRECTORY_NAME))
+            return attrs.isDirectory();
+        if (attribute.equals(IS_REGULAR_FILE_NAME))
+            return attrs.isRegularFile();
+        if (attribute.equals(IS_SYMBOLIC_LINK_NAME))
+            return attrs.isSymbolicLink();
+        if (attribute.equals(IS_OTHER_NAME))
+            return attrs.isOther();
+        return null;
+    }
+
+    private Long toTimeValue(Object value) {
+        if (value == null)
+            throw new NullPointerException();
+        Long time = (Long)value;
+        if (time < 0L && time != -1L)
+            throw new IllegalArgumentException("time value cannot be negative");
+        return time;
+    }
+
+    @Override
+    public void setAttribute(String attribute, Object value)
+        throws IOException
+    {
+        if (attribute.equals(LAST_MODIFIED_TIME_NAME)) {
+            setTimes(toTimeValue(value), null, null, TimeUnit.MILLISECONDS);
+            return;
+        }
+        if (attribute.equals(LAST_ACCESS_TIME_NAME)) {
+            setTimes(null, toTimeValue(value), null, TimeUnit.MILLISECONDS);
+            return;
+        }
+        if (attribute.equals(CREATION_TIME_NAME)) {
+            setTimes(null, null, toTimeValue(value), TimeUnit.MILLISECONDS);
+            return;
+        }
+        throw new UnsupportedOperationException("'" + attribute +
+            "' is unknown or read-only attribute");
+    }
+
+    /**
+     *
+     */
+    static class AttributesBuilder {
+        private Set<String> set = new HashSet<String>();
+        private Map<String,Object> map = new HashMap<String,Object>();
+        private boolean copyAll;
+
+        private AttributesBuilder(String first, String[] rest) {
+            if (first.equals("*")) {
+                copyAll = true;
+            } else {
+                set.add(first);
+                // copy names into the given Set bailing out if "*" is found
+                for (String attribute: rest) {
+                    if (attribute.equals("*")) {
+                        copyAll = true;
+                        break;
+                    }
+                    set.add(attribute);
+                }
+            }
+        }
+
+        /**
+         * Creates builder to build up a map of the matching attributes
+         */
+        static AttributesBuilder create(String first, String[] rest) {
+            return new AttributesBuilder(first, rest);
+        }
+
+        /**
+         * Returns true if the attribute should be returned in the map
+         */
+        boolean match(String attribute) {
+            if (copyAll)
+                return true;
+            return set.contains(attribute);
+        }
+
+        void add(String attribute, Object value) {
+            map.put(attribute, value);
+        }
+
+        /**
+         * Returns the map. Discard all references to the AttributesBuilder
+         * after invoking this method.
+         */
+        Map<String,Object> unmodifiableMap() {
+            return Collections.unmodifiableMap(map);
+        }
+    }
+
+    /**
+     * Invoked by readAttributes or sub-classes to add all matching basic
+     * attributes to the builder
+     */
+    final void addBasicAttributesToBuilder(BasicFileAttributes attrs,
+                                           AttributesBuilder builder)
+    {
+        if (builder.match(SIZE_NAME))
+            builder.add(SIZE_NAME, attrs.size());
+        if (builder.match(CREATION_TIME_NAME))
+            builder.add(CREATION_TIME_NAME, attrs.creationTime());
+        if (builder.match(LAST_ACCESS_TIME_NAME))
+            builder.add(LAST_ACCESS_TIME_NAME, attrs.lastAccessTime());
+        if (builder.match(LAST_MODIFIED_TIME_NAME))
+            builder.add(LAST_MODIFIED_TIME_NAME, attrs.lastModifiedTime());
+        if (builder.match(RESOLUTION_NAME))
+            builder.add(RESOLUTION_NAME, attrs.resolution());
+        if (builder.match(FILE_KEY_NAME))
+            builder.add(FILE_KEY_NAME, attrs.fileKey());
+        if (builder.match(LINK_COUNT_NAME))
+            builder.add(LINK_COUNT_NAME, attrs.linkCount());
+        if (builder.match(IS_DIRECTORY_NAME))
+            builder.add(IS_DIRECTORY_NAME, attrs.isDirectory());
+        if (builder.match(IS_REGULAR_FILE_NAME))
+            builder.add(IS_REGULAR_FILE_NAME, attrs.isRegularFile());
+        if (builder.match(IS_SYMBOLIC_LINK_NAME))
+            builder.add(IS_SYMBOLIC_LINK_NAME, attrs.isSymbolicLink());
+        if (builder.match(IS_OTHER_NAME))
+            builder.add(IS_OTHER_NAME, attrs.isOther());
+    }
+
+    @Override
+    public Map<String,?> readAttributes(String first, String[] rest)
+        throws IOException
+    {
+        AttributesBuilder builder = AttributesBuilder.create(first, rest);
+        addBasicAttributesToBuilder(readAttributes(), builder);
+        return builder.unmodifiableMap();
+    }
+}
diff --git a/jdk/src/share/classes/sun/nio/fs/AbstractFileStoreSpaceAttributeView.java b/jdk/src/share/classes/sun/nio/fs/AbstractFileStoreSpaceAttributeView.java
new file mode 100644
index 0000000..73c8c2a
--- /dev/null
+++ b/jdk/src/share/classes/sun/nio/fs/AbstractFileStoreSpaceAttributeView.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.attribute.*;
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * Base implementation of FileStoreSpaceAttributeView
+ */
+
+abstract class AbstractFileStoreSpaceAttributeView
+    implements FileStoreSpaceAttributeView
+{
+    private static final String TOTAL_SPACE_NAME = "totalSpace";
+    private static final String USABLE_SPACE_NAME = "usableSpace";
+    private static final String UNALLOCATED_SPACE_NAME = "unallocatedSpace";
+
+    @Override
+    public final String name() {
+        return "space";
+    }
+
+    @Override
+    public final Object getAttribute(String attribute) throws IOException {
+        FileStoreSpaceAttributes attrs = readAttributes();
+        if (attribute.equals(TOTAL_SPACE_NAME))
+            return attrs.totalSpace();
+        if (attribute.equals(USABLE_SPACE_NAME))
+            return attrs.usableSpace();
+        if (attribute.equals(UNALLOCATED_SPACE_NAME))
+            return attrs.unallocatedSpace();
+        return null;
+    }
+
+    @Override
+    public final void setAttribute(String attribute, Object value)
+        throws IOException
+    {
+        if (attribute == null || value == null)
+            throw new NullPointerException();
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public final Map<String,?> readAttributes(String first, String[] rest)
+        throws IOException
+    {
+        boolean total = false;
+        boolean usable = false;
+        boolean unallocated = false;
+
+        if (first.equals(TOTAL_SPACE_NAME)) total = true;
+        else if (first.equals(USABLE_SPACE_NAME)) usable = true;
+        else if (first.equals(UNALLOCATED_SPACE_NAME)) unallocated = true;
+        else if (first.equals("*")) {
+            total = true;
+            usable = true;
+            unallocated = true;
+        }
+
+        if (!total || !usable || !unallocated) {
+            for (String attribute: rest) {
+                if (attribute.equals("*")) {
+                    total = true;
+                    usable = true;
+                    unallocated = true;
+                    break;
+                }
+                if (attribute.equals(TOTAL_SPACE_NAME)) {
+                    total = true;
+                    continue;
+                }
+                if (attribute.equals(USABLE_SPACE_NAME)) {
+                    usable = true;
+                    continue;
+                }
+                if (attribute.equals(UNALLOCATED_SPACE_NAME)) {
+                    unallocated = true;
+                    continue;
+                }
+            }
+        }
+
+        FileStoreSpaceAttributes attrs = readAttributes();
+        Map<String,Object> result = new HashMap<String,Object>(2);
+        if (total)
+            result.put(TOTAL_SPACE_NAME, attrs.totalSpace());
+        if (usable)
+            result.put(USABLE_SPACE_NAME, attrs.usableSpace());
+        if (unallocated)
+            result.put(UNALLOCATED_SPACE_NAME, attrs.unallocatedSpace());
+        return Collections.unmodifiableMap(result);
+    }
+}
diff --git a/jdk/src/share/classes/sun/nio/fs/AbstractFileTypeDetector.java b/jdk/src/share/classes/sun/nio/fs/AbstractFileTypeDetector.java
new file mode 100644
index 0000000..d8a391b
--- /dev/null
+++ b/jdk/src/share/classes/sun/nio/fs/AbstractFileTypeDetector.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.FileRef;
+import java.nio.file.spi.FileTypeDetector;
+import java.io.IOException;
+import sun.nio.fs.MimeType;
+
+/**
+ * Base implementation of FileTypeDetector
+ */
+
+public abstract class AbstractFileTypeDetector
+    extends FileTypeDetector
+{
+    protected AbstractFileTypeDetector() {
+        super();
+    }
+
+    /**
+     * Invokes the implProbeContentType method to guess the file's content type,
+     * and this validates that the content type's syntax is valid.
+     */
+    @Override
+    public final String probeContentType(FileRef file) throws IOException {
+        if (file == null)
+            throw new NullPointerException("'file' is null");
+        String result = implProbeContentType(file);
+        if (result != null) {
+            // check the content type
+            try {
+                MimeType.parse(result);
+            } catch (IllegalArgumentException ignore) {
+                result = null;
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Probes the given file to guess its content type.
+     */
+    protected abstract String implProbeContentType(FileRef file)
+        throws IOException;
+}
diff --git a/jdk/src/share/classes/sun/nio/fs/AbstractPoller.java b/jdk/src/share/classes/sun/nio/fs/AbstractPoller.java
new file mode 100644
index 0000000..3ab8af8
--- /dev/null
+++ b/jdk/src/share/classes/sun/nio/fs/AbstractPoller.java
@@ -0,0 +1,290 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.*;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * Base implementation of background poller thread used in watch service
+ * implementations. A poller thread waits on events from the file system and
+ * also services "requests" from clients to register for new events or cancel
+ * existing registrations.
+ */
+
+abstract class AbstractPoller implements Runnable {
+
+    // list of requests pending to the poller thread
+    private final LinkedList<Request> requestList;
+
+    // set to true when shutdown
+    private boolean shutdown;
+
+    protected AbstractPoller() {
+        this.requestList = new LinkedList<Request>();
+        this.shutdown = false;
+    }
+
+    /**
+     * Starts the poller thread
+     */
+    public void start() {
+        final Runnable thisRunnable = this;
+        AccessController.doPrivileged(new PrivilegedAction<Object>() {
+            @Override
+            public Object run() {
+                Thread thr = new Thread(thisRunnable);
+                thr.setDaemon(true);
+                thr.start();
+                return null;
+            }
+         });
+    }
+
+    /**
+     * Wakeup poller thread so that it can service pending requests
+     */
+    abstract void wakeup() throws IOException;
+
+    /**
+     * Executed by poller thread to register directory for changes
+     */
+    abstract Object implRegister(Path path,
+                                 Set<? extends WatchEvent.Kind<?>> events,
+                                 WatchEvent.Modifier... modifiers);
+
+    /**
+     * Executed by poller thread to cancel key
+     */
+    abstract void implCancelKey(WatchKey key);
+
+    /**
+     * Executed by poller thread to shutdown and cancel all keys
+     */
+    abstract void implCloseAll();
+
+    /**
+     * Requests, and waits on, poller thread to register given file.
+     */
+    final WatchKey register(FileRef dir,
+                            WatchEvent.Kind<?>[] events,
+                            WatchEvent.Modifier... modifiers)
+        throws IOException
+    {
+        // validate arguments before request to poller
+        if (dir == null)
+            throw new NullPointerException();
+        if (events.length == 0)
+            throw new IllegalArgumentException("No events to register");
+        Set<WatchEvent.Kind<?>> eventSet = new HashSet<WatchEvent.Kind<?>>(events.length);
+        for (WatchEvent.Kind<?> event: events) {
+            // standard events
+            if (event == StandardWatchEventKind.ENTRY_CREATE ||
+                event == StandardWatchEventKind.ENTRY_MODIFY ||
+                event == StandardWatchEventKind.ENTRY_DELETE)
+            {
+                eventSet.add(event);
+                continue;
+            }
+
+            // OVERFLOW is ignored
+            if (event == StandardWatchEventKind.OVERFLOW) {
+                if (events.length == 1)
+                    throw new IllegalArgumentException("No events to register");
+                continue;
+            }
+
+            // null/unsupported
+            if (event == null)
+                throw new NullPointerException("An element in event set is 'null'");
+            throw new UnsupportedOperationException(event.name());
+        }
+        return (WatchKey)invoke(RequestType.REGISTER, dir, eventSet, modifiers);
+    }
+
+    /**
+     * Cancels, and waits on, poller thread to cancel given key.
+     */
+    final void cancel(WatchKey key) {
+        try {
+            invoke(RequestType.CANCEL, key);
+        } catch (IOException x) {
+            // should not happen
+            throw new AssertionError(x.getMessage());
+        }
+    }
+
+    /**
+     * Shutdown poller thread
+     */
+    final void close() throws IOException {
+        invoke(RequestType.CLOSE);
+    }
+
+    /**
+     * Types of request that the poller thread must handle
+     */
+    private static enum RequestType {
+        REGISTER,
+        CANCEL,
+        CLOSE;
+    }
+
+    /**
+     * Encapsulates a request (command) to the poller thread.
+     */
+    private static class Request {
+        private final RequestType type;
+        private final Object[] params;
+
+        private boolean completed = false;
+        private Object result = null;
+
+        Request(RequestType type, Object... params) {
+            this.type = type;
+            this.params = params;
+        }
+
+        RequestType type() {
+            return type;
+        }
+
+        Object[] parameters() {
+            return params;
+        }
+
+        void release(Object result) {
+            synchronized (this) {
+                this.completed = true;
+                this.result = result;
+                notifyAll();
+            }
+        }
+
+        /**
+         * Await completion of the request. The return value is the result of
+         * the request.
+         */
+        Object awaitResult() {
+            synchronized (this) {
+                while (!completed) {
+                    try {
+                        wait();
+                    } catch (InterruptedException x) {
+                        // ignore
+                    }
+                }
+                return result;
+            }
+        }
+    }
+
+    /**
+     * Enqueues request to poller thread and waits for result
+     */
+    private Object invoke(RequestType type, Object... params) throws IOException {
+        // submit request
+        Request req = new Request(type, params);
+        synchronized (requestList) {
+            if (shutdown) {
+                throw new ClosedWatchServiceException();
+            }
+            requestList.add(req);
+        }
+
+        // wakeup thread
+        wakeup();
+
+        // wait for result
+        Object result = req.awaitResult();
+
+        if (result instanceof RuntimeException)
+            throw (RuntimeException)result;
+        if (result instanceof IOException )
+            throw (IOException)result;
+        return result;
+    }
+
+    /**
+     * Invoked by poller thread to process all pending requests
+     *
+     * @return  true if poller thread should shutdown
+     */
+    @SuppressWarnings("unchecked")
+    boolean processRequests() {
+        synchronized (requestList) {
+            Request req;
+            while ((req = requestList.poll()) != null) {
+                // if in process of shutdown then reject request
+                if (shutdown) {
+                    req.release(new ClosedWatchServiceException());
+                }
+
+                switch (req.type()) {
+                    /**
+                     * Register directory
+                     */
+                    case REGISTER: {
+                        Object[] params = req.parameters();
+                        Path path = (Path)params[0];
+                        Set<? extends WatchEvent.Kind<?>> events =
+                            (Set<? extends WatchEvent.Kind<?>>)params[1];
+                        WatchEvent.Modifier[] modifiers =
+                            (WatchEvent.Modifier[])params[2];
+                        req.release(implRegister(path, events, modifiers));
+                        break;
+                    }
+                    /**
+                     * Cancel existing key
+                     */
+                    case CANCEL : {
+                        Object[] params = req.parameters();
+                        WatchKey key = (WatchKey)params[0];
+                        implCancelKey(key);
+                        req.release(null);
+                        break;
+                    }
+                    /**
+                     * Close watch service
+                     */
+                    case CLOSE: {
+                        implCloseAll();
+                        req.release(null);
+                        shutdown = true;
+                        break;
+                    }
+
+                    default:
+                        req.release(new IOException("request not recognized"));
+                }
+            }
+        }
+        return shutdown;
+    }
+}
diff --git a/jdk/src/share/classes/sun/nio/fs/AbstractUserDefinedFileAttributeView.java b/jdk/src/share/classes/sun/nio/fs/AbstractUserDefinedFileAttributeView.java
new file mode 100644
index 0000000..3ac9b50
--- /dev/null
+++ b/jdk/src/share/classes/sun/nio/fs/AbstractUserDefinedFileAttributeView.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.ByteBuffer;
+import java.nio.file.attribute.UserDefinedFileAttributeView;
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * Base implementation of NamedAttributeView
+ */
+
+abstract class AbstractUserDefinedFileAttributeView
+    implements UserDefinedFileAttributeView
+{
+    protected AbstractUserDefinedFileAttributeView() { }
+
+    protected void checkAccess(String file,
+                               boolean checkRead,
+                               boolean checkWrite)
+    {
+        assert checkRead || checkWrite;
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            if (checkRead)
+                sm.checkRead(file);
+            if (checkWrite)
+                sm.checkWrite(file);
+            sm.checkPermission(new RuntimePermission("accessUserDefinedAttributes"));
+        }
+    }
+
+    @Override
+    public final String name() {
+        return "xattr";
+    }
+
+    @Override
+    public final Object getAttribute(String attribute) throws IOException {
+        int size;
+        try {
+            size = size(attribute);
+        } catch (IOException e) {
+            // not found or some other I/O error
+            if (list().contains(attribute))
+                throw e;
+            return null;
+        }
+        byte[] buf = new byte[size];
+        int n = read(attribute, ByteBuffer.wrap(buf));
+        return (n == size) ? buf : Arrays.copyOf(buf, n);
+    }
+
+    @Override
+    public final void setAttribute(String attribute, Object value)
+        throws IOException
+    {
+        ByteBuffer bb;
+        if (value instanceof byte[]) {
+            bb = ByteBuffer.wrap((byte[])value);
+        } else {
+            bb = (ByteBuffer)value;
+        }
+        write(attribute, bb);
+    }
+
+    @Override
+    public final Map<String,?> readAttributes(String first, String... rest)
+        throws IOException
+    {
+        // names of attributes to return
+        List<String> names = new ArrayList<String>();
+
+        boolean readAll = false;
+        if (first.equals("*")) {
+            readAll = true;
+        } else {
+            names.add(first);
+        }
+        for (String name: rest) {
+            if (name.equals("*")) {
+                readAll = true;
+            } else {
+                names.add(name);
+            }
+        }
+        if (readAll)
+            names = list();
+
+        // read each value and return in map
+        Map<String,Object> result = new HashMap<String,Object>();
+        for (String name: names) {
+            Object value = getAttribute(name);
+            if (value != null)
+                result.put(name, value);
+        }
+
+        return result;
+    }
+}
diff --git a/jdk/src/share/classes/sun/nio/fs/AbstractWatchKey.java b/jdk/src/share/classes/sun/nio/fs/AbstractWatchKey.java
new file mode 100644
index 0000000..8e33f81
--- /dev/null
+++ b/jdk/src/share/classes/sun/nio/fs/AbstractWatchKey.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.*;
+import java.util.*;
+
+/**
+ * Base implementation class for watch keys.
+ */
+
+abstract class AbstractWatchKey extends WatchKey {
+
+    /**
+     * Maximum size of event list (in the future this may be tunable)
+     */
+    static final int MAX_EVENT_LIST_SIZE    = 512;
+
+    /**
+     * Special event to signal overflow
+     */
+    static final Event<Void> OVERFLOW_EVENT =
+        new Event<Void>(StandardWatchEventKind.OVERFLOW, null);
+
+    /**
+     * Possible key states
+     */
+    private static enum State { READY, SIGNALLED };
+
+    // reference to watcher
+    private final AbstractWatchService watcher;
+
+    // key state
+    private State state;
+
+    // pending events
+    private List<WatchEvent<?>> events;
+
+    protected AbstractWatchKey(AbstractWatchService watcher) {
+        this.watcher = watcher;
+        this.state = State.READY;
+        this.events = new ArrayList<WatchEvent<?>>();
+    }
+
+    final AbstractWatchService watcher() {
+        return watcher;
+    }
+
+    /**
+     * Enqueues this key to the watch service
+     */
+    final void signal() {
+        synchronized (this) {
+            if (state == State.READY) {
+                state = State.SIGNALLED;
+                watcher.enqueueKey(this);
+            }
+        }
+    }
+
+    /**
+     * Adds the event to this key and signals it.
+     */
+    @SuppressWarnings("unchecked")
+    final void signalEvent(WatchEvent.Kind<?> kind, Object context) {
+        synchronized (this) {
+            int size = events.size();
+            if (size > 1) {
+                // don't let list get too big
+                if (size >= MAX_EVENT_LIST_SIZE) {
+                    kind = StandardWatchEventKind.OVERFLOW;
+                    context = null;
+                }
+
+                // repeated event
+                WatchEvent<?> prev = events.get(size-1);
+                if (kind == prev.kind()) {
+                    boolean isRepeat;
+                    if (context == null) {
+                        isRepeat = (prev.context() == null);
+                    } else {
+                        isRepeat = context.equals(prev.context());
+                    }
+                    if (isRepeat) {
+                        ((Event<?>)prev).increment();
+                        return;
+                    }
+                }
+            }
+
+            // non-repeated event
+            events.add(new Event<Object>((WatchEvent.Kind<Object>)kind, context));
+            signal();
+        }
+    }
+
+    @Override
+    public final List<WatchEvent<?>> pollEvents() {
+        synchronized (this) {
+            List<WatchEvent<?>> result = events;
+            events = new ArrayList<WatchEvent<?>>();
+            return result;
+        }
+    }
+
+    @Override
+    public final boolean reset() {
+        synchronized (this) {
+            if (state == State.SIGNALLED && isValid()) {
+                if (events.isEmpty()) {
+                    state = State.READY;
+                } else {
+                    // pending events so re-queue key
+                    watcher.enqueueKey(this);
+                }
+            }
+            return isValid();
+        }
+    }
+
+    /**
+     * WatchEvent implementation
+     */
+    private static class Event<T> extends WatchEvent<T> {
+        private final WatchEvent.Kind<T> kind;
+        private final T context;
+
+        // synchronize on watch key to access/increment count
+        private int count;
+
+        Event(WatchEvent.Kind<T> type, T context) {
+            this.kind = type;
+            this.context = context;
+            this.count = 1;
+        }
+
+        @Override
+        public WatchEvent.Kind<T> kind() {
+            return kind;
+        }
+
+        @Override
+        public T context() {
+            return context;
+        }
+
+        @Override
+        public int count() {
+            return count;
+        }
+
+        // for repeated events
+        void increment() {
+            count++;
+        }
+    }
+}
diff --git a/jdk/src/share/classes/sun/nio/fs/AbstractWatchService.java b/jdk/src/share/classes/sun/nio/fs/AbstractWatchService.java
new file mode 100644
index 0000000..c29d78b
--- /dev/null
+++ b/jdk/src/share/classes/sun/nio/fs/AbstractWatchService.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.*;
+import java.util.concurrent.*;
+import java.io.IOException;
+
+/**
+ * Base implementation class for watch services.
+ */
+
+abstract class AbstractWatchService extends WatchService {
+
+    // signaled keys waiting to be dequeued
+    private final LinkedBlockingDeque<WatchKey> pendingKeys =
+        new LinkedBlockingDeque<WatchKey>();
+
+    // special key to indicate that watch service is closed
+    private final WatchKey CLOSE_KEY =
+        new AbstractWatchKey(null) {
+            @Override
+            public boolean isValid() {
+                return true;
+            }
+
+            @Override
+            public void cancel() {
+            }
+        };
+
+    // used when closing watch service
+    private volatile boolean closed;
+    private Object closeLock = new Object();
+
+    protected AbstractWatchService() {
+    }
+
+    /**
+     * Register the given object with this watch service
+     */
+    abstract WatchKey register(Path path,
+                               WatchEvent.Kind<?>[] events,
+                               WatchEvent.Modifier... modifers)
+        throws IOException;
+
+    // used by AbstractWatchKey to enqueue key
+    final void enqueueKey(WatchKey key) {
+        pendingKeys.offer(key);
+    }
+
+    /**
+     * Throws ClosedWatchServiceException if watch service is closed
+     */
+    private void checkOpen() {
+        if (closed)
+            throw new ClosedWatchServiceException();
+    }
+
+    /**
+     * Checks the key isn't the special CLOSE_KEY used to unblock threads when
+     * the watch service is closed.
+     */
+    private void checkKey(WatchKey key) {
+        if (key == CLOSE_KEY) {
+            // re-queue in case there are other threads blocked in take/poll
+            enqueueKey(key);
+        }
+        checkOpen();
+    }
+
+    @Override
+    public final WatchKey  poll() {
+        checkOpen();
+        WatchKey key = pendingKeys.poll();
+        checkKey(key);
+        return key;
+    }
+
+    @Override
+    public final WatchKey poll(long timeout, TimeUnit unit)
+        throws InterruptedException
+    {
+        checkOpen();
+        WatchKey key = pendingKeys.poll(timeout, unit);
+        checkKey(key);
+        return key;
+    }
+
+    @Override
+    public final WatchKey take()
+        throws InterruptedException
+    {
+        checkOpen();
+        WatchKey key = pendingKeys.take();
+        checkKey(key);
+        return key;
+    }
+
+    /**
+     * Tells whether or not this watch service is open.
+     */
+    final boolean isOpen() {
+        return !closed;
+    }
+
+    /**
+     * Retrieves the object upon which the close method synchronizes.
+     */
+    final Object closeLock() {
+        return closeLock;
+    }
+
+    /**
+     * Closes this watch service. This method is invoked by the close
+     * method to perform the actual work of closing the watch service.
+     */
+    abstract void implClose() throws IOException;
+
+    @Override
+    public final void close()
+        throws IOException
+    {
+        synchronized (closeLock) {
+            // nothing to do if already closed
+            if (closed)
+                return;
+            closed = true;
+
+            implClose();
+
+            // clear pending keys and queue special key to ensure that any
+            // threads blocked in take/poll wakeup
+            pendingKeys.clear();
+            pendingKeys.offer(CLOSE_KEY);
+        }
+    }
+}
diff --git a/jdk/src/share/classes/sun/nio/fs/BasicFileAttributesHolder.java b/jdk/src/share/classes/sun/nio/fs/BasicFileAttributesHolder.java
new file mode 100644
index 0000000..28f8691
--- /dev/null
+++ b/jdk/src/share/classes/sun/nio/fs/BasicFileAttributesHolder.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.attribute.BasicFileAttributes;
+
+/**
+ * Implemented by objects that may hold or cache the attributes of a file.
+ */
+
+public interface BasicFileAttributesHolder {
+    /**
+     * Returns cached attributes (may be null). If file is a symbolic link then
+     * the attributes are the link attributes and not the final target of the
+     * file.
+     */
+    BasicFileAttributes get();
+
+    /**
+     * Invalidates cached attributes
+     */
+    void invalidate();
+}
diff --git a/jdk/src/share/classes/sun/nio/fs/Cancellable.java b/jdk/src/share/classes/sun/nio/fs/Cancellable.java
new file mode 100644
index 0000000..3b40ddd1
--- /dev/null
+++ b/jdk/src/share/classes/sun/nio/fs/Cancellable.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import sun.misc.Unsafe;
+import java.util.concurrent.ExecutionException;
+
+/**
+ * Base implementation of a task (typically native) that polls a memory location
+ * during execution so that it may be aborted/cancelled before completion. The
+ * task is executed by invoking the {@link runInterruptibly} method defined
+ * here and cancelled by invoking Thread.interrupt.
+ */
+
+abstract class Cancellable implements Runnable {
+    private static final Unsafe unsafe = Unsafe.getUnsafe();
+
+    private final long pollingAddress;
+    private final Object lock = new Object();
+
+    // the following require lock when examining or changing
+    private boolean completed;
+    private Throwable exception;
+
+    protected Cancellable() {
+        pollingAddress = unsafe.allocateMemory(4);
+        unsafe.putIntVolatile(null, pollingAddress, 0);
+    }
+
+    /**
+     * Returns the memory address of a 4-byte int that should be polled to
+     * detect cancellation.
+     */
+    protected long addressToPollForCancel() {
+        return pollingAddress;
+    }
+
+    /**
+     * The value to write to the polled memory location to indicate that the
+     * task has been cancelled. If this method is not overridden then it
+     * defaults to MAX_VALUE.
+     */
+    protected int cancelValue() {
+        return Integer.MAX_VALUE;
+    }
+
+    /**
+     * "cancels" the task by writing bits into memory location that it polled
+     * by the task.
+     */
+    final void cancel() {
+        synchronized (lock) {
+            if (!completed) {
+                unsafe.putIntVolatile(null, pollingAddress, cancelValue());
+            }
+        }
+    }
+
+    /**
+     * Returns the exception thrown by the task or null if the task completed
+     * successfully.
+     */
+    private Throwable exception() {
+        synchronized (lock) {
+            return exception;
+        }
+    }
+
+    @Override
+    public final void run() {
+        try {
+            implRun();
+        } catch (Throwable t) {
+            synchronized (lock) {
+                exception = t;
+            }
+        } finally {
+            synchronized (lock) {
+                completed = true;
+                unsafe.freeMemory(pollingAddress);
+            }
+        }
+    }
+
+    /**
+     * The task body. This should periodically poll the memory location
+     * to check for cancellation.
+     */
+    abstract void implRun() throws Throwable;
+
+    /**
+     * Invokes the given task in its own thread. If this (meaning the current)
+     * thread is interrupted then an attempt is make to cancel the background
+     * thread by writing into the memory location that it polls cooperatively.
+     */
+    static void runInterruptibly(Cancellable task) throws ExecutionException {
+        Thread t = new Thread(task);
+        t.start();
+        boolean cancelledByInterrupt = false;
+        while (t.isAlive()) {
+            try {
+                t.join();
+            } catch (InterruptedException e) {
+                cancelledByInterrupt = true;
+                task.cancel();
+            }
+        }
+        if (cancelledByInterrupt)
+            Thread.currentThread().interrupt();
+        Throwable exc = task.exception();
+        if (exc != null)
+            throw new ExecutionException(exc);
+    }
+}
diff --git a/jdk/src/share/classes/sun/nio/fs/FileOwnerAttributeViewImpl.java b/jdk/src/share/classes/sun/nio/fs/FileOwnerAttributeViewImpl.java
new file mode 100644
index 0000000..f40c2a7
--- /dev/null
+++ b/jdk/src/share/classes/sun/nio/fs/FileOwnerAttributeViewImpl.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.attribute.*;
+import java.util.*;
+import java.io.IOException;
+
+/**
+ * An implementation of FileOwnerAttributeView that delegates to a given
+ * PosixFileAttributeView or AclFileAttributeView object.
+ */
+
+final class FileOwnerAttributeViewImpl implements FileOwnerAttributeView {
+    private static final String OWNER_NAME = "owner";
+
+    private final FileAttributeView view;
+    private final boolean isPosixView;
+
+    FileOwnerAttributeViewImpl(PosixFileAttributeView view) {
+        this.view = view;
+        this.isPosixView = true;
+    }
+
+    FileOwnerAttributeViewImpl(AclFileAttributeView view) {
+        this.view = view;
+        this.isPosixView = false;
+    }
+
+    @Override
+    public String name() {
+        return "owner";
+    }
+
+    @Override
+    public Object getAttribute(String attribute) throws IOException {
+        if (attribute.equals(OWNER_NAME))
+            return getOwner();
+        return null;
+    }
+
+    @Override
+    public void setAttribute(String attribute, Object value)
+        throws IOException
+    {
+        if (attribute.equals(OWNER_NAME)) {
+            setOwner((UserPrincipal)value);
+            return;
+        }
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Map<String,?> readAttributes(String first, String[] rest) throws IOException {
+        Map<String,Object> result = new HashMap<String,Object>();
+        if (first.equals("*") || first.equals(OWNER_NAME)) {
+            result.put(OWNER_NAME, getOwner());
+        } else {
+            for (String attribute: rest) {
+                if (attribute.equals("*") || attribute.equals(OWNER_NAME)) {
+                    result.put(OWNER_NAME, getOwner());
+                    break;
+                }
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public UserPrincipal getOwner() throws IOException {
+        if (isPosixView) {
+            return ((PosixFileAttributeView)view).readAttributes().owner();
+        } else {
+            return ((AclFileAttributeView)view).getOwner();
+        }
+    }
+
+    @Override
+    public void setOwner(UserPrincipal owner)
+        throws IOException
+    {
+        if (isPosixView) {
+            ((PosixFileAttributeView)view).setOwner(owner);
+        } else {
+            ((AclFileAttributeView)view).setOwner(owner);
+        }
+    }
+ }
diff --git a/jdk/src/share/classes/sun/nio/fs/Globs.java b/jdk/src/share/classes/sun/nio/fs/Globs.java
new file mode 100644
index 0000000..33857ea
--- /dev/null
+++ b/jdk/src/share/classes/sun/nio/fs/Globs.java
@@ -0,0 +1,217 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.util.regex.PatternSyntaxException;
+
+public class Globs {
+    private Globs() { }
+
+    private static final String regexMetaChars = ".^$+{[]|()";
+    private static final String globMetaChars = "\\*?[{";
+
+    private static boolean isRegexMeta(char c) {
+        return regexMetaChars.indexOf(c) != -1;
+    }
+
+    private static boolean isGlobMeta(char c) {
+        return globMetaChars.indexOf(c) != -1;
+    }
+    private static char EOL = 0;  //TBD
+
+    private static char next(String glob, int i) {
+        if (i < glob.length()) {
+            return glob.charAt(i);
+        }
+        return EOL;
+    }
+
+    /**
+     * Creates a regex pattern from the given glob expression.
+     *
+     * @throws  PatternSyntaxException
+     */
+    private static String toRegexPattern(String globPattern, boolean isDos) {
+        boolean inGroup = false;
+        StringBuilder regex = new StringBuilder("^");
+
+        int i = 0;
+        while (i < globPattern.length()) {
+            char c = globPattern.charAt(i++);
+            switch (c) {
+                case '\\':
+                    // escape special characters
+                    if (i == globPattern.length()) {
+                        throw new PatternSyntaxException("No character to escape",
+                                globPattern, i - 1);
+                    }
+                    char next = globPattern.charAt(i++);
+                    if (isGlobMeta(next) || isRegexMeta(next)) {
+                        regex.append('\\');
+                    }
+                    regex.append(next);
+                    break;
+                case '/':
+                    if (isDos) {
+                        regex.append("\\\\");
+                    } else {
+                        regex.append(c);
+                    }
+                    break;
+                case '[':
+                    // don't match name separator in class
+                    if (isDos) {
+                        regex.append("[[^\\\\]&&[");
+                    } else {
+                        regex.append("[[^/]&&[");
+                    }
+                    if (next(globPattern, i) == '^') {
+                        // escape the regex negation char if it appears
+                        regex.append("\\^");
+                        i++;
+                    } else {
+                        // negation
+                        if (next(globPattern, i) == '!') {
+                            regex.append('^');
+                            i++;
+                        }
+                        // hyphen allowed at start
+                        if (next(globPattern, i) == '-') {
+                            regex.append('-');
+                            i++;
+                        }
+                    }
+                    boolean hasRangeStart = false;
+                    char last = 0;
+                    while (i < globPattern.length()) {
+                        c = globPattern.charAt(i++);
+                        if (c == ']') {
+                            break;
+                        }
+                        if (c == '/' || (isDos && c == '\\')) {
+                            throw new PatternSyntaxException("Explicit 'name separator' in class",
+                                    globPattern, i - 1);
+                        }
+                        // TBD: how to specify ']' in a class?
+                        if (c == '\\' || c == '[' ||
+                                c == '&' && next(globPattern, i) == '&') {
+                            // escape '\', '[' or "&&" for regex class
+                            regex.append('\\');
+                        }
+                        regex.append(c);
+
+                        if (c == '-') {
+                            if (!hasRangeStart) {
+                                throw new PatternSyntaxException("Invalid range",
+                                        globPattern, i - 1);
+                            }
+                            if ((c = next(globPattern, i++)) == EOL || c == ']') {
+                                break;
+                            }
+                            if (c < last) {
+                                throw new PatternSyntaxException("Invalid range",
+                                        globPattern, i - 3);
+                            }
+                            regex.append(c);
+                            hasRangeStart = false;
+                        } else {
+                            hasRangeStart = true;
+                            last = c;
+                        }
+                    }
+                    if (c != ']') {
+                        throw new PatternSyntaxException("Missing ']", globPattern, i - 1);
+                    }
+                    regex.append("]]");
+                    break;
+                case '{':
+                    if (inGroup) {
+                        throw new PatternSyntaxException("Cannot nest groups",
+                                globPattern, i - 1);
+                    }
+                    regex.append("(?:(?:");
+                    inGroup = true;
+                    break;
+                case '}':
+                    if (inGroup) {
+                        regex.append("))");
+                        inGroup = false;
+                    } else {
+                        regex.append('}');
+                    }
+                    break;
+                case ',':
+                    if (inGroup) {
+                        regex.append(")|(?:");
+                    } else {
+                        regex.append(',');
+                    }
+                    break;
+                case '*':
+                    if (next(globPattern, i) == '*') {
+                        // crosses directory boundaries
+                        regex.append(".*");
+                        i++;
+                    } else {
+                        // within directory boundary
+                        if (isDos) {
+                            regex.append("[^\\\\]*");
+                        } else {
+                            regex.append("[^/]*");
+                        }
+                    }
+                    break;
+                case '?':
+                   if (isDos) {
+                       regex.append("[^\\\\]");
+                   } else {
+                       regex.append("[^/]");
+                   }
+                   break;
+
+                default:
+                    if (isRegexMeta(c)) {
+                        regex.append('\\');
+                    }
+                    regex.append(c);
+            }
+        }
+
+        if (inGroup) {
+            throw new PatternSyntaxException("Missing '}", globPattern, i - 1);
+        }
+
+        return regex.append('$').toString();
+    }
+
+    static String toUnixRegexPattern(String globPattern) {
+        return toRegexPattern(globPattern, false);
+    }
+
+    static String toWindowsRegexPattern(String globPattern) {
+        return toRegexPattern(globPattern, true);
+    }
+}
diff --git a/jdk/src/share/classes/sun/nio/fs/MimeType.java b/jdk/src/share/classes/sun/nio/fs/MimeType.java
new file mode 100644
index 0000000..053ea44
--- /dev/null
+++ b/jdk/src/share/classes/sun/nio/fs/MimeType.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+/**
+ * Represents a MIME type for the purposes of validation and matching. For
+ * now this class is implemented using the javax.activation.MimeType class but
+ * this dependency can easily be eliminated when required.
+ */
+
+public class MimeType {
+    private final javax.activation.MimeType type;
+
+    private MimeType(javax.activation.MimeType type) {
+        this.type = type;
+    }
+
+    /**
+     * Parses the given string as a MIME type.
+     *
+     * @throws  IllegalArgumentException
+     *          If the string is not a valid MIME type
+     */
+    public static MimeType parse(String type) {
+        try {
+            return new MimeType(new javax.activation.MimeType(type));
+        } catch (javax.activation.MimeTypeParseException x) {
+            throw new IllegalArgumentException(x);
+        }
+    }
+
+    /**
+     * Returns {@code true} if this MIME type has parameters.
+     */
+    public boolean hasParameters() {
+        return !type.getParameters().isEmpty();
+    }
+
+    /**
+     * Matches this MIME type against a given MIME type. This method returns
+     * true if the given string is a MIME type and it matches this type.
+     */
+    public boolean match(String other) {
+        try {
+            return type.match(other);
+        } catch (javax.activation.MimeTypeParseException x) {
+            return false;
+        }
+    }
+}
diff --git a/jdk/src/share/classes/sun/nio/fs/NativeBuffer.java b/jdk/src/share/classes/sun/nio/fs/NativeBuffer.java
new file mode 100644
index 0000000..975c1c2
--- /dev/null
+++ b/jdk/src/share/classes/sun/nio/fs/NativeBuffer.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import sun.misc.Unsafe;
+import sun.misc.Cleaner;
+
+/**
+ * A light-weight buffer in native memory.
+ */
+
+class NativeBuffer {
+    private static final Unsafe unsafe = Unsafe.getUnsafe();
+
+    private final long address;
+    private final int size;
+    private final Cleaner cleaner;
+
+    // optional "owner" to avoid copying
+    // (only safe for use by thread-local caches)
+    private Object owner;
+
+    private static class Deallocator implements Runnable {
+        private final long address;
+        Deallocator(long address) {
+            this.address = address;
+        }
+        public void run() {
+            unsafe.freeMemory(address);
+        }
+    }
+
+    NativeBuffer(int size) {
+        this.address = unsafe.allocateMemory(size);
+        this.size = size;
+        this.cleaner = Cleaner.create(this, new Deallocator(address));
+    }
+
+    void release() {
+        NativeBuffers.releaseNativeBuffer(this);
+    }
+
+    long address() {
+        return address;
+    }
+
+    int size() {
+        return size;
+    }
+
+    Cleaner cleaner() {
+        return cleaner;
+    }
+
+    // not synchronized; only safe for use by thread-local caches
+    void setOwner(Object owner) {
+        this.owner = owner;
+    }
+
+    // not synchronized; only safe for use by thread-local caches
+    Object owner() {
+        return owner;
+    }
+}
diff --git a/jdk/src/share/classes/sun/nio/fs/NativeBuffers.java b/jdk/src/share/classes/sun/nio/fs/NativeBuffers.java
new file mode 100644
index 0000000..fa247a6
--- /dev/null
+++ b/jdk/src/share/classes/sun/nio/fs/NativeBuffers.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import sun.misc.Unsafe;
+
+/**
+ * Factory for native buffers.
+ */
+
+class NativeBuffers {
+    private NativeBuffers() { }
+
+    private static final Unsafe unsafe = Unsafe.getUnsafe();
+
+    private static final int TEMP_BUF_POOL_SIZE = 3;
+    private static ThreadLocal<NativeBuffer[]> threadLocal =
+        new ThreadLocal<NativeBuffer[]>();
+
+    /**
+     * Allocates a native buffer, of at least the given size, from the heap.
+     */
+    static NativeBuffer allocNativeBuffer(int size) {
+        // Make a new one of at least 2k
+        if (size < 2048) size = 2048;
+        return new NativeBuffer(size);
+    }
+
+    /**
+     * Returns a native buffer, of at least the given size, from the thread
+     * local cache.
+     */
+    static NativeBuffer getNativeBufferFromCache(int size) {
+        // return from cache if possible
+        NativeBuffer[] buffers = threadLocal.get();
+        if (buffers != null) {
+            for (int i=0; i<TEMP_BUF_POOL_SIZE; i++) {
+                NativeBuffer buffer = buffers[i];
+                if (buffer != null && buffer.size() >= size) {
+                    buffers[i] = null;
+                    return buffer;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns a native buffer, of at least the given size. The native buffer
+     * is taken from the thread local cache if possible; otherwise it is
+     * allocated from the heap.
+     */
+    static NativeBuffer getNativeBuffer(int size) {
+        NativeBuffer buffer = getNativeBufferFromCache(size);
+        if (buffer != null) {
+            buffer.setOwner(null);
+            return buffer;
+        } else {
+            return allocNativeBuffer(size);
+        }
+    }
+
+    /**
+     * Releases the given buffer. If there is space in the thread local cache
+     * then the buffer goes into the cache; otherwise the memory is deallocated.
+     */
+    static void releaseNativeBuffer(NativeBuffer buffer) {
+        // create cache if it doesn't exist
+        NativeBuffer[] buffers = threadLocal.get();
+        if (buffers == null) {
+            buffers = new NativeBuffer[TEMP_BUF_POOL_SIZE];
+            buffers[0] = buffer;
+            threadLocal.set(buffers);
+            return;
+        }
+        // Put it in an empty slot if such exists
+        for (int i=0; i<TEMP_BUF_POOL_SIZE; i++) {
+            if (buffers[i] == null) {
+                buffers[i] = buffer;
+                return;
+            }
+        }
+        // Otherwise replace a smaller one in the cache if such exists
+        for (int i=0; i<TEMP_BUF_POOL_SIZE; i++) {
+            NativeBuffer existing = buffers[i];
+            if (existing.size() < buffer.size()) {
+                existing.cleaner().clean();
+                buffers[i] = buffer;
+                return;
+            }
+        }
+
+        // free it
+        buffer.cleaner().clean();
+    }
+
+    /**
+     * Copies a byte array and zero terminator into a given native buffer.
+     */
+    static void copyCStringToNativeBuffer(byte[] cstr, NativeBuffer buffer) {
+        long offset = Unsafe.ARRAY_BYTE_BASE_OFFSET;
+        long len = cstr.length;
+        assert buffer.size() >= (len + 1);
+        unsafe.copyMemory(cstr, offset, null, buffer.address(), len);
+        unsafe.putByte(buffer.address() + len, (byte)0);
+    }
+
+    /**
+     * Copies a byte array and zero terminator into a native buffer, returning
+     * the buffer.
+     */
+    static NativeBuffer asNativeBuffer(byte[] cstr) {
+        NativeBuffer buffer = getNativeBuffer(cstr.length+1);
+        copyCStringToNativeBuffer(cstr, buffer);
+        return buffer;
+    }
+}
diff --git a/jdk/src/share/classes/sun/nio/fs/PollingWatchService.java b/jdk/src/share/classes/sun/nio/fs/PollingWatchService.java
new file mode 100644
index 0000000..73a89c2
--- /dev/null
+++ b/jdk/src/share/classes/sun/nio/fs/PollingWatchService.java
@@ -0,0 +1,429 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedExceptionAction;
+import java.security.PrivilegedActionException;
+import java.io.IOException;
+import java.util.*;
+import java.util.concurrent.*;
+import com.sun.nio.file.SensitivityWatchEventModifier;
+
+/**
+ * Simple WatchService implementation that uses periodic tasks to poll
+ * registered directories for changes.  This implementation is for use on
+ * operating systems that do not have native file change notification support.
+ */
+
+class PollingWatchService
+    extends AbstractWatchService
+{
+    // map of registrations
+    private final Map<Object,PollingWatchKey> map =
+        new HashMap<Object,PollingWatchKey>();
+
+    // used to execute the periodic tasks that poll for changes
+    private final ScheduledExecutorService scheduledExecutor;
+
+    PollingWatchService() {
+        // TBD: Make the number of threads configurable
+        scheduledExecutor = Executors
+            .newSingleThreadScheduledExecutor(new ThreadFactory() {
+                 @Override
+                 public Thread newThread(Runnable r) {
+                     Thread t = new Thread(r);
+                     t.setDaemon(true);
+                     return t;
+                 }});
+    }
+
+    /**
+     * Register the given file with this watch service
+     */
+    @Override
+    WatchKey register(final Path path,
+                      WatchEvent.Kind<?>[] events,
+                      WatchEvent.Modifier... modifiers)
+         throws IOException
+    {
+        // check events - CCE will be thrown if there are invalid elements
+        if (events.length == 0)
+            throw new IllegalArgumentException("No events to register");
+        final Set<WatchEvent.Kind<?>> eventSet =
+            new HashSet<WatchEvent.Kind<?>>(events.length);
+        for (WatchEvent.Kind<?> event: events) {
+            // standard events
+            if (event == StandardWatchEventKind.ENTRY_CREATE ||
+                event == StandardWatchEventKind.ENTRY_MODIFY ||
+                event == StandardWatchEventKind.ENTRY_DELETE)
+            {
+                eventSet.add(event);
+                continue;
+            }
+
+            // OVERFLOW is ignored
+            if (event == StandardWatchEventKind.OVERFLOW) {
+                if (events.length == 1)
+                    throw new IllegalArgumentException("No events to register");
+                continue;
+            }
+
+            // null/unsupported
+            if (event == null)
+                throw new NullPointerException("An element in event set is 'null'");
+            throw new UnsupportedOperationException(event.name());
+        }
+
+        // A modifier may be used to specify the sensitivity level
+        SensitivityWatchEventModifier sensivity = SensitivityWatchEventModifier.MEDIUM;
+        if (modifiers.length > 0) {
+            for (WatchEvent.Modifier modifier: modifiers) {
+                if (modifier == null)
+                    throw new NullPointerException();
+                if (modifier instanceof SensitivityWatchEventModifier) {
+                    sensivity = (SensitivityWatchEventModifier)modifier;
+                    continue;
+                }
+                throw new UnsupportedOperationException("Modifier not supported");
+            }
+        }
+
+        // check if watch service is closed
+        if (!isOpen())
+            throw new ClosedWatchServiceException();
+
+        // registration is done in privileged block as it requires the
+        // attributes of the entries in the directory.
+        try {
+            final SensitivityWatchEventModifier s = sensivity;
+            return AccessController.doPrivileged(
+                new PrivilegedExceptionAction<PollingWatchKey>() {
+                    @Override
+                    public PollingWatchKey run() throws IOException {
+                        return doPrivilegedRegister(path, eventSet, s);
+                    }
+                });
+        } catch (PrivilegedActionException pae) {
+            Throwable cause = pae.getCause();
+            if (cause != null && cause instanceof IOException)
+                throw (IOException)cause;
+            throw new AssertionError(pae);
+        }
+    }
+
+    // registers directory returning a new key if not already registered or
+    // existing key if already registered
+    private PollingWatchKey doPrivilegedRegister(Path path,
+                                                 Set<? extends WatchEvent.Kind<?>> events,
+                                                 SensitivityWatchEventModifier sensivity)
+        throws IOException
+    {
+        // check file is a directory and get its file key if possible
+        BasicFileAttributes attrs = Attributes.readBasicFileAttributes(path);
+        if (!attrs.isDirectory()) {
+            throw new NotDirectoryException(path.toString());
+        }
+        Object fileKey = attrs.fileKey();
+        if (fileKey == null)
+            throw new AssertionError("File keys must be supported");
+
+        // grab close lock to ensure that watch service cannot be closed
+        synchronized (closeLock()) {
+            if (!isOpen())
+                throw new ClosedWatchServiceException();
+
+            PollingWatchKey watchKey;
+            synchronized (map) {
+                watchKey = map.get(fileKey);
+                if (watchKey == null) {
+                    // new registration
+                    watchKey = new PollingWatchKey(this, path, fileKey);
+                    map.put(fileKey, watchKey);
+                } else {
+                    // update to existing registration
+                    watchKey.disable();
+                }
+            }
+            watchKey.enable(events, sensivity.sensitivityValueInSeconds());
+            return watchKey;
+        }
+
+    }
+
+    @Override
+    void implClose() throws IOException {
+        synchronized (map) {
+            for (Map.Entry<Object,PollingWatchKey> entry: map.entrySet()) {
+                PollingWatchKey watchKey = entry.getValue();
+                watchKey.disable();
+                watchKey.invalidate();
+            }
+            map.clear();
+        }
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+            @Override
+            public Void run() {
+                scheduledExecutor.shutdown();
+                return null;
+            }
+         });
+    }
+
+    /**
+     * Entry in directory cache to record file last-modified-time and tick-count
+     */
+    private static class CacheEntry {
+        private long lastModified;
+        private int lastTickCount;
+
+        CacheEntry(long lastModified, int lastTickCount) {
+            this.lastModified = lastModified;
+            this.lastTickCount = lastTickCount;
+        }
+
+        int lastTickCount() {
+            return lastTickCount;
+        }
+
+        long lastModified() {
+            return lastModified;
+        }
+
+        void update(long lastModified, int tickCount) {
+            this.lastModified = lastModified;
+            this.lastTickCount = tickCount;
+        }
+    }
+
+    /**
+     * WatchKey implementation that encapsulates a map of the entries of the
+     * entries in the directory. Polling the key causes it to re-scan the
+     * directory and queue keys when entries are added, modified, or deleted.
+     */
+    private class PollingWatchKey extends AbstractWatchKey {
+        private final Path dir;
+        private final Object fileKey;
+
+        // current event set
+        private Set<? extends WatchEvent.Kind<?>> events;
+
+        // the result of the periodic task that causes this key to be polled
+        private ScheduledFuture<?> poller;
+
+        // indicates if the key is valid
+        private volatile boolean valid;
+
+        // used to detect files that have been deleted
+        private int tickCount;
+
+        // map of entries in directory
+        private Map<Path,CacheEntry> entries;
+
+        PollingWatchKey(PollingWatchService watcher,
+                        Path dir,
+                        Object fileKey)
+            throws IOException
+        {
+            super(watcher);
+            this.dir = dir;
+            this.fileKey = fileKey;
+            this.valid = true;
+            this.tickCount = 0;
+            this.entries = new HashMap<Path,CacheEntry>();
+
+            // get the initial entries in the directory
+            DirectoryStream<Path> stream = dir.newDirectoryStream();
+            try {
+                for (Path entry: stream) {
+                    // don't follow links
+                    long lastModified = Attributes
+                        .readBasicFileAttributes(entry, LinkOption.NOFOLLOW_LINKS)
+                        .lastModifiedTime();
+                    entries.put(entry.getName(),
+                                new CacheEntry(lastModified, tickCount));
+                }
+            } catch (ConcurrentModificationException cme) {
+                // thrown if directory iteration fails
+                Throwable cause = cme.getCause();
+                if (cause != null && cause instanceof IOException)
+                    throw (IOException)cause;
+                throw new AssertionError(cme);
+            } finally {
+                stream.close();
+            }
+        }
+
+        FileRef directory() {
+            return dir;
+        }
+
+        Object fileKey() {
+            return fileKey;
+        }
+
+        @Override
+        public boolean isValid() {
+            return valid;
+        }
+
+        void invalidate() {
+            valid = false;
+        }
+
+        // enables periodic polling
+        void enable(Set<? extends WatchEvent.Kind<?>> events, long period) {
+            synchronized (this) {
+                // update the events
+                this.events = events;
+
+                // create the periodic task
+                Runnable thunk = new Runnable() { public void run() { poll(); }};
+                this.poller = scheduledExecutor
+                    .scheduleAtFixedRate(thunk, period, period, TimeUnit.SECONDS);
+            }
+        }
+
+        // disables periodic polling
+        void disable() {
+            synchronized (this) {
+                if (poller != null)
+                    poller.cancel(false);
+            }
+        }
+
+        @Override
+        public void cancel() {
+            valid = false;
+            synchronized (map) {
+                map.remove(fileKey());
+            }
+            disable();
+        }
+
+        /**
+         * Polls the directory to detect for new files, modified files, or
+         * deleted files.
+         */
+        synchronized void poll() {
+            if (!valid) {
+                return;
+            }
+
+            // update tick
+            tickCount++;
+
+            // open directory
+            DirectoryStream<Path> stream = null;
+            try {
+                stream = dir.newDirectoryStream();
+            } catch (IOException x) {
+                // directory is no longer accessible so cancel key
+                cancel();
+                signal();
+                return;
+            }
+
+            // iterate over all entries in directory
+            try {
+                for (Path entry: stream) {
+                    long lastModified = 0L;
+                    try {
+                        lastModified = Attributes
+                            .readBasicFileAttributes(entry, LinkOption.NOFOLLOW_LINKS)
+                            .lastModifiedTime();
+                    } catch (IOException x) {
+                        // unable to get attributes of entry. If file has just
+                        // been deleted then we'll report it as deleted on the
+                        // next poll
+                        continue;
+                    }
+
+                    // lookup cache
+                    CacheEntry e = entries.get(entry.getName());
+                    if (e == null) {
+                        // new file found
+                        entries.put(entry.getName(),
+                                     new CacheEntry(lastModified, tickCount));
+
+                        // queue ENTRY_CREATE if event enabled
+                        if (events.contains(StandardWatchEventKind.ENTRY_CREATE)) {
+                            signalEvent(StandardWatchEventKind.ENTRY_CREATE, entry.getName());
+                            continue;
+                        } else {
+                            // if ENTRY_CREATE is not enabled and ENTRY_MODIFY is
+                            // enabled then queue event to avoid missing out on
+                            // modifications to the file immediately after it is
+                            // created.
+                            if (events.contains(StandardWatchEventKind.ENTRY_MODIFY)) {
+                                signalEvent(StandardWatchEventKind.ENTRY_MODIFY, entry.getName());
+                            }
+                        }
+                        continue;
+                    }
+
+                    // check if file has changed
+                    if (e.lastModified != lastModified) {
+                        if (events.contains(StandardWatchEventKind.ENTRY_MODIFY)) {
+                            signalEvent(StandardWatchEventKind.ENTRY_MODIFY, entry.getName());
+                        }
+                    }
+                    // entry in cache so update poll time
+                    e.update(lastModified, tickCount);
+
+                }
+            } catch (ConcurrentModificationException x) {
+                // FIXME - should handle this
+            } finally {
+
+                // close directory stream
+                try {
+                    stream.close();
+                } catch (IOException x) {
+                    // ignore
+                }
+            }
+
+            // iterate over cache to detect entries that have been deleted
+            Iterator<Map.Entry<Path,CacheEntry>> i = entries.entrySet().iterator();
+            while (i.hasNext()) {
+                Map.Entry<Path,CacheEntry> mapEntry = i.next();
+                CacheEntry entry = mapEntry.getValue();
+                if (entry.lastTickCount() != tickCount) {
+                    Path name = mapEntry.getKey();
+                    // remove from map and queue delete event (if enabled)
+                    i.remove();
+                    if (events.contains(StandardWatchEventKind.ENTRY_DELETE)) {
+                        signalEvent(StandardWatchEventKind.ENTRY_DELETE, name);
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/jdk/src/share/classes/sun/nio/fs/Reflect.java b/jdk/src/share/classes/sun/nio/fs/Reflect.java
new file mode 100644
index 0000000..d425ef2
--- /dev/null
+++ b/jdk/src/share/classes/sun/nio/fs/Reflect.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.lang.reflect.*;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * Utility class for reflection.
+ */
+
+class Reflect {
+    private Reflect() {}
+
+    private static void setAccessible(final AccessibleObject ao) {
+        AccessController.doPrivileged(new PrivilegedAction<Object>() {
+                @Override
+                public Object run() {
+                    ao.setAccessible(true);
+                    return null;
+                }});
+    }
+
+    /**
+     * Lookup the field of a given class.
+     */
+    static Field lookupField(String className, String fieldName) {
+        try {
+            Class<?> cl = Class.forName(className);
+            Field f = cl.getDeclaredField(fieldName);
+            setAccessible(f);
+            return f;
+        } catch (ClassNotFoundException x) {
+            throw new AssertionError(x);
+        } catch (NoSuchFieldException x) {
+            throw new AssertionError(x);
+        }
+    }
+}
diff --git a/jdk/src/share/classes/sun/security/krb5/Realm.java b/jdk/src/share/classes/sun/security/krb5/Realm.java
index 1dbffe2..a34745d 100644
--- a/jdk/src/share/classes/sun/security/krb5/Realm.java
+++ b/jdk/src/share/classes/sun/security/krb5/Realm.java
@@ -39,7 +39,6 @@
 import sun.security.krb5.internal.Krb5;
 import sun.security.util.*;
 import java.io.IOException;
-import java.io.OutputStream;
 import java.util.StringTokenizer;
 import java.util.Vector;
 import java.util.Stack;
@@ -364,7 +363,6 @@
         }
 
         String tempTarget = null, tempRealm = null;
-        StringTokenizer strTok = null;
         Stack<String> iStack = new Stack<String> ();
 
         /*
@@ -382,7 +380,7 @@
             tempTarget = sRealm;
         }
 
-        do {
+        out: do {
             if (DEBUG) {
                 count++;
                 System.out.println(">>> Realm parseCapaths: loop " +
@@ -400,15 +398,21 @@
 
                 /*
                  * We have one or more space-separated intermediary realms.
-                 * Stack them.
+                 * Stack them. A null is always added between intermedies of
+                 * different targets. When this null is popped, it means none
+                 * of the intermedies for this target is useful (because of
+                 * infinite loop), the target is then removed from the partial
+                 * tempList, and the next possible intermediary is tried.
                  */
-                strTok = new StringTokenizer(intermediaries, " ");
-                while (strTok.hasMoreTokens())
+                iStack.push(null);
+                String[] ints = intermediaries.split("\\s+");
+                for (int i = ints.length-1; i>=0; i--)
                 {
-                    tempRealm = strTok.nextToken();
-                    if (!tempRealm.equals(PrincipalName.
-                                          REALM_COMPONENT_SEPARATOR_STR) &&
-                        !iStack.contains(tempRealm)) {
+                    tempRealm = ints[i];
+                    if (tempRealm.equals(PrincipalName.REALM_COMPONENT_SEPARATOR_STR)) {
+                        break out;
+                    }
+                    if (!tempList.contains(tempRealm)) {
                         iStack.push(tempRealm);
                         if (DEBUG) {
                             System.out.println(">>> Realm parseCapaths: loop " +
@@ -418,16 +422,18 @@
                         }
                     } else if (DEBUG) {
                         System.out.println(">>> Realm parseCapaths: loop " +
-
                                            count +
                                            ": ignoring realm: [" +
                                            tempRealm + "]");
                     }
                 }
-            } else if (DEBUG) {
-                System.out.println(">>> Realm parseCapaths: loop " +
-                                   count +
-                                   ": no intermediaries");
+            } else {
+                if (DEBUG) {
+                    System.out.println(">>> Realm parseCapaths: loop " +
+                                       count +
+                                       ": no intermediaries");
+                }
+                break;
             }
 
             /*
@@ -435,7 +441,12 @@
              */
 
             try {
-                tempTarget = iStack.pop();
+                while ((tempTarget = iStack.pop()) == null) {
+                    tempList.removeElementAt(tempList.size()-1);
+                    if (DEBUG) {
+                        System.out.println(">>> Realm parseCapaths: backtrack, remove tail");
+                    }
+                }
             } catch (EmptyStackException exc) {
                 tempTarget = null;
             }
diff --git a/jdk/src/share/classes/sun/security/provider/X509Factory.java b/jdk/src/share/classes/sun/security/provider/X509Factory.java
index 8fc755c..ce0d120 100644
--- a/jdk/src/share/classes/sun/security/provider/X509Factory.java
+++ b/jdk/src/share/classes/sun/security/provider/X509Factory.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1998-2009 Sun Microsystems, Inc.  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
@@ -638,10 +638,15 @@
         // First read all of the data that is found between
         // the "-----BEGIN" and "-----END" boundaries into a buffer.
         String temp;
-        if ((temp=readLine(br))==null || !temp.startsWith("-----BEGIN")) {
-            throw new IOException("Unsupported encoding");
-        } else {
+        while (true) {
+            temp=readLine(br);
+            if (temp == null) {
+                throw new IOException("Unsupported encoding");
+            }
             len += temp.length();
+            if (temp.startsWith("-----BEGIN")) {
+                break;
+            }
         }
         StringBuffer strBuf = new StringBuffer();
         while ((temp=readLine(br))!=null && !temp.startsWith("-----END")) {
@@ -683,22 +688,11 @@
      * Determines if input is binary or Base64 encoded.
      */
     private boolean isBase64(InputStream is) throws IOException {
-        if (is.available() >= 10) {
-            is.mark(10);
+        if (is.available() >= 1) {
+            is.mark(1);
             int c1 = is.read();
-            int c2 = is.read();
-            int c3 = is.read();
-            int c4 = is.read();
-            int c5 = is.read();
-            int c6 = is.read();
-            int c7 = is.read();
-            int c8 = is.read();
-            int c9 = is.read();
-            int c10 = is.read();
             is.reset();
-            if (c1 == '-' && c2 == '-' && c3 == '-' && c4 == '-'
-                && c5 == '-' && c6 == 'B' && c7 == 'E' && c8 == 'G'
-                && c9 == 'I' && c10 == 'N') {
+            if (c1 != DerValue.tag_Sequence) {
                 return true;
             } else {
                 return false;
diff --git a/jdk/src/share/classes/sun/security/ssl/AppInputStream.java b/jdk/src/share/classes/sun/security/ssl/AppInputStream.java
index d638b8f..2ca8895 100644
--- a/jdk/src/share/classes/sun/security/ssl/AppInputStream.java
+++ b/jdk/src/share/classes/sun/security/ssl/AppInputStream.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 1996-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1996-2009 Sun Microsystems, Inc.  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
@@ -81,6 +81,14 @@
      */
     public synchronized int read(byte b[], int off, int len)
             throws IOException {
+        if (b == null) {
+            throw new NullPointerException();
+        } else if (off < 0 || len < 0 || len > b.length - off) {
+            throw new IndexOutOfBoundsException();
+        } else if (len == 0) {
+            return 0;
+        }
+
         if (c.checkEOF()) {
             return -1;
         }
diff --git a/jdk/src/share/classes/sun/security/ssl/AppOutputStream.java b/jdk/src/share/classes/sun/security/ssl/AppOutputStream.java
index d039cac..d8c78a8 100644
--- a/jdk/src/share/classes/sun/security/ssl/AppOutputStream.java
+++ b/jdk/src/share/classes/sun/security/ssl/AppOutputStream.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 1996-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1996-2009 Sun Microsystems, Inc.  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
@@ -58,18 +58,25 @@
      */
     synchronized public void write(byte b[], int off, int len)
             throws IOException {
+        if (b == null) {
+            throw new NullPointerException();
+        } else if (off < 0 || len < 0 || len > b.length - off) {
+            throw new IndexOutOfBoundsException();
+        } else if (len == 0) {
+            return;
+        }
+
         // check if the Socket is invalid (error or closed)
         c.checkWrite();
-        //
+
         // Always flush at the end of each application level record.
         // This lets application synchronize read and write streams
         // however they like; if we buffered here, they couldn't.
-        //
-        // NOTE: *must* call c.writeRecord() even for len == 0
         try {
             do {
                 int howmuch = Math.min(len, r.availableDataBytes());
 
+                // NOTE: *must* call c.writeRecord() even for howmuch == 0
                 if (howmuch > 0) {
                     r.write(b, off, howmuch);
                     off += howmuch;
diff --git a/jdk/src/share/classes/sun/security/ssl/ByteBufferInputStream.java b/jdk/src/share/classes/sun/security/ssl/ByteBufferInputStream.java
index 9c484d8..d69e2bf 100644
--- a/jdk/src/share/classes/sun/security/ssl/ByteBufferInputStream.java
+++ b/jdk/src/share/classes/sun/security/ssl/ByteBufferInputStream.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-2009 Sun Microsystems, Inc.  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
@@ -89,8 +89,7 @@
 
         if (b == null) {
             throw new NullPointerException();
-        } else if ((off < 0) || (off > b.length) || (len < 0) ||
-                   ((off + len) > b.length) || ((off + len) < 0)) {
+        } else if (off < 0 || len < 0 || len > b.length - off) {
             throw new IndexOutOfBoundsException();
         } else if (len == 0) {
             return 0;
diff --git a/jdk/src/share/classes/sun/security/ssl/SSLSessionContextImpl.java b/jdk/src/share/classes/sun/security/ssl/SSLSessionContextImpl.java
index c98f1cc..3aeef2d 100644
--- a/jdk/src/share/classes/sun/security/ssl/SSLSessionContextImpl.java
+++ b/jdk/src/share/classes/sun/security/ssl/SSLSessionContextImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1999-2009 Sun Microsystems, Inc.  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
@@ -41,88 +41,112 @@
 import javax.net.ssl.SSLPeerUnverifiedException;
 import javax.net.ssl.SSLSession;
 
-import sun.misc.Cache;
+import sun.security.util.Cache;
 
 
-final class SSLSessionContextImpl implements SSLSessionContext
-{
-    private Cache       sessionCache = new Cache();
-    private Cache       sessionHostPortCache = new Cache();
-    private int         cacheLimit;
-    private long        timeoutMillis;
+final class SSLSessionContextImpl implements SSLSessionContext {
+    private Cache sessionCache;         // session cache, session id as key
+    private Cache sessionHostPortCache; // session cache, "host:port" as key
+    private int cacheLimit;             // the max cache size
+    private int timeout;                // timeout in seconds
+
     private static final Debug debug = Debug.getInstance("ssl");
 
-    // file private
-    SSLSessionContextImpl()
-    {
-        cacheLimit = getCacheLimit();
-        timeoutMillis = 86400000; // default, 24 hours
+    // package private
+    SSLSessionContextImpl() {
+        cacheLimit = getDefaultCacheLimit();    // default cache size
+        timeout = 86400;                        // default, 24 hours
+
+        // use soft reference
+        sessionCache = Cache.newSoftMemoryCache(cacheLimit, timeout);
+        sessionHostPortCache = Cache.newSoftMemoryCache(cacheLimit, timeout);
     }
 
     /**
-     * Returns the SSL session object associated with the
-     * specific session ID passed.
+     * Returns the <code>SSLSession</code> bound to the specified session id.
      */
-    public SSLSession   getSession(byte[] id)
-    {
-        SSLSession sess = (SSLSession) sessionCache.get(
-                                new SessionId(id));
-        return checkTimeValidity(sess);
+    public SSLSession getSession(byte[] sessionId) {
+        if (sessionId == null) {
+            throw new NullPointerException("session id cannot be null");
+        }
+
+        SSLSessionImpl sess =
+                (SSLSessionImpl)sessionCache.get(new SessionId(sessionId));
+        if (!isTimedout(sess)) {
+            return sess;
+        }
+
+        return null;
     }
 
     /**
      * Returns an enumeration of the active SSL sessions.
      */
     public Enumeration<byte[]> getIds() {
-        Vector<byte[]> v = new Vector<byte[]>(sessionCache.size());
-        SessionId sessId;
+        SessionCacheVisitor scVisitor = new SessionCacheVisitor();
+        sessionCache.accept(scVisitor);
 
-        for (Enumeration e = sessionCache.keys(); e.hasMoreElements(); ) {
-            sessId = (SessionId) e.nextElement();
-            if (!isTimedout((SSLSession)sessionCache.get(sessId)))
-                v.addElement(sessId.getId());
-        }
-        return v.elements();
+        return scVisitor.getSessionIds();
     }
 
+    /**
+     * Sets the timeout limit for cached <code>SSLSession</code> objects
+     *
+     * Note that after reset the timeout, the cached session before
+     * should be timed within the shorter one of the old timeout and the
+     * new timeout.
+     */
     public void setSessionTimeout(int seconds)
                  throws IllegalArgumentException {
-        if (seconds < 0)
+        if (seconds < 0) {
             throw new IllegalArgumentException();
-        timeoutMillis = seconds * 1000L;
+        }
+
+        if (timeout != seconds) {
+            sessionCache.setTimeout(seconds);
+            sessionHostPortCache.setTimeout(seconds);
+            timeout = seconds;
+        }
     }
 
+    /**
+     * Gets the timeout limit for cached <code>SSLSession</code> objects
+     */
     public int getSessionTimeout() {
-        return (int) (timeoutMillis / 1000);
+        return timeout;
     }
 
+    /**
+     * Sets the size of the cache used for storing
+     * <code>SSLSession</code> objects.
+     */
     public void setSessionCacheSize(int size)
                  throws IllegalArgumentException {
         if (size < 0)
             throw new IllegalArgumentException();
-        cacheLimit = size;
 
-        /**
-         * If cache size limit is reduced, when the cache is full to its
-         * previous limit, trim the cache before its contents
-         * are used.
-         */
-        if ((cacheLimit != 0) && (sessionCache.size() > cacheLimit))
-            adjustCacheSizeTo(cacheLimit);
+        if (cacheLimit != size) {
+            sessionCache.setCapacity(size);
+            sessionHostPortCache.setCapacity(size);
+            cacheLimit = size;
+        }
     }
 
+    /**
+     * Gets the size of the cache used for storing
+     * <code>SSLSession</code> objects.
+     */
     public int getSessionCacheSize() {
         return cacheLimit;
     }
 
+
+    // package-private method, used ONLY by ServerHandshaker
     SSLSessionImpl get(byte[] id) {
-        return (SSLSessionImpl) getSession(id);
+        return (SSLSessionImpl)getSession(id);
     }
 
-    /**
-     * Returns the SSL session object associated with the
-     * specific host name and port number passed.
-     */
+    // package-private method, used ONLY by ClientHandshaker
     SSLSessionImpl get(String hostname, int port) {
         /*
          * If no session caching info is available, we won't
@@ -131,96 +155,51 @@
         if (hostname == null && port == -1) {
             return null;
         }
-        SSLSession sess =  (SSLSessionImpl) sessionHostPortCache
-                                .get(getKey(hostname, port));
-        return (SSLSessionImpl) checkTimeValidity(sess);
+
+        SSLSessionImpl sess =
+            (SSLSessionImpl)sessionHostPortCache.get(getKey(hostname, port));
+        if (!isTimedout(sess)) {
+            return sess;
+        }
+
+        return null;
     }
 
     private String getKey(String hostname, int port) {
-        return (hostname + ":" + String.valueOf(port))
-                        .toLowerCase();
+        return (hostname + ":" + String.valueOf(port)).toLowerCase();
     }
 
+    // cache a SSLSession
+    //
+    // In SunJSSE implementation, a session is created while getting a
+    // client hello or a server hello message, and cached while the
+    // handshaking finished.
+    // Here we time the session from the time it cached instead of the
+    // time it created, which is a little longer than the expected. So
+    // please do check isTimedout() while getting entry from the cache.
     void put(SSLSessionImpl s) {
-        // make space for the new session to be added
-        if ((cacheLimit != 0) && (sessionCache.size() >= cacheLimit))
-            adjustCacheSizeTo(cacheLimit - 1);
-
-        /*
-         * Can always add the session id.
-         */
         sessionCache.put(s.getSessionId(), s);
 
-        /*
-         * If no hostname/port info is available, don't add this one.
-         */
+        // If no hostname/port info is available, don't add this one.
         if ((s.getPeerHost() != null) && (s.getPeerPort() != -1)) {
             sessionHostPortCache.put(
                 getKey(s.getPeerHost(), s.getPeerPort()), s);
         }
+
         s.setContext(this);
     }
 
-    private void adjustCacheSizeTo(int targetSize) {
-
-        int cacheSize = sessionCache.size();
-
-        if (targetSize < 0)
-           return;
-
-        while (cacheSize > targetSize) {
-            SSLSessionImpl lru = null;
-            SSLSessionImpl s = null;
-            Enumeration e;
-
-            if (debug != null && Debug.isOn("sessioncache")) {
-                System.out.println("exceeded cache limit of " + cacheLimit);
-            }
-
-            /*
-             * Count the number of elements in the cache. The size() method
-             * does not reflect the cache entries that are no longer available,
-             * i.e entries that are garbage collected (the cache entries are
-             * held using soft references and are garbage collected when not
-             * in use).
-             */
-            int count;
-            for (count = 0, e = sessionCache.elements();
-                         e.hasMoreElements(); count++) {
-                try {
-                    s = (SSLSessionImpl)e.nextElement();
-                } catch (NoSuchElementException nsee) {
-                    break;
-                }
-                if (isTimedout(s)) {
-                    lru = s;
-                    break;
-                } else if ((lru == null) || (s.getLastAccessedTime()
-                         < lru.getLastAccessedTime())) {
-                    lru = s;
-                }
-            }
-            if ((lru != null) && (count > targetSize)) {
-                if (debug != null && Debug.isOn("sessioncache")) {
-                    System.out.println("uncaching " + lru);
-                }
-                lru.invalidate();
-                count--; // element removed from the cache
-            }
-            cacheSize = count;
+    // package-private method, remove a cached SSLSession
+    void remove(SessionId key) {
+        SSLSessionImpl s = (SSLSessionImpl)sessionCache.get(key);
+        if (s != null) {
+            sessionCache.remove(key);
+            sessionHostPortCache.remove(
+                        getKey(s.getPeerHost(), s.getPeerPort()));
         }
     }
 
-    // file private
-    void remove(SessionId key)
-    {
-        SSLSessionImpl s = (SSLSessionImpl) sessionCache.get(key);
-        sessionCache.remove(key);
-        sessionHostPortCache.remove(getKey(s.getPeerHost(),
-                                         s.getPeerPort()));
-    }
-
-    private int getCacheLimit() {
+    private int getDefaultCacheLimit() {
         int cacheLimit = 0;
         try {
         String s = java.security.AccessController.doPrivileged(
@@ -237,21 +216,40 @@
         return (cacheLimit > 0) ? cacheLimit : 0;
     }
 
-    SSLSession checkTimeValidity(SSLSession sess) {
-        if (isTimedout(sess)) {
-            sess.invalidate();
-            return null;
-        } else
-            return sess;
-    }
-
     boolean isTimedout(SSLSession sess) {
-        if (timeoutMillis == 0)
+        if (timeout == 0) {
             return false;
-        if ((sess != null) &&
-            ((sess.getCreationTime() + timeoutMillis)
-                <= (System.currentTimeMillis())))
+        }
+
+        if ((sess != null) && ((sess.getCreationTime() + timeout * 1000L)
+                                        <= (System.currentTimeMillis()))) {
+            sess.invalidate();
             return true;
+        }
+
         return false;
     }
+
+    final class SessionCacheVisitor
+            implements sun.security.util.Cache.CacheVisitor {
+        Vector<byte[]> ids = null;
+
+        // public void visit(java.util.Map<Object, Object> map) {}
+        public void visit(java.util.Map<Object, Object> map) {
+            ids = new Vector<byte[]>(map.size());
+
+            for (Object key : map.keySet()) {
+                SSLSessionImpl value = (SSLSessionImpl)map.get(key);
+                if (!isTimedout(value)) {
+                    ids.addElement(((SessionId)key).getId());
+                }
+            }
+        }
+
+        public Enumeration<byte[]> getSessionIds() {
+            return  ids != null ? ids.elements() :
+                                  new Vector<byte[]>().elements();
+        }
+    }
+
 }
diff --git a/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java b/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java
index 7974f1b..820954f 100644
--- a/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java
+++ b/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 1996-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1996-2009 Sun Microsystems, Inc.  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
@@ -368,7 +368,9 @@
         super();
         this.host = host;
         init(context, false);
-        SocketAddress socketAddress = new InetSocketAddress(host, port);
+        SocketAddress socketAddress =
+               host != null ? new InetSocketAddress(host, port) :
+               new InetSocketAddress(InetAddress.getByName(null), port);
         connect(socketAddress, 0);
     }
 
@@ -409,7 +411,9 @@
         this.host = host;
         init(context, false);
         bind(new InetSocketAddress(localAddr, localPort));
-        SocketAddress socketAddress = new InetSocketAddress(host, port);
+        SocketAddress socketAddress =
+               host != null ? new InetSocketAddress(host, port) :
+               new InetSocketAddress(InetAddress.getByName(null), port);
         connect(socketAddress, 0);
     }
 
@@ -1829,7 +1833,8 @@
     }
 
     synchronized String getHost() {
-        if (host == null) {
+        // Note that the host may be null or empty for localhost.
+        if (host == null || host.length() == 0) {
             host = getInetAddress().getHostName();
         }
         return host;
diff --git a/jdk/src/share/classes/sun/security/tools/KeyTool.java b/jdk/src/share/classes/sun/security/tools/KeyTool.java
index 220dbd0..e99c40d 100644
--- a/jdk/src/share/classes/sun/security/tools/KeyTool.java
+++ b/jdk/src/share/classes/sun/security/tools/KeyTool.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc.  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
@@ -69,6 +69,10 @@
 import javax.net.ssl.SSLSession;
 import javax.net.ssl.TrustManager;
 import javax.net.ssl.X509TrustManager;
+import sun.misc.BASE64Decoder;
+import sun.security.pkcs.PKCS10Attribute;
+import sun.security.pkcs.PKCS9Attribute;
+import sun.security.util.DerValue;
 import sun.security.x509.*;
 
 import static java.security.KeyStore.*;
@@ -85,7 +89,6 @@
  *
  * @since 1.2
  */
-
 public final class KeyTool {
 
     private boolean debug = false;
@@ -100,6 +103,8 @@
     private String dname = null;
     private String dest = null;
     private String filename = null;
+    private String infilename = null;
+    private String outfilename = null;
     private String srcksfname = null;
 
     // User-specified providers are added before any command is called.
@@ -117,7 +122,6 @@
     private char[] storePassNew = null;
     private char[] keyPass = null;
     private char[] keyPassNew = null;
-    private char[] oldPass = null;
     private char[] newPass = null;
     private char[] destKeyPass = null;
     private char[] srckeyPass = null;
@@ -140,6 +144,8 @@
     private Set<char[]> passwords = new HashSet<char[]> ();
     private String startDate = null;
 
+    private List <String> v3ext = new ArrayList <String> ();
+
     private static final int CERTREQ = 1;
     private static final int CHANGEALIAS = 2;
     private static final int DELETE = 3;
@@ -156,6 +162,8 @@
     private static final int PRINTCERT = 13;
     private static final int SELFCERT = 14;
     private static final int STOREPASSWD = 15;
+    private static final int GENCERT = 16;
+    private static final int PRINTCERTREQ = 17;
 
     private static final Class[] PARAM_STRING = { String.class };
 
@@ -184,7 +192,9 @@
     private void run(String[] args, PrintStream out) throws Exception {
         try {
             parseArgs(args);
-            doCommands(out);
+            if (command != -1) {
+                doCommands(out);
+            }
         } catch (Exception e) {
             System.out.println(rb.getString("keytool error: ") + e);
             if (verbose) {
@@ -214,7 +224,10 @@
      */
     void parseArgs(String[] args) {
 
-        if (args.length == 0) usage();
+        if (args.length == 0) {
+            usage();
+            return;
+        }
 
         int i=0;
 
@@ -260,6 +273,10 @@
                 command = IMPORTKEYSTORE;
             } else if (collator.compare(flags, "-genseckey") == 0) {
                 command = GENSECKEY;
+            } else if (collator.compare(flags, "-gencert") == 0) {
+                command = GENCERT;
+            } else if (collator.compare(flags, "-printcertreq") == 0) {
+                command = PRINTCERTREQ;
             }
 
             /*
@@ -337,9 +354,18 @@
             } else if (collator.compare(flags, "-validity") == 0) {
                 if (++i == args.length) errorNeedArgument(flags);
                 validity = Long.parseLong(args[i]);
+            } else if (collator.compare(flags, "-ext") == 0) {
+                if (++i == args.length) errorNeedArgument(flags);
+                v3ext.add(args[i]);
             } else if (collator.compare(flags, "-file") == 0) {
                 if (++i == args.length) errorNeedArgument(flags);
                 filename = args[i];
+            } else if (collator.compare(flags, "-infile") == 0) {
+                if (++i == args.length) errorNeedArgument(flags);
+                infilename = args[i];
+            } else if (collator.compare(flags, "-outfile") == 0) {
+                if (++i == args.length) errorNeedArgument(flags);
+                outfilename = args[i];
             } else if (collator.compare(flags, "-sslserver") == 0) {
                 if (++i == args.length) errorNeedArgument(flags);
                 sslserver = args[i];
@@ -364,7 +390,7 @@
                     }
                 }
                 providers.add(
-                        new Pair<String, String>(providerClass, providerArg));
+                        Pair.of(providerClass, providerArg));
             }
 
             /*
@@ -404,6 +430,10 @@
         }
     }
 
+    boolean isKeyStoreRelated(int cmd) {
+        return cmd != PRINTCERT && cmd != PRINTCERTREQ;
+    }
+
     /**
      * Execute the commands.
      */
@@ -568,7 +598,7 @@
         // the default, which is located in $HOME/.keystore.
         // If the command is "genkey", "identitydb", "import", or "printcert",
         // it is OK not to have a keystore.
-        if (command != PRINTCERT) {
+        if (isKeyStoreRelated(command)) {
             if (ksfname == null) {
                 ksfname = System.getProperty("user.home") + File.separator
                     + ".keystore";
@@ -721,7 +751,7 @@
                 }
             } else if (!protectedPath
                     && !KeyStoreUtil.isWindowsKeyStore(storetype)
-                    && !(command == PRINTCERT)) {
+                    && isKeyStoreRelated(command)) {
                 // here we have EXPORTCERT and LIST (info valid until STOREPASSWD)
                 System.err.print(rb.getString("Enter keystore password:  "));
                 System.err.flush();
@@ -763,7 +793,7 @@
 
         // Create a certificate factory
         if (command == PRINTCERT || command == IMPORTCERT
-               || command == IDENTITYDB) {
+                || command == IDENTITYDB) {
             cf = CertificateFactory.getInstance("X509");
         }
 
@@ -930,6 +960,41 @@
                 storePassNew = getNewPasswd("keystore password", storePass);
             }
             kssave = true;
+        } else if (command == GENCERT) {
+            if (alias == null) {
+                alias = keyAlias;
+            }
+            InputStream inStream = System.in;
+            if (infilename != null) {
+                inStream = new FileInputStream(infilename);
+            }
+            PrintStream ps = null;
+            if (outfilename != null) {
+                ps = new PrintStream(new FileOutputStream(outfilename));
+                out = ps;
+            }
+            try {
+                doGenCert(alias, sigAlgName, inStream, out);
+            } finally {
+                if (inStream != System.in) {
+                    inStream.close();
+                }
+                if (ps != null) {
+                    ps.close();
+                }
+            }
+        } else if (command == PRINTCERTREQ) {
+            InputStream inStream = System.in;
+            if (filename != null) {
+                inStream = new FileInputStream(filename);
+            }
+            try {
+                doPrintCertReq(inStream, out);
+            } finally {
+                if (inStream != System.in) {
+                    inStream.close();
+                }
+            }
         }
 
         // If we need to save the keystore, do so.
@@ -962,6 +1027,91 @@
     }
 
     /**
+     * Generate a certificate: Read PKCS10 request from in, and print
+     * certificate to out. Use alias as CA, sigAlgName as the signature
+     * type.
+     */
+    private void doGenCert(String alias, String sigAlgName, InputStream in, PrintStream out)
+            throws Exception {
+
+
+        Certificate signerCert = keyStore.getCertificate(alias);
+        byte[] encoded = signerCert.getEncoded();
+        X509CertImpl signerCertImpl = new X509CertImpl(encoded);
+        X509CertInfo signerCertInfo = (X509CertInfo)signerCertImpl.get(
+                X509CertImpl.NAME + "." + X509CertImpl.INFO);
+        X500Name owner = (X500Name)signerCertInfo.get(X509CertInfo.SUBJECT + "." +
+                                           CertificateSubjectName.DN_NAME);
+
+        Date firstDate = getStartDate(startDate);
+        Date lastDate = new Date();
+        lastDate.setTime(firstDate.getTime() + validity*1000L*24L*60L*60L);
+        CertificateValidity interval = new CertificateValidity(firstDate,
+                                                               lastDate);
+
+        PrivateKey privateKey = (PrivateKey)recoverKey(alias, storePass, keyPass).fst;
+        if (sigAlgName == null) {
+            sigAlgName = getCompatibleSigAlgName(privateKey.getAlgorithm());
+        }
+        Signature signature = Signature.getInstance(sigAlgName);
+        signature.initSign(privateKey);
+
+        X500Signer signer = new X500Signer(signature, owner);
+
+        X509CertInfo info = new X509CertInfo();
+        info.set(X509CertInfo.VALIDITY, interval);
+        info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber
+                 ((int)(firstDate.getTime()/1000)));
+        info.set(X509CertInfo.VERSION,
+                     new CertificateVersion(CertificateVersion.V3));
+        info.set(X509CertInfo.ALGORITHM_ID,
+                     new CertificateAlgorithmId(signer.getAlgorithmId()));
+        info.set(X509CertInfo.ISSUER,
+                     new CertificateIssuerName(signer.getSigner()));
+
+        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+        boolean canRead = false;
+        StringBuffer sb = new StringBuffer();
+        while (true) {
+            String s = reader.readLine();
+            if (s == null) break;
+            // OpenSSL does not use NEW
+            //if (s.startsWith("-----BEGIN NEW CERTIFICATE REQUEST-----")) {
+            if (s.startsWith("-----BEGIN") && s.indexOf("REQUEST") >= 0) {
+                canRead = true;
+            //} else if (s.startsWith("-----END NEW CERTIFICATE REQUEST-----")) {
+            } else if (s.startsWith("-----END") && s.indexOf("REQUEST") >= 0) {
+                break;
+            } else if (canRead) {
+                sb.append(s);
+            }
+        }
+        byte[] rawReq = new BASE64Decoder().decodeBuffer(new String(sb));
+        PKCS10 req = new PKCS10(rawReq);
+
+        info.set(X509CertInfo.KEY, new CertificateX509Key(req.getSubjectPublicKeyInfo()));
+        info.set(X509CertInfo.SUBJECT, new CertificateSubjectName(req.getSubjectName()));
+        CertificateExtensions reqex = null;
+        Iterator<PKCS10Attribute> attrs = req.getAttributes().getAttributes().iterator();
+        while (attrs.hasNext()) {
+            PKCS10Attribute attr = attrs.next();
+            if (attr.getAttributeId().equals(PKCS9Attribute.EXTENSION_REQUEST_OID)) {
+                reqex = (CertificateExtensions)attr.getAttributeValue();
+            }
+        }
+        CertificateExtensions ext = createV3Extensions(
+                reqex,
+                null,
+                v3ext,
+                req.getSubjectPublicKeyInfo(),
+                signerCert.getPublicKey());
+        info.set(X509CertInfo.EXTENSIONS, ext);
+        X509CertImpl cert = new X509CertImpl(info);
+        cert.sign(privateKey, sigAlgName);
+        dumpCert(cert, out);
+    }
+
+    /**
      * Creates a PKCS#10 cert signing request, corresponding to the
      * keys (and name) associated with a given alias.
      */
@@ -972,10 +1122,10 @@
             alias = keyAlias;
         }
 
-        Object[] objs = recoverKey(alias, storePass, keyPass);
-        PrivateKey privKey = (PrivateKey)objs[0];
+        Pair<Key,char[]> objs = recoverKey(alias, storePass, keyPass);
+        PrivateKey privKey = (PrivateKey)objs.fst;
         if (keyPass == null) {
-            keyPass = (char[])objs[1];
+            keyPass = objs.snd;
         }
 
         Certificate cert = keyStore.getCertificate(alias);
@@ -986,21 +1136,14 @@
             throw new Exception(form.format(source));
         }
         PKCS10 request = new PKCS10(cert.getPublicKey());
+        CertificateExtensions ext = createV3Extensions(null, null, v3ext, cert.getPublicKey(), null);
+        // Attribute name is not significant
+        request.getAttributes().setAttribute(X509CertInfo.EXTENSIONS,
+                new PKCS10Attribute(PKCS9Attribute.EXTENSION_REQUEST_OID, ext));
 
         // Construct an X500Signer object, so that we can sign the request
         if (sigAlgName == null) {
-            // If no signature algorithm was specified at the command line,
-            // we choose one that is compatible with the selected private key
-            String keyAlgName = privKey.getAlgorithm();
-            if ("DSA".equalsIgnoreCase(keyAlgName)
-                   || "DSS".equalsIgnoreCase(keyAlgName)) {
-                sigAlgName = "SHA1WithDSA";
-            } else if ("RSA".equalsIgnoreCase(keyAlgName)) {
-                sigAlgName = "SHA1WithRSA";
-            } else {
-                throw new Exception(rb.getString
-                        ("Cannot derive signature algorithm"));
-            }
+            sigAlgName = getCompatibleSigAlgName(privKey.getAlgorithm());
         }
 
         Signature signature = Signature.getInstance(sigAlgName);
@@ -1153,6 +1296,23 @@
     }
 
     /**
+     * If no signature algorithm was specified at the command line,
+     * we choose one that is compatible with the selected private key
+     */
+    private static String getCompatibleSigAlgName(String keyAlgName)
+            throws Exception {
+        if ("DSA".equalsIgnoreCase(keyAlgName)) {
+            return "SHA1WithDSA";
+        } else if ("RSA".equalsIgnoreCase(keyAlgName)) {
+            return "SHA1WithRSA";
+        } else if ("EC".equalsIgnoreCase(keyAlgName)) {
+            return "SHA1withECDSA";
+        } else {
+            throw new Exception(rb.getString
+                    ("Cannot derive signature algorithm"));
+        }
+    }
+    /**
      * Creates a new key pair and self-signed certificate.
      */
     private void doGenKeyPair(String alias, String dname, String keyAlgName,
@@ -1179,16 +1339,7 @@
         }
 
         if (sigAlgName == null) {
-            if ("DSA".equalsIgnoreCase(keyAlgName)) {
-                sigAlgName = "SHA1WithDSA";
-            } else if ("RSA".equalsIgnoreCase(keyAlgName)) {
-                sigAlgName = "SHA1WithRSA";
-            } else if ("EC".equalsIgnoreCase(keyAlgName)) {
-                sigAlgName = "SHA1withECDSA";
-            } else {
-                throw new Exception(rb.getString
-                        ("Cannot derive signature algorithm"));
-            }
+            sigAlgName = getCompatibleSigAlgName(keyAlgName);
         }
         CertAndKeyGen keypair =
                 new CertAndKeyGen(keyAlgName, sigAlgName, providerName);
@@ -1225,6 +1376,9 @@
             keyPass = promptForKeyPass(alias, null, storePass);
         }
         keyStore.setKeyEntry(alias, privKey, keyPass, chain);
+
+        // resign so that -ext are applied.
+        doSelfCert(alias, null, sigAlgName);
     }
 
     /**
@@ -1247,9 +1401,9 @@
             throw new Exception(form.format(source));
         }
 
-        Object[] objs = recoverEntry(keyStore, orig, storePass, keyPass);
-        Entry entry = (Entry)objs[0];
-        keyPass = (char[])objs[1];
+        Pair<Entry,char[]> objs = recoverEntry(keyStore, orig, storePass, keyPass);
+        Entry entry = objs.fst;
+        keyPass = objs.snd;
 
         PasswordProtection pp = null;
 
@@ -1275,10 +1429,10 @@
         if (alias == null) {
             alias = keyAlias;
         }
-        Object[] objs = recoverKey(alias, storePass, keyPass);
-        Key privKey = (Key)objs[0];
+        Pair<Key,char[]> objs = recoverKey(alias, storePass, keyPass);
+        Key privKey = objs.fst;
         if (keyPass == null) {
-            keyPass = (char[])objs[1];
+            keyPass = objs.snd;
         }
 
         if (keyPassNew == null) {
@@ -1629,8 +1783,8 @@
             }
         }
 
-        Object[] objs = recoverEntry(srckeystore, alias, srcstorePass, srckeyPass);
-        Entry entry = (Entry)objs[0];
+        Pair<Entry,char[]> objs = recoverEntry(srckeystore, alias, srcstorePass, srckeyPass);
+        Entry entry = objs.fst;
 
         PasswordProtection pp = null;
 
@@ -1640,8 +1794,8 @@
         // so always try to protect with destKeyPass.
         if (destKeyPass != null) {
             pp = new PasswordProtection(destKeyPass);
-        } else if (objs[1] != null) {
-            pp = new PasswordProtection((char[])objs[1]);
+        } else if (objs.snd != null) {
+            pp = new PasswordProtection(objs.snd);
         }
 
         try {
@@ -1726,9 +1880,50 @@
         }
     }
 
+    private void doPrintCertReq(InputStream in, PrintStream out)
+            throws Exception {
+
+        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+        StringBuffer sb = new StringBuffer();
+        boolean started = false;
+        while (true) {
+            String s = reader.readLine();
+            if (s == null) break;
+            if (!started) {
+                if (s.startsWith("-----")) {
+                    started = true;
+                }
+            } else {
+                if (s.startsWith("-----")) {
+                    break;
+                }
+                sb.append(s);
+            }
+        }
+        PKCS10 req = new PKCS10(new BASE64Decoder().decodeBuffer(new String(sb)));
+
+        PublicKey pkey = req.getSubjectPublicKeyInfo();
+        out.printf(rb.getString("PKCS #10 Certificate Request (Version 1.0)\n" +
+                "Subject: %s\nPublic Key: %s format %s key\n"),
+                req.getSubjectName(), pkey.getFormat(), pkey.getAlgorithm());
+        for (PKCS10Attribute attr: req.getAttributes().getAttributes()) {
+            ObjectIdentifier oid = attr.getAttributeId();
+            if (oid.equals(PKCS9Attribute.EXTENSION_REQUEST_OID)) {
+                CertificateExtensions exts = (CertificateExtensions)attr.getAttributeValue();
+                printExtensions(rb.getString("Extension Request:"), exts, out);
+            } else {
+                out.println(attr.getAttributeId());
+                out.println(attr.getAttributeValue());
+            }
+        }
+        if (debug) {
+            out.println(req);   // Just to see more, say, public key length...
+        }
+    }
+
     /**
      * Reads a certificate (or certificate chain) and prints its contents in
-     * a human readbable format.
+     * a human readable format.
      */
     private void printCertFromStream(InputStream in, PrintStream out)
         throws Exception
@@ -1840,7 +2035,18 @@
                 inStream = new FileInputStream(filename);
             }
             try {
-                printCertFromStream(inStream, out);
+                // Read the full stream before feeding to X509Factory,
+                // otherwise, keytool -gencert | keytool -printcert
+                // might not work properly, since -gencert is slow
+                // and there's no data in the pipe at the beginning.
+                ByteArrayOutputStream bout = new ByteArrayOutputStream();
+                byte[] b = new byte[4096];
+                while (true) {
+                    int len = inStream.read(b);
+                    if (len < 0) break;
+                    bout.write(b, 0, len);
+                }
+                printCertFromStream(new ByteArrayInputStream(bout.toByteArray()), out);
             } finally {
                 if (inStream != System.in) {
                     inStream.close();
@@ -1859,27 +2065,14 @@
             alias = keyAlias;
         }
 
-        Object[] objs = recoverKey(alias, storePass, keyPass);
-        PrivateKey privKey = (PrivateKey)objs[0];
+        Pair<Key,char[]> objs = recoverKey(alias, storePass, keyPass);
+        PrivateKey privKey = (PrivateKey)objs.fst;
         if (keyPass == null)
-            keyPass = (char[])objs[1];
+            keyPass = objs.snd;
 
         // Determine the signature algorithm
         if (sigAlgName == null) {
-            // If no signature algorithm was specified at the command line,
-            // we choose one that is compatible with the selected private key
-            String keyAlgName = privKey.getAlgorithm();
-            if ("DSA".equalsIgnoreCase(keyAlgName)
-                   || "DSS".equalsIgnoreCase(keyAlgName)) {
-                sigAlgName = "SHA1WithDSA";
-            } else if ("RSA".equalsIgnoreCase(keyAlgName)) {
-                sigAlgName = "SHA1WithRSA";
-            } else if ("EC".equalsIgnoreCase(keyAlgName)) {
-                sigAlgName = "SHA1withECDSA";
-            } else {
-                throw new Exception
-                        (rb.getString("Cannot derive signature algorithm"));
-            }
+            sigAlgName = getCompatibleSigAlgName(privKey.getAlgorithm());
         }
 
         // Get the old certificate
@@ -1943,11 +2136,16 @@
         certInfo.set(CertificateAlgorithmId.NAME + "." +
                      CertificateAlgorithmId.ALGORITHM, sigAlgid);
 
-        // first upgrade to version 3
-
         certInfo.set(X509CertInfo.VERSION,
                         new CertificateVersion(CertificateVersion.V3));
 
+        CertificateExtensions ext = createV3Extensions(
+                null,
+                (CertificateExtensions)certInfo.get(X509CertInfo.EXTENSIONS),
+                v3ext,
+                oldCert.getPublicKey(),
+                null);
+        certInfo.set(X509CertInfo.EXTENSIONS, ext);
         // Sign the new certificate
         newCert = new X509CertImpl(certInfo);
         newCert.sign(privKey, sigAlgName);
@@ -1985,10 +2183,10 @@
             alias = keyAlias;
         }
 
-        Object[] objs = recoverKey(alias, storePass, keyPass);
-        PrivateKey privKey = (PrivateKey)objs[0];
+        Pair<Key,char[]> objs = recoverKey(alias, storePass, keyPass);
+        PrivateKey privKey = (PrivateKey)objs.fst;
         if (keyPass == null) {
-            keyPass = (char[])objs[1];
+            keyPass = objs.snd;
         }
 
         Certificate userCert = keyStore.getCertificate(alias);
@@ -2290,36 +2488,40 @@
                         };
         out.println(form.format(source));
 
-        int extnum = 0;
         if (cert instanceof X509CertImpl) {
             X509CertImpl impl = (X509CertImpl)cert;
-            if (cert.getCriticalExtensionOIDs() != null) {
-                for (String extOID : cert.getCriticalExtensionOIDs()) {
-                    if (extnum == 0) {
-                        out.println();
-                        out.println(rb.getString("Extensions: "));
-                        out.println();
-                    }
-                    out.println("#"+(++extnum)+": "+
-                            impl.getExtension(new ObjectIdentifier(extOID)));
+            X509CertInfo certInfo = (X509CertInfo)impl.get(X509CertImpl.NAME
+                                                           + "." +
+                                                           X509CertImpl.INFO);
+            CertificateExtensions exts = (CertificateExtensions)
+                    certInfo.get(X509CertInfo.EXTENSIONS);
+            printExtensions(rb.getString("Extensions: "), exts, out);
+        }
+    }
+
+    private static void printExtensions(String title, CertificateExtensions exts, PrintStream out)
+            throws Exception {
+        int extnum = 0;
+        Iterator<Extension> i1 = exts.getAllExtensions().iterator();
+        Iterator<Extension> i2 = exts.getUnparseableExtensions().values().iterator();
+        while (i1.hasNext() || i2.hasNext()) {
+            Extension ext = i1.hasNext()?i1.next():i2.next();
+            if (extnum == 0) {
+                out.println();
+                out.println(title);
+                out.println();
+            }
+            out.print("#"+(++extnum)+": "+ ext);
+            if (ext.getClass() == Extension.class) {
+                byte[] v = ext.getExtensionValue();
+                if (v.length == 0) {
+                    out.println(rb.getString("(Empty value)"));
+                } else {
+                    new sun.misc.HexDumpEncoder().encode(ext.getExtensionValue(), out);
+                    out.println();
                 }
             }
-            if (cert.getNonCriticalExtensionOIDs() != null) {
-                for (String extOID : cert.getNonCriticalExtensionOIDs()) {
-                    if (extnum == 0) {
-                        out.println();
-                        out.println(rb.getString("Extensions: "));
-                        out.println();
-                    }
-                    Extension ext = impl.getExtension(new ObjectIdentifier(extOID));
-                    if (ext != null) {
-                        out.println("#"+(++extnum)+": "+ ext);
-                    } else {
-                        out.println("#"+(++extnum)+": "+
-                                impl.getUnparseableExtension(new ObjectIdentifier(extOID)));
-                    }
-                }
-            }
+            out.println();
         }
     }
 
@@ -2470,7 +2672,7 @@
      * recovered private key, and the 2nd element is the password used to
      * recover it.
      */
-    private Object[] recoverKey(String alias, char[] storePass,
+    private Pair<Key,char[]> recoverKey(String alias, char[] storePass,
                                        char[] keyPass)
         throws Exception
     {
@@ -2510,7 +2712,7 @@
             key = keyStore.getKey(alias, keyPass);
         }
 
-        return new Object[] {key, keyPass};
+        return Pair.of(key, keyPass);
     }
 
     /**
@@ -2520,7 +2722,7 @@
      * recovered entry, and the 2nd element is the password used to
      * recover it (null if no password).
      */
-    private Object[] recoverEntry(KeyStore ks,
+    private Pair<Entry,char[]> recoverEntry(KeyStore ks,
                             String alias,
                             char[] pstore,
                             char[] pkey) throws Exception {
@@ -2585,7 +2787,7 @@
             }
         }
 
-        return new Object[] {entry, pkey};
+        return Pair.of(entry, pkey);
     }
     /**
      * Gets the requested finger print of the certificate.
@@ -3027,6 +3229,443 @@
     }
 
     /**
+     * Match a command (may be abbreviated) with a command set.
+     * @param s the command provided
+     * @param list the legal command set
+     * @return the position of a single match, or -1 if none matched
+     * @throws Exception if s is ambiguous
+     */
+    private static int oneOf(String s, String... list) throws Exception {
+        int[] match = new int[list.length];
+        int nmatch = 0;
+        for (int i = 0; i<list.length; i++) {
+            String one = list[i];
+            if (one.toLowerCase().startsWith(s.toLowerCase())) {
+                match[nmatch++] = i;
+            } else {
+                StringBuffer sb = new StringBuffer();
+                boolean first = true;
+                for (char c: one.toCharArray()) {
+                    if (first) {
+                        sb.append(c);
+                        first = false;
+                    } else {
+                        if (!Character.isLowerCase(c)) {
+                            sb.append(c);
+                        }
+                    }
+                }
+                if (sb.toString().equalsIgnoreCase(s)) {
+                    match[nmatch++] = i;
+                }
+            }
+        }
+        if (nmatch == 0) return -1;
+        if (nmatch == 1) return match[0];
+        StringBuffer sb = new StringBuffer();
+        MessageFormat form = new MessageFormat(rb.getString
+            ("command {0} is ambiguous:"));
+        Object[] source = {s};
+        sb.append(form.format(source) +"\n    ");
+        for (int i=0; i<nmatch; i++) {
+            sb.append(" " + list[match[i]]);
+        }
+        throw new Exception(sb.toString());
+    }
+
+    /**
+     * Create a GeneralName object from known types
+     * @param t one of 5 known types
+     * @param v value
+     * @return which one
+     */
+    private GeneralName createGeneralName(String t, String v)
+            throws Exception {
+        GeneralNameInterface gn;
+        int p = oneOf(t, "EMAIL", "URI", "DNS", "IP", "OID");
+        if (p < 0) {
+            throw new Exception(rb.getString(
+                    "Unrecognized GeneralName type: ") + t);
+        }
+        switch (p) {
+            case 0: gn = new RFC822Name(v); break;
+            case 1: gn = new URIName(v); break;
+            case 2: gn = new DNSName(v); break;
+            case 3: gn = new IPAddressName(v); break;
+            default: gn = new OIDName(v); break; //4
+        }
+        return new GeneralName(gn);
+    }
+
+    private static final String[] extSupported = {
+                        "BasicConstraints",
+                        "KeyUsage",
+                        "ExtendedKeyUsage",
+                        "SubjectAlternativeName",
+                        "IssuerAlternativeName",
+                        "SubjectInfoAccess",
+                        "AuthorityInfoAccess",
+    };
+
+    private ObjectIdentifier findOidForExtName(String type)
+            throws Exception {
+        switch (oneOf(type, extSupported)) {
+            case 0: return PKIXExtensions.BasicConstraints_Id;
+            case 1: return PKIXExtensions.KeyUsage_Id;
+            case 2: return PKIXExtensions.ExtendedKeyUsage_Id;
+            case 3: return PKIXExtensions.SubjectAlternativeName_Id;
+            case 4: return PKIXExtensions.IssuerAlternativeName_Id;
+            case 5: return PKIXExtensions.SubjectInfoAccess_Id;
+            case 6: return PKIXExtensions.AuthInfoAccess_Id;
+            default: return new ObjectIdentifier(type);
+        }
+    }
+
+    /**
+     * Create X509v3 extensions from a string representation. Note that the
+     * SubjectKeyIdentifierExtension will always be created non-critical besides
+     * the extension requested in the <code>extstr</code> argument.
+     *
+     * @param reqex the requested extensions, can be null, used for -gencert
+     * @param ext the original extensions, can be null, used for -selfcert
+     * @param extstrs -ext values, Read keytool doc
+     * @param pkey the public key for the certificate
+     * @param akey the public key for the authority (issuer)
+     * @return the created CertificateExtensions
+     */
+    private CertificateExtensions createV3Extensions(
+            CertificateExtensions reqex,
+            CertificateExtensions ext,
+            List <String> extstrs,
+            PublicKey pkey,
+            PublicKey akey) throws Exception {
+
+        if (ext != null && reqex != null) {
+            // This should not happen
+            throw new Exception("One of request and original should be null.");
+        }
+        if (ext == null) ext = new CertificateExtensions();
+        try {
+            // name{:critical}{=value}
+            // Honoring requested extensions
+            if (reqex != null) {
+                for(String extstr: extstrs) {
+                    if (extstr.toLowerCase().startsWith("honored=")) {
+                        List<String> list = Arrays.asList(
+                                extstr.toLowerCase().substring(8).split(","));
+                        // First check existence of "all"
+                        if (list.contains("all")) {
+                            ext = reqex;    // we know ext was null
+                        }
+                        // one by one for others
+                        for (String item: list) {
+                            if (item.equals("all")) continue;
+
+                            // add or remove
+                            boolean add = true;
+                            // -1, unchanged, 0 crtical, 1 non-critical
+                            int action = -1;
+                            String type = null;
+                            if (item.startsWith("-")) {
+                                add = false;
+                                type = item.substring(1);
+                            } else {
+                                int colonpos = item.indexOf(':');
+                                if (colonpos >= 0) {
+                                    type = item.substring(0, colonpos);
+                                    action = oneOf(item.substring(colonpos+1),
+                                            "critical", "non-critical");
+                                    if (action == -1) {
+                                        throw new Exception(rb.getString
+                                            ("Illegal value: ") + item);
+                                    }
+                                }
+                            }
+                            String n = reqex.getNameByOid(findOidForExtName(type));
+                            if (add) {
+                                Extension e = (Extension)reqex.get(n);
+                                if (!e.isCritical() && action == 0
+                                        || e.isCritical() && action == 1) {
+                                    e = Extension.newExtension(
+                                            e.getExtensionId(),
+                                            !e.isCritical(),
+                                            e.getExtensionValue());
+                                    ext.set(n, e);
+                                }
+                            } else {
+                                ext.delete(n);
+                            }
+                        }
+                        break;
+                    }
+                }
+            }
+            for(String extstr: extstrs) {
+                String name, value;
+                boolean isCritical = false;
+
+                int eqpos = extstr.indexOf('=');
+                if (eqpos >= 0) {
+                    name = extstr.substring(0, eqpos);
+                    value = extstr.substring(eqpos+1);
+                } else {
+                    name = extstr;
+                    value = null;
+                }
+
+                int colonpos = name.indexOf(':');
+                if (colonpos >= 0) {
+                    if (name.substring(colonpos+1).equalsIgnoreCase("critical")) {
+                        isCritical = true;
+                    }
+                    name = name.substring(0, colonpos);
+                }
+
+                if (name.equalsIgnoreCase("honored")) {
+                    continue;
+                }
+                int exttype = oneOf(name, extSupported);
+                switch (exttype) {
+                    case 0:     // BC
+                        int pathLen = -1;
+                        boolean isCA = false;
+                        if (value == null) {
+                            isCA = true;
+                        } else {
+                            try {   // the abbr format
+                                pathLen = Integer.parseInt(value);
+                                isCA = true;
+                            } catch (NumberFormatException ufe) {
+                                // ca:true,pathlen:1
+                                for (String part: value.split(",")) {
+                                    String[] nv = part.split(":");
+                                    if (nv.length != 2) {
+                                        throw new Exception(rb.getString
+                                                ("Illegal value: ") + extstr);
+                                    } else {
+                                        if (nv[0].equalsIgnoreCase("ca")) {
+                                            isCA = Boolean.parseBoolean(nv[1]);
+                                        } else if (nv[0].equalsIgnoreCase("pathlen")) {
+                                            pathLen = Integer.parseInt(nv[1]);
+                                        } else {
+                                            throw new Exception(rb.getString
+                                                ("Illegal value: ") + extstr);
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                        ext.set(BasicConstraintsExtension.NAME,
+                                new BasicConstraintsExtension(isCritical, isCA,
+                                pathLen));
+                        break;
+                    case 1:     // KU
+                        if(value != null) {
+                            boolean[] ok = new boolean[9];
+                            for (String s: value.split(",")) {
+                                int p = oneOf(s,
+                                       "digitalSignature",  // (0),
+                                       "nonRepudiation",    // (1)
+                                       "keyEncipherment",   // (2),
+                                       "dataEncipherment",  // (3),
+                                       "keyAgreement",      // (4),
+                                       "keyCertSign",       // (5),
+                                       "cRLSign",           // (6),
+                                       "encipherOnly",      // (7),
+                                       "decipherOnly",      // (8)
+                                       "contentCommitment"  // also (1)
+                                       );
+                                if (p < 0) {
+                                    throw new Exception(rb.getString("Unknown keyUsage type: ") + s);
+                                }
+                                if (p == 9) p = 1;
+                                ok[p] = true;
+                            }
+                            KeyUsageExtension kue = new KeyUsageExtension(ok);
+                            // The above KeyUsageExtension constructor does not
+                            // allow isCritical value, so...
+                            ext.set(KeyUsageExtension.NAME, Extension.newExtension(
+                                    kue.getExtensionId(),
+                                    isCritical,
+                                    kue.getExtensionValue()));
+                        } else {
+                            throw new Exception(rb.getString
+                                    ("Illegal value: ") + extstr);
+                        }
+                        break;
+                    case 2:     // EKU
+                        if(value != null) {
+                            Vector <ObjectIdentifier> v =
+                                    new Vector <ObjectIdentifier>();
+                            for (String s: value.split(",")) {
+                                int p = oneOf(s,
+                                        "anyExtendedKeyUsage",
+                                        "serverAuth",       //1
+                                        "clientAuth",       //2
+                                        "codeSigning",      //3
+                                        "emailProtection",  //4
+                                        "",                 //5
+                                        "",                 //6
+                                        "",                 //7
+                                        "timeStamping",     //8
+                                        "OCSPSigning"       //9
+                                       );
+                                if (p < 0) {
+                                    try {
+                                        v.add(new ObjectIdentifier(s));
+                                    } catch (Exception e) {
+                                        throw new Exception(rb.getString(
+                                                "Unknown extendedkeyUsage type: ") + s);
+                                    }
+                                } else if (p == 0) {
+                                    v.add(new ObjectIdentifier("2.5.29.37.0"));
+                                } else {
+                                    v.add(new ObjectIdentifier("1.3.6.1.5.5.7.3." + p));
+                                }
+                            }
+                            ext.set(ExtendedKeyUsageExtension.NAME,
+                                    new ExtendedKeyUsageExtension(isCritical, v));
+                        } else {
+                            throw new Exception(rb.getString
+                                    ("Illegal value: ") + extstr);
+                        }
+                        break;
+                    case 3:     // SAN
+                    case 4:     // IAN
+                        if(value != null) {
+                            String[] ps = value.split(",");
+                            GeneralNames gnames = new GeneralNames();
+                            for(String item: ps) {
+                                colonpos = item.indexOf(':');
+                                if (colonpos < 0) {
+                                    throw new Exception("Illegal item " + item + " in " + extstr);
+                                }
+                                String t = item.substring(0, colonpos);
+                                String v = item.substring(colonpos+1);
+                                gnames.add(createGeneralName(t, v));
+                            }
+                            if (exttype == 3) {
+                                ext.set(SubjectAlternativeNameExtension.NAME,
+                                        new SubjectAlternativeNameExtension(
+                                            isCritical, gnames));
+                            } else {
+                                ext.set(IssuerAlternativeNameExtension.NAME,
+                                        new IssuerAlternativeNameExtension(
+                                            isCritical, gnames));
+                            }
+                        } else {
+                            throw new Exception(rb.getString
+                                    ("Illegal value: ") + extstr);
+                        }
+                        break;
+                    case 5:     // SIA, always non-critical
+                    case 6:     // AIA, always non-critical
+                        if (isCritical) {
+                            throw new Exception(rb.getString(
+                                    "This extension cannot be marked as critical. ") + extstr);
+                        }
+                        if(value != null) {
+                            List<AccessDescription> accessDescriptions =
+                                    new ArrayList<AccessDescription>();
+                            String[] ps = value.split(",");
+                            for(String item: ps) {
+                                colonpos = item.indexOf(':');
+                                int colonpos2 = item.indexOf(':', colonpos+1);
+                                if (colonpos < 0 || colonpos2 < 0) {
+                                    throw new Exception(rb.getString
+                                            ("Illegal value: ") + extstr);
+                                }
+                                String m = item.substring(0, colonpos);
+                                String t = item.substring(colonpos+1, colonpos2);
+                                String v = item.substring(colonpos2+1);
+                                int p = oneOf(m,
+                                        "",
+                                        "ocsp",         //1
+                                        "caIssuers",    //2
+                                        "timeStamping", //3
+                                        "",
+                                        "caRepository"  //5
+                                        );
+                                ObjectIdentifier oid;
+                                if (p < 0) {
+                                    try {
+                                        oid = new ObjectIdentifier(m);
+                                    } catch (Exception e) {
+                                        throw new Exception(rb.getString(
+                                                "Unknown AccessDescription type: ") + m);
+                                    }
+                                } else {
+                                    oid = new ObjectIdentifier("1.3.6.1.5.5.7.48." + p);
+                                }
+                                accessDescriptions.add(new AccessDescription(
+                                        oid, createGeneralName(t, v)));
+                            }
+                            if (exttype == 5) {
+                                ext.set(SubjectInfoAccessExtension.NAME,
+                                        new SubjectInfoAccessExtension(accessDescriptions));
+                            } else {
+                                ext.set(AuthorityInfoAccessExtension.NAME,
+                                        new AuthorityInfoAccessExtension(accessDescriptions));
+                            }
+                        } else {
+                            throw new Exception(rb.getString
+                                    ("Illegal value: ") + extstr);
+                        }
+                        break;
+                    case -1:
+                        ObjectIdentifier oid = new ObjectIdentifier(name);
+                        byte[] data = null;
+                        if (value != null) {
+                            data = new byte[value.length() / 2 + 1];
+                            int pos = 0;
+                            for (char c: value.toCharArray()) {
+                                int hex;
+                                if (c >= '0' && c <= '9') {
+                                    hex = c - '0' ;
+                                } else if (c >= 'A' && c <= 'F') {
+                                    hex = c - 'A' + 10;
+                                } else if (c >= 'a' && c <= 'f') {
+                                    hex = c - 'a' + 10;
+                                } else {
+                                    continue;
+                                }
+                                if (pos % 2 == 0) {
+                                    data[pos/2] = (byte)(hex << 4);
+                                } else {
+                                    data[pos/2] += hex;
+                                }
+                                pos++;
+                            }
+                            if (pos % 2 != 0) {
+                                throw new Exception(rb.getString(
+                                        "Odd number of hex digits found: ") + extstr);
+                            }
+                            data = Arrays.copyOf(data, pos/2);
+                        } else {
+                            data = new byte[0];
+                        }
+                        ext.set(oid.toString(), new Extension(oid, isCritical,
+                                new DerValue(DerValue.tag_OctetString, data)
+                                        .toByteArray()));
+                        break;
+                }
+            }
+            // always non-critical
+            ext.set(SubjectKeyIdentifierExtension.NAME,
+                    new SubjectKeyIdentifierExtension(
+                        new KeyIdentifier(pkey).getIdentifier()));
+            if (akey != null && !pkey.equals(akey)) {
+                ext.set(AuthorityKeyIdentifierExtension.NAME,
+                        new AuthorityKeyIdentifierExtension(
+                        new KeyIdentifier(akey), null, null));
+            }
+        } catch(IOException e) {
+            throw new RuntimeException(e);
+        }
+        return ext;
+    }
+
+    /**
      * Prints the usage of this tool.
      */
     private void usage() {
@@ -3099,6 +3738,32 @@
         System.err.println(rb.getString
                 ("\t     [-startdate <startdate>]"));
         System.err.println(rb.getString
+                ("\t     [-ext <key>[:critical][=<value>]]..."));
+        System.err.println(rb.getString
+                ("\t     [-validity <valDays>] [-keypass <keypass>]"));
+        System.err.println(rb.getString
+                ("\t     [-keystore <keystore>] [-storepass <storepass>]"));
+        System.err.println(rb.getString
+                ("\t     [-storetype <storetype>] [-providername <name>]"));
+        System.err.println(rb.getString
+                ("\t     [-providerclass <provider_class_name> [-providerarg <arg>]] ..."));
+        System.err.println(rb.getString
+                ("\t     [-providerpath <pathlist>]"));
+        System.err.println();
+
+        System.err.println(rb.getString
+                ("-gencert     [-v] [-rfc] [-protected]"));
+        System.err.println(rb.getString
+                ("\t     [-infile <infile>] [-outfile <outfile>]"));
+        System.err.println(rb.getString
+                ("\t     [-alias <alias>]"));
+        System.err.println(rb.getString
+                ("\t     [-sigalg <sigalg>]"));
+        System.err.println(rb.getString
+                ("\t     [-startdate <startdate>]"));
+        System.err.println(rb.getString
+                ("\t     [-ext <key>[:critical][=<value>]]..."));
+        System.err.println(rb.getString
                 ("\t     [-validity <valDays>] [-keypass <keypass>]"));
         System.err.println(rb.getString
                 ("\t     [-keystore <keystore>] [-storepass <storepass>]"));
@@ -3202,6 +3867,10 @@
         System.err.println();
 
         System.err.println(rb.getString
+                ("-printcertreq   [-v] [-file <cert_file>]"));
+        System.err.println();
+
+        System.err.println(rb.getString
                 ("-storepasswd [-v] [-new <new_storepass>]"));
         System.err.println(rb.getString
                 ("\t     [-keystore <keystore>] [-storepass <storepass>]"));
@@ -3211,12 +3880,6 @@
                 ("\t     [-providerclass <provider_class_name> [-providerarg <arg>]] ..."));
         System.err.println(rb.getString
                 ("\t     [-providerpath <pathlist>]"));
-
-        if (debug) {
-            throw new RuntimeException("NO ERROR, SORRY");
-        } else {
-            System.exit(1);
-        }
     }
 
     private void tinyHelp() {
@@ -3270,4 +3933,8 @@
         else if (snd == null) return fst.hashCode() + 2;
         else return fst.hashCode() * 17 + snd.hashCode();
     }
+
+    public static <A,B> Pair<A,B> of(A a, B b) {
+        return new Pair<A,B>(a,b);
+    }
 }
diff --git a/jdk/src/share/classes/sun/security/util/Cache.java b/jdk/src/share/classes/sun/security/util/Cache.java
index e6eddb6f..35d648a 100644
--- a/jdk/src/share/classes/sun/security/util/Cache.java
+++ b/jdk/src/share/classes/sun/security/util/Cache.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2002-2009 Sun Microsystems, Inc.  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
@@ -101,6 +101,21 @@
     public abstract void remove(Object key);
 
     /**
+     * Set the maximum size.
+     */
+    public abstract void setCapacity(int size);
+
+    /**
+     * Set the timeout(in seconds).
+     */
+    public abstract void setTimeout(int timeout);
+
+    /**
+     * accept a visitor
+     */
+    public abstract void accept(CacheVisitor visitor);
+
+    /**
      * Return a new memory cache with the specified maximum size, unlimited
      * lifetime for entries, with the values held by SoftReferences.
      */
@@ -178,6 +193,10 @@
         }
     }
 
+    public interface CacheVisitor {
+        public void visit(Map<Object, Object> map);
+    }
+
 }
 
 class NullCache extends Cache {
@@ -208,6 +227,18 @@
         // empty
     }
 
+    public void setCapacity(int size) {
+        // empty
+    }
+
+    public void setTimeout(int timeout) {
+        // empty
+    }
+
+    public void accept(CacheVisitor visitor) {
+        // empty
+    }
+
 }
 
 class MemoryCache extends Cache {
@@ -218,8 +249,8 @@
     private final static boolean DEBUG = false;
 
     private final Map<Object, CacheEntry> cacheMap;
-    private final int maxSize;
-    private final int lifetime;
+    private int maxSize;
+    private long lifetime;
     private final ReferenceQueue queue;
 
     public MemoryCache(boolean soft, int maxSize) {
@@ -328,7 +359,7 @@
             oldEntry.invalidate();
             return;
         }
-        if (cacheMap.size() > maxSize) {
+        if (maxSize > 0 && cacheMap.size() > maxSize) {
             expungeExpiredEntries();
             if (cacheMap.size() > maxSize) { // still too large?
                 Iterator<CacheEntry> t = cacheMap.values().iterator();
@@ -368,6 +399,55 @@
         }
     }
 
+    public synchronized void setCapacity(int size) {
+        expungeExpiredEntries();
+        if (size > 0 && cacheMap.size() > size) {
+            Iterator<CacheEntry> t = cacheMap.values().iterator();
+            for (int i = cacheMap.size() - size; i > 0; i--) {
+                CacheEntry lruEntry = t.next();
+                if (DEBUG) {
+                    System.out.println("** capacity reset removal "
+                        + lruEntry.getKey() + " | " + lruEntry.getValue());
+                }
+                t.remove();
+                lruEntry.invalidate();
+            }
+        }
+
+        maxSize = size > 0 ? size : 0;
+
+        if (DEBUG) {
+            System.out.println("** capacity reset to " + size);
+        }
+    }
+
+    public synchronized void setTimeout(int timeout) {
+        emptyQueue();
+        lifetime = timeout > 0 ? timeout * 1000L : 0L;
+
+        if (DEBUG) {
+            System.out.println("** lifetime reset to " + timeout);
+        }
+    }
+
+    // it is a heavyweight method.
+    public synchronized void accept(CacheVisitor visitor) {
+        expungeExpiredEntries();
+        Map<Object, Object> cached = getCachedEntries();
+
+        visitor.visit(cached);
+    }
+
+    private Map<Object, Object> getCachedEntries() {
+        Map<Object,Object> kvmap = new HashMap<Object,Object>(cacheMap.size());
+
+        for (CacheEntry entry : cacheMap.values()) {
+            kvmap.put(entry.getKey(), entry.getValue());
+        }
+
+        return kvmap;
+    }
+
     protected CacheEntry newEntry(Object key, Object value,
             long expirationTime, ReferenceQueue queue) {
         if (queue != null) {
diff --git a/jdk/src/share/classes/sun/security/util/DerValue.java b/jdk/src/share/classes/sun/security/util/DerValue.java
index 74e59f6..114788b 100644
--- a/jdk/src/share/classes/sun/security/util/DerValue.java
+++ b/jdk/src/share/classes/sun/security/util/DerValue.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 1996-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1996-2009 Sun Microsystems, Inc.  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
@@ -65,7 +65,7 @@
     protected DerInputBuffer    buffer;
 
     /**
-     * The DER-encoded data of the value.
+     * The DER-encoded data of the value, never null
      */
     public final DerInputStream data;
 
@@ -378,8 +378,6 @@
                         ("Indefinite length encoding not supported");
             length = DerInputStream.getLength(in);
         }
-        if (length == 0)
-            return null;
 
         if (fullyBuffered && in.available() != length)
             throw new IOException("extra data given to DerValue constructor");
@@ -477,6 +475,11 @@
                 "DerValue.getOctetString, not an Octet String: " + tag);
         }
         bytes = new byte[length];
+        // Note: do not tempt to call buffer.read(bytes) at all. There's a
+        // known bug that it returns -1 instead of 0.
+        if (length == 0) {
+            return bytes;
+        }
         if (buffer.read(bytes) != length)
             throw new IOException("short read on DerValue buffer");
         if (isConstructed()) {
diff --git a/jdk/src/share/classes/sun/security/util/Resources.java b/jdk/src/share/classes/sun/security/util/Resources.java
index e89d6cd..c8c5e38 100644
--- a/jdk/src/share/classes/sun/security/util/Resources.java
+++ b/jdk/src/share/classes/sun/security/util/Resources.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2009 Sun Microsystems, Inc.  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
@@ -49,6 +49,7 @@
         // keytool
         {"keytool error: ", "keytool error: "},
         {"Illegal option:  ", "Illegal option:  "},
+        {"Illegal value: ", "Illegal value: "},
         {"Try keytool -help","Try keytool -help"},
         {"Command option <flag> needs an argument.", "Command option {0} needs an argument."},
         {"Warning:  Different store and key passwords not supported for PKCS12 KeyStores. Ignoring user-specified <command> value.",
@@ -281,6 +282,20 @@
         {"keytool usage:\n", "keytool usage:\n"},
 
         {"Extensions: ", "Extensions: "},
+        {"(Empty value)", "(Empty value)"},
+        {"Extension Request:", "Extension Request:"},
+        {"PKCS #10 Certificate Request (Version 1.0)\n" +
+                "Subject: %s\nPublic Key: %s format %s key\n",
+                "PKCS #10 Certificate Request (Version 1.0)\n" +
+                "Subject: %s\nPublic Key: %s format %s key\n"},
+        {"Unknown keyUsage type: ", "Unknown keyUsage type: "},
+        {"Unknown extendedkeyUsage type: ", "Unknown extendedkeyUsage type: "},
+        {"Unknown AccessDescription type: ", "Unknown AccessDescription type: "},
+        {"Unrecognized GeneralName type: ", "Unrecognized GeneralName type: "},
+        {"This extension cannot be marked as critical. ",
+                 "This extension cannot be marked as critical. "},
+        {"Odd number of hex digits found: ", "Odd number of hex digits found: "},
+        {"command {0} is ambiguous:", "command {0} is ambiguous:"},
 
         {"-certreq     [-v] [-protected]",
                 "-certreq     [-v] [-protected]"},
@@ -322,6 +337,14 @@
         {"\t     [-validity <valDays>] [-keypass <keypass>]",
                 "\t     [-validity <valDays>] [-keypass <keypass>]"},
         /** rest is same as -certreq starting from -keystore **/
+        {"-gencert     [-v] [-rfc] [-protected]",
+                "-gencert     [-v] [-rfc] [-protected]"},
+        {"\t     [-infile <infile>] [-outfile <outfile>]",
+                 "\t     [-infile <infile>] [-outfile <outfile>]"},
+        {"\t     [-sigalg <sigalg>]",
+                "\t     [-sigalg <sigalg>]"},
+        {"\t     [-ext <key>[:critical][=<value>]]...",
+                "\t     [-ext <key>[:critical][=<value>]]..."},
 
         {"-genseckey   [-v] [-protected]",
                 "-genseckey   [-v] [-protected]"},
@@ -388,6 +411,8 @@
 
         {"-printcert   [-v] [-rfc] [-file <cert_file> | -sslserver <host[:port]>]",
                 "-printcert   [-v] [-rfc] [-file <cert_file> | -sslserver <host[:port]>]"},
+        {"-printcertreq   [-v] [-file <cert_file>]",
+                 "-printcertreq   [-v] [-file <cert_file>]"},
         {"No certificate from the SSL server",
                 "No certificate from the SSL server"},
 
diff --git a/jdk/src/share/classes/sun/security/util/SecurityConstants.java b/jdk/src/share/classes/sun/security/util/SecurityConstants.java
index 95cd1f5..43e2cd3 100644
--- a/jdk/src/share/classes/sun/security/util/SecurityConstants.java
+++ b/jdk/src/share/classes/sun/security/util/SecurityConstants.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-2009 Sun Microsystems, Inc.  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
@@ -52,6 +52,7 @@
     public static final String FILE_EXECUTE_ACTION = "execute";
     public static final String FILE_READ_ACTION = "read";
     public static final String FILE_WRITE_ACTION = "write";
+    public static final String FILE_READLINK_ACTION = "readlink";
 
     public static final String SOCKET_RESOLVE_ACTION = "resolve";
     public static final String SOCKET_CONNECT_ACTION = "connect";
diff --git a/jdk/src/share/classes/sun/security/x509/AccessDescription.java b/jdk/src/share/classes/sun/security/x509/AccessDescription.java
index a9ccbb8..1544ea9 100644
--- a/jdk/src/share/classes/sun/security/x509/AccessDescription.java
+++ b/jdk/src/share/classes/sun/security/x509/AccessDescription.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-2009 Sun Microsystems, Inc.  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
@@ -48,6 +48,17 @@
     public static final ObjectIdentifier Ad_CAISSUERS_Id =
         ObjectIdentifier.newInternal(new int[] {1, 3, 6, 1, 5, 5, 7, 48, 2});
 
+    public static final ObjectIdentifier Ad_TIMESTAMPING_Id =
+        ObjectIdentifier.newInternal(new int[] {1, 3, 6, 1, 5, 5, 7, 48, 3});
+
+    public static final ObjectIdentifier Ad_CAREPOSITORY_Id =
+        ObjectIdentifier.newInternal(new int[] {1, 3, 6, 1, 5, 5, 7, 48, 5});
+
+    public AccessDescription(ObjectIdentifier accessMethod, GeneralName accessLocation) {
+        this.accessMethod = accessMethod;
+        this.accessLocation = accessLocation;
+    }
+
     public AccessDescription(DerValue derValue) throws IOException {
         DerInputStream derIn = derValue.getData();
         accessMethod = derIn.getOID();
@@ -90,7 +101,19 @@
     }
 
     public String toString() {
-        return ("accessMethod: " + accessMethod.toString() +
-                "\n   accessLocation: " + accessLocation.toString());
+        String method = null;
+        if (accessMethod.equals(Ad_CAISSUERS_Id)) {
+            method = "caIssuers";
+        } else if (accessMethod.equals(Ad_CAREPOSITORY_Id)) {
+            method = "caRepository";
+        } else if (accessMethod.equals(Ad_TIMESTAMPING_Id)) {
+            method = "timeStamping";
+        } else if (accessMethod.equals(Ad_OCSP_Id)) {
+            method = "ocsp";
+        } else {
+            method = accessMethod.toString();
+        }
+        return ("accessMethod: " + method +
+                "\n   accessLocation: " + accessLocation.toString() + "\n");
     }
 }
diff --git a/jdk/src/share/classes/sun/security/x509/AuthorityInfoAccessExtension.java b/jdk/src/share/classes/sun/security/x509/AuthorityInfoAccessExtension.java
index 5b0b287..da14007 100644
--- a/jdk/src/share/classes/sun/security/x509/AuthorityInfoAccessExtension.java
+++ b/jdk/src/share/classes/sun/security/x509/AuthorityInfoAccessExtension.java
@@ -43,8 +43,9 @@
  * certificate that identifies the specific OCSP Responder to use when
  * performing on-line validation of that certificate.
  * <p>
- * This extension is defined in
- * <a href="http://www.ietf.org/rfc/rfc3280.txt">Internet X.509 PKI Certificate and Certificate Revocation List (CRL) Profile</a>. The profile permits
+ * This extension is defined in <a href="http://www.ietf.org/rfc/rfc3280.txt">
+ * Internet X.509 PKI Certificate and Certificate Revocation List
+ * (CRL) Profile</a>. The profile permits
  * the extension to be included in end-entity or CA certificates,
  * and it must be marked as non-critical. Its ASN.1 definition is as follows:
  * <pre>
diff --git a/jdk/src/share/classes/sun/security/x509/AuthorityKeyIdentifierExtension.java b/jdk/src/share/classes/sun/security/x509/AuthorityKeyIdentifierExtension.java
index f63dca9..b14c843 100644
--- a/jdk/src/share/classes/sun/security/x509/AuthorityKeyIdentifierExtension.java
+++ b/jdk/src/share/classes/sun/security/x509/AuthorityKeyIdentifierExtension.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc.  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
@@ -198,7 +198,7 @@
     public String toString() {
         String s = super.toString() + "AuthorityKeyIdentifier [\n";
         if (id != null) {
-            s += id.toString() + "\n";
+            s += id.toString();     // id already has a newline
         }
         if (names != null) {
             s += names.toString() + "\n";
diff --git a/jdk/src/share/classes/sun/security/x509/BasicConstraintsExtension.java b/jdk/src/share/classes/sun/security/x509/BasicConstraintsExtension.java
index 26344ee..c38bb00 100644
--- a/jdk/src/share/classes/sun/security/x509/BasicConstraintsExtension.java
+++ b/jdk/src/share/classes/sun/security/x509/BasicConstraintsExtension.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc.  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
@@ -70,18 +70,15 @@
 
     // Encode this extension value
     private void encodeThis() throws IOException {
-        if (ca == false && pathLen < 0) {
-            this.extensionValue = null;
-            return;
-        }
         DerOutputStream out = new DerOutputStream();
         DerOutputStream tmp = new DerOutputStream();
 
         if (ca) {
             tmp.putBoolean(ca);
-        }
-        if (pathLen >= 0) {
-            tmp.putInteger(pathLen);
+            // Only encode pathLen when ca == true
+            if (pathLen >= 0) {
+                tmp.putInteger(pathLen);
+            }
         }
         out.write(DerValue.tag_Sequence, tmp);
         this.extensionValue = out.toByteArray();
@@ -134,7 +131,7 @@
              throw new IOException("Invalid encoding of BasicConstraints");
          }
 
-         if (val.data == null) {
+         if (val.data == null || val.data.available() == 0) {
              // non-CA cert ("cA" field is FALSE by default), return -1
              return;
          }
diff --git a/jdk/src/share/classes/sun/security/x509/CertAndKeyGen.java b/jdk/src/share/classes/sun/security/x509/CertAndKeyGen.java
index 0e08009..38ca600 100644
--- a/jdk/src/share/classes/sun/security/x509/CertAndKeyGen.java
+++ b/jdk/src/share/classes/sun/security/x509/CertAndKeyGen.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 1996-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1996-2009 Sun Microsystems, Inc.  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
@@ -276,12 +276,6 @@
             info.set(X509CertInfo.ISSUER,
                      new CertificateIssuerName(issuer.getSigner()));
 
-            CertificateExtensions ext = new CertificateExtensions();
-                ext.set(SubjectKeyIdentifierExtension.NAME,
-                        new SubjectKeyIdentifierExtension(
-                            new KeyIdentifier(publicKey).getIdentifier()));
-            info.set(X509CertInfo.EXTENSIONS, ext);
-
             cert = new X509CertImpl(info);
             cert.sign(privateKey, this.sigAlg);
 
diff --git a/jdk/src/share/classes/sun/security/x509/CertificateExtensions.java b/jdk/src/share/classes/sun/security/x509/CertificateExtensions.java
index 7049d01..cd32e74 100644
--- a/jdk/src/share/classes/sun/security/x509/CertificateExtensions.java
+++ b/jdk/src/share/classes/sun/security/x509/CertificateExtensions.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc.  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
@@ -231,6 +231,15 @@
         map.remove(name);
     }
 
+    public String getNameByOid(ObjectIdentifier oid) throws IOException {
+        for (String name: map.keySet()) {
+            if (map.get(name).getExtensionId().equals(oid)) {
+                return name;
+            }
+        }
+        return null;
+    }
+
     /**
      * Return an enumeration of names of attributes existing within this
      * attribute.
diff --git a/jdk/src/share/classes/sun/security/x509/IssuerAlternativeNameExtension.java b/jdk/src/share/classes/sun/security/x509/IssuerAlternativeNameExtension.java
index aad153b..73f3ecd 100644
--- a/jdk/src/share/classes/sun/security/x509/IssuerAlternativeNameExtension.java
+++ b/jdk/src/share/classes/sun/security/x509/IssuerAlternativeNameExtension.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc.  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
@@ -90,6 +90,22 @@
     }
 
     /**
+     * Create a IssuerAlternativeNameExtension with the passed criticality
+     * and GeneralNames.
+     *
+     * @param critical true if the extension is to be treated as critical.
+     * @param names the GeneralNames for the issuer.
+     * @exception IOException on error.
+     */
+    public IssuerAlternativeNameExtension(Boolean critical, GeneralNames names)
+    throws IOException {
+        this.names = names;
+        this.extensionId = PKIXExtensions.IssuerAlternativeName_Id;
+        this.critical = critical.booleanValue();
+        encodeThis();
+    }
+
+    /**
      * Create a default IssuerAlternativeNameExtension.
      */
     public IssuerAlternativeNameExtension() {
diff --git a/jdk/src/share/classes/sun/security/x509/OIDMap.java b/jdk/src/share/classes/sun/security/x509/OIDMap.java
index ddbb1d6..bb7cffe 100644
--- a/jdk/src/share/classes/sun/security/x509/OIDMap.java
+++ b/jdk/src/share/classes/sun/security/x509/OIDMap.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc.  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
@@ -90,6 +90,8 @@
 
     private static final String CERT_ISSUER = ROOT + "." +
                                         CertificateIssuerExtension.NAME;
+    private static final String SUBJECT_INFO_ACCESS = ROOT + "." +
+                                          SubjectInfoAccessExtension.NAME;
     private static final String AUTH_INFO_ACCESS = ROOT + "." +
                                           AuthorityInfoAccessExtension.NAME;
     private static final String ISSUING_DIST_POINT = ROOT + "." +
@@ -148,6 +150,8 @@
                     "sun.security.x509.CRLDistributionPointsExtension");
         addInternal(CERT_ISSUER, PKIXExtensions.CertificateIssuer_Id,
                     "sun.security.x509.CertificateIssuerExtension");
+        addInternal(SUBJECT_INFO_ACCESS, PKIXExtensions.SubjectInfoAccess_Id,
+                    "sun.security.x509.SubjectInfoAccessExtension");
         addInternal(AUTH_INFO_ACCESS, PKIXExtensions.AuthInfoAccess_Id,
                     "sun.security.x509.AuthorityInfoAccessExtension");
         addInternal(ISSUING_DIST_POINT,
diff --git a/jdk/src/share/classes/sun/security/x509/SubjectInfoAccessExtension.java b/jdk/src/share/classes/sun/security/x509/SubjectInfoAccessExtension.java
new file mode 100644
index 0000000..449f45e
--- /dev/null
+++ b/jdk/src/share/classes/sun/security/x509/SubjectInfoAccessExtension.java
@@ -0,0 +1,244 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.security.x509;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import java.util.*;
+
+import sun.security.util.DerOutputStream;
+import sun.security.util.DerValue;
+
+/**
+ * The Subject Information Access Extension (OID = 1.3.6.1.5.5.7.1.11).
+ * <p>
+ * The subject information access extension indicates how to access
+ * information and services for the subject of the certificate in which
+ * the extension appears.  When the subject is a CA, information and
+ * services may include certificate validation services and CA policy
+ * data.  When the subject is an end entity, the information describes
+ * the type of services offered and how to access them.  In this case,
+ * the contents of this extension are defined in the protocol
+ * specifications for the supported services.  This extension may be
+ * included in end entity or CA certificates.  Conforming CAs MUST mark
+ * this extension as non-critical.
+ * <p>
+ * This extension is defined in <a href="http://www.ietf.org/rfc/rfc3280.txt">
+ * Internet X.509 PKI Certificate and Certificate Revocation List
+ * (CRL) Profile</a>. The profile permits
+ * the extension to be included in end-entity or CA certificates,
+ * and it must be marked as non-critical. Its ASN.1 definition is as follows:
+ * <pre>
+ *   id-pe-subjectInfoAccess OBJECT IDENTIFIER ::= { id-pe 11 }
+ *
+ *   SubjectInfoAccessSyntax  ::=
+ *          SEQUENCE SIZE (1..MAX) OF AccessDescription
+ *
+ *   AccessDescription  ::=  SEQUENCE {
+ *          accessMethod          OBJECT IDENTIFIER,
+ *          accessLocation        GeneralName  }
+ * </pre>
+ * <p>
+ * @see Extension
+ * @see CertAttrSet
+ */
+
+public class SubjectInfoAccessExtension extends Extension
+        implements CertAttrSet<String> {
+
+    /**
+     * Identifier for this attribute, to be used with the
+     * get, set, delete methods of Certificate, x509 type.
+     */
+    public static final String IDENT =
+                                "x509.info.extensions.SubjectInfoAccess";
+
+    /**
+     * Attribute name.
+     */
+    public static final String NAME = "SubjectInfoAccess";
+    public static final String DESCRIPTIONS = "descriptions";
+
+    /**
+     * The List of AccessDescription objects.
+     */
+    private List<AccessDescription> accessDescriptions;
+
+    /**
+     * Create an SubjectInfoAccessExtension from a List of
+     * AccessDescription; the criticality is set to false.
+     *
+     * @param accessDescriptions the List of AccessDescription
+     * @throws IOException on error
+     */
+    public SubjectInfoAccessExtension(
+            List<AccessDescription> accessDescriptions) throws IOException {
+        this.extensionId = PKIXExtensions.SubjectInfoAccess_Id;
+        this.critical = false;
+        this.accessDescriptions = accessDescriptions;
+        encodeThis();
+    }
+
+    /**
+     * Create the extension from the passed DER encoded value of the same.
+     *
+     * @param critical true if the extension is to be treated as critical.
+     * @param value Array of DER encoded bytes of the actual value.
+     * @exception IOException on error.
+     */
+    public SubjectInfoAccessExtension(Boolean critical, Object value)
+            throws IOException {
+        this.extensionId = PKIXExtensions.SubjectInfoAccess_Id;
+        this.critical = critical.booleanValue();
+
+        if (!(value instanceof byte[])) {
+            throw new IOException("Illegal argument type");
+        }
+
+        extensionValue = (byte[])value;
+        DerValue val = new DerValue(extensionValue);
+        if (val.tag != DerValue.tag_Sequence) {
+            throw new IOException("Invalid encoding for " +
+                                  "SubjectInfoAccessExtension.");
+        }
+        accessDescriptions = new ArrayList<AccessDescription>();
+        while (val.data.available() != 0) {
+            DerValue seq = val.data.getDerValue();
+            AccessDescription accessDescription = new AccessDescription(seq);
+            accessDescriptions.add(accessDescription);
+        }
+    }
+
+    /**
+     * Return the list of AccessDescription objects.
+     */
+    public List<AccessDescription> getAccessDescriptions() {
+        return accessDescriptions;
+    }
+
+    /**
+     * Return the name of this attribute.
+     */
+    public String getName() {
+        return NAME;
+    }
+
+    /**
+     * Write the extension to the DerOutputStream.
+     *
+     * @param out the DerOutputStream to write the extension to.
+     * @exception IOException on encoding errors.
+     */
+    public void encode(OutputStream out) throws IOException {
+        DerOutputStream tmp = new DerOutputStream();
+        if (this.extensionValue == null) {
+            this.extensionId = PKIXExtensions.SubjectInfoAccess_Id;
+            this.critical = false;
+            encodeThis();
+        }
+        super.encode(tmp);
+        out.write(tmp.toByteArray());
+    }
+
+    /**
+     * Set the attribute value.
+     */
+    public void set(String name, Object obj) throws IOException {
+        if (name.equalsIgnoreCase(DESCRIPTIONS)) {
+            if (!(obj instanceof List)) {
+                throw new IOException("Attribute value should be of type List.");
+            }
+            accessDescriptions = (List<AccessDescription>)obj;
+        } else {
+            throw new IOException("Attribute name [" + name +
+                                "] not recognized by " +
+                                "CertAttrSet:SubjectInfoAccessExtension.");
+        }
+        encodeThis();
+    }
+
+    /**
+     * Get the attribute value.
+     */
+    public Object get(String name) throws IOException {
+        if (name.equalsIgnoreCase(DESCRIPTIONS)) {
+            return accessDescriptions;
+        } else {
+            throw new IOException("Attribute name [" + name +
+                                "] not recognized by " +
+                                "CertAttrSet:SubjectInfoAccessExtension.");
+        }
+    }
+
+    /**
+     * Delete the attribute value.
+     */
+    public void delete(String name) throws IOException {
+        if (name.equalsIgnoreCase(DESCRIPTIONS)) {
+            accessDescriptions = new ArrayList<AccessDescription>();
+        } else {
+            throw new IOException("Attribute name [" + name +
+                                "] not recognized by " +
+                                "CertAttrSet:SubjectInfoAccessExtension.");
+        }
+        encodeThis();
+    }
+
+    /**
+     * Return an enumeration of names of attributes existing within this
+     * attribute.
+     */
+    public Enumeration<String> getElements() {
+        AttributeNameEnumeration elements = new AttributeNameEnumeration();
+        elements.addElement(DESCRIPTIONS);
+        return elements.elements();
+    }
+
+     // Encode this extension value
+    private void encodeThis() throws IOException {
+        if (accessDescriptions.isEmpty()) {
+            this.extensionValue = null;
+        } else {
+            DerOutputStream ads = new DerOutputStream();
+            for (AccessDescription accessDescription : accessDescriptions) {
+                accessDescription.encode(ads);
+            }
+            DerOutputStream seq = new DerOutputStream();
+            seq.write(DerValue.tag_Sequence, ads);
+            this.extensionValue = seq.toByteArray();
+        }
+    }
+
+    /**
+     * Return the extension as user readable string.
+     */
+    public String toString() {
+        return super.toString() + "SubjectInfoAccess [\n  "
+               + accessDescriptions + "\n]\n";
+    }
+
+}
diff --git a/jdk/src/share/native/java/util/zip/zip_util.c b/jdk/src/share/native/java/util/zip/zip_util.c
index 3b00b95..9767dba 100644
--- a/jdk/src/share/native/java/util/zip/zip_util.c
+++ b/jdk/src/share/native/java/util/zip/zip_util.c
@@ -135,11 +135,6 @@
 #endif
 }
 
-static jlong
-ZFILE_Lseek(ZFILE zfd, off_t offset, int whence) {
-    return IO_Lseek(zfd, offset, whence);
-}
-
 static int
 ZFILE_read(ZFILE zfd, char *buf, jint nbytes) {
 #ifdef WIN32
@@ -216,7 +211,7 @@
 static int
 readFullyAt(ZFILE zfd, void *buf, jlong len, jlong offset)
 {
-    if (ZFILE_Lseek(zfd, (off_t) offset, SEEK_SET) == -1) {
+    if (IO_Lseek(zfd, offset, SEEK_SET) == -1) {
         return -1; /* lseek failure. */
     }
 
@@ -476,7 +471,7 @@
     unsigned char *cp;
 #ifdef USE_MMAP
     static jlong pagesize;
-    off_t offset;
+    jlong offset;
 #endif
     unsigned char endbuf[ENDHDR];
     jzcell *entries;
@@ -534,7 +529,7 @@
         */
         zip->mlen = cenpos - offset + cenlen + ENDHDR;
         zip->offset = offset;
-        mappedAddr = mmap(0, zip->mlen, PROT_READ, MAP_SHARED, zip->zfd, offset);
+        mappedAddr = mmap64(0, zip->mlen, PROT_READ, MAP_SHARED, zip->zfd, (off64_t) offset);
         zip->maddr = (mappedAddr == (void*) MAP_FAILED) ? NULL :
             (unsigned char*)mappedAddr;
 
@@ -720,7 +715,7 @@
         return NULL;
     }
 
-    len = zip->len = ZFILE_Lseek(zfd, 0, SEEK_END);
+    len = zip->len = IO_Lseek(zfd, 0, SEEK_END);
     if (len <= 0) {
         if (len == 0) { /* zip file is empty */
             if (pmsg) {
diff --git a/jdk/src/share/native/java/util/zip/zip_util.h b/jdk/src/share/native/java/util/zip/zip_util.h
index 5fdebaf..353ebd2 100644
--- a/jdk/src/share/native/java/util/zip/zip_util.h
+++ b/jdk/src/share/native/java/util/zip/zip_util.h
@@ -174,7 +174,7 @@
 #ifdef USE_MMAP
     unsigned char *maddr; /* beginning address of the CEN & ENDHDR */
     jlong mlen;           /* length (in bytes) mmaped */
-    off_t offset;         /* offset of the mmapped region from the
+    jlong offset;         /* offset of the mmapped region from the
                              start of the file. */
 #else
     cencache cencache;    /* CEN header cache */
diff --git a/jdk/src/share/native/sun/nio/ch/genSocketOptionRegistry.c b/jdk/src/share/native/sun/nio/ch/genSocketOptionRegistry.c
index 70f95c6..bcd546b 100644
--- a/jdk/src/share/native/sun/nio/ch/genSocketOptionRegistry.c
+++ b/jdk/src/share/native/sun/nio/ch/genSocketOptionRegistry.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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
@@ -71,9 +71,9 @@
     out("class SocketOptionRegistry {                                                   ");
     out("    private SocketOptionRegistry() { }                                         ");
     out("    private static class RegistryKey {                                         ");
-    out("        private final SocketOption name;                                       ");
+    out("        private final SocketOption<?> name;                                    ");
     out("        private final ProtocolFamily family;                                   ");
-    out("        RegistryKey(SocketOption name, ProtocolFamily family) {                ");
+    out("        RegistryKey(SocketOption<?> name, ProtocolFamily family) {                ");
     out("            this.name = name;                                                  ");
     out("            this.family = family;                                              ");
     out("        }                                                                      ");
@@ -119,7 +119,7 @@
     out("            return map;                                                        ");
     out("        }                                                                      ");
     out("    }                                                                          ");
-    out("    public static OptionKey findOption(SocketOption name, ProtocolFamily family) { ");
+    out("    public static OptionKey findOption(SocketOption<?> name, ProtocolFamily family) { ");
     out("        RegistryKey key = new RegistryKey(name, family);                       ");
     out("        return LazyInitialization.options.get(key);                            ");
     out("    }                                                                          ");
diff --git a/jdk/src/share/sample/nio/file/AclEdit.java b/jdk/src/share/sample/nio/file/AclEdit.java
new file mode 100644
index 0000000..55ed9c0
--- /dev/null
+++ b/jdk/src/share/sample/nio/file/AclEdit.java
@@ -0,0 +1,296 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Sun Microsystems nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.io.IOException;
+import java.util.*;
+import java.util.regex.Pattern;
+
+/**
+ * Sample utility for editing a file's ACL.
+ */
+
+public class AclEdit {
+
+    // parse string as list of ACE permissions separated by /
+    static Set<AclEntryPermission> parsePermissions(String permsString) {
+        Set<AclEntryPermission> perms = new HashSet<AclEntryPermission>();
+        String[] result = permsString.split("/");
+        for (String s : result) {
+            if (s.equals(""))
+                continue;
+            try {
+                perms.add(AclEntryPermission.valueOf(s.toUpperCase()));
+            } catch (IllegalArgumentException x) {
+                System.err.format("Invalid permission '%s'\n", s);
+                System.exit(-1);
+            }
+        }
+        return perms;
+    }
+
+    // parse string as list of ACE flags separated by /
+    static Set<AclEntryFlag> parseFlags(String flagsString) {
+        Set<AclEntryFlag> flags = new HashSet<AclEntryFlag>();
+        String[] result = flagsString.split("/");
+        for (String s : result) {
+            if (s.equals(""))
+                continue;
+            try {
+                flags.add(AclEntryFlag.valueOf(s.toUpperCase()));
+            } catch (IllegalArgumentException x) {
+                System.err.format("Invalid flag '%s'\n", s);
+                System.exit(-1);
+            }
+        }
+        return flags;
+    }
+
+    // parse ACE type
+    static AclEntryType parseType(String typeString) {
+        // FIXME: support audit and alarm types in the future
+        if (typeString.equalsIgnoreCase("allow"))
+            return AclEntryType.ALLOW;
+        if (typeString.equalsIgnoreCase("deny"))
+            return AclEntryType.DENY;
+        System.err.format("Invalid type '%s'\n", typeString);
+        System.exit(-1);
+        return null;    // keep compiler happy
+    }
+
+    /**
+     * Parse string of the form:
+     *   [user|group:]<username|groupname>:<perms>[:flags]:<allow|deny>
+     */
+    static AclEntry parseAceString(String s,
+                                   UserPrincipalLookupService lookupService)
+    {
+        String[] result = s.split(":");
+
+        // must have at least 3 components (username:perms:type)
+        if (result.length < 3)
+            usage();
+
+        int index = 0;
+        int remaining = result.length;
+
+        // optional first component can indicate user or group type
+        boolean isGroup = false;
+        if (result[index].equalsIgnoreCase("user") ||
+            result[index].equalsIgnoreCase("group"))
+        {
+            if (--remaining < 3)
+                usage();
+            isGroup = result[index++].equalsIgnoreCase("group");
+        }
+
+        // user and permissions required
+        String userString = result[index++]; remaining--;
+        String permsString = result[index++]; remaining--;
+
+        // flags are optional
+        String flagsString = "";
+        String typeString = null;
+        if (remaining == 1) {
+            typeString = result[index++];
+        } else {
+            if (remaining == 2) {
+                flagsString = result[index++];
+                typeString = result[index++];
+            } else {
+                usage();
+            }
+        }
+
+        // lookup UserPrincipal
+        UserPrincipal user = null;
+        try {
+            user = (isGroup) ?
+                lookupService.lookupPrincipalByGroupName(userString) :
+                lookupService.lookupPrincipalByName(userString);
+        } catch (UserPrincipalNotFoundException x) {
+            System.err.format("Invalid %s '%s'\n",
+                ((isGroup) ? "group" : "user"),
+                userString);
+            System.exit(-1);
+        } catch (IOException x) {
+            System.err.format("Lookup of '%s' failed: %s\n", userString, x);
+            System.exit(-1);
+        }
+
+        // map string representation of permissions, flags, and type
+        Set<AclEntryPermission> perms = parsePermissions(permsString);
+        Set<AclEntryFlag> flags = parseFlags(flagsString);
+        AclEntryType type = parseType(typeString);
+
+        // build the ACL entry
+        return AclEntry.newBuilder()
+            .setType(type)
+            .setPrincipal(user)
+            .setPermissions(perms).setFlags(flags).build();
+    }
+
+    static void usage() {
+        System.err.println("usage: java AclEdit [ACL-operation] file");
+        System.err.println("");
+        System.err.println("Example 1: Prepends access control entry to the begining of the myfile's ACL");
+        System.err.println("       java AclEdit A+alice:read_data/read_attributes:allow myfile");
+        System.err.println("");
+        System.err.println("Example 2: Remove the entry at index 6 of myfile's ACL");
+        System.err.println("       java AclEdit A6- myfile");
+        System.err.println("");
+        System.err.println("Example 3: Replace the entry at index 2 of myfile's ACL");
+        System.err.println("       java AclEdit A2=bob:write_data/append_data:deny myfile");
+        System.exit(-1);
+    }
+
+    static enum Action {
+        PRINT,
+        ADD,
+        REMOVE,
+        REPLACE;
+    }
+
+    /**
+     * Main class: parses arguments and prints or edits ACL
+     */
+    public static void main(String[] args) throws IOException {
+        Action action = null;
+        int index = -1;
+        String entryString = null;
+
+        // parse arguments
+        if (args.length < 1 || args[0].equals("-help") || args[0].equals("-?"))
+            usage();
+
+        if (args.length == 1) {
+            action = Action.PRINT;
+        } else {
+            String s = args[0];
+
+            // A[index]+entry
+            if (Pattern.matches("^A[0-9]*\\+.*", s)) {
+                String[] result = s.split("\\+", 2);
+                if (result.length == 2) {
+                    if (result[0].length() < 2) {
+                        index = 0;
+                    } else {
+                        index = Integer.parseInt(result[0].substring(1));
+                    }
+                    entryString = result[1];
+                    action = Action.ADD;
+                }
+            }
+
+            // Aindex-
+            if (Pattern.matches("^A[0-9]+\\-", s)) {
+                String[] result = s.split("\\-", 2);
+                if (result.length == 2) {
+                    index = Integer.parseInt(result[0].substring(1));
+                    entryString = result[1];
+                    action = Action.REMOVE;
+                }
+            }
+
+            // Aindex=entry
+            if (Pattern.matches("^A[0-9]+=.*", s)) {
+                String[] result = s.split("=", 2);
+                if (result.length == 2) {
+                    index = Integer.parseInt(result[0].substring(1));
+                    entryString = result[1];
+                    action = Action.REPLACE;
+                }
+            }
+        }
+        if (action == null)
+            usage();
+
+        int fileArg = (action == Action.PRINT) ? 0 : 1;
+        Path file = Paths.get(args[fileArg]);
+
+        // read file's ACL
+        AclFileAttributeView view =
+            file.getFileAttributeView(AclFileAttributeView.class);
+        if (view == null) {
+            System.err.println("ACLs not supported on this platform");
+            System.exit(-1);
+        }
+        List<AclEntry> acl = view.getAcl();
+
+        switch (action) {
+            // print ACL
+            case PRINT : {
+                for (int i=0; i<acl.size(); i++) {
+                    System.out.format("%5d: %s\n", i, acl.get(i));
+                }
+                break;
+            }
+
+            // add ACE to existing ACL
+            case ADD: {
+                AclEntry entry = parseAceString(entryString, file
+                    .getFileSystem().getUserPrincipalLookupService());
+                if (index >= acl.size()) {
+                    acl.add(entry);
+                } else {
+                    acl.add(index, entry);
+                }
+                view.setAcl(acl);
+                break;
+            }
+
+            // remove ACE
+            case REMOVE: {
+                if (index >= acl.size()) {
+                    System.err.format("Index '%d' is invalid", index);
+                    System.exit(-1);
+                }
+                acl.remove(index);
+                view.setAcl(acl);
+                break;
+            }
+
+            // replace ACE
+            case REPLACE: {
+                if (index >= acl.size()) {
+                    System.err.format("Index '%d' is invalid", index);
+                    System.exit(-1);
+                }
+                AclEntry entry = parseAceString(entryString, file
+                    .getFileSystem().getUserPrincipalLookupService());
+                acl.set(index, entry);
+                view.setAcl(acl);
+                break;
+            }
+        }
+    }
+}
diff --git a/jdk/src/share/sample/nio/file/Chmod.java b/jdk/src/share/sample/nio/file/Chmod.java
new file mode 100644
index 0000000..eeb54ad
--- /dev/null
+++ b/jdk/src/share/sample/nio/file/Chmod.java
@@ -0,0 +1,347 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Sun Microsystems nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import static java.nio.file.attribute.PosixFilePermission.*;
+import static java.nio.file.FileVisitResult.*;
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * Sample code that changes the permissions of files in a similar manner to the
+ * chmod(1) program.
+ */
+
+public class Chmod {
+
+    /**
+     * Compiles a list of one or more <em>symbolic mode expressions</em> that
+     * may be used to change a set of file permissions. This method is
+     * intended for use where file permissions are required to be changed in
+     * a manner similar to the UNIX <i>chmod</i> program.
+     *
+     * <p> The {@code exprs} parameter is a comma separated list of expressions
+     * where each takes the form:
+     * <blockquote>
+     * <i>who operator</i> [<i>permissions</i>]
+     * </blockquote>
+     * where <i>who</i> is one or more of the characters {@code 'u'}, {@code 'g'},
+     * {@code 'o'}, or {@code 'a'} meaning the owner (user), group, others, or
+     * all (owner, group, and others) respectively.
+     *
+     * <p> <i>operator</i> is the character {@code '+'}, {@code '-'}, or {@code
+     * '='} signifying how permissions are to be changed. {@code '+'} means the
+     * permissions are added, {@code '-'} means the permissions are removed, and
+     * {@code '='} means the permissions are assigned absolutely.
+     *
+     * <p> <i>permissions</i> is a sequence of zero or more of the following:
+     * {@code 'r'} for read permission, {@code 'w'} for write permission, and
+     * {@code 'x'} for execute permission. If <i>permissions</i> is omitted
+     * when assigned absolutely, then the permissions are cleared for
+     * the owner, group, or others as identified by <i>who</i>. When omitted
+     * when adding or removing then the expression is ignored.
+     *
+     * <p> The following examples demonstrate possible values for the {@code
+     * exprs} parameter:
+     *
+     * <table border="0">
+     * <tr>
+     *   <td> {@code u=rw} </td>
+     *   <td> Sets the owner permissions to be read and write. </td>
+     * </tr>
+     * <tr>
+     *   <td> {@code ug+w} </td>
+     *   <td> Sets the owner write and group write permissions. </td>
+     * </tr>
+     * <tr>
+     *   <td> {@code u+w,o-rwx} </td>
+     *   <td> Sets the owner write, and removes the others read, others write
+     *     and others execute permissions. </td>
+     * </tr>
+     * <tr>
+     *   <td> {@code o=} </td>
+     *   <td> Sets the others permission to none (others read, others write and
+     *     others execute permissions are removed if set) </td>
+     * </tr>
+     * </table>
+     *
+     * @param   exprs
+     *          List of one or more <em>symbolic mode expressions</em>
+     *
+     * @return  A {@code Changer} that may be used to changer a set of
+     *          file permissions
+     *
+     * @throws  IllegalArgumentException
+     *          If the value of the {@code exprs} parameter is invalid
+     */
+    public static Changer compile(String exprs) {
+        // minimum is who and operator (u= for example)
+        if (exprs.length() < 2)
+            throw new IllegalArgumentException("Invalid mode");
+
+        // permissions that the changer will add or remove
+        final Set<PosixFilePermission> toAdd = new HashSet<PosixFilePermission>();
+        final Set<PosixFilePermission> toRemove = new HashSet<PosixFilePermission>();
+
+        // iterate over each of expression modes
+        for (String expr: exprs.split(",")) {
+            // minimum of who and operator
+            if (expr.length() < 2)
+                throw new IllegalArgumentException("Invalid mode");
+
+            int pos = 0;
+
+            // who
+            boolean u = false;
+            boolean g = false;
+            boolean o = false;
+            boolean done = false;
+            for (;;) {
+                switch (expr.charAt(pos)) {
+                    case 'u' : u = true; break;
+                    case 'g' : g = true; break;
+                    case 'o' : o = true; break;
+                    case 'a' : u = true; g = true; o = true; break;
+                    default : done = true;
+                }
+                if (done)
+                    break;
+                pos++;
+            }
+            if (!u && !g && !o)
+                throw new IllegalArgumentException("Invalid mode");
+
+            // get operator and permissions
+            char op = expr.charAt(pos++);
+            String mask = (expr.length() == pos) ? "" : expr.substring(pos);
+
+            // operator
+            boolean add = (op == '+');
+            boolean remove = (op == '-');
+            boolean assign = (op == '=');
+            if (!add && !remove && !assign)
+                throw new IllegalArgumentException("Invalid mode");
+
+            // who= means remove all
+            if (assign && mask.length() == 0) {
+                assign = false;
+                remove = true;
+                mask = "rwx";
+            }
+
+            // permissions
+            boolean r = false;
+            boolean w = false;
+            boolean x = false;
+            for (int i=0; i<mask.length(); i++) {
+                switch (mask.charAt(i)) {
+                    case 'r' : r = true; break;
+                    case 'w' : w = true; break;
+                    case 'x' : x = true; break;
+                    default:
+                        throw new IllegalArgumentException("Invalid mode");
+                }
+            }
+
+            // update permissions set
+            if (add) {
+                if (u) {
+                    if (r) toAdd.add(OWNER_READ);
+                    if (w) toAdd.add(OWNER_WRITE);
+                    if (x) toAdd.add(OWNER_EXECUTE);
+                }
+                if (g) {
+                    if (r) toAdd.add(GROUP_READ);
+                    if (w) toAdd.add(GROUP_WRITE);
+                    if (x) toAdd.add(GROUP_EXECUTE);
+                }
+                if (o) {
+                    if (r) toAdd.add(OTHERS_READ);
+                    if (w) toAdd.add(OTHERS_WRITE);
+                    if (x) toAdd.add(OTHERS_EXECUTE);
+                }
+            }
+            if (remove) {
+                if (u) {
+                    if (r) toRemove.add(OWNER_READ);
+                    if (w) toRemove.add(OWNER_WRITE);
+                    if (x) toRemove.add(OWNER_EXECUTE);
+                }
+                if (g) {
+                    if (r) toRemove.add(GROUP_READ);
+                    if (w) toRemove.add(GROUP_WRITE);
+                    if (x) toRemove.add(GROUP_EXECUTE);
+                }
+                if (o) {
+                    if (r) toRemove.add(OTHERS_READ);
+                    if (w) toRemove.add(OTHERS_WRITE);
+                    if (x) toRemove.add(OTHERS_EXECUTE);
+                }
+            }
+            if (assign) {
+                if (u) {
+                    if (r) toAdd.add(OWNER_READ);
+                      else toRemove.add(OWNER_READ);
+                    if (w) toAdd.add(OWNER_WRITE);
+                      else toRemove.add(OWNER_WRITE);
+                    if (x) toAdd.add(OWNER_EXECUTE);
+                      else toRemove.add(OWNER_EXECUTE);
+                }
+                if (g) {
+                    if (r) toAdd.add(GROUP_READ);
+                      else toRemove.add(GROUP_READ);
+                    if (w) toAdd.add(GROUP_WRITE);
+                      else toRemove.add(GROUP_WRITE);
+                    if (x) toAdd.add(GROUP_EXECUTE);
+                      else toRemove.add(GROUP_EXECUTE);
+                }
+                if (o) {
+                    if (r) toAdd.add(OTHERS_READ);
+                      else toRemove.add(OTHERS_READ);
+                    if (w) toAdd.add(OTHERS_WRITE);
+                      else toRemove.add(OTHERS_WRITE);
+                    if (x) toAdd.add(OTHERS_EXECUTE);
+                      else toRemove.add(OTHERS_EXECUTE);
+                }
+            }
+        }
+
+        // return changer
+        return new Changer() {
+            @Override
+            public Set<PosixFilePermission> change(Set<PosixFilePermission> perms) {
+                perms.addAll(toAdd);
+                perms.removeAll(toRemove);
+                return perms;
+            }
+        };
+    }
+
+    /**
+     * A task that <i>changes</i> a set of {@link PosixFilePermission} elements.
+     */
+    public interface Changer {
+        /**
+         * Applies the changes to the given set of permissions.
+         *
+         * @param   perms
+         *          The set of permissions to change
+         *
+         * @return  The {@code perms} parameter
+         */
+        Set<PosixFilePermission> change(Set<PosixFilePermission> perms);
+    }
+
+    /**
+     * Changes the permissions of the file using the given Changer.
+     */
+    static void chmod(FileRef file, Changer changer) {
+        try {
+            Set<PosixFilePermission> perms = Attributes
+                .readPosixFileAttributes(file).permissions();
+            Attributes.setPosixFilePermissions(file, changer.change(perms));
+        } catch (IOException x) {
+            System.err.println(x);
+        }
+    }
+
+    /**
+     * Changes the permission of each file and directory visited
+     */
+    static class TreeVisitor implements FileVisitor<FileRef> {
+        private final Changer changer;
+
+        TreeVisitor(Changer changer) {
+            this.changer = changer;
+        }
+
+        @Override
+        public FileVisitResult preVisitDirectory(FileRef dir) {
+            chmod(dir, changer);
+            return CONTINUE;
+        }
+
+        @Override
+        public FileVisitResult preVisitDirectoryFailed(FileRef dir, IOException exc) {
+            System.err.println("WARNING: " + exc);
+            return CONTINUE;
+        }
+
+        @Override
+        public FileVisitResult visitFile(FileRef file, BasicFileAttributes attrs) {
+            chmod(file, changer);
+            return CONTINUE;
+        }
+
+        @Override
+        public FileVisitResult postVisitDirectory(FileRef dir, IOException exc) {
+            if (exc != null)
+                System.err.println("WARNING: " + exc);
+            return CONTINUE;
+        }
+
+        @Override
+        public FileVisitResult visitFileFailed(FileRef file, IOException exc) {
+            System.err.println("WARNING: " + exc);
+            return CONTINUE;
+        }
+    }
+
+    static void usage() {
+        System.err.println("java Chmod [-R] symbolic-mode-list file...");
+        System.exit(-1);
+    }
+
+    public static void main(String[] args) throws IOException {
+        if (args.length < 2)
+            usage();
+        int argi = 0;
+        int maxDepth = 0;
+        if (args[argi].equals("-R")) {
+            if (args.length < 3)
+                usage();
+            argi++;
+            maxDepth = Integer.MAX_VALUE;
+        }
+
+        // compile the symbolic mode expressions
+        Changer changer = compile(args[argi++]);
+        TreeVisitor visitor = new TreeVisitor(changer);
+
+        Set<FileVisitOption> opts = Collections.emptySet();
+        while (argi < args.length) {
+            Path file = Paths.get(args[argi]);
+            Files.walkFileTree(file, opts, maxDepth, visitor);
+            argi++;
+        }
+    }
+}
diff --git a/jdk/src/share/sample/nio/file/Copy.java b/jdk/src/share/sample/nio/file/Copy.java
new file mode 100644
index 0000000..e1d5d04
--- /dev/null
+++ b/jdk/src/share/sample/nio/file/Copy.java
@@ -0,0 +1,217 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Sun Microsystems nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.nio.file.*;
+import static java.nio.file.StandardCopyOption.*;
+import java.nio.file.attribute.*;
+import static java.nio.file.FileVisitResult.*;
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * Sample code that copies files in a similar manner to the cp(1) program.
+ */
+
+public class Copy {
+
+    /**
+     * Returns {@code true} if okay to overwrite a  file ("cp -i")
+     */
+    static boolean okayToOverwrite(FileRef file) {
+        String answer = System.console().readLine("overwrite %s (yes/no)? ", file);
+        return (answer.equalsIgnoreCase("y") || answer.equalsIgnoreCase("yes"));
+    }
+
+    /**
+     * Copy source file to target location. If {@code prompt} is true then
+     * prompted user to overwrite target if it exists. The {@code preserve}
+     * parameter determines if file attributes should be copied/preserved.
+     */
+    static void copyFile(Path source, Path target, boolean prompt, boolean preserve) {
+        CopyOption[] options = (preserve) ?
+            new CopyOption[] { COPY_ATTRIBUTES, REPLACE_EXISTING } :
+            new CopyOption[] { REPLACE_EXISTING };
+        if (!prompt || target.notExists() || okayToOverwrite(target)) {
+            try {
+                source.copyTo(target, options);
+            } catch (IOException x) {
+                System.err.format("Unable to create: %s: %s%n", target, x);
+            }
+        }
+    }
+
+    /**
+     * A {@code FileVisitor} that copies a file-tree ("cp -r")
+     */
+    static class TreeCopier implements FileVisitor<Path> {
+        private final Path source;
+        private final Path target;
+        private final boolean prompt;
+        private final boolean preserve;
+
+        TreeCopier(Path source, Path target, boolean prompt, boolean preserve) {
+            this.source = source;
+            this.target = target;
+            this.prompt = prompt;
+            this.preserve = preserve;
+        }
+
+        @Override
+        public FileVisitResult preVisitDirectory(Path dir) {
+            // before visiting entries in a directory we copy the directory
+            // (okay if directory already exists).
+            CopyOption[] options = (preserve) ?
+                new CopyOption[] { COPY_ATTRIBUTES } : new CopyOption[0];
+
+            Path newdir = target.resolve(source.relativize(dir));
+            try {
+                dir.copyTo(newdir, options);
+            } catch (FileAlreadyExistsException x) {
+                // ignore
+            } catch (IOException x) {
+                System.err.format("Unable to create: %s: %s%n", newdir, x);
+                return SKIP_SUBTREE;
+            }
+            return CONTINUE;
+        }
+
+        @Override
+        public FileVisitResult preVisitDirectoryFailed(Path dir, IOException exc) {
+            System.err.format("Unable to copy: %s: %s%n", dir, exc);
+            return CONTINUE;
+        }
+
+        @Override
+        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
+            if (attrs.isDirectory()) {
+                System.err.println("cycle detected: " + file);
+            } else {
+                copyFile(file, target.resolve(source.relativize(file)),
+                         prompt, preserve);
+            }
+            return CONTINUE;
+        }
+
+        @Override
+        public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
+            // fix up modification time of directory when done
+            if (exc == null && preserve) {
+                try {
+                    BasicFileAttributes attrs = Attributes.readBasicFileAttributes(dir);
+                    Path newdir = target.resolve(source.relativize(dir));
+                    Attributes.setLastModifiedTime(newdir,
+                        attrs.lastModifiedTime(), attrs.resolution());
+                } catch (IOException x) {
+                    // ignore
+                }
+            }
+            return CONTINUE;
+        }
+
+        @Override
+        public FileVisitResult visitFileFailed(Path file, IOException exc) {
+            System.err.format("Unable to copy: %s: %s%n", file, exc);
+            return CONTINUE;
+        }
+    }
+
+    static void usage() {
+        System.err.println("java Copy [-ip] source... target");
+        System.err.println("java Copy -r [-ip] source-dir... target");
+        System.exit(-1);
+    }
+
+    public static void main(String[] args) throws IOException {
+        boolean recursive = false;
+        boolean prompt = false;
+        boolean preserve = false;
+
+        // process options
+        int argi = 0;
+        while (argi < args.length) {
+            String arg = args[argi];
+            if (!arg.startsWith("-"))
+                break;
+            if (arg.length() < 2)
+                usage();
+            for (int i=1; i<arg.length(); i++) {
+                char c = arg.charAt(i);
+                switch (c) {
+                    case 'r' : recursive = true; break;
+                    case 'i' : prompt = true; break;
+                    case 'p' : preserve = true; break;
+                    default : usage();
+                }
+            }
+            argi++;
+        }
+
+        // remaining arguments are the source files(s) and the target location
+        int remaining = args.length - argi;
+        if (remaining < 2)
+            usage();
+        Path[] source = new Path[remaining-1];
+        int i=0;
+        while (remaining > 1) {
+            source[i++] = Paths.get(args[argi++]);
+            remaining--;
+        }
+        Path target = Paths.get(args[argi]);
+
+        // check if target is a directory
+        boolean isDir = false;
+        try {
+            isDir = Attributes.readBasicFileAttributes(target).isDirectory();
+        } catch (IOException x) {
+        }
+
+        // copy each source file/directory to target
+        for (i=0; i<source.length; i++) {
+            Path dest = (isDir) ? target.resolve(source[i].getName()) : target;
+
+            if (recursive) {
+                // follow links when copying files
+                EnumSet<FileVisitOption> opts = EnumSet.of(FileVisitOption.FOLLOW_LINKS);
+                TreeCopier tc = new TreeCopier(source[i], dest, prompt, preserve);
+                Files.walkFileTree(source[i], opts, -1, tc);
+            } else {
+                // not recursive so source must not be a directory
+                try {
+                    if (Attributes.readBasicFileAttributes(source[i]).isDirectory()) {
+                        System.err.format("%s: is a directory%n", source[i]);
+                        continue;
+                    }
+                } catch (IOException x) { }
+                copyFile(source[i], dest, prompt, preserve);
+            }
+        }
+    }
+}
diff --git a/jdk/src/share/sample/nio/file/DiskUsage.java b/jdk/src/share/sample/nio/file/DiskUsage.java
new file mode 100644
index 0000000..ff16d88
--- /dev/null
+++ b/jdk/src/share/sample/nio/file/DiskUsage.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Sun Microsystems nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.io.IOException;
+
+/**
+ * Example utility that works like the df(1M) program to print out disk space
+ * information
+ */
+
+public class DiskUsage {
+
+    static final long K = 1024;
+
+    static void printFileStore(FileStore store) throws IOException {
+        FileStoreSpaceAttributes attrs = Attributes.readFileStoreSpaceAttributes(store);
+
+        long total = attrs.totalSpace() / K;
+        long used = (attrs.totalSpace() - attrs.unallocatedSpace()) / K;
+        long avail = attrs.usableSpace() / K;
+
+        String s = store.toString();
+        if (s.length() > 20) {
+            System.out.println(s);
+            s = "";
+        }
+        System.out.format("%-20s %12d %12d %12d\n", s, total, used, avail);
+    }
+
+    public static void main(String[] args) throws IOException {
+        System.out.format("%-20s %12s %12s %12s\n", "Filesystem", "kbytes", "used", "avail");
+        if (args.length == 0) {
+            FileSystem fs = FileSystems.getDefault();
+            for (FileStore store: fs.getFileStores()) {
+                printFileStore(store);
+            }
+        } else {
+            for (String file: args) {
+                FileStore store = Paths.get(file).getFileStore();
+                printFileStore(store);
+            }
+        }
+    }
+}
diff --git a/jdk/src/share/sample/nio/file/FileType.java b/jdk/src/share/sample/nio/file/FileType.java
new file mode 100644
index 0000000..31fb452
--- /dev/null
+++ b/jdk/src/share/sample/nio/file/FileType.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Sun Microsystems nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.io.IOException;
+
+public class FileType {
+    public static void main(String[] args) throws IOException {
+        if (args.length == 0) {
+            System.err.println("usage: java FileType file...");
+            System.exit(-1);
+        }
+        for (String arg: args) {
+            Path file = Paths.get(arg);
+            BasicFileAttributes attrs = Attributes.readBasicFileAttributes(file);
+
+            String type;
+            if (attrs.isDirectory()) {
+                type = "directory";
+            } else {
+                type = Files.probeContentType(file);
+                if (type == null)
+                    type = "<not recognized>";
+            }
+            System.out.format("%s\t%s%n", file, type);
+        }
+    }
+}
diff --git a/jdk/src/share/sample/nio/file/WatchDir.java b/jdk/src/share/sample/nio/file/WatchDir.java
new file mode 100644
index 0000000..b8b6474
--- /dev/null
+++ b/jdk/src/share/sample/nio/file/WatchDir.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Sun Microsystems nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.nio.file.*;
+import static java.nio.file.StandardWatchEventKind.*;
+import static java.nio.file.LinkOption.*;
+import java.nio.file.attribute.*;
+import java.io.*;
+import java.util.*;
+
+/**
+ * Example to watch a directory (or tree) for changes to files.
+ */
+
+public class WatchDir {
+
+    private final WatchService watcher;
+    private final Map<WatchKey,Path> keys;
+    private final boolean recursive;
+    private boolean trace = false;
+
+    @SuppressWarnings("unchecked")
+    static <T> WatchEvent<T> cast(WatchEvent<?> event) {
+        return (WatchEvent<T>)event;
+    }
+
+    /**
+     * Register the given directory with the WatchService
+     */
+    private void register(Path dir) throws IOException {
+        WatchKey key = dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
+        if (trace) {
+            FileRef prev = keys.get(key);
+            if (prev == null) {
+                System.out.format("register: %s\n", dir);
+            } else {
+                if (!dir.equals(prev)) {
+                    System.out.format("update: %s -> %s\n", prev, dir);
+                }
+            }
+        }
+        keys.put(key, dir);
+    }
+
+    /**
+     * Register the given directory, and all its sub-directories, with the
+     * WatchService.
+     */
+    private void registerAll(final Path start) throws IOException {
+        // register directory and sub-directories
+        Files.walkFileTree(start, new SimpleFileVisitor<Path>() {
+            @Override
+            public FileVisitResult preVisitDirectory(Path dir) {
+                try {
+                    register(dir);
+                } catch (IOException x) {
+                    throw new IOError(x);
+                }
+                return FileVisitResult.CONTINUE;
+            }
+        });
+    }
+
+    /**
+     * Creates a WatchService and registers the given directory
+     */
+    WatchDir(Path dir, boolean recursive) throws IOException {
+        this.watcher = FileSystems.getDefault().newWatchService();
+        this.keys = new HashMap<WatchKey,Path>();
+        this.recursive = recursive;
+
+        if (recursive) {
+            System.out.format("Scanning %s ...\n", dir);
+            registerAll(dir);
+            System.out.println("Done.");
+        } else {
+            register(dir);
+        }
+
+        // enable trace after initial registration
+        this.trace = true;
+    }
+
+    /**
+     * Process all events for keys queued to the watcher
+     */
+    void processEvents() {
+        for (;;) {
+
+            // wait for key to be signalled
+            WatchKey key;
+            try {
+                key = watcher.take();
+            } catch (InterruptedException x) {
+                return;
+            }
+
+            Path dir = keys.get(key);
+            if (dir == null) {
+                System.err.println("WatchKey not recognized!!");
+                continue;
+            }
+
+            for (WatchEvent<?> event: key.pollEvents()) {
+                WatchEvent.Kind kind = event.kind();
+
+                // TBD - provide example of how OVERFLOW event is handled
+                if (kind == OVERFLOW) {
+                    continue;
+                }
+
+                // Context for directory entry event is the file name of entry
+                WatchEvent<Path> ev = cast(event);
+                Path name = ev.context();
+                Path child = dir.resolve(name);
+
+                // print out event
+                System.out.format("%s: %s\n", event.kind().name(), child);
+
+                // if directory is created, and watching recursively, then
+                // register it and its sub-directories
+                if (recursive && (kind == ENTRY_CREATE)) {
+                    try {
+                        if (Attributes.readBasicFileAttributes(child, NOFOLLOW_LINKS).isDirectory()) {
+                            registerAll(child);
+                        }
+                    } catch (IOException x) {
+                        // ignore to keep sample readbale
+                    }
+                }
+            }
+
+            // reset key and remove from set if directory no longer accessible
+            boolean valid = key.reset();
+            if (!valid) {
+                keys.remove(key);
+
+                // all directories are inaccessible
+                if (keys.isEmpty()) {
+                    break;
+                }
+            }
+        }
+    }
+
+    static void usage() {
+        System.err.println("usage: java WatchDir [-r] dir");
+        System.exit(-1);
+    }
+
+    public static void main(String[] args) throws IOException {
+        // parse arguments
+        if (args.length == 0 || args.length > 2)
+            usage();
+        boolean recursive = false;
+        int dirArg = 0;
+        if (args[0].equals("-r")) {
+            if (args.length < 2)
+                usage();
+            recursive = true;
+            dirArg++;
+        }
+
+        // register directory and process its events
+        Path dir = Paths.get(args[dirArg]);
+        new WatchDir(dir, recursive).processEvents();
+    }
+}
diff --git a/jdk/src/share/sample/nio/file/Xdd.java b/jdk/src/share/sample/nio/file/Xdd.java
new file mode 100644
index 0000000..f66597e
--- /dev/null
+++ b/jdk/src/share/sample/nio/file/Xdd.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Sun Microsystems nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.io.IOException;
+
+/**
+ * Example code to list/set/get/delete the user-defined attributes of a file.
+ */
+
+public class Xdd {
+
+    static void usage() {
+        System.out.println("Usage: java Xdd <file>");
+        System.out.println("       java Xdd -set <name>=<value> <file>");
+        System.out.println("       java Xdd -get <name> <file>");
+        System.out.println("       java Xdd -del <name> <file>");
+        System.exit(-1);
+    }
+
+    public static void main(String[] args) throws IOException {
+        // one or three parameters
+        if (args.length != 1 && args.length != 3)
+            usage();
+
+        Path file = (args.length == 1) ?
+            Paths.get(args[0]) : Paths.get(args[2]);
+
+        // check that user defined attributes are supported by the file system
+        FileStore store = file.getFileStore();
+        if (!store.supportsFileAttributeView("xattr")) {
+            System.err.format("UserDefinedFileAttributeView not supported on %s\n", store);
+            System.exit(-1);
+
+        }
+        UserDefinedFileAttributeView view = file.
+            getFileAttributeView(UserDefinedFileAttributeView.class);
+
+        // list user defined attributes
+        if (args.length == 1) {
+            System.out.println("    Size  Name");
+            System.out.println("--------  --------------------------------------");
+            for (String name: view.list()) {
+                System.out.format("%8d  %s\n", view.size(name), name);
+            }
+            return;
+        }
+
+        // Add/replace a file's user defined attribute
+        if (args[0].equals("-set")) {
+            // name=value
+            String[] s = args[1].split("=");
+            if (s.length != 2)
+                usage();
+            String name = s[0];
+            String value = s[1];
+            view.write(name, Charset.defaultCharset().encode(value));
+            return;
+        }
+
+        // Print out the value of a file's user defined attribute
+        if (args[0].equals("-get")) {
+            String name = args[1];
+            int size = view.size(name);
+            ByteBuffer buf = ByteBuffer.allocateDirect(size);
+            view.read(name, buf);
+            buf.flip();
+            System.out.println(Charset.defaultCharset().decode(buf).toString());
+            return;
+        }
+
+        // Delete a file's user defined attribute
+        if (args[0].equals("-del")) {
+            view.delete(args[1]);
+            return;
+        }
+
+        // option not recognized
+        usage();
+    }
+ }
diff --git a/jdk/src/solaris/classes/sun/nio/ch/DatagramDispatcher.java b/jdk/src/solaris/classes/sun/nio/ch/DatagramDispatcher.java
index 8ac3e1e..9d0a1d1 100644
--- a/jdk/src/solaris/classes/sun/nio/ch/DatagramDispatcher.java
+++ b/jdk/src/solaris/classes/sun/nio/ch/DatagramDispatcher.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2001-2009 Sun Microsystems, Inc.  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
@@ -56,11 +56,11 @@
     }
 
     void close(FileDescriptor fd) throws IOException {
-        FileDispatcher.close0(fd);
+        FileDispatcherImpl.close0(fd);
     }
 
     void preClose(FileDescriptor fd) throws IOException {
-        FileDispatcher.preClose0(fd);
+        FileDispatcherImpl.preClose0(fd);
     }
 
     static native int read0(FileDescriptor fd, long address, int len)
diff --git a/jdk/src/solaris/classes/sun/nio/ch/DefaultAsynchronousChannelProvider.java b/jdk/src/solaris/classes/sun/nio/ch/DefaultAsynchronousChannelProvider.java
new file mode 100644
index 0000000..949c817
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/ch/DefaultAsynchronousChannelProvider.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.ch;
+
+import java.nio.channels.spi.AsynchronousChannelProvider;
+import java.security.AccessController;
+import sun.security.action.GetPropertyAction;
+
+/**
+ * Creates this platform's default asynchronous channel provider
+ */
+
+public class DefaultAsynchronousChannelProvider {
+
+    /**
+     * Prevent instantiation.
+     */
+    private DefaultAsynchronousChannelProvider() { }
+
+    /**
+     * Returns the default AsynchronousChannelProvider.
+     */
+    public static AsynchronousChannelProvider create() {
+        String osname = AccessController
+            .doPrivileged(new GetPropertyAction("os.name"));
+        if (osname.equals("SunOS"))
+            return new SolarisAsynchronousChannelProvider();
+        if (osname.equals("Linux"))
+            return new LinuxAsynchronousChannelProvider();
+        throw new InternalError("platform not recognized");
+    }
+
+}
diff --git a/jdk/src/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java b/jdk/src/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java
index 7317a8e..f569c2d 100644
--- a/jdk/src/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java
+++ b/jdk/src/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2001-2009 Sun Microsystems, Inc.  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
@@ -172,7 +172,7 @@
     }
 
     void closeDevPollFD() throws IOException {
-        FileDispatcher.closeIntFD(wfd);
+        FileDispatcherImpl.closeIntFD(wfd);
         pollArray.free();
     }
 
diff --git a/jdk/src/solaris/classes/sun/nio/ch/DevPollSelectorImpl.java b/jdk/src/solaris/classes/sun/nio/ch/DevPollSelectorImpl.java
index cdf19cd..f3f26e4 100644
--- a/jdk/src/solaris/classes/sun/nio/ch/DevPollSelectorImpl.java
+++ b/jdk/src/solaris/classes/sun/nio/ch/DevPollSelectorImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2001-2009 Sun Microsystems, Inc.  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
@@ -139,8 +139,8 @@
             interruptTriggered = true;
         }
 
-        FileDispatcher.closeIntFD(fd0);
-        FileDispatcher.closeIntFD(fd1);
+        FileDispatcherImpl.closeIntFD(fd0);
+        FileDispatcherImpl.closeIntFD(fd1);
 
         pollWrapper.release(fd0);
         pollWrapper.closeDevPollFD();
diff --git a/jdk/src/solaris/classes/sun/nio/ch/EPoll.java b/jdk/src/solaris/classes/sun/nio/ch/EPoll.java
new file mode 100644
index 0000000..065dced
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/ch/EPoll.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.ch;
+
+import java.io.IOException;
+import sun.misc.Unsafe;
+
+/**
+ * Provides access to the Linux epoll facility.
+ */
+
+class EPoll {
+    private EPoll() { }
+
+    private static final Unsafe unsafe = Unsafe.getUnsafe();
+
+    /**
+     * typedef union epoll_data {
+     *     void *ptr;
+     *     int fd;
+     *     __uint32_t u32;
+     *     __uint64_t u64;
+     *  } epoll_data_t;
+     *
+     * struct epoll_event {
+     *     __uint32_t events;
+     *     epoll_data_t data;
+     * }
+     */
+    private static final int SIZEOF_EPOLLEVENT   = eventSize();
+    private static final int OFFSETOF_EVENTS     = eventsOffset();
+    private static final int OFFSETOF_FD         = dataOffset();
+
+    // opcodes
+    static final int EPOLL_CTL_ADD  = 1;
+    static final int EPOLL_CTL_DEL  = 2;
+    static final int EPOLL_CTL_MOD  = 3;
+
+    // flags
+    static final int EPOLLONESHOT   = (1 << 30);
+
+    /**
+     * Allocates a poll array to handle up to {@code count} events.
+     */
+    static long allocatePollArray(int count) {
+        return unsafe.allocateMemory(count * SIZEOF_EPOLLEVENT);
+    }
+
+    /**
+     * Free a poll array
+     */
+    static void freePollArray(long address) {
+        unsafe.freeMemory(address);
+    }
+
+    /**
+     * Returns event[i];
+     */
+    static long getEvent(long address, int i) {
+        return address + (SIZEOF_EPOLLEVENT*i);
+    }
+
+    /**
+     * Returns event->data.fd
+     */
+    static int getDescriptor(long eventAddress) {
+        return unsafe.getInt(eventAddress + OFFSETOF_FD);
+    }
+
+    /**
+     * Returns event->events
+     */
+    static int getEvents(long eventAddress) {
+        return unsafe.getInt(eventAddress + OFFSETOF_EVENTS);
+    }
+
+    // -- Native methods --
+
+    private static native void init();
+
+    private static native int eventSize();
+
+    private static native int eventsOffset();
+
+    private static native int dataOffset();
+
+    static native int epollCreate() throws IOException;
+
+    static native int epollCtl(int epfd, int opcode, int fd, int events);
+
+    static native int epollWait(int epfd, long pollAddress, int numfds)
+        throws IOException;
+
+    static {
+        Util.load();
+        init();
+    }
+}
diff --git a/jdk/src/solaris/classes/sun/nio/ch/EPollArrayWrapper.java b/jdk/src/solaris/classes/sun/nio/ch/EPollArrayWrapper.java
index d8542e1..362bd97 100644
--- a/jdk/src/solaris/classes/sun/nio/ch/EPollArrayWrapper.java
+++ b/jdk/src/solaris/classes/sun/nio/ch/EPollArrayWrapper.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2005-2009 Sun Microsystems, Inc.  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
@@ -224,7 +224,7 @@
      * Close epoll file descriptor and free poll array
      */
     void closeEPollFD() throws IOException {
-        FileDispatcher.closeIntFD(epfd);
+        FileDispatcherImpl.closeIntFD(epfd);
         pollArray.free();
     }
 
diff --git a/jdk/src/solaris/classes/sun/nio/ch/EPollPort.java b/jdk/src/solaris/classes/sun/nio/ch/EPollPort.java
new file mode 100644
index 0000000..a79cb73
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/ch/EPollPort.java
@@ -0,0 +1,322 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.ch;
+
+import java.nio.channels.spi.AsynchronousChannelProvider;
+import java.io.IOException;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.atomic.AtomicInteger;
+import static sun.nio.ch.EPoll.*;
+
+/**
+ * AsynchronousChannelGroup implementation based on the Linux epoll facility.
+ */
+
+final class EPollPort
+    extends Port
+{
+    // maximum number of events to poll at a time
+    private static final int MAX_EPOLL_EVENTS = 512;
+
+    // errors
+    private static final int ENOENT     = 2;
+
+    // epoll file descriptor
+    private final int epfd;
+
+    // true if epoll closed
+    private boolean closed;
+
+    // socket pair used for wakeup
+    private final int sp[];
+
+    // number of wakeups pending
+    private final AtomicInteger wakeupCount = new AtomicInteger();
+
+    // address of the poll array passed to epoll_wait
+    private final long address;
+
+    // encapsulates an event for a channel
+    static class Event {
+        final PollableChannel channel;
+        final int events;
+
+        Event(PollableChannel channel, int events) {
+            this.channel = channel;
+            this.events = events;
+        }
+
+        PollableChannel channel()   { return channel; }
+        int events()                { return events; }
+    }
+
+    // queue of events for cases that a polling thread dequeues more than one
+    // event
+    private final ArrayBlockingQueue<Event> queue;
+    private final Event NEED_TO_POLL = new Event(null, 0);
+    private final Event EXECUTE_TASK_OR_SHUTDOWN = new Event(null, 0);
+
+    EPollPort(AsynchronousChannelProvider provider, ThreadPool pool)
+        throws IOException
+    {
+        super(provider, pool);
+
+        // open epoll
+        this.epfd = epollCreate();
+
+        // create socket pair for wakeup mechanism
+        int[] sv = new int[2];
+        try {
+            socketpair(sv);
+            // register one end with epoll
+            epollCtl(epfd, EPOLL_CTL_ADD, sv[0], POLLIN);
+        } catch (IOException x) {
+            close0(epfd);
+            throw x;
+        }
+        this.sp = sv;
+
+        // allocate the poll array
+        this.address = allocatePollArray(MAX_EPOLL_EVENTS);
+
+        // create the queue and offer the special event to ensure that the first
+        // threads polls
+        this.queue = new ArrayBlockingQueue<Event>(MAX_EPOLL_EVENTS);
+        this.queue.offer(NEED_TO_POLL);
+    }
+
+    EPollPort start() {
+        startThreads(new EventHandlerTask());
+        return this;
+    }
+
+    /**
+     * Release all resources
+     */
+    private void implClose() {
+        synchronized (this) {
+            if (closed)
+                return;
+            closed = true;
+        }
+        freePollArray(address);
+        close0(sp[0]);
+        close0(sp[1]);
+        close0(epfd);
+    }
+
+    private void wakeup() {
+        if (wakeupCount.incrementAndGet() == 1) {
+            // write byte to socketpair to force wakeup
+            try {
+                interrupt(sp[1]);
+            } catch (IOException x) {
+                throw new AssertionError(x);
+            }
+        }
+    }
+
+    @Override
+    void executeOnHandlerTask(Runnable task) {
+        synchronized (this) {
+            if (closed)
+                throw new RejectedExecutionException();
+            offerTask(task);
+            wakeup();
+        }
+    }
+
+    @Override
+    void shutdownHandlerTasks() {
+        /*
+         * If no tasks are running then just release resources; otherwise
+         * write to the one end of the socketpair to wakeup any polling threads.
+         */
+        int nThreads = threadCount();
+        if (nThreads == 0) {
+            implClose();
+        } else {
+            // send interrupt to each thread
+            while (nThreads-- > 0) {
+                wakeup();
+            }
+        }
+    }
+
+    // invoke by clients to register a file descriptor
+    @Override
+    void startPoll(int fd, int events) {
+        // update events (or add to epoll on first usage)
+        int err = epollCtl(epfd, EPOLL_CTL_MOD, fd, (events | EPOLLONESHOT));
+        if (err == ENOENT)
+            err = epollCtl(epfd, EPOLL_CTL_ADD, fd, (events | EPOLLONESHOT));
+        if (err != 0)
+            throw new AssertionError();     // should not happen
+    }
+
+    /*
+     * Task to process events from epoll and dispatch to the channel's
+     * onEvent handler.
+     *
+     * Events are retreived from epoll in batch and offered to a BlockingQueue
+     * where they are consumed by handler threads. A special "NEED_TO_POLL"
+     * event is used to signal one consumer to re-poll when all events have
+     * been consumed.
+     */
+    private class EventHandlerTask implements Runnable {
+        private Event poll() throws IOException {
+            try {
+                for (;;) {
+                    int n = epollWait(epfd, address, MAX_EPOLL_EVENTS);
+                    /*
+                     * 'n' events have been read. Here we map them to their
+                     * corresponding channel in batch and queue n-1 so that
+                     * they can be handled by other handler threads. The last
+                     * event is handled by this thread (and so is not queued).
+                     */
+                    fdToChannelLock.readLock().lock();
+                    try {
+                        while (n-- > 0) {
+                            long eventAddress = getEvent(address, n);
+                            int fd = getDescriptor(eventAddress);
+
+                            // wakeup
+                            if (fd == sp[0]) {
+                                if (wakeupCount.decrementAndGet() == 0) {
+                                    // no more wakeups so drain pipe
+                                    drain1(sp[0]);
+                                }
+
+                                // queue special event if there are more events
+                                // to handle.
+                                if (n > 0) {
+                                    queue.offer(EXECUTE_TASK_OR_SHUTDOWN);
+                                    continue;
+                                }
+                                return EXECUTE_TASK_OR_SHUTDOWN;
+                            }
+
+                            PollableChannel channel = fdToChannel.get(fd);
+                            if (channel != null) {
+                                int events = getEvents(eventAddress);
+                                Event ev = new Event(channel, events);
+
+                                // n-1 events are queued; This thread handles
+                                // the last one except for the wakeup
+                                if (n > 0) {
+                                    queue.offer(ev);
+                                } else {
+                                    return ev;
+                                }
+                            }
+                        }
+                    } finally {
+                        fdToChannelLock.readLock().unlock();
+                    }
+                }
+            } finally {
+                // to ensure that some thread will poll when all events have
+                // been consumed
+                queue.offer(NEED_TO_POLL);
+            }
+        }
+
+        public void run() {
+            Invoker.GroupAndInvokeCount myGroupAndInvokeCount =
+                Invoker.getGroupAndInvokeCount();
+            boolean replaceMe = false;
+            Event ev;
+            try {
+                for (;;) {
+                    // reset invoke count
+                    if (myGroupAndInvokeCount != null)
+                        myGroupAndInvokeCount.resetInvokeCount();
+
+                    try {
+                        replaceMe = false;
+                        ev = queue.take();
+
+                        // no events and this thread has been "selected" to
+                        // poll for more.
+                        if (ev == NEED_TO_POLL) {
+                            try {
+                                ev = poll();
+                            } catch (IOException x) {
+                                x.printStackTrace();
+                                return;
+                            }
+                        }
+                    } catch (InterruptedException x) {
+                        continue;
+                    }
+
+                    // handle wakeup to execute task or shutdown
+                    if (ev == EXECUTE_TASK_OR_SHUTDOWN) {
+                        Runnable task = pollTask();
+                        if (task == null) {
+                            // shutdown request
+                            return;
+                        }
+                        // run task (may throw error/exception)
+                        replaceMe = true;
+                        task.run();
+                        continue;
+                    }
+
+                    // process event
+                    try {
+                        ev.channel().onEvent(ev.events());
+                    } catch (Error x) {
+                        replaceMe = true; throw x;
+                    } catch (RuntimeException x) {
+                        replaceMe = true; throw x;
+                    }
+                }
+            } finally {
+                // last handler to exit when shutdown releases resources
+                int remaining = threadExit(this, replaceMe);
+                if (remaining == 0 && isShutdown()) {
+                    implClose();
+                }
+            }
+        }
+    }
+
+    // -- Native methods --
+
+    private static native void socketpair(int[] sv) throws IOException;
+
+    private static native void interrupt(int fd) throws IOException;
+
+    private static native void drain1(int fd) throws IOException;
+
+    private static native void close0(int fd);
+
+    static {
+        Util.load();
+    }
+}
diff --git a/jdk/src/solaris/classes/sun/nio/ch/EPollSelectorImpl.java b/jdk/src/solaris/classes/sun/nio/ch/EPollSelectorImpl.java
index 5dc17bb..a9bf823 100644
--- a/jdk/src/solaris/classes/sun/nio/ch/EPollSelectorImpl.java
+++ b/jdk/src/solaris/classes/sun/nio/ch/EPollSelectorImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2005-2009 Sun Microsystems, Inc.  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
@@ -136,8 +136,8 @@
             interruptTriggered = true;
         }
 
-        FileDispatcher.closeIntFD(fd0);
-        FileDispatcher.closeIntFD(fd1);
+        FileDispatcherImpl.closeIntFD(fd0);
+        FileDispatcherImpl.closeIntFD(fd1);
 
         pollWrapper.release(fd0);
         pollWrapper.closeEPollFD();
diff --git a/jdk/src/solaris/classes/sun/nio/ch/FileDispatcher.java b/jdk/src/solaris/classes/sun/nio/ch/FileDispatcherImpl.java
similarity index 72%
rename from jdk/src/solaris/classes/sun/nio/ch/FileDispatcher.java
rename to jdk/src/solaris/classes/sun/nio/ch/FileDispatcherImpl.java
index 335ac49..34d3451 100644
--- a/jdk/src/solaris/classes/sun/nio/ch/FileDispatcher.java
+++ b/jdk/src/solaris/classes/sun/nio/ch/FileDispatcherImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2002 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2009 Sun Microsystems, Inc.  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
@@ -27,12 +27,7 @@
 
 import java.io.*;
 
-/**
- * Allows different platforms to call different native methods
- * for read and write operations.
- */
-
-class FileDispatcher extends NativeDispatcher
+class FileDispatcherImpl extends FileDispatcher
 {
 
     static {
@@ -69,6 +64,28 @@
         return writev0(fd, address, len);
     }
 
+    int force(FileDescriptor fd, boolean metaData) throws IOException {
+        return force0(fd, metaData);
+    }
+
+    int truncate(FileDescriptor fd, long size) throws IOException {
+        return truncate0(fd, size);
+    }
+
+    long size(FileDescriptor fd) throws IOException {
+        return size0(fd);
+    }
+
+    int lock(FileDescriptor fd, boolean blocking, long pos, long size,
+             boolean shared) throws IOException
+    {
+        return lock0(fd, blocking, pos, size, shared);
+    }
+
+    void release(FileDescriptor fd, long pos, long size) throws IOException {
+        release0(fd, pos, size);
+    }
+
     void close(FileDescriptor fd) throws IOException {
         close0(fd);
     }
@@ -97,6 +114,20 @@
     static native long writev0(FileDescriptor fd, long address, int len)
         throws IOException;
 
+    static native int force0(FileDescriptor fd, boolean metaData)
+        throws IOException;
+
+    static native int truncate0(FileDescriptor fd, long size)
+        throws IOException;
+
+    static native long size0(FileDescriptor fd) throws IOException;
+
+    static native int lock0(FileDescriptor fd, boolean blocking, long pos,
+                            long size, boolean shared) throws IOException;
+
+    static native void release0(FileDescriptor fd, long pos, long size)
+        throws IOException;
+
     static native void close0(FileDescriptor fd) throws IOException;
 
     static native void preClose0(FileDescriptor fd) throws IOException;
diff --git a/jdk/src/solaris/classes/sun/nio/ch/LinuxAsynchronousChannelProvider.java b/jdk/src/solaris/classes/sun/nio/ch/LinuxAsynchronousChannelProvider.java
new file mode 100644
index 0000000..775380e
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/ch/LinuxAsynchronousChannelProvider.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.ch;
+
+import java.nio.channels.*;
+import java.nio.channels.spi.AsynchronousChannelProvider;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.ThreadFactory;
+import java.net.ProtocolFamily;
+import java.io.IOException;
+
+public class LinuxAsynchronousChannelProvider
+    extends AsynchronousChannelProvider
+{
+    private static volatile EPollPort defaultPort;
+
+    private EPollPort defaultEventPort() throws IOException {
+        if (defaultPort == null) {
+            synchronized (LinuxAsynchronousChannelProvider.class) {
+                if (defaultPort == null) {
+                    defaultPort = new EPollPort(this, ThreadPool.getDefault()).start();
+                }
+            }
+        }
+        return defaultPort;
+    }
+
+    public LinuxAsynchronousChannelProvider() {
+    }
+
+    @Override
+    public AsynchronousChannelGroup openAsynchronousChannelGroup(int nThreads, ThreadFactory factory)
+        throws IOException
+    {
+        return new EPollPort(this, ThreadPool.create(nThreads, factory)).start();
+    }
+
+    @Override
+    public AsynchronousChannelGroup openAsynchronousChannelGroup(ExecutorService executor, int initialSize)
+        throws IOException
+    {
+        return new EPollPort(this, ThreadPool.wrap(executor, initialSize)).start();
+    }
+
+    private Port toPort(AsynchronousChannelGroup group) throws IOException {
+        if (group == null) {
+            return defaultEventPort();
+        } else {
+            if (!(group instanceof EPollPort))
+                throw new IllegalChannelGroupException();
+            return (Port)group;
+        }
+    }
+
+    @Override
+    public AsynchronousServerSocketChannel openAsynchronousServerSocketChannel(AsynchronousChannelGroup group)
+        throws IOException
+    {
+        return new UnixAsynchronousServerSocketChannelImpl(toPort(group));
+    }
+
+    @Override
+    public AsynchronousSocketChannel openAsynchronousSocketChannel(AsynchronousChannelGroup group)
+        throws IOException
+    {
+        return new UnixAsynchronousSocketChannelImpl(toPort(group));
+    }
+
+    @Override
+    public AsynchronousDatagramChannel openAsynchronousDatagramChannel(ProtocolFamily family,
+                                                                       AsynchronousChannelGroup group)
+        throws IOException
+    {
+        return new SimpleAsynchronousDatagramChannelImpl(family, toPort(group));
+    }
+}
diff --git a/jdk/src/solaris/classes/sun/nio/ch/PollSelectorImpl.java b/jdk/src/solaris/classes/sun/nio/ch/PollSelectorImpl.java
index ab135c9..05fbda5 100644
--- a/jdk/src/solaris/classes/sun/nio/ch/PollSelectorImpl.java
+++ b/jdk/src/solaris/classes/sun/nio/ch/PollSelectorImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2001-2009 Sun Microsystems, Inc.  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
@@ -93,8 +93,8 @@
         synchronized (interruptLock) {
             interruptTriggered = true;
         }
-        FileDispatcher.closeIntFD(fd0);
-        FileDispatcher.closeIntFD(fd1);
+        FileDispatcherImpl.closeIntFD(fd0);
+        FileDispatcherImpl.closeIntFD(fd1);
         fd0 = -1;
         fd1 = -1;
         pollWrapper.release(0);
diff --git a/jdk/src/solaris/classes/sun/nio/ch/Port.java b/jdk/src/solaris/classes/sun/nio/ch/Port.java
new file mode 100644
index 0000000..8b19637
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/ch/Port.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.ch;
+
+import java.nio.channels.spi.AsynchronousChannelProvider;
+import java.nio.channels.*;
+import java.io.IOException;
+import java.io.Closeable;
+import java.io.FileDescriptor;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+/**
+ * Base implementation of AsynchronousChannelGroupImpl for Unix systems.
+ */
+
+abstract class Port extends AsynchronousChannelGroupImpl {
+    static final short POLLIN       = 0x0001;
+    static final short POLLOUT      = 0x0004;
+    static final short POLLERR      = 0x0008;
+    static final short POLLHUP      = 0x0010;
+
+    /**
+     * Implemented by clients registered with this port.
+     */
+    interface PollableChannel extends Closeable {
+        void onEvent(int events);
+    }
+
+    // maps fd to "pollable" channel
+    protected final ReadWriteLock fdToChannelLock = new ReentrantReadWriteLock();
+    protected final Map<Integer,PollableChannel> fdToChannel =
+        new HashMap<Integer,PollableChannel>();
+
+
+    Port(AsynchronousChannelProvider provider, ThreadPool pool) {
+        super(provider, pool);
+    }
+
+    /**
+     * Register channel identified by its file descriptor
+     */
+    final void register(int fd, PollableChannel ch) {
+        fdToChannelLock.writeLock().lock();
+        try {
+            if (isShutdown())
+                throw new ShutdownChannelGroupException();
+            fdToChannel.put(Integer.valueOf(fd), ch);
+        } finally {
+            fdToChannelLock.writeLock().unlock();
+        }
+    }
+
+    /**
+     * Unregister channel identified by its file descriptor
+     */
+    final void unregister(int fd) {
+        boolean checkForShutdown = false;
+
+        fdToChannelLock.writeLock().lock();
+        try {
+            fdToChannel.remove(Integer.valueOf(fd));
+
+            // last key to be removed so check if group is shutdown
+            if (fdToChannel.isEmpty())
+                checkForShutdown = true;
+
+        } finally {
+            fdToChannelLock.writeLock().unlock();
+        }
+
+        // continue shutdown
+        if (checkForShutdown && isShutdown()) {
+            try {
+                shutdownNow();
+            } catch (IOException ignore) { }
+        }
+    }
+    /**
+     * Register file descriptor with polling mechanism for given events.
+     * The implementation should translate the events as required.
+     */
+    abstract void startPoll(int fd, int events);
+
+    @Override
+    final boolean isEmpty() {
+        fdToChannelLock.writeLock().lock();
+        try {
+            return fdToChannel.isEmpty();
+        } finally {
+            fdToChannelLock.writeLock().unlock();
+        }
+    }
+
+    @Override
+    final Object attachForeignChannel(final Channel channel, FileDescriptor fd) {
+        int fdVal = IOUtil.fdVal(fd);
+        register(fdVal, new PollableChannel() {
+            public void onEvent(int events) { }
+            public void close() throws IOException {
+                channel.close();
+            }
+        });
+        return Integer.valueOf(fdVal);
+    }
+
+    @Override
+    final void detachForeignChannel(Object key) {
+        unregister((Integer)key);
+    }
+
+    @Override
+    final void closeAllChannels() {
+        /**
+         * Close channels in batches of up to 128 channels. This allows close
+         * to remove the channel from the map without interference.
+         */
+        final int MAX_BATCH_SIZE = 128;
+        PollableChannel channels[] = new PollableChannel[MAX_BATCH_SIZE];
+        int count;
+        do {
+            // grab a batch of up to 128 channels
+            fdToChannelLock.writeLock().lock();
+            count = 0;
+            try {
+                for (Integer fd: fdToChannel.keySet()) {
+                    channels[count++] = fdToChannel.get(fd);
+                    if (count >= MAX_BATCH_SIZE)
+                        break;
+                }
+            } finally {
+                fdToChannelLock.writeLock().unlock();
+            }
+
+            // close them
+            for (int i=0; i<count; i++) {
+                try {
+                    channels[i].close();
+                } catch (IOException ignore) { }
+            }
+        } while (count > 0);
+    }
+}
diff --git a/jdk/src/solaris/classes/sun/nio/ch/SinkChannelImpl.java b/jdk/src/solaris/classes/sun/nio/ch/SinkChannelImpl.java
index bc58ba9..ced3b60 100644
--- a/jdk/src/solaris/classes/sun/nio/ch/SinkChannelImpl.java
+++ b/jdk/src/solaris/classes/sun/nio/ch/SinkChannelImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2009 Sun Microsystems, Inc.  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
@@ -208,7 +208,7 @@
 
     static {
         Util.load();
-        nd = new FileDispatcher();
+        nd = new FileDispatcherImpl();
     }
 
 }
diff --git a/jdk/src/solaris/classes/sun/nio/ch/SocketDispatcher.java b/jdk/src/solaris/classes/sun/nio/ch/SocketDispatcher.java
index 46c8e13..fc884c4 100644
--- a/jdk/src/solaris/classes/sun/nio/ch/SocketDispatcher.java
+++ b/jdk/src/solaris/classes/sun/nio/ch/SocketDispatcher.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2009 Sun Microsystems, Inc.  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
@@ -36,26 +36,26 @@
 {
 
     int read(FileDescriptor fd, long address, int len) throws IOException {
-        return FileDispatcher.read0(fd, address, len);
+        return FileDispatcherImpl.read0(fd, address, len);
     }
 
     long readv(FileDescriptor fd, long address, int len) throws IOException {
-        return FileDispatcher.readv0(fd, address, len);
+        return FileDispatcherImpl.readv0(fd, address, len);
     }
 
     int write(FileDescriptor fd, long address, int len) throws IOException {
-        return FileDispatcher.write0(fd, address, len);
+        return FileDispatcherImpl.write0(fd, address, len);
     }
 
     long writev(FileDescriptor fd, long address, int len) throws IOException {
-        return FileDispatcher.writev0(fd, address, len);
+        return FileDispatcherImpl.writev0(fd, address, len);
     }
 
     void close(FileDescriptor fd) throws IOException {
-        FileDispatcher.close0(fd);
+        FileDispatcherImpl.close0(fd);
     }
 
     void preClose(FileDescriptor fd) throws IOException {
-        FileDispatcher.preClose0(fd);
+        FileDispatcherImpl.preClose0(fd);
     }
 }
diff --git a/jdk/src/solaris/classes/sun/nio/ch/SolarisAsynchronousChannelProvider.java b/jdk/src/solaris/classes/sun/nio/ch/SolarisAsynchronousChannelProvider.java
new file mode 100644
index 0000000..0da0935
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/ch/SolarisAsynchronousChannelProvider.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.ch;
+
+import java.nio.channels.*;
+import java.nio.channels.spi.AsynchronousChannelProvider;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.ThreadFactory;
+import java.net.ProtocolFamily;
+import java.io.IOException;
+
+public class SolarisAsynchronousChannelProvider
+    extends AsynchronousChannelProvider
+{
+    private static volatile SolarisEventPort defaultEventPort;
+
+    private SolarisEventPort defaultEventPort() throws IOException {
+        if (defaultEventPort == null) {
+            synchronized (SolarisAsynchronousChannelProvider.class) {
+                if (defaultEventPort == null) {
+                    defaultEventPort =
+                        new SolarisEventPort(this, ThreadPool.getDefault()).start();
+                }
+            }
+        }
+        return defaultEventPort;
+    }
+
+    public SolarisAsynchronousChannelProvider() {
+    }
+
+    @Override
+    public AsynchronousChannelGroup openAsynchronousChannelGroup(int nThreads, ThreadFactory factory)
+        throws IOException
+    {
+        return new SolarisEventPort(this, ThreadPool.create(nThreads, factory)).start();
+    }
+
+    @Override
+    public AsynchronousChannelGroup openAsynchronousChannelGroup(ExecutorService executor, int initialSize)
+        throws IOException
+    {
+        return new SolarisEventPort(this, ThreadPool.wrap(executor, initialSize)).start();
+    }
+
+    private SolarisEventPort toEventPort(AsynchronousChannelGroup group)
+        throws IOException
+    {
+        if (group == null) {
+            return defaultEventPort();
+        } else {
+            if (!(group instanceof SolarisEventPort))
+                throw new IllegalChannelGroupException();
+            return (SolarisEventPort)group;
+        }
+    }
+
+    @Override
+    public AsynchronousServerSocketChannel openAsynchronousServerSocketChannel(AsynchronousChannelGroup group)
+        throws IOException
+    {
+        return new UnixAsynchronousServerSocketChannelImpl(toEventPort(group));
+    }
+
+    @Override
+    public AsynchronousSocketChannel openAsynchronousSocketChannel(AsynchronousChannelGroup group)
+        throws IOException
+    {
+        return new UnixAsynchronousSocketChannelImpl(toEventPort(group));
+    }
+
+    @Override
+    public AsynchronousDatagramChannel openAsynchronousDatagramChannel(ProtocolFamily family,
+                                                                       AsynchronousChannelGroup group)
+        throws IOException
+    {
+        return new SimpleAsynchronousDatagramChannelImpl(family, toEventPort(group));
+    }
+}
diff --git a/jdk/src/solaris/classes/sun/nio/ch/SolarisEventPort.java b/jdk/src/solaris/classes/sun/nio/ch/SolarisEventPort.java
new file mode 100644
index 0000000..908eecc
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/ch/SolarisEventPort.java
@@ -0,0 +1,244 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.ch;
+
+import java.nio.channels.spi.AsynchronousChannelProvider;
+import java.util.concurrent.RejectedExecutionException;
+import java.io.IOException;
+import sun.misc.Unsafe;
+
+/**
+ * AsynchronousChannelGroup implementation based on the Solaris 10 event port
+ * framework.
+ */
+
+class SolarisEventPort
+    extends Port
+{
+    private static final Unsafe unsafe = Unsafe.getUnsafe();
+    private static final int addressSize = unsafe.addressSize();
+
+    private static int dependsArch(int value32, int value64) {
+        return (addressSize == 4) ? value32 : value64;
+    }
+
+    /*
+     * typedef struct port_event {
+     *     int             portev_events;
+     *     ushort_t        portev_source;
+     *     ushort_t        portev_pad;
+     *     uintptr_t       portev_object;
+     *     void            *portev_user;
+     * } port_event_t;
+     */
+    private static final int SIZEOF_PORT_EVENT  = dependsArch(16, 24);
+    private static final int OFFSETOF_EVENTS    = 0;
+    private static final int OFFSETOF_SOURCE    = 4;
+    private static final int OFFSETOF_OBJECT    = 8;
+
+    // port sources
+    private static final short PORT_SOURCE_USER     = 3;
+    private static final short PORT_SOURCE_FD       = 4;
+
+    // file descriptor to event port.
+    private final int port;
+
+    // true when port is closed
+    private boolean closed;
+
+    SolarisEventPort(AsynchronousChannelProvider provider, ThreadPool pool)
+        throws IOException
+    {
+        super(provider, pool);
+
+        // create event port
+        this.port = portCreate();
+    }
+
+    SolarisEventPort start() {
+        startThreads(new EventHandlerTask());
+        return this;
+    }
+
+    // releass resources
+    private void implClose() {
+        synchronized (this) {
+            if (closed)
+                return;
+            closed = true;
+        }
+        portClose(port);
+    }
+
+    private void wakeup() {
+        try {
+            portSend(port, 0);
+        } catch (IOException x) {
+            throw new AssertionError(x);
+        }
+    }
+
+    @Override
+    void executeOnHandlerTask(Runnable task) {
+        synchronized (this) {
+            if (closed)
+                throw new RejectedExecutionException();
+            offerTask(task);
+            wakeup();
+        }
+    }
+
+    @Override
+    void shutdownHandlerTasks() {
+       /*
+         * If no tasks are running then just release resources; otherwise
+         * write to the one end of the socketpair to wakeup any polling threads..
+         */
+        int nThreads = threadCount();
+        if (nThreads == 0) {
+            implClose();
+        } else {
+            // send user event to wakeup each thread
+            while (nThreads-- > 0) {
+                try {
+                    portSend(port, 0);
+                } catch (IOException x) {
+                    throw new AssertionError(x);
+                }
+            }
+        }
+    }
+
+    @Override
+    void startPoll(int fd, int events) {
+        // (re-)associate file descriptor
+        // no need to translate events
+        try {
+            portAssociate(port, PORT_SOURCE_FD, fd, events);
+        } catch (IOException x) {
+            throw new AssertionError();     // should not happen
+        }
+    }
+
+    /*
+     * Task to read a single event from the port and dispatch it to the
+     * channel's onEvent handler.
+     */
+    private class EventHandlerTask implements Runnable {
+        public void run() {
+            Invoker.GroupAndInvokeCount myGroupAndInvokeCount =
+                Invoker.getGroupAndInvokeCount();
+            boolean replaceMe = false;
+            long address = unsafe.allocateMemory(SIZEOF_PORT_EVENT);
+            try {
+                for (;;) {
+                    // reset invoke count
+                    if (myGroupAndInvokeCount != null)
+                        myGroupAndInvokeCount.resetInvokeCount();
+
+                    // wait for I/O completion event
+                    // A error here is fatal (thread will not be replaced)
+                    replaceMe = false;
+                    try {
+                        portGet(port, address);
+                    } catch (IOException x) {
+                        x.printStackTrace();
+                        return;
+                    }
+
+                    // event source
+                    short source = unsafe.getShort(address + OFFSETOF_SOURCE);
+                    if (source != PORT_SOURCE_FD) {
+                        // user event is trigger to invoke task or shutdown
+                        if (source == PORT_SOURCE_USER) {
+                            Runnable task = pollTask();
+                            if (task == null) {
+                                // shutdown request
+                                return;
+                            }
+                            // run task (may throw error/exception)
+                            replaceMe = true;
+                            task.run();
+                        }
+                        // ignore
+                        continue;
+                    }
+
+                    // pe->portev_object is file descriptor
+                    int fd = (int)unsafe.getAddress(address + OFFSETOF_OBJECT);
+                    // pe->portev_events
+                    int events = unsafe.getInt(address + OFFSETOF_EVENTS);
+
+                    // lookup channel
+                    PollableChannel ch;
+                    fdToChannelLock.readLock().lock();
+                    try {
+                        ch = fdToChannel.get(fd);
+                    } finally {
+                        fdToChannelLock.readLock().unlock();
+                    }
+
+                    // notify channel
+                    if (ch != null) {
+                        replaceMe = true;
+                        // no need to translate events
+                        ch.onEvent(events);
+                    }
+                }
+            } finally {
+                // free per-thread resources
+                unsafe.freeMemory(address);
+                // last task to exit when shutdown release resources
+                int remaining = threadExit(this, replaceMe);
+                if (remaining == 0 && isShutdown())
+                    implClose();
+            }
+        }
+    }
+
+    // -- Native methods --
+
+    private static native void init();
+
+    private static native int portCreate() throws IOException;
+
+    private static native void portAssociate(int port, int source, long object,
+        int events) throws IOException;
+
+    private static native void portGet(int port, long pe) throws IOException;
+
+    private static native int portGetn(int port, long address, int max)
+        throws IOException;
+
+    private static native void portSend(int port, int events) throws IOException;
+
+    private static native void portClose(int port);
+
+    static {
+        Util.load();
+        init();
+    }
+}
diff --git a/jdk/src/solaris/classes/sun/nio/ch/SourceChannelImpl.java b/jdk/src/solaris/classes/sun/nio/ch/SourceChannelImpl.java
index a55543e..e1080c9 100644
--- a/jdk/src/solaris/classes/sun/nio/ch/SourceChannelImpl.java
+++ b/jdk/src/solaris/classes/sun/nio/ch/SourceChannelImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2009 Sun Microsystems, Inc.  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
@@ -208,7 +208,7 @@
 
     static {
         Util.load();
-        nd = new FileDispatcher();
+        nd = new FileDispatcherImpl();
     }
 
 }
diff --git a/jdk/src/solaris/classes/sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.java b/jdk/src/solaris/classes/sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.java
new file mode 100644
index 0000000..1a8c923
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.java
@@ -0,0 +1,327 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.ch;
+
+import java.nio.channels.*;
+import java.util.concurrent.*;
+import java.io.IOException;
+import java.io.FileDescriptor;
+import java.net.InetSocketAddress;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * Unix implementation of AsynchronousServerSocketChannel
+ */
+
+class UnixAsynchronousServerSocketChannelImpl
+    extends AsynchronousServerSocketChannelImpl
+    implements Port.PollableChannel
+{
+    private final static NativeDispatcher nd = new SocketDispatcher();
+
+    private final Port port;
+    private final int fdVal;
+
+    // flag to indicate an accept is outstanding
+    private final AtomicBoolean accepting = new AtomicBoolean();
+    private void enableAccept() {
+        accepting.set(false);
+    }
+
+    // used to ensure that the context for an asynchronous accept is visible
+    // the pooled thread that handles the I/O event
+    private final Object updateLock = new Object();
+
+    // pending accept
+    private PendingFuture<AsynchronousSocketChannel,Object> pendingAccept;
+
+    // context for permission check when security manager set
+    private AccessControlContext acc;
+
+
+    UnixAsynchronousServerSocketChannelImpl(Port port)
+        throws IOException
+    {
+        super(port);
+
+        try {
+            IOUtil.configureBlocking(fd, false);
+        } catch (IOException x) {
+            nd.close(fd);  // prevent leak
+            throw x;
+        }
+        this.port = port;
+        this.fdVal = IOUtil.fdVal(fd);
+
+        // add mapping from file descriptor to this channel
+        port.register(fdVal, this);
+    }
+
+    // returns and clears the result of a pending accept
+    private PendingFuture<AsynchronousSocketChannel,Object> grabPendingAccept() {
+        synchronized (updateLock) {
+            PendingFuture<AsynchronousSocketChannel,Object> result = pendingAccept;
+            pendingAccept = null;
+            return result;
+        }
+    }
+
+    @Override
+    void implClose() throws IOException {
+        // remove the mapping
+        port.unregister(fdVal);
+
+        // close file descriptor
+        nd.close(fd);
+
+        // if there is a pending accept then complete it
+        final PendingFuture<AsynchronousSocketChannel,Object> result =
+            grabPendingAccept();
+        if (result != null) {
+            // discard the stack trace as otherwise it may appear that implClose
+            // has thrown the exception.
+            AsynchronousCloseException x = new AsynchronousCloseException();
+            x.setStackTrace(new StackTraceElement[0]);
+            result.setFailure(x);
+
+            // invoke by submitting task rather than directly
+            Invoker.invokeIndirectly(result.handler(), result);
+        }
+    }
+
+    @Override
+    public AsynchronousChannelGroupImpl group() {
+        return port;
+    }
+
+    /**
+     * Invoked by event handling thread when listener socket is polled
+     */
+    @Override
+    public void onEvent(int events) {
+        PendingFuture<AsynchronousSocketChannel,Object> result = grabPendingAccept();
+        if (result == null)
+            return; // may have been grabbed by asynchronous close
+
+        // attempt to accept connection
+        FileDescriptor newfd = new FileDescriptor();
+        InetSocketAddress[] isaa = new InetSocketAddress[1];
+        boolean accepted = false;
+        try {
+            begin();
+            int n = accept0(this.fd, newfd, isaa);
+
+            // spurious wakeup, is this possible?
+            if (n == IOStatus.UNAVAILABLE) {
+                synchronized (updateLock) {
+                    this.pendingAccept = result;
+                }
+                port.startPoll(fdVal, Port.POLLIN);
+                return;
+            }
+
+            // connection accepted
+            accepted = true;
+
+        } catch (Throwable x) {
+            if (x instanceof ClosedChannelException)
+                x = new AsynchronousCloseException();
+            enableAccept();
+            result.setFailure(x);
+        } finally {
+            end();
+        }
+
+        // Connection accepted so finish it when not holding locks.
+        AsynchronousSocketChannel child = null;
+        if (accepted) {
+            try {
+                child = finishAccept(newfd, isaa[0], acc);
+                enableAccept();
+                result.setResult(child);
+            } catch (Throwable x) {
+                enableAccept();
+                if (!(x instanceof IOException) && !(x instanceof SecurityException))
+                    x = new IOException(x);
+                result.setFailure(x);
+            }
+        }
+
+        // if an async cancel has already cancelled the operation then
+        // close the new channel so as to free resources
+        if (child != null && result.isCancelled()) {
+            try {
+                child.close();
+            } catch (IOException ignore) { }
+        }
+
+        // invoke the handler
+        Invoker.invoke(result.handler(), result);
+    }
+
+    /**
+     * Completes the accept by creating the AsynchronousSocketChannel for
+     * the given file descriptor and remote address. If this method completes
+     * with an IOException or SecurityException then the channel/file descriptor
+     * will be closed.
+     */
+    private AsynchronousSocketChannel finishAccept(FileDescriptor newfd,
+                                                   final InetSocketAddress remote,
+                                                   AccessControlContext acc)
+        throws IOException, SecurityException
+    {
+        AsynchronousSocketChannel ch = null;
+        try {
+            ch = new UnixAsynchronousSocketChannelImpl(port, newfd, remote);
+        } catch (IOException x) {
+            nd.close(newfd);
+            throw x;
+        }
+
+        // permission check must always be in initiator's context
+        try {
+            if (acc != null) {
+                AccessController.doPrivileged(new PrivilegedAction<Void>() {
+                    public Void run() {
+                        SecurityManager sm = System.getSecurityManager();
+                        if (sm != null) {
+                            sm.checkAccept(remote.getAddress().getHostAddress(),
+                                           remote.getPort());
+                        }
+                        return null;
+                    }
+                }, acc);
+            } else {
+                SecurityManager sm = System.getSecurityManager();
+                if (sm != null) {
+                    sm.checkAccept(remote.getAddress().getHostAddress(),
+                                   remote.getPort());
+                }
+            }
+        } catch (SecurityException x) {
+            try {
+                ch.close();
+            } catch (IOException ignore) { }
+            throw x;
+        }
+        return ch;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public <A> Future<AsynchronousSocketChannel> accept(A attachment,
+        final CompletionHandler<AsynchronousSocketChannel,? super A> handler)
+    {
+        // complete immediately if channel is closed
+        if (!isOpen()) {
+            CompletedFuture<AsynchronousSocketChannel,A> result = CompletedFuture
+                .withFailure(this, new ClosedChannelException(), attachment);
+            Invoker.invokeIndirectly(handler, result);
+            return result;
+        }
+        if (localAddress == null)
+            throw new NotYetBoundException();
+
+        // cancel was invoked with pending accept so connection may have been
+        // dropped.
+        if (isAcceptKilled())
+            throw new RuntimeException("Accept not allowed due cancellation");
+
+        // check and set flag to prevent concurrent accepting
+        if (!accepting.compareAndSet(false, true))
+            throw new AcceptPendingException();
+
+        // attempt accept
+        AbstractFuture<AsynchronousSocketChannel,A> result = null;
+        FileDescriptor newfd = new FileDescriptor();
+        InetSocketAddress[] isaa = new InetSocketAddress[1];
+        try {
+            begin();
+
+            int n = accept0(this.fd, newfd, isaa);
+            if (n == IOStatus.UNAVAILABLE) {
+                // no connection to accept
+                result = new PendingFuture<AsynchronousSocketChannel,A>(this, handler, attachment);
+
+                // need calling context when there is security manager as
+                // permission check may be done in a different thread without
+                // any application call frames on the stack
+                synchronized (this) {
+                    this.acc = (System.getSecurityManager() == null) ?
+                        null : AccessController.getContext();
+                    this.pendingAccept =
+                        (PendingFuture<AsynchronousSocketChannel,Object>)result;
+                }
+
+                // register for connections
+                port.startPoll(fdVal, Port.POLLIN);
+                return result;
+            }
+        } catch (Throwable x) {
+            // accept failed
+            if (x instanceof ClosedChannelException)
+                x = new AsynchronousCloseException();
+            result = CompletedFuture.withFailure(this, x, attachment);
+        } finally {
+            end();
+        }
+
+        // connection accepted immediately
+        if (result == null) {
+            try {
+                AsynchronousSocketChannel ch = finishAccept(newfd, isaa[0], null);
+                result = CompletedFuture.withResult(this, ch, attachment);
+            } catch (Throwable x) {
+                result = CompletedFuture.withFailure(this, x, attachment);
+            }
+        }
+
+        // re-enable accepting and invoke handler
+        enableAccept();
+        Invoker.invokeIndirectly(handler, result);
+        return result;
+    }
+
+    // -- Native methods --
+
+    private static native void initIDs();
+
+    // Accepts a new connection, setting the given file descriptor to refer to
+    // the new socket and setting isaa[0] to the socket's remote address.
+    // Returns 1 on success, or IOStatus.UNAVAILABLE.
+    //
+    private native int accept0(FileDescriptor ssfd, FileDescriptor newfd,
+                               InetSocketAddress[] isaa)
+        throws IOException;
+
+    static {
+        Util.load();
+        initIDs();
+    }
+}
diff --git a/jdk/src/solaris/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java b/jdk/src/solaris/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java
new file mode 100644
index 0000000..702b28c
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java
@@ -0,0 +1,673 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 conne02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.ch;
+
+import java.nio.channels.*;
+import java.nio.ByteBuffer;
+import java.net.*;
+import java.util.concurrent.*;
+import java.io.IOException;
+import java.io.FileDescriptor;
+import java.security.AccessController;
+import sun.security.action.GetPropertyAction;
+
+/**
+ * Unix implementation of AsynchronousSocketChannel
+ */
+
+class UnixAsynchronousSocketChannelImpl
+    extends AsynchronousSocketChannelImpl implements Port.PollableChannel
+{
+    private final static NativeDispatcher nd = new SocketDispatcher();
+    private static enum OpType { CONNECT, READ, WRITE };
+
+    private static final boolean disableSynchronousRead;
+    static {
+        String propValue = AccessController.doPrivileged(
+            new GetPropertyAction("sun.nio.ch.disableSynchronousRead", "false"));
+        disableSynchronousRead = (propValue.length() == 0) ?
+            true : Boolean.valueOf(propValue);
+    }
+
+    private final Port port;
+    private final int fdVal;
+
+    // used to ensure that the context for I/O operations that complete
+    // ascynrhonously is visible to the pooled threads handling I/O events.
+    private final Object updateLock = new Object();
+
+    // pending connect (updateLock)
+    private PendingFuture<Void,Object> pendingConnect;
+
+    // pending remote address (statLock)
+    private SocketAddress pendingRemote;
+
+    // pending read (updateLock)
+    private ByteBuffer[] readBuffers;
+    private boolean scatteringRead;
+    private PendingFuture<Number,Object> pendingRead;
+
+    // pending write (updateLock)
+    private ByteBuffer[] writeBuffers;
+    private boolean gatheringWrite;
+    private PendingFuture<Number,Object> pendingWrite;
+
+
+    UnixAsynchronousSocketChannelImpl(Port port)
+        throws IOException
+    {
+        super(port);
+
+        // set non-blocking
+        try {
+            IOUtil.configureBlocking(fd, false);
+        } catch (IOException x) {
+            nd.close(fd);
+            throw x;
+        }
+
+        this.port = port;
+        this.fdVal = IOUtil.fdVal(fd);
+
+        // add mapping from file descriptor to this channel
+        port.register(fdVal, this);
+    }
+
+    // Constructor for sockets created by UnixAsynchronousServerSocketChannelImpl
+    UnixAsynchronousSocketChannelImpl(Port port,
+                                      FileDescriptor fd,
+                                      InetSocketAddress remote)
+        throws IOException
+    {
+        super(port, fd, remote);
+
+        this.fdVal = IOUtil.fdVal(fd);
+        IOUtil.configureBlocking(fd, false);
+
+        try {
+            port.register(fdVal, this);
+        } catch (ShutdownChannelGroupException x) {
+            // ShutdownChannelGroupException thrown if we attempt to register a
+            // new channel after the group is shutdown
+            throw new IOException(x);
+        }
+
+        this.port = port;
+    }
+
+    @Override
+    public AsynchronousChannelGroupImpl group() {
+        return port;
+    }
+
+    // register for events if there are outstanding I/O operations
+    private void updateEvents() {
+        assert Thread.holdsLock(updateLock);
+        int events = 0;
+        if (pendingRead != null)
+            events |= Port.POLLIN;
+        if (pendingConnect != null || pendingWrite != null)
+            events |= Port.POLLOUT;
+        if (events != 0)
+            port.startPoll(fdVal, events);
+    }
+
+    /**
+     * Invoked by event handler thread when file descriptor is polled
+     */
+    @Override
+    public void onEvent(int events) {
+        boolean readable = (events & Port.POLLIN) > 0;
+        boolean writable = (events & Port.POLLOUT) > 0;
+        if ((events & (Port.POLLERR | Port.POLLHUP)) > 0) {
+            readable = true;
+            writable = true;
+        }
+
+        PendingFuture<Void,Object> connectResult = null;
+        PendingFuture<Number,Object> readResult = null;
+        PendingFuture<Number,Object> writeResult = null;
+
+        // map event to pending result
+        synchronized (updateLock) {
+            if (readable && (pendingRead != null)) {
+                readResult = pendingRead;
+                pendingRead = null;
+            }
+            if (writable) {
+                if (pendingWrite != null) {
+                    writeResult = pendingWrite;
+                    pendingWrite = null;
+                } else if (pendingConnect != null) {
+                    connectResult = pendingConnect;
+                    pendingConnect = null;
+                }
+            }
+        }
+
+        // complete the I/O operation. Special case for when channel is
+        // ready for both reading and writing. In that case, submit task to
+        // complete write if write operation has a completion handler.
+        if (readResult != null) {
+            if (writeResult != null)
+                finishWrite(writeResult, false);
+            finishRead(readResult, true);
+            return;
+        }
+        if (writeResult != null) {
+            finishWrite(writeResult, true);
+        }
+        if (connectResult != null) {
+            finishConnect(connectResult, true);
+        }
+    }
+
+    // returns and clears the result of a pending read
+    PendingFuture<Number,Object> grabPendingRead() {
+        synchronized (updateLock) {
+            PendingFuture<Number,Object> result = pendingRead;
+            pendingRead = null;
+            return result;
+        }
+    }
+
+    // returns and clears the result of a pending write
+    PendingFuture<Number,Object> grabPendingWrite() {
+        synchronized (updateLock) {
+            PendingFuture<Number,Object> result = pendingWrite;
+            pendingWrite = null;
+            return result;
+        }
+    }
+
+    @Override
+    void implClose() throws IOException {
+        // remove the mapping
+        port.unregister(fdVal);
+
+        // close file descriptor
+        nd.close(fd);
+
+        // All outstanding I/O operations are required to fail
+        final PendingFuture<Void,Object> readyToConnect;
+        final PendingFuture<Number,Object> readyToRead;
+        final PendingFuture<Number,Object> readyToWrite;
+        synchronized (updateLock) {
+            readyToConnect = pendingConnect;
+            pendingConnect = null;
+            readyToRead = pendingRead;
+            pendingRead = null;
+            readyToWrite = pendingWrite;
+            pendingWrite = null;
+        }
+        if (readyToConnect != null) {
+            finishConnect(readyToConnect, false);
+        }
+        if (readyToRead != null) {
+            finishRead(readyToRead, false);
+        }
+        if (readyToWrite != null) {
+            finishWrite(readyToWrite, false);
+        }
+    }
+
+    @Override
+    public void onCancel(PendingFuture<?,?> task) {
+        if (task.getContext() == OpType.CONNECT)
+            killConnect();
+        if (task.getContext() == OpType.READ)
+            killConnect();
+        if (task.getContext() == OpType.WRITE)
+            killConnect();
+    }
+
+    // -- connect --
+
+    private void setConnected() throws IOException {
+        synchronized (stateLock) {
+            state = ST_CONNECTED;
+            localAddress = Net.localAddress(fd);
+            remoteAddress = pendingRemote;
+        }
+    }
+
+    private void finishConnect(PendingFuture<Void,Object> result,
+                               boolean invokeDirect)
+    {
+        Throwable e = null;
+        try {
+            begin();
+            checkConnect(fdVal);
+            setConnected();
+            result.setResult(null);
+        } catch (Throwable x) {
+            if (x instanceof ClosedChannelException)
+                x = new AsynchronousCloseException();
+            e = x;
+        } finally {
+            end();
+        }
+        if (e != null) {
+            // close channel if connection cannot be established
+            try {
+                close();
+            } catch (IOException ignore) { }
+            result.setFailure(e);
+        }
+        if (invokeDirect) {
+            Invoker.invoke(result.handler(), result);
+        } else {
+            Invoker.invokeIndirectly(result.handler(), result);
+        }
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public <A> Future<Void> connect(SocketAddress remote,
+                                    A attachment,
+                                    CompletionHandler<Void,? super A> handler)
+    {
+        if (!isOpen()) {
+            CompletedFuture<Void,A> result = CompletedFuture
+                .withFailure(this, new ClosedChannelException(), attachment);
+            Invoker.invoke(handler, result);
+            return result;
+        }
+
+        InetSocketAddress isa = Net.checkAddress(remote);
+
+        // permission check
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null)
+            sm.checkConnect(isa.getAddress().getHostAddress(), isa.getPort());
+
+        // check and set state
+        synchronized (stateLock) {
+            if (state == ST_CONNECTED)
+                throw new AlreadyConnectedException();
+            if (state == ST_PENDING)
+                throw new ConnectionPendingException();
+            state = ST_PENDING;
+            pendingRemote = remote;
+        }
+
+        AbstractFuture<Void,A> result = null;
+        Throwable e = null;
+        try {
+            begin();
+            int n = Net.connect(fd, isa.getAddress(), isa.getPort());
+            if (n == IOStatus.UNAVAILABLE) {
+                // connection could not be established immediately
+                result = new PendingFuture<Void,A>(this, handler, attachment, OpType.CONNECT);
+                synchronized (updateLock) {
+                    this.pendingConnect = (PendingFuture<Void,Object>)result;
+                    updateEvents();
+                }
+                return result;
+            }
+            setConnected();
+            result = CompletedFuture.withResult(this, null, attachment);
+        } catch (Throwable x) {
+            if (x instanceof ClosedChannelException)
+                x = new AsynchronousCloseException();
+            e = x;
+        } finally {
+            end();
+        }
+
+        // close channel if connect fails
+        if (e != null) {
+            try {
+                close();
+            } catch (IOException ignore) { }
+            result = CompletedFuture.withFailure(this, e, attachment);
+        }
+
+        Invoker.invoke(handler, result);
+        return result;
+    }
+
+    // -- read --
+
+    @SuppressWarnings("unchecked")
+    private void finishRead(PendingFuture<Number,Object> result,
+                            boolean invokeDirect)
+    {
+        int n = -1;
+        PendingFuture<Number,Object> pending = null;
+        try {
+            begin();
+
+            ByteBuffer[] dsts = readBuffers;
+            if (dsts.length == 1) {
+                n = IOUtil.read(fd, dsts[0], -1, nd, null);
+            } else {
+                n = (int)IOUtil.read(fd, dsts, nd);
+            }
+            if (n == IOStatus.UNAVAILABLE) {
+                // spurious wakeup, is this possible?
+                pending = result;
+                return;
+            }
+
+            // allow buffer(s) to be GC'ed.
+            readBuffers = null;
+
+            // allow another read to be initiated
+            boolean wasScatteringRead = scatteringRead;
+            enableReading();
+
+            // result is Integer or Long
+            if (wasScatteringRead) {
+                result.setResult(Long.valueOf(n));
+            } else {
+                result.setResult(Integer.valueOf(n));
+            }
+
+        } catch (Throwable x) {
+            enableReading();
+            if (x instanceof ClosedChannelException)
+                x = new AsynchronousCloseException();
+            result.setFailure(x);
+        } finally {
+            // restart poll in case of concurrent write
+            synchronized (updateLock) {
+                if (pending != null)
+                    this.pendingRead = pending;
+                updateEvents();
+            }
+            end();
+        }
+
+        if (invokeDirect) {
+            Invoker.invoke(result.handler(), result);
+        } else {
+            Invoker.invokeIndirectly(result.handler(), result);
+        }
+    }
+
+    private Runnable readTimeoutTask = new Runnable() {
+        public void run() {
+            PendingFuture<Number,Object> result = grabPendingRead();
+            if (result == null)
+                return;     // already completed
+
+            // kill further reading before releasing waiters
+            enableReading(true);
+
+            // set completed and invoke handler
+            result.setFailure(new InterruptedByTimeoutException());
+            Invoker.invokeIndirectly(result.handler(), result);
+        }
+    };
+
+    /**
+     * Initiates a read or scattering read operation
+     */
+    @Override
+    @SuppressWarnings("unchecked")
+    <V extends Number,A> Future<V> readImpl(ByteBuffer[] dsts,
+                                            boolean isScatteringRead,
+                                            long timeout,
+                                            TimeUnit unit,
+                                            A attachment,
+                                            CompletionHandler<V,? super A> handler)
+    {
+        // A synchronous read is not attempted if disallowed by system property
+        // or, we are using a fixed thread pool and the completion handler may
+        // not be invoked directly (because the thread is not a pooled thread or
+        // there are too many handlers on the stack).
+        Invoker.GroupAndInvokeCount myGroupAndInvokeCount = null;
+        boolean invokeDirect = false;
+        boolean attemptRead = false;
+        if (!disableSynchronousRead) {
+            myGroupAndInvokeCount = Invoker.getGroupAndInvokeCount();
+            invokeDirect = Invoker.mayInvokeDirect(myGroupAndInvokeCount, port);
+            attemptRead = (handler == null) || invokeDirect ||
+                !port.isFixedThreadPool();  // okay to attempt read with user thread pool
+        }
+
+        AbstractFuture<V,A> result;
+        try {
+            begin();
+
+            int n;
+            if (attemptRead) {
+                if (isScatteringRead) {
+                    n = (int)IOUtil.read(fd, dsts, nd);
+                } else {
+                    n = IOUtil.read(fd, dsts[0], -1, nd, null);
+                }
+            } else {
+                n = IOStatus.UNAVAILABLE;
+            }
+
+            if (n == IOStatus.UNAVAILABLE) {
+                result = new PendingFuture<V,A>(this, handler, attachment, OpType.READ);
+
+                // update evetns so that read will complete asynchronously
+                synchronized (updateLock) {
+                    this.readBuffers = dsts;
+                    this.scatteringRead = isScatteringRead;
+                    this.pendingRead = (PendingFuture<Number,Object>)result;
+                    updateEvents();
+                }
+
+                // schedule timeout
+                if (timeout > 0L) {
+                    Future<?> timeoutTask =
+                        port.schedule(readTimeoutTask, timeout, unit);
+                    ((PendingFuture<V,A>)result).setTimeoutTask(timeoutTask);
+                }
+                return result;
+            }
+
+            // data available
+            enableReading();
+
+            // result type is Long or Integer
+            if (isScatteringRead) {
+                result = (CompletedFuture<V,A>)CompletedFuture
+                    .withResult(this, Long.valueOf(n), attachment);
+            } else {
+                result = (CompletedFuture<V,A>)CompletedFuture
+                    .withResult(this, Integer.valueOf(n), attachment);
+            }
+        } catch (Throwable x) {
+            enableReading();
+            if (x instanceof ClosedChannelException)
+                x = new AsynchronousCloseException();
+            result = CompletedFuture.withFailure(this, x, attachment);
+        } finally {
+            end();
+        }
+
+        if (invokeDirect) {
+            Invoker.invokeDirect(myGroupAndInvokeCount, handler, result);
+        } else {
+            Invoker.invokeIndirectly(handler, result);
+        }
+        return result;
+    }
+
+    // -- write --
+
+    private void finishWrite(PendingFuture<Number,Object> result,
+                             boolean invokeDirect)
+    {
+        PendingFuture<Number,Object> pending = null;
+        try {
+            begin();
+
+            ByteBuffer[] srcs = writeBuffers;
+            int n;
+            if (srcs.length == 1) {
+                n = IOUtil.write(fd, srcs[0], -1, nd, null);
+            } else {
+                n = (int)IOUtil.write(fd, srcs, nd);
+            }
+            if (n == IOStatus.UNAVAILABLE) {
+                // spurious wakeup, is this possible?
+                pending = result;
+                return;
+            }
+
+            // allow buffer(s) to be GC'ed.
+            writeBuffers = null;
+
+            // allow another write to be initiated
+            boolean wasGatheringWrite = gatheringWrite;
+            enableWriting();
+
+            // result is a Long or Integer
+            if (wasGatheringWrite) {
+                result.setResult(Long.valueOf(n));
+            } else {
+                result.setResult(Integer.valueOf(n));
+            }
+
+        } catch (Throwable x) {
+            enableWriting();
+            if (x instanceof ClosedChannelException)
+                x = new AsynchronousCloseException();
+            result.setFailure(x);
+        } finally {
+            // restart poll in case of concurrent read
+            synchronized (this) {
+                if (pending != null)
+                    this.pendingWrite = pending;
+                updateEvents();
+            }
+            end();
+        }
+        if (invokeDirect) {
+            Invoker.invoke(result.handler(), result);
+        } else {
+            Invoker.invokeIndirectly(result.handler(), result);
+        }
+    }
+
+    private Runnable writeTimeoutTask = new Runnable() {
+        public void run() {
+            PendingFuture<Number,Object> result = grabPendingWrite();
+            if (result == null)
+                return;     // already completed
+
+            // kill further writing before releasing waiters
+            enableWriting(true);
+
+            // set completed and invoke handler
+            result.setFailure(new InterruptedByTimeoutException());
+            Invoker.invokeIndirectly(result.handler(), result);
+        }
+    };
+
+    /**
+     * Initiates a read or scattering read operation
+     */
+    @Override
+    @SuppressWarnings("unchecked")
+    <V extends Number,A> Future<V> writeImpl(ByteBuffer[] srcs,
+                                             boolean isGatheringWrite,
+                                             long timeout,
+                                             TimeUnit unit,
+                                             A attachment,
+                                             CompletionHandler<V,? super A> handler)
+    {
+        Invoker.GroupAndInvokeCount myGroupAndInvokeCount =
+            Invoker.getGroupAndInvokeCount();
+        boolean invokeDirect = Invoker.mayInvokeDirect(myGroupAndInvokeCount, port);
+        boolean attemptWrite = (handler == null) || invokeDirect ||
+            !port.isFixedThreadPool();  // okay to attempt read with user thread pool
+
+        AbstractFuture<V,A> result;
+        try {
+            begin();
+
+            int n;
+            if (attemptWrite) {
+                if (isGatheringWrite) {
+                    n = (int)IOUtil.write(fd, srcs, nd);
+                } else {
+                    n = IOUtil.write(fd, srcs[0], -1, nd, null);
+                }
+            } else {
+                n = IOStatus.UNAVAILABLE;
+            }
+
+            if (n == IOStatus.UNAVAILABLE) {
+                result = new PendingFuture<V,A>(this, handler, attachment, OpType.WRITE);
+
+                // update evetns so that read will complete asynchronously
+                synchronized (updateLock) {
+                    this.writeBuffers = srcs;
+                    this.gatheringWrite = isGatheringWrite;
+                    this.pendingWrite = (PendingFuture<Number,Object>)result;
+                    updateEvents();
+                }
+
+                // schedule timeout
+                if (timeout > 0L) {
+                    Future<?> timeoutTask =
+                        port.schedule(writeTimeoutTask, timeout, unit);
+                    ((PendingFuture<V,A>)result).setTimeoutTask(timeoutTask);
+                }
+                return result;
+            }
+
+            // data available
+            enableWriting();
+            if (isGatheringWrite) {
+                result = (CompletedFuture<V,A>)CompletedFuture
+                    .withResult(this, Long.valueOf(n), attachment);
+            } else {
+                result = (CompletedFuture<V,A>)CompletedFuture
+                    .withResult(this, Integer.valueOf(n), attachment);
+            }
+        } catch (Throwable x) {
+            enableWriting();
+            if (x instanceof ClosedChannelException)
+                x = new AsynchronousCloseException();
+            result = CompletedFuture.withFailure(this, x, attachment);
+        } finally {
+            end();
+        }
+        if (invokeDirect) {
+            Invoker.invokeDirect(myGroupAndInvokeCount, handler, result);
+        } else {
+            Invoker.invokeIndirectly(handler, result);
+        }
+        return result;
+    }
+
+    // -- Native methods --
+
+    private static native void checkConnect(int fdVal) throws IOException;
+
+    static {
+        Util.load();
+    }
+}
diff --git a/jdk/src/solaris/classes/sun/nio/fs/DefaultFileSystemProvider.java b/jdk/src/solaris/classes/sun/nio/fs/DefaultFileSystemProvider.java
new file mode 100644
index 0000000..e86ff07
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/fs/DefaultFileSystemProvider.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.spi.FileSystemProvider;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import sun.security.action.GetPropertyAction;
+
+/**
+ * Creates this platform's default FileSystemProvider.
+ */
+
+public class DefaultFileSystemProvider {
+    private DefaultFileSystemProvider() { }
+
+    @SuppressWarnings("unchecked")
+    private static FileSystemProvider createProvider(final String cn) {
+        return AccessController
+            .doPrivileged(new PrivilegedAction<FileSystemProvider>() {
+                public FileSystemProvider run() {
+                    Class<FileSystemProvider> c;
+                    try {
+                        c = (Class<FileSystemProvider>)Class.forName(cn, true, null);
+                    } catch (ClassNotFoundException x) {
+                        throw new AssertionError(x);
+                    }
+                    try {
+                        return c.newInstance();
+                    } catch (IllegalAccessException x) {
+                        throw new AssertionError(x);
+                    } catch (InstantiationException x) {
+                        throw new AssertionError(x);
+                    }
+            }});
+    }
+
+    /**
+     * Returns the default FileSystemProvider.
+     */
+    public static FileSystemProvider create() {
+        String osname = AccessController
+            .doPrivileged(new GetPropertyAction("os.name"));
+        if (osname.equals("SunOS"))
+            return createProvider("sun.nio.fs.SolarisFileSystemProvider");
+        if (osname.equals("Linux"))
+            return createProvider("sun.nio.fs.LinuxFileSystemProvider");
+        throw new AssertionError("Platform not recognized");
+    }
+}
diff --git a/jdk/src/solaris/classes/sun/nio/fs/DefaultFileTypeDetector.java b/jdk/src/solaris/classes/sun/nio/fs/DefaultFileTypeDetector.java
new file mode 100644
index 0000000..22db316
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/fs/DefaultFileTypeDetector.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.spi.FileTypeDetector;
+
+public class DefaultFileTypeDetector {
+    private DefaultFileTypeDetector() { }
+
+    public static FileTypeDetector create() {
+        return new GnomeFileTypeDetector();
+    }
+}
diff --git a/jdk/src/solaris/classes/sun/nio/fs/GnomeFileTypeDetector.java b/jdk/src/solaris/classes/sun/nio/fs/GnomeFileTypeDetector.java
new file mode 100644
index 0000000..bf9e87a
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/fs/GnomeFileTypeDetector.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.FileRef;
+import java.io.IOException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * File type detector that uses the GNOME I/O library or the deprecated
+ * GNOME VFS to guess the MIME type of a file.
+ */
+
+public class GnomeFileTypeDetector
+    extends AbstractFileTypeDetector
+{
+    private static final String GNOME_VFS_MIME_TYPE_UNKNOWN =
+        "application/octet-stream";
+
+    // true if GIO available
+    private final boolean gioAvailable;
+
+    // true if GNOME VFS available and GIO is not available
+    private final boolean gnomeVfsAvailable;
+
+    public GnomeFileTypeDetector() {
+        gioAvailable = initializeGio();
+        if (gioAvailable) {
+            gnomeVfsAvailable = false;
+        } else {
+            gnomeVfsAvailable = initializeGnomeVfs();
+        }
+    }
+
+    @Override
+    public String implProbeContentType(FileRef obj) throws IOException {
+        if (!gioAvailable && !gnomeVfsAvailable)
+            return null;
+        if (!(obj instanceof UnixPath))
+            return null;
+
+        UnixPath path = (UnixPath)obj;
+        NativeBuffer buffer = NativeBuffers.asNativeBuffer(path.getByteArrayForSysCalls());
+        try {
+            if (gioAvailable) {
+                byte[] type = probeUsingGio(buffer.address());
+                return (type == null) ? null : new String(type);
+            } else {
+                byte[] type = probeUsingGnomeVfs(buffer.address());
+                if (type == null)
+                    return null;
+                String s = new String(type);
+                return s.equals(GNOME_VFS_MIME_TYPE_UNKNOWN) ? null : s;
+            }
+
+        } finally {
+            buffer.release();
+        }
+
+    }
+
+    // GIO
+    private static native boolean initializeGio();
+    private static native byte[] probeUsingGio(long pathAddress);
+
+    // GNOME VFS
+    private static native boolean initializeGnomeVfs();
+    private static native byte[] probeUsingGnomeVfs(long pathAddress);
+
+    static {
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+            public Void run() {
+                System.loadLibrary("nio");
+                return null;
+        }});
+    }
+}
diff --git a/jdk/src/solaris/classes/sun/nio/fs/LinuxDosFileAttributeView.java b/jdk/src/solaris/classes/sun/nio/fs/LinuxDosFileAttributeView.java
new file mode 100644
index 0000000..85f83e2
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/fs/LinuxDosFileAttributeView.java
@@ -0,0 +1,297 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.attribute.*;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import java.io.IOException;
+import sun.misc.Unsafe;
+
+import static sun.nio.fs.UnixNativeDispatcher.*;
+import static sun.nio.fs.UnixConstants.*;
+
+/**
+ * Linux implementation of DosFileAttributeView for use on file systems such
+ * as ext3 that have extended attributes enabled and SAMBA configured to store
+ * DOS attributes.
+ */
+
+class LinuxDosFileAttributeView
+    extends UnixFileAttributeViews.Basic implements DosFileAttributeView
+{
+    private static final Unsafe unsafe = Unsafe.getUnsafe();
+
+    private static final String READONLY_NAME = "readonly";
+    private static final String ARCHIVE_NAME = "archive";
+    private static final String SYSTEM_NAME = "system";
+    private static final String HIDDEN_NAME = "hidden";
+
+    private static final String DOS_XATTR_NAME = "user.DOSATTRIB";
+    private static final byte[] DOS_XATTR_NAME_AS_BYTES = DOS_XATTR_NAME.getBytes();
+
+    private static final int DOS_XATTR_READONLY = 0x01;
+    private static final int DOS_XATTR_HIDDEN   = 0x02;
+    private static final int DOS_XATTR_SYSTEM   = 0x04;
+    private static final int DOS_XATTR_ARCHIVE  = 0x20;
+
+    LinuxDosFileAttributeView(UnixPath file, boolean followLinks) {
+        super(file, followLinks);
+    }
+
+    @Override
+    public String name() {
+        return "dos";
+    }
+
+    @Override
+    public Object getAttribute(String attribute) throws IOException {
+        if (attribute.equals(READONLY_NAME))
+            return readAttributes().isReadOnly();
+        if (attribute.equals(ARCHIVE_NAME))
+            return readAttributes().isArchive();
+        if (attribute.equals(SYSTEM_NAME))
+            return readAttributes().isSystem();
+        if (attribute.equals(HIDDEN_NAME))
+            return readAttributes().isHidden();
+        return super.getAttribute(attribute);
+    }
+
+    @Override
+    public void setAttribute(String attribute, Object value)
+        throws IOException
+    {
+        if (attribute.equals(READONLY_NAME)) {
+            setReadOnly((Boolean)value);
+            return;
+        }
+        if (attribute.equals(ARCHIVE_NAME)) {
+            setArchive((Boolean)value);
+            return;
+        }
+        if (attribute.equals(SYSTEM_NAME)) {
+            setSystem((Boolean)value);
+            return;
+        }
+        if (attribute.equals(HIDDEN_NAME)) {
+            setHidden((Boolean)value);
+            return;
+        }
+        super.setAttribute(attribute, value);
+    }
+
+    @Override
+    public Map<String,?> readAttributes(String first, String[] rest)
+        throws IOException
+    {
+        AttributesBuilder builder = AttributesBuilder.create(first, rest);
+        DosFileAttributes attrs = readAttributes();
+        addBasicAttributesToBuilder(attrs, builder);
+        if (builder.match(READONLY_NAME))
+            builder.add(READONLY_NAME, attrs.isReadOnly());
+        if (builder.match(ARCHIVE_NAME))
+            builder.add(ARCHIVE_NAME, attrs.isArchive());
+        if (builder.match(SYSTEM_NAME))
+            builder.add(SYSTEM_NAME, attrs.isSystem());
+        if (builder.match(HIDDEN_NAME))
+            builder.add(HIDDEN_NAME, attrs.isHidden());
+        return builder.unmodifiableMap();
+    }
+
+    @Override
+    public DosFileAttributes readAttributes() throws IOException {
+        file.checkRead();
+
+        int fd = file.openForAttributeAccess(followLinks);
+        try {
+             final UnixFileAttributes attrs = UnixFileAttributes.get(fd);
+             final int dosAttribute = getDosAttribute(fd);
+
+             return new DosFileAttributes() {
+                @Override
+                public long lastModifiedTime() {
+                    return attrs.lastModifiedTime();
+                }
+                @Override
+                public long lastAccessTime() {
+                    return attrs.lastAccessTime();
+                }
+                @Override
+                public long creationTime() {
+                    return attrs.creationTime();
+                }
+                @Override
+                public TimeUnit resolution() {
+                    return attrs.resolution();
+                }
+                @Override
+                public boolean isRegularFile() {
+                    return attrs.isRegularFile();
+                }
+                @Override
+                public boolean isDirectory() {
+                    return attrs.isDirectory();
+                }
+                @Override
+                public boolean isSymbolicLink() {
+                    return attrs.isSymbolicLink();
+                }
+                @Override
+                public boolean isOther() {
+                    return attrs.isOther();
+                }
+                @Override
+                public long size() {
+                    return attrs.size();
+                }
+                @Override
+                public int linkCount() {
+                    return attrs.linkCount();
+                }
+                @Override
+                public Object fileKey() {
+                    return attrs.fileKey();
+                }
+                @Override
+                public boolean isReadOnly() {
+                    return (dosAttribute & DOS_XATTR_READONLY) != 0;
+                }
+                @Override
+                public boolean isHidden() {
+                    return (dosAttribute & DOS_XATTR_HIDDEN) != 0;
+                }
+                @Override
+                public boolean isArchive() {
+                    return (dosAttribute & DOS_XATTR_ARCHIVE) != 0;
+                }
+                @Override
+                public boolean isSystem() {
+                    return (dosAttribute & DOS_XATTR_SYSTEM) != 0;
+                }
+             };
+
+        } catch (UnixException x) {
+            x.rethrowAsIOException(file);
+            return null;    // keep compiler happy
+        } finally {
+            close(fd);
+        }
+    }
+
+    @Override
+    public void setReadOnly(boolean value) throws IOException {
+        updateDosAttribute(DOS_XATTR_READONLY, value);
+    }
+
+    @Override
+    public void setHidden(boolean value) throws IOException {
+        updateDosAttribute(DOS_XATTR_HIDDEN, value);
+    }
+
+    @Override
+    public void setArchive(boolean value) throws IOException {
+        updateDosAttribute(DOS_XATTR_ARCHIVE, value);
+    }
+
+    @Override
+    public void setSystem(boolean value) throws IOException {
+        updateDosAttribute(DOS_XATTR_SYSTEM, value);
+    }
+
+    /**
+     * Reads the value of the user.DOSATTRIB extended attribute
+     */
+    private int getDosAttribute(int fd) throws UnixException {
+        final int size = 24;
+
+        NativeBuffer buffer = NativeBuffers.getNativeBuffer(size);
+        try {
+            int len = LinuxNativeDispatcher
+                .fgetxattr(fd, DOS_XATTR_NAME_AS_BYTES, buffer.address(), size);
+
+            if (len > 0) {
+                // ignore null terminator
+                if (unsafe.getByte(buffer.address()+len-1) == 0)
+                    len--;
+
+                // convert to String and parse
+                byte[] buf = new byte[len];
+                unsafe.copyMemory(null, buffer.address(), buf,
+                    Unsafe.ARRAY_BYTE_BASE_OFFSET, len);
+                String value = new String(buf); // platform encoding
+
+                // should be something like 0x20
+                if (value.length() >= 3 && value.startsWith("0x")) {
+                    try {
+                        return Integer.parseInt(value.substring(2), 16);
+                    } catch (NumberFormatException x) {
+                        // ignore
+                    }
+                }
+            }
+            throw new UnixException("Value of " + DOS_XATTR_NAME + " attribute is invalid");
+        } catch (UnixException x) {
+            // default value when attribute does not exist
+            if (x.errno() == ENODATA)
+                return 0;
+            throw x;
+        } finally {
+            buffer.release();
+        }
+    }
+
+    /**
+     * Updates the value of the user.DOSATTRIB extended attribute
+     */
+    private void updateDosAttribute(int flag, boolean enable) throws IOException {
+        file.checkWrite();
+
+        int fd = file.openForAttributeAccess(followLinks);
+        try {
+            int oldValue = getDosAttribute(fd);
+            int newValue = oldValue;
+            if (enable) {
+                newValue |= flag;
+            } else {
+                newValue &= ~flag;
+            }
+            if (newValue != oldValue) {
+                byte[] value = ("0x" + Integer.toHexString(newValue)).getBytes();
+                NativeBuffer buffer = NativeBuffers.asNativeBuffer(value);
+                try {
+                    LinuxNativeDispatcher.fsetxattr(fd, DOS_XATTR_NAME_AS_BYTES,
+                        buffer.address(), value.length+1);
+                } finally {
+                    buffer.release();
+                }
+            }
+        } catch (UnixException x) {
+            x.rethrowAsIOException(file);
+        } finally {
+            close(fd);
+        }
+    }
+}
diff --git a/jdk/src/solaris/classes/sun/nio/fs/LinuxFileStore.java b/jdk/src/solaris/classes/sun/nio/fs/LinuxFileStore.java
new file mode 100644
index 0000000..8c07ce5
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/fs/LinuxFileStore.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.util.*;
+import java.io.IOException;
+
+/**
+ * Linux implementation of FileStore
+ */
+
+class LinuxFileStore
+    extends UnixFileStore
+{
+    // used when checking if extended attributes are enabled or not
+    private volatile boolean xattrChecked;
+    private volatile boolean xattrEnabled;
+
+    LinuxFileStore(UnixPath file) throws IOException {
+        super(file);
+    }
+
+    LinuxFileStore(UnixFileSystem fs, UnixMountEntry entry) throws IOException {
+        super(fs, entry);
+    }
+
+    /**
+     * Finds, and returns, the mount entry for the file system where the file
+     * resides.
+     */
+    @Override
+    UnixMountEntry findMountEntry() throws IOException {
+        UnixFileSystem fs = file().getFileSystem();
+
+        // step 1: get realpath
+        UnixPath path = null;
+        try {
+            byte[] rp = UnixNativeDispatcher.realpath(file());
+            path = new UnixPath(fs, rp);
+        } catch (UnixException x) {
+            x.rethrowAsIOException(file());
+        }
+
+        // step 2: find mount point
+        UnixPath parent = path.getParent();
+        while (parent != null) {
+            UnixFileAttributes attrs = null;
+            try {
+                attrs = UnixFileAttributes.get(parent, true);
+            } catch (UnixException x) {
+                x.rethrowAsIOException(parent);
+            }
+            if (attrs.dev() != dev())
+                break;
+            path = parent;
+            parent = parent.getParent();
+        }
+
+        // step 3: lookup mounted file systems
+        byte[] dir = path.asByteArray();
+        for (UnixMountEntry entry: fs.getMountEntries()) {
+            if (Arrays.equals(dir, entry.dir()))
+                return entry;
+        }
+
+        throw new IOException("Mount point not found in mtab");
+    }
+
+    // returns true if extended attributes enabled on file system where given
+    // file resides, returns false if disabled or unable to determine.
+    private boolean isExtendedAttributesEnabled(UnixPath path) {
+        try {
+            int fd = path.openForAttributeAccess(false);
+            try {
+                // fgetxattr returns size if called with size==0
+                LinuxNativeDispatcher.fgetxattr(fd, "user.java".getBytes(), 0L, 0);
+                return true;
+            } catch (UnixException e) {
+                // attribute does not exist
+                if (e.errno() == UnixConstants.ENODATA)
+                    return true;
+            } finally {
+                UnixNativeDispatcher.close(fd);
+            }
+        } catch (IOException ignore) {
+            // nothing we can do
+        }
+        return false;
+    }
+
+    @Override
+    public boolean supportsFileAttributeView(String name) {
+        // support DosFileAttributeView and NamedAttributeView if extended
+        // attributes enabled
+        if (name.equals("dos") || name.equals("xattr")) {
+            // lookup fstypes.properties
+            FeatureStatus status = checkIfFeaturePresent("user_xattr");
+            if (status == FeatureStatus.PRESENT)
+                return true;
+            if (status == FeatureStatus.NOT_PRESENT)
+                return false;
+
+            // if file system is mounted with user_xattr option then assume
+            // extended attributes are enabled
+            if ((entry().hasOption("user_xattr")))
+                return true;
+
+            // user_xattr option not present but we special-case ext3/4 as we
+            // know that extended attributes are not enabled by default.
+            if (entry().fstype().equals("ext3") || entry().fstype().equals("ext4"))
+                return false;
+
+            // not ext3/4 so probe mount point
+            if (!xattrChecked) {
+                UnixPath dir = new UnixPath(file().getFileSystem(), entry().dir());
+                xattrEnabled = isExtendedAttributesEnabled(dir);
+                xattrChecked = true;
+            }
+            return xattrEnabled;
+        }
+
+        return super.supportsFileAttributeView(name);
+    }
+
+    @Override
+    boolean isLoopback() {
+        return false;
+    }
+}
diff --git a/jdk/src/solaris/classes/sun/nio/fs/LinuxFileSystem.java b/jdk/src/solaris/classes/sun/nio/fs/LinuxFileSystem.java
new file mode 100644
index 0000000..d574c9d
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/fs/LinuxFileSystem.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.io.IOException;
+import java.util.*;
+import java.security.AccessController;
+import sun.security.action.GetPropertyAction;
+import static sun.nio.fs.LinuxNativeDispatcher.*;
+
+/**
+ * Linux implementation of FileSystem
+ */
+
+class LinuxFileSystem extends UnixFileSystem {
+    private final boolean hasInotify;
+    private final boolean hasAtSysCalls;
+
+    LinuxFileSystem(UnixFileSystemProvider provider, String dir) {
+        super(provider, dir);
+
+        // assume X.Y[-Z] format
+        String osversion = AccessController
+            .doPrivileged(new GetPropertyAction("os.version"));
+        String[] vers = osversion.split("\\.", 0);
+        assert vers.length >= 2;
+
+        int majorVersion = Integer.parseInt(vers[0]);
+        int minorVersion = Integer.parseInt(vers[1]);
+        int microVersion = 0;
+        if (vers.length > 2) {
+            String[] microVers = vers[2].split("-", 0);
+            microVersion = (microVers.length > 0) ?
+                Integer.parseInt(microVers[0]) : 0;
+        }
+
+        // inotify available since 2.6.13
+        this.hasInotify = ((majorVersion > 2) ||
+            (majorVersion == 2 && minorVersion > 6) ||
+            ((majorVersion == 2) && (minorVersion == 6) && (microVersion >= 13)));
+
+        // openat etc. available since 2.6.16
+        this.hasAtSysCalls = ((majorVersion > 2) ||
+            (majorVersion == 2 && minorVersion > 6) ||
+            ((majorVersion == 2) && (minorVersion == 6) && (microVersion >= 16)));
+    }
+
+    @Override
+    public WatchService newWatchService()
+        throws IOException
+    {
+        if (hasInotify) {
+            return new LinuxWatchService(this);
+        } else {
+            // use polling implementation on older kernels
+            return new PollingWatchService();
+        }
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public <V extends FileAttributeView> V newFileAttributeView(Class<V> view,
+                                                                UnixPath file,
+                                                                LinkOption... options)
+    {
+        if (view == DosFileAttributeView.class)
+            return (V) new LinuxDosFileAttributeView(file, followLinks(options));
+        if (view == UserDefinedFileAttributeView.class)
+            return (V) new LinuxUserDefinedFileAttributeView(file, followLinks(options));
+        return super.newFileAttributeView(view, file, options);
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public FileAttributeView newFileAttributeView(String name,
+                                                  UnixPath file,
+                                                  LinkOption... options)
+    {
+        if (name.equals("dos"))
+            return new LinuxDosFileAttributeView(file, followLinks(options));
+        if (name.equals("xattr"))
+            return new LinuxUserDefinedFileAttributeView(file, followLinks(options));
+        return super.newFileAttributeView(name, file, options);
+    }
+
+    // lazy initialization of the list of supported attribute views
+    private static class SupportedFileFileAttributeViewsHolder {
+        static final Set<String> supportedFileAttributeViews =
+            supportedFileAttributeViews();
+        private static Set<String> supportedFileAttributeViews() {
+            Set<String> result = new HashSet<String>();
+            result.addAll(UnixFileSystem.standardFileAttributeViews());
+            // additional Linux-specific views
+            result.add("dos");
+            result.add("xattr");
+            return Collections.unmodifiableSet(result);
+        }
+    }
+
+    @Override
+    public Set<String> supportedFileAttributeViews() {
+        return SupportedFileFileAttributeViewsHolder.supportedFileAttributeViews;
+    }
+
+    @Override
+    void copyNonPosixAttributes(int ofd, int nfd) {
+        LinuxUserDefinedFileAttributeView.copyExtendedAttributes(ofd, nfd);
+    }
+
+    @Override
+    boolean supportsSecureDirectoryStreams() {
+        return hasAtSysCalls;
+    }
+
+    /**
+     * Returns object to iterate over entries in /etc/mtab
+     */
+    @Override
+    Iterable<UnixMountEntry> getMountEntries() {
+        ArrayList<UnixMountEntry> entries = new ArrayList<UnixMountEntry>();
+        try {
+            long fp = setmntent("/etc/mtab".getBytes(), "r".getBytes());
+            try {
+                for (;;) {
+                    UnixMountEntry entry = new UnixMountEntry();
+                    int res = getextmntent(fp, entry);
+                    if (res < 0)
+                        break;
+                    entries.add(entry);
+                }
+            } finally {
+                endmntent(fp);
+            }
+
+        } catch (UnixException x) {
+            // nothing we can do
+        }
+        return entries;
+    }
+
+    @Override
+    FileStore getFileStore(UnixPath path) throws IOException {
+        return new LinuxFileStore(path);
+    }
+
+    @Override
+    FileStore getFileStore(UnixMountEntry entry) throws IOException {
+        return new LinuxFileStore(this, entry);
+    }
+}
diff --git a/jdk/src/solaris/classes/sun/nio/fs/LinuxFileSystemProvider.java b/jdk/src/solaris/classes/sun/nio/fs/LinuxFileSystemProvider.java
new file mode 100644
index 0000000..aa979c4
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/fs/LinuxFileSystemProvider.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+/**
+ * Linux implementation of FileSystemProvider
+ */
+
+public class LinuxFileSystemProvider extends UnixFileSystemProvider {
+    public LinuxFileSystemProvider() {
+        super();
+    }
+
+    @Override
+    LinuxFileSystem newFileSystem(String dir) {
+        return new LinuxFileSystem(this, dir);
+    }
+}
diff --git a/jdk/src/solaris/classes/sun/nio/fs/LinuxNativeDispatcher.java b/jdk/src/solaris/classes/sun/nio/fs/LinuxNativeDispatcher.java
new file mode 100644
index 0000000..65547ba
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/fs/LinuxNativeDispatcher.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * Linux specific system calls.
+ */
+
+class LinuxNativeDispatcher extends UnixNativeDispatcher {
+    private LinuxNativeDispatcher() { }
+
+   /**
+    * FILE *setmntent(const char *filename, const char *type);
+    */
+    static long setmntent(byte[] filename, byte[] type) throws UnixException {
+        NativeBuffer pathBuffer = NativeBuffers.asNativeBuffer(filename);
+        NativeBuffer typeBuffer = NativeBuffers.asNativeBuffer(type);
+        try {
+            return setmntent0(pathBuffer.address(), typeBuffer.address());
+        } finally {
+            typeBuffer.release();
+            pathBuffer.release();
+        }
+    }
+    private static native long setmntent0(long pathAddress, long typeAddress)
+        throws UnixException;
+
+   /**
+    * int endmntent(FILE* filep);
+    */
+    static native void endmntent(long stream) throws UnixException;
+
+    /**
+     * ssize_t fgetxattr(int filedes, const char *name, void *value, size_t size);
+     */
+    static int fgetxattr(int filedes, byte[] name, long valueAddress,
+                         int valueLen) throws UnixException
+    {
+        NativeBuffer buffer = NativeBuffers.asNativeBuffer(name);
+        try {
+            return fgetxattr0(filedes, buffer.address(), valueAddress, valueLen);
+        } finally {
+            buffer.release();
+        }
+    }
+
+    private static native int fgetxattr0(int filedes, long nameAddress,
+        long valueAdddress, int valueLen) throws UnixException;
+
+    /**
+     *  fsetxattr(int filedes, const char *name, const void *value, size_t size, int flags);
+     */
+    static void fsetxattr(int filedes, byte[] name, long valueAddress,
+        int valueLen) throws UnixException
+    {
+        NativeBuffer buffer = NativeBuffers.asNativeBuffer(name);
+        try {
+            fsetxattr0(filedes, buffer.address(), valueAddress, valueLen);
+        } finally {
+            buffer.release();
+        }
+    }
+
+    private static native void fsetxattr0(int filedes, long nameAddress,
+        long valueAdddress, int valueLen) throws UnixException;
+
+
+    /**
+     * fremovexattr(int filedes, const char *name);
+     */
+    static void fremovexattr(int filedes, byte[] name) throws UnixException {
+        NativeBuffer buffer = NativeBuffers.asNativeBuffer(name);
+        try {
+            fremovexattr0(filedes, buffer.address());
+        } finally {
+            buffer.release();
+        }
+    }
+
+    private static native void fremovexattr0(int filedes, long nameAddress)
+        throws UnixException;
+
+    /**
+     * size_t flistxattr(int filedes, const char *list, size_t size)
+     */
+    static native int flistxattr(int filedes, long listAddress, int size)
+        throws UnixException;
+
+    // initialize
+    private static native void init();
+
+    static {
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+            public Void run() {
+                System.loadLibrary("nio");
+                return null;
+        }});
+        init();
+    }
+}
diff --git a/jdk/src/solaris/classes/sun/nio/fs/LinuxUserDefinedFileAttributeView.java b/jdk/src/solaris/classes/sun/nio/fs/LinuxUserDefinedFileAttributeView.java
new file mode 100644
index 0000000..b51a9e9
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/fs/LinuxUserDefinedFileAttributeView.java
@@ -0,0 +1,350 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.*;
+import java.nio.ByteBuffer;
+import java.io.IOException;
+import java.util.*;
+import sun.misc.Unsafe;
+
+import static sun.nio.fs.UnixConstants.*;
+import static sun.nio.fs.LinuxNativeDispatcher.*;
+
+/**
+ * Linux implementation of UserDefinedFileAttributeView using extended attributes.
+ */
+
+class LinuxUserDefinedFileAttributeView
+    extends AbstractUserDefinedFileAttributeView
+{
+    private static final Unsafe unsafe = Unsafe.getUnsafe();
+
+    // namespace for extended user attributes
+    private static final String USER_NAMESPACE = "user.";
+
+    // maximum bytes in extended attribute name (includes namespace)
+    private static final int XATTR_NAME_MAX = 255;
+
+    private byte[] nameAsBytes(UnixPath file, String name) throws IOException {
+        if (name == null)
+            throw new NullPointerException("'name' is null");
+        name = USER_NAMESPACE + name;
+        byte[] bytes = name.getBytes();
+        if (bytes.length > XATTR_NAME_MAX) {
+            throw new FileSystemException(file.getPathForExecptionMessage(),
+                null, "'" + name + "' is too big");
+        }
+        return bytes;
+    }
+
+    // Parses buffer as array of NULL-terminated C strings.
+    private List<String> asList(long address, int size) {
+        final List<String> list = new ArrayList<String>();
+        int start = 0;
+        int pos = 0;
+        while (pos < size) {
+            if (unsafe.getByte(address + pos) == 0) {
+                int len = pos - start;
+                byte[] value = new byte[len];
+                unsafe.copyMemory(null, address+start, value,
+                    Unsafe.ARRAY_BYTE_BASE_OFFSET, len);
+                String s = new String(value);
+                if (s.startsWith(USER_NAMESPACE)) {
+                    s = s.substring(USER_NAMESPACE.length());
+                    list.add(s);
+                }
+                start = pos + 1;
+            }
+            pos++;
+        }
+        return list;
+    }
+
+    private final UnixPath file;
+    private final boolean followLinks;
+
+    LinuxUserDefinedFileAttributeView(UnixPath file, boolean followLinks) {
+        this.file = file;
+        this.followLinks = followLinks;
+    }
+
+    @Override
+    public List<String> list() throws IOException  {
+        if (System.getSecurityManager() != null)
+            checkAccess(file.getPathForPermissionCheck(), true, false);
+
+        int fd = file.openForAttributeAccess(followLinks);
+        NativeBuffer buffer = null;
+        try {
+            int size = 1024;
+            buffer = NativeBuffers.getNativeBuffer(size);
+            for (;;) {
+                try {
+                    int n = flistxattr(fd, buffer.address(), size);
+                    List<String> list = asList(buffer.address(), n);
+                    return Collections.unmodifiableList(list);
+                } catch (UnixException x) {
+                    // allocate larger buffer if required
+                    if (x.errno() == ERANGE && size < 32*1024) {
+                        buffer.release();
+                        size *= 2;
+                        buffer = null;
+                        buffer = NativeBuffers.getNativeBuffer(size);
+                        continue;
+                    }
+                    throw new FileSystemException(file.getPathForExecptionMessage(),
+                        null, "Unable to get list of extended attributes: " +
+                        x.getMessage());
+                }
+            }
+        } finally {
+            if (buffer != null)
+                buffer.release();
+            close(fd);
+        }
+    }
+
+    @Override
+    public int size(String name) throws IOException  {
+        if (System.getSecurityManager() != null)
+            checkAccess(file.getPathForPermissionCheck(), true, false);
+
+        int fd = file.openForAttributeAccess(followLinks);
+        try {
+            // fgetxattr returns size if called with size==0
+            return fgetxattr(fd, nameAsBytes(file,name), 0L, 0);
+        } catch (UnixException x) {
+            throw new FileSystemException(file.getPathForExecptionMessage(),
+                null, "Unable to get size of extended attribute '" + name +
+                "': " + x.getMessage());
+        } finally {
+            close(fd);
+        }
+    }
+
+    @Override
+    public int read(String name, ByteBuffer dst) throws IOException {
+        if (System.getSecurityManager() != null)
+            checkAccess(file.getPathForPermissionCheck(), true, false);
+
+        if (dst.isReadOnly())
+            throw new IllegalArgumentException("Read-only buffer");
+        int pos = dst.position();
+        int lim = dst.limit();
+        assert (pos <= lim);
+        int rem = (pos <= lim ? lim - pos : 0);
+
+        NativeBuffer nb;
+        long address;
+        if (dst instanceof sun.nio.ch.DirectBuffer) {
+            nb = null;
+            address = ((sun.nio.ch.DirectBuffer)dst).address() + pos;
+        } else {
+            // substitute with native buffer
+            nb = NativeBuffers.getNativeBuffer(rem);
+            address = nb.address();
+        }
+
+        int fd = file.openForAttributeAccess(followLinks);
+        try {
+            try {
+                int n = fgetxattr(fd, nameAsBytes(file,name), address, rem);
+
+                // if remaining is zero then fgetxattr returns the size
+                if (rem == 0) {
+                    if (n > 0)
+                        throw new UnixException(ERANGE);
+                    return 0;
+                }
+
+                // copy from buffer into backing array if necessary
+                if (nb != null) {
+                    int off = dst.arrayOffset() + pos + Unsafe.ARRAY_BYTE_BASE_OFFSET;
+                    unsafe.copyMemory(null, address, dst.array(), off, n);
+                }
+                dst.position(pos + n);
+                return n;
+            } catch (UnixException x) {
+                String msg = (x.errno() == ERANGE) ?
+                    "Insufficient space in buffer" : x.getMessage();
+                throw new FileSystemException(file.getPathForExecptionMessage(),
+                    null, "Error reading extended attribute '" + name + "': " + msg);
+            } finally {
+                close(fd);
+            }
+        } finally {
+            if (nb != null)
+                nb.release();
+        }
+    }
+
+    @Override
+    public int write(String name, ByteBuffer src) throws IOException {
+        if (System.getSecurityManager() != null)
+            checkAccess(file.getPathForPermissionCheck(), false, true);
+
+        int pos = src.position();
+        int lim = src.limit();
+        assert (pos <= lim);
+        int rem = (pos <= lim ? lim - pos : 0);
+
+        NativeBuffer nb;
+        long address;
+        if (src instanceof sun.nio.ch.DirectBuffer) {
+            nb = null;
+            address = ((sun.nio.ch.DirectBuffer)src).address() + pos;
+        } else {
+            // substitute with native buffer
+            nb = NativeBuffers.getNativeBuffer(rem);
+            address = nb.address();
+
+            if (src.hasArray()) {
+                // copy from backing array into buffer
+                int off = src.arrayOffset() + pos + Unsafe.ARRAY_BYTE_BASE_OFFSET;
+                unsafe.copyMemory(src.array(), off, null, address, rem);
+            } else {
+                // backing array not accessible so transfer via temporary array
+                byte[] tmp = new byte[rem];
+                src.get(tmp);
+                src.position(pos);  // reset position as write may fail
+                unsafe.copyMemory(tmp, Unsafe.ARRAY_BYTE_BASE_OFFSET, null,
+                    address, rem);
+            }
+        }
+
+        int fd = file.openForAttributeAccess(followLinks);
+        try {
+            try {
+                fsetxattr(fd, nameAsBytes(file,name), address, rem);
+                src.position(pos + rem);
+                return rem;
+            } catch (UnixException x) {
+                throw new FileSystemException(file.getPathForExecptionMessage(),
+                    null, "Error writing extended attribute '" + name + "': " +
+                    x.getMessage());
+            } finally {
+                close(fd);
+            }
+        } finally {
+            if (nb != null)
+                nb.release();
+        }
+    }
+
+    @Override
+    public void delete(String name) throws IOException {
+        if (System.getSecurityManager() != null)
+            checkAccess(file.getPathForPermissionCheck(), false, true);
+
+        int fd = file.openForAttributeAccess(followLinks);
+        try {
+            fremovexattr(fd, nameAsBytes(file,name));
+        } catch (UnixException x) {
+            throw new FileSystemException(file.getPathForExecptionMessage(),
+                null, "Unable to delete extended attribute '" + name + "': " + x.getMessage());
+        } finally {
+            close(fd);
+        }
+    }
+
+    /**
+     * Used by copyTo/moveTo to copy extended attributes from source to target.
+     *
+     * @param   ofd
+     *          file descriptor for source file
+     * @param   nfd
+     *          file descriptor for target file
+     */
+    static void copyExtendedAttributes(int ofd, int nfd) {
+        NativeBuffer buffer = null;
+        try {
+
+            // call flistxattr to get list of extended attributes.
+            int size = 1024;
+            buffer = NativeBuffers.getNativeBuffer(size);
+            for (;;) {
+                try {
+                    size = flistxattr(ofd, buffer.address(), size);
+                    break;
+                } catch (UnixException x) {
+                    // allocate larger buffer if required
+                    if (x.errno() == ERANGE && size < 32*1024) {
+                        buffer.release();
+                        size *= 2;
+                        buffer = null;
+                        buffer = NativeBuffers.getNativeBuffer(size);
+                        continue;
+                    }
+
+                    // unable to get list of attributes
+                    return;
+                }
+            }
+
+            // parse buffer as array of NULL-terminated C strings.
+            long address = buffer.address();
+            int start = 0;
+            int pos = 0;
+            while (pos < size) {
+                if (unsafe.getByte(address + pos) == 0) {
+                    // extract attribute name and copy attribute to target.
+                    // FIXME: We can avoid needless copying by using address+pos
+                    // as the address of the name.
+                    int len = pos - start;
+                    byte[] name = new byte[len];
+                    unsafe.copyMemory(null, address+start, name,
+                        Unsafe.ARRAY_BYTE_BASE_OFFSET, len);
+                    try {
+                        copyExtendedAttribute(ofd, name, nfd);
+                    } catch (UnixException ignore) {
+                        // ignore
+                    }
+                    start = pos + 1;
+                }
+                pos++;
+            }
+
+        } finally {
+            if (buffer != null)
+                buffer.release();
+        }
+    }
+
+    private static void copyExtendedAttribute(int ofd, byte[] name, int nfd)
+        throws UnixException
+    {
+        int size = fgetxattr(ofd, name, 0L, 0);
+        NativeBuffer buffer = NativeBuffers.getNativeBuffer(size);
+        try {
+            long address = buffer.address();
+            size = fgetxattr(ofd, name, address, size);
+            fsetxattr(nfd, name, address, size);
+        } finally {
+            buffer.release();
+        }
+    }
+}
diff --git a/jdk/src/solaris/classes/sun/nio/fs/LinuxWatchService.java b/jdk/src/solaris/classes/sun/nio/fs/LinuxWatchService.java
new file mode 100644
index 0000000..0d4a2ff
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/fs/LinuxWatchService.java
@@ -0,0 +1,466 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.*;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.*;
+import java.io.IOException;
+import sun.misc.Unsafe;
+
+import static sun.nio.fs.UnixNativeDispatcher.*;
+import static sun.nio.fs.UnixConstants.*;
+
+/**
+ * Linux implementation of WatchService based on inotify.
+ *
+ * In summary a background thread polls inotify plus a socket used for the wakeup
+ * mechanism. Requests to add or remove a watch, or close the watch service,
+ * cause the thread to wakeup and process the request. Events are processed
+ * by the thread which causes it to signal/queue the corresponding watch keys.
+ */
+
+class LinuxWatchService
+    extends AbstractWatchService
+{
+    private static final Unsafe unsafe = Unsafe.getUnsafe();
+
+    // background thread to read change events
+    private final Poller poller;
+
+    LinuxWatchService(UnixFileSystem fs) throws IOException {
+        // initialize inotify
+        int ifd = - 1;
+        try {
+            ifd = inotifyInit();
+        } catch (UnixException x) {
+            throw new IOException(x.errorString());
+        }
+
+        // configure inotify to be non-blocking
+        // create socketpair used in the close mechanism
+        int sp[] = new int[2];
+        try {
+            configureBlocking(ifd, false);
+            socketpair(sp);
+            configureBlocking(sp[0], false);
+        } catch (UnixException x) {
+            UnixNativeDispatcher.close(ifd);
+            throw new IOException(x.errorString());
+        }
+
+        this.poller = new Poller(fs, this, ifd, sp);
+        this.poller.start();
+    }
+
+    @Override
+    WatchKey register(Path dir,
+                      WatchEvent.Kind<?>[] events,
+                      WatchEvent.Modifier... modifiers)
+         throws IOException
+    {
+        // delegate to poller
+        return poller.register(dir, events, modifiers);
+    }
+
+    @Override
+    void implClose() throws IOException {
+        // delegate to poller
+        poller.close();
+    }
+
+    /**
+     * WatchKey implementation
+     */
+    private static class LinuxWatchKey extends AbstractWatchKey {
+        // inotify descriptor
+        private final int ifd;
+        // watch descriptor
+        private volatile int wd;
+
+        LinuxWatchKey(LinuxWatchService watcher, int ifd, int wd) {
+            super(watcher);
+            this.ifd = ifd;
+            this.wd = wd;
+        }
+
+        int descriptor() {
+            return wd;
+        }
+
+        void invalidate(boolean remove) {
+            if (remove) {
+                try {
+                    inotifyRmWatch(ifd, wd);
+                } catch (UnixException x) {
+                    // ignore
+                }
+            }
+            wd = -1;
+        }
+
+        @Override
+        public boolean isValid() {
+            return (wd != -1);
+        }
+
+        @Override
+        public void cancel() {
+            if (isValid()) {
+                // delegate to poller
+                ((LinuxWatchService)watcher()).poller.cancel(this);
+            }
+        }
+    }
+
+    /**
+     * Background thread to read from inotify
+     */
+    private static class Poller extends AbstractPoller {
+        /**
+         * struct inotify_event {
+         *     int          wd;
+         *     uint32_t     mask;
+         *     uint32_t     len;
+         *     char name    __flexarr;  // present if len > 0
+         * } act_t;
+         */
+        private static final int SIZEOF_INOTIFY_EVENT  = eventSize();
+        private static final int[] offsets             = eventOffsets();
+        private static final int OFFSETOF_WD           = offsets[0];
+        private static final int OFFSETOF_MASK         = offsets[1];
+        private static final int OFFSETOF_LEN          = offsets[3];
+        private static final int OFFSETOF_NAME         = offsets[4];
+
+        private static final int IN_MODIFY          = 0x00000002;
+        private static final int IN_ATTRIB          = 0x00000004;
+        private static final int IN_MOVED_FROM      = 0x00000040;
+        private static final int IN_MOVED_TO        = 0x00000080;
+        private static final int IN_CREATE          = 0x00000100;
+        private static final int IN_DELETE          = 0x00000200;
+
+        private static final int IN_UNMOUNT         = 0x00002000;
+        private static final int IN_Q_OVERFLOW      = 0x00004000;
+        private static final int IN_IGNORED         = 0x00008000;
+
+        // sizeof buffer for when polling inotify
+        private static final int BUFFER_SIZE = 8192;
+
+        private final UnixFileSystem fs;
+        private final LinuxWatchService watcher;
+
+        // inotify file descriptor
+        private final int ifd;
+        // socketpair used to shutdown polling thread
+        private final int socketpair[];
+        // maps watch descriptor to Key
+        private final Map<Integer,LinuxWatchKey> wdToKey;
+        // address of read buffer
+        private final long address;
+
+        Poller(UnixFileSystem fs, LinuxWatchService watcher, int ifd, int[] sp) {
+            this.fs = fs;
+            this.watcher = watcher;
+            this.ifd = ifd;
+            this.socketpair = sp;
+            this.wdToKey = new HashMap<Integer,LinuxWatchKey>();
+            this.address = unsafe.allocateMemory(BUFFER_SIZE);
+        }
+
+        @Override
+        void wakeup() throws IOException {
+            // write to socketpair to wakeup polling thread
+            try {
+                write(socketpair[1], address, 1);
+            } catch (UnixException x) {
+                throw new IOException(x.errorString());
+            }
+        }
+
+        @Override
+        Object implRegister(Path obj,
+                            Set<? extends WatchEvent.Kind<?>> events,
+                            WatchEvent.Modifier... modifiers)
+        {
+            UnixPath dir = (UnixPath)obj;
+
+            int mask = 0;
+            for (WatchEvent.Kind<?> event: events) {
+                if (event == StandardWatchEventKind.ENTRY_CREATE) {
+                    mask |= IN_CREATE | IN_MOVED_TO;
+                    continue;
+                }
+                if (event == StandardWatchEventKind.ENTRY_DELETE) {
+                    mask |= IN_DELETE | IN_MOVED_FROM;
+                    continue;
+                }
+                if (event == StandardWatchEventKind.ENTRY_MODIFY) {
+                    mask |= IN_MODIFY | IN_ATTRIB;
+                    continue;
+                }
+            }
+
+            // no modifiers supported at this time
+            if (modifiers.length > 0) {
+                for (WatchEvent.Modifier modifier: modifiers) {
+                    if (modifier == null)
+                        return new NullPointerException();
+                    if (modifier instanceof com.sun.nio.file.SensitivityWatchEventModifier)
+                        continue; // ignore
+                    return new UnsupportedOperationException("Modifier not supported");
+                }
+            }
+
+            // check file is directory
+            UnixFileAttributes attrs = null;
+            try {
+                attrs = UnixFileAttributes.get(dir, true);
+            } catch (UnixException x) {
+                return x.asIOException(dir);
+            }
+            if (!attrs.isDirectory()) {
+                return new NotDirectoryException(dir.getPathForExecptionMessage());
+            }
+
+            // register with inotify (replaces existing mask if already registered)
+            int wd = -1;
+            try {
+                NativeBuffer buffer =
+                    NativeBuffers.asNativeBuffer(dir.getByteArrayForSysCalls());
+                try {
+                    wd = inotifyAddWatch(ifd, buffer.address(), mask);
+                } finally {
+                    buffer.release();
+                }
+            } catch (UnixException x) {
+                if (x.errno() == ENOSPC) {
+                    return new IOException("User limit of inotify watches reached");
+                }
+                return x.asIOException(dir);
+            }
+
+            // ensure watch descriptor is in map
+            LinuxWatchKey key = wdToKey.get(wd);
+            if (key == null) {
+                key = new LinuxWatchKey(watcher, ifd, wd);
+                wdToKey.put(wd, key);
+            }
+            return key;
+        }
+
+        // cancel single key
+        @Override
+        void implCancelKey(WatchKey obj) {
+            LinuxWatchKey key = (LinuxWatchKey)obj;
+            if (key.isValid()) {
+                wdToKey.remove(key.descriptor());
+                key.invalidate(true);
+            }
+        }
+
+        // close watch service
+        @Override
+        void implCloseAll() {
+            // invalidate all keys
+            for (Map.Entry<Integer,LinuxWatchKey> entry: wdToKey.entrySet()) {
+                entry.getValue().invalidate(true);
+            }
+            wdToKey.clear();
+
+            // free resources
+            unsafe.freeMemory(address);
+            UnixNativeDispatcher.close(socketpair[0]);
+            UnixNativeDispatcher.close(socketpair[1]);
+            UnixNativeDispatcher.close(ifd);
+        }
+
+        /**
+         * Poller main loop
+         */
+        @Override
+        public void run() {
+            try {
+                for (;;) {
+                    int nReady, bytesRead;
+
+                    // wait for close or inotify event
+                    nReady = poll(ifd, socketpair[0]);
+
+                    // read from inotify
+                    try {
+                        bytesRead = read(ifd, address, BUFFER_SIZE);
+                    } catch (UnixException x) {
+                        if (x.errno() != EAGAIN)
+                            throw x;
+                        bytesRead = 0;
+                    }
+
+                    // process any pending requests
+                    if ((nReady > 1) || (nReady == 1 && bytesRead == 0)) {
+                        try {
+                            read(socketpair[0], address, BUFFER_SIZE);
+                            boolean shutdown = processRequests();
+                            if (shutdown)
+                                break;
+                        } catch (UnixException x) {
+                            if (x.errno() != UnixConstants.EAGAIN)
+                                throw x;
+                        }
+                    }
+
+                    // iterate over buffer to decode events
+                    int offset = 0;
+                    while (offset < bytesRead) {
+                        long event = address + offset;
+                        int wd = unsafe.getInt(event + OFFSETOF_WD);
+                        int mask = unsafe.getInt(event + OFFSETOF_MASK);
+                        int len = unsafe.getInt(event + OFFSETOF_LEN);
+
+                        // file name
+                        UnixPath name = null;
+                        if (len > 0) {
+                            int actual = len;
+
+                            // null-terminated and maybe additional null bytes to
+                            // align the next event
+                            while (actual > 0) {
+                                long last = event + OFFSETOF_NAME + actual - 1;
+                                if (unsafe.getByte(last) != 0)
+                                    break;
+                                actual--;
+                            }
+                            if (actual > 0) {
+                                byte[] buf = new byte[actual];
+                                unsafe.copyMemory(null, event + OFFSETOF_NAME,
+                                    buf, Unsafe.ARRAY_BYTE_BASE_OFFSET, actual);
+                                name = new UnixPath(fs, buf);
+                            }
+                        }
+
+                        // process event
+                        processEvent(wd, mask, name);
+
+                        offset += (SIZEOF_INOTIFY_EVENT + len);
+                    }
+                }
+            } catch (UnixException x) {
+                x.printStackTrace();
+            }
+        }
+
+
+        /**
+         * map inotify event to WatchEvent.Kind
+         */
+        private WatchEvent.Kind<?> maskToEventKind(int mask) {
+            if ((mask & IN_MODIFY) > 0)
+                return StandardWatchEventKind.ENTRY_MODIFY;
+            if ((mask & IN_ATTRIB) > 0)
+                return StandardWatchEventKind.ENTRY_MODIFY;
+            if ((mask & IN_CREATE) > 0)
+                return StandardWatchEventKind.ENTRY_CREATE;
+            if ((mask & IN_MOVED_TO) > 0)
+                return StandardWatchEventKind.ENTRY_CREATE;
+            if ((mask & IN_DELETE) > 0)
+                return StandardWatchEventKind.ENTRY_DELETE;
+            if ((mask & IN_MOVED_FROM) > 0)
+                return StandardWatchEventKind.ENTRY_DELETE;
+            return null;
+        }
+
+        /**
+         * Process event from inotify
+         */
+        private void processEvent(int wd, int mask, final UnixPath name) {
+            // overflow - signal all keys
+            if ((mask & IN_Q_OVERFLOW) > 0) {
+                for (Map.Entry<Integer,LinuxWatchKey> entry: wdToKey.entrySet()) {
+                    entry.getValue()
+                        .signalEvent(StandardWatchEventKind.OVERFLOW, null);
+                }
+                return;
+            }
+
+            // lookup wd to get key
+            LinuxWatchKey key = wdToKey.get(wd);
+            if (key == null)
+                return; // should not happen
+
+            // file deleted
+            if ((mask & IN_IGNORED) > 0) {
+                wdToKey.remove(wd);
+                key.invalidate(false);
+                key.signal();
+                return;
+            }
+
+            // event for directory itself
+            if (name == null)
+                return;
+
+            // map to event and queue to key
+            WatchEvent.Kind<?> kind = maskToEventKind(mask);
+            if (kind != null) {
+                key.signalEvent(kind, name);
+            }
+        }
+    }
+
+    // -- native methods --
+
+    private static native void init();
+
+    // sizeof inotify_event
+    private static native int eventSize();
+
+    // offsets of inotify_event
+    private static native int[] eventOffsets();
+
+    private static native int inotifyInit() throws UnixException;
+
+    private static native int inotifyAddWatch(int fd, long pathAddress, int mask)
+        throws UnixException;
+
+    private static native void inotifyRmWatch(int fd, int wd)
+        throws UnixException;
+
+    private static native void configureBlocking(int fd, boolean blocking)
+        throws UnixException;
+
+    private static native void socketpair(int[] sv) throws UnixException;
+
+    private static native int poll(int fd1, int fd2) throws UnixException;
+
+    static {
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+            public Void run() {
+                System.loadLibrary("nio");
+                return null;
+        }});
+        init();
+    }
+}
diff --git a/jdk/src/solaris/classes/sun/nio/fs/SolarisAclFileAttributeView.java b/jdk/src/solaris/classes/sun/nio/fs/SolarisAclFileAttributeView.java
new file mode 100644
index 0000000..e96361e
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/fs/SolarisAclFileAttributeView.java
@@ -0,0 +1,408 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.util.*;
+import java.io.IOException;
+import sun.misc.Unsafe;
+
+import static sun.nio.fs.UnixConstants.*;
+import static sun.nio.fs.SolarisConstants.*;
+import static sun.nio.fs.SolarisNativeDispatcher.*;
+
+
+/**
+ * Solaris implementation of AclFileAttributeView with native support for
+ * NFSv4 ACLs on ZFS.
+ */
+
+class SolarisAclFileAttributeView
+    extends AbstractAclFileAttributeView
+{
+    private static final Unsafe unsafe = Unsafe.getUnsafe();
+
+    // Maximum number of entries allowed in an ACL
+    private static final int MAX_ACL_ENTRIES = 1024;
+
+    /**
+     * typedef struct ace {
+     *     uid_t        a_who;
+     *     uitn32_t     a_access_mark;
+     *     uint16_t     a_flags;
+     *     uint16_t     a_type;
+     * } act_t;
+     */
+    private static final short SIZEOF_ACE_T     = 12;
+    private static final short OFFSETOF_UID     = 0;
+    private static final short OFFSETOF_MASK    = 4;
+    private static final short OFFSETOF_FLAGS   = 8;
+    private static final short OFFSETOF_TYPE    = 10;
+
+    private final UnixPath file;
+    private final boolean followLinks;
+
+    SolarisAclFileAttributeView(UnixPath file, boolean followLinks) {
+        this.file = file;
+        this.followLinks = followLinks;
+    }
+
+    /**
+     * Permission checks to access file
+     */
+    private void checkAccess(UnixPath file,
+                             boolean checkRead,
+                             boolean checkWrite)
+    {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            if (checkRead)
+                file.checkRead();
+            if (checkWrite)
+                file.checkWrite();
+            sm.checkPermission(new RuntimePermission("accessUserInformation"));
+        }
+    }
+
+    /**
+     * Encode the ACL to the given buffer
+     */
+    private static void encode(List<AclEntry> acl, long address) {
+        long offset = address;
+        for (AclEntry ace: acl) {
+            int flags = 0;
+
+            // map UserPrincipal to uid and flags
+            UserPrincipal who = ace.principal();
+            if (!(who instanceof UnixUserPrincipals))
+                throw new ProviderMismatchException();
+            UnixUserPrincipals.User user = (UnixUserPrincipals.User)who;
+            int uid;
+            if (user.isSpecial()) {
+                uid = -1;
+                if (who.getName().equals(UnixUserPrincipals.SPECIAL_OWNER.getName()))
+                    flags |= ACE_OWNER;
+                else if (who.getName().equals(UnixUserPrincipals.SPECIAL_GROUP.getName()))
+                    flags |= ACE_GROUP;
+                else if (who.getName().equals(UnixUserPrincipals.SPECIAL_EVERYONE.getName()))
+                    flags |= ACE_EVERYONE;
+                else
+                    throw new AssertionError("Unable to map special identifier");
+            } else {
+                if (user instanceof UnixUserPrincipals.Group) {
+                    uid = user.gid();
+                    flags |= ACE_IDENTIFIER_GROUP;
+                } else {
+                    uid = user.uid();
+                }
+            }
+
+            // map ACE type
+            int type;
+            switch (ace.type()) {
+                case ALLOW:
+                    type = ACE_ACCESS_ALLOWED_ACE_TYPE;
+                    break;
+                case DENY:
+                    type = ACE_ACCESS_DENIED_ACE_TYPE;
+                    break;
+                case AUDIT:
+                    type = ACE_SYSTEM_AUDIT_ACE_TYPE;
+                    break;
+                case ALARM:
+                    type = ACE_SYSTEM_ALARM_ACE_TYPE;
+                    break;
+                default:
+                    throw new AssertionError("Unable to map ACE type");
+            }
+
+            // map permissions
+            Set<AclEntryPermission> aceMask = ace.permissions();
+            int mask = 0;
+            if (aceMask.contains(AclEntryPermission.READ_DATA))
+                mask |= ACE_READ_DATA;
+            if (aceMask.contains(AclEntryPermission.WRITE_DATA))
+                mask |= ACE_WRITE_DATA;
+            if (aceMask.contains(AclEntryPermission.APPEND_DATA))
+                mask |= ACE_APPEND_DATA;
+            if (aceMask.contains(AclEntryPermission.READ_NAMED_ATTRS))
+                mask |= ACE_READ_NAMED_ATTRS;
+            if (aceMask.contains(AclEntryPermission.WRITE_NAMED_ATTRS))
+                mask |= ACE_WRITE_NAMED_ATTRS;
+            if (aceMask.contains(AclEntryPermission.EXECUTE))
+                mask |= ACE_EXECUTE;
+            if (aceMask.contains(AclEntryPermission.DELETE_CHILD))
+                mask |= ACE_DELETE_CHILD;
+            if (aceMask.contains(AclEntryPermission.READ_ATTRIBUTES))
+                mask |= ACE_READ_ATTRIBUTES;
+            if (aceMask.contains(AclEntryPermission.WRITE_ATTRIBUTES))
+                mask |= ACE_WRITE_ATTRIBUTES;
+            if (aceMask.contains(AclEntryPermission.DELETE))
+                mask |= ACE_DELETE;
+            if (aceMask.contains(AclEntryPermission.READ_ACL))
+                mask |= ACE_READ_ACL;
+            if (aceMask.contains(AclEntryPermission.WRITE_ACL))
+                mask |= ACE_WRITE_ACL;
+            if (aceMask.contains(AclEntryPermission.WRITE_OWNER))
+                mask |= ACE_WRITE_OWNER;
+            if (aceMask.contains(AclEntryPermission.SYNCHRONIZE))
+                mask |= ACE_SYNCHRONIZE;
+
+            // FIXME - it would be desirable to know here if the file is a
+            // directory or not. Solaris returns EINVAL if an ACE has a directory
+            // -only flag and the file is not a directory.
+            Set<AclEntryFlag> aceFlags = ace.flags();
+            if (aceFlags.contains(AclEntryFlag.FILE_INHERIT))
+                flags |= ACE_FILE_INHERIT_ACE;
+            if (aceFlags.contains(AclEntryFlag.DIRECTORY_INHERIT))
+                flags |= ACE_DIRECTORY_INHERIT_ACE;
+            if (aceFlags.contains(AclEntryFlag.NO_PROPAGATE_INHERIT))
+                flags |= ACE_NO_PROPAGATE_INHERIT_ACE;
+            if (aceFlags.contains(AclEntryFlag.INHERIT_ONLY))
+                flags |= ACE_INHERIT_ONLY_ACE;
+
+            unsafe.putInt(offset + OFFSETOF_UID, uid);
+            unsafe.putInt(offset + OFFSETOF_MASK, mask);
+            unsafe.putShort(offset + OFFSETOF_FLAGS, (short)flags);
+            unsafe.putShort(offset + OFFSETOF_TYPE, (short)type);
+
+            offset += SIZEOF_ACE_T;
+        }
+    }
+
+    /**
+     * Decode the buffer, returning an ACL
+     */
+    private static List<AclEntry> decode(long address, int n) {
+        ArrayList<AclEntry> acl = new ArrayList<AclEntry>(n);
+        for (int i=0; i<n; i++) {
+            long offset = address + i*SIZEOF_ACE_T;
+
+            int uid = unsafe.getInt(offset + OFFSETOF_UID);
+            int mask = unsafe.getInt(offset + OFFSETOF_MASK);
+            int flags = (int)unsafe.getShort(offset + OFFSETOF_FLAGS);
+            int type = (int)unsafe.getShort(offset + OFFSETOF_TYPE);
+
+            // map uid and flags to UserPrincipal
+            UnixUserPrincipals.User who = null;
+            if (uid == -1) {
+                if ((flags & ACE_OWNER) > 0)
+                    who = UnixUserPrincipals.SPECIAL_OWNER;
+                if ((flags & ACE_GROUP) > 0)
+                    who = UnixUserPrincipals.SPECIAL_GROUP;
+                if ((flags & ACE_EVERYONE) > 0)
+                    who = UnixUserPrincipals.SPECIAL_EVERYONE;
+                if (who == null)
+                    throw new AssertionError("ACE who not handled");
+            } else {
+                // can be gid
+                if ((flags & ACE_IDENTIFIER_GROUP) > 0)
+                    who = UnixUserPrincipals.fromGid(uid);
+                else
+                    who = UnixUserPrincipals.fromUid(uid);
+            }
+
+            AclEntryType aceType = null;
+            switch (type) {
+                case ACE_ACCESS_ALLOWED_ACE_TYPE:
+                    aceType = AclEntryType.ALLOW;
+                    break;
+                case ACE_ACCESS_DENIED_ACE_TYPE:
+                    aceType = AclEntryType.DENY;
+                    break;
+                case ACE_SYSTEM_AUDIT_ACE_TYPE:
+                    aceType = AclEntryType.AUDIT;
+                    break;
+                case ACE_SYSTEM_ALARM_ACE_TYPE:
+                    aceType = AclEntryType.ALARM;
+                    break;
+                default:
+                    assert false;
+            }
+
+            HashSet<AclEntryPermission> aceMask = new HashSet<AclEntryPermission>();
+            if ((mask & ACE_READ_DATA) > 0)
+                aceMask.add(AclEntryPermission.READ_DATA);
+            if ((mask & ACE_WRITE_DATA) > 0)
+                aceMask.add(AclEntryPermission.WRITE_DATA);
+            if ((mask & ACE_APPEND_DATA ) > 0)
+                aceMask.add(AclEntryPermission.APPEND_DATA);
+            if ((mask & ACE_READ_NAMED_ATTRS) > 0)
+                aceMask.add(AclEntryPermission.READ_NAMED_ATTRS);
+            if ((mask & ACE_WRITE_NAMED_ATTRS) > 0)
+                aceMask.add(AclEntryPermission.WRITE_NAMED_ATTRS);
+            if ((mask & ACE_EXECUTE) > 0)
+                aceMask.add(AclEntryPermission.EXECUTE);
+            if ((mask & ACE_DELETE_CHILD ) > 0)
+                aceMask.add(AclEntryPermission.DELETE_CHILD);
+            if ((mask & ACE_READ_ATTRIBUTES) > 0)
+                aceMask.add(AclEntryPermission.READ_ATTRIBUTES);
+            if ((mask & ACE_WRITE_ATTRIBUTES) > 0)
+                aceMask.add(AclEntryPermission.WRITE_ATTRIBUTES);
+            if ((mask & ACE_DELETE) > 0)
+                aceMask.add(AclEntryPermission.DELETE);
+            if ((mask & ACE_READ_ACL) > 0)
+                aceMask.add(AclEntryPermission.READ_ACL);
+            if ((mask & ACE_WRITE_ACL) > 0)
+                aceMask.add(AclEntryPermission.WRITE_ACL);
+            if ((mask & ACE_WRITE_OWNER) > 0)
+                aceMask.add(AclEntryPermission.WRITE_OWNER);
+            if ((mask & ACE_SYNCHRONIZE) > 0)
+                aceMask.add(AclEntryPermission.SYNCHRONIZE);
+
+            HashSet<AclEntryFlag> aceFlags = new HashSet<AclEntryFlag>();
+            if ((flags & ACE_FILE_INHERIT_ACE) > 0)
+                aceFlags.add(AclEntryFlag.FILE_INHERIT);
+            if ((flags & ACE_DIRECTORY_INHERIT_ACE) > 0)
+                aceFlags.add(AclEntryFlag.DIRECTORY_INHERIT);
+            if ((flags & ACE_NO_PROPAGATE_INHERIT_ACE) > 0)
+                aceFlags.add(AclEntryFlag.NO_PROPAGATE_INHERIT);
+            if ((flags & ACE_INHERIT_ONLY_ACE ) > 0)
+                aceFlags.add(AclEntryFlag.INHERIT_ONLY);
+
+            // build the ACL entry and add it to the list
+            AclEntry ace = AclEntry.newBuilder()
+                .setType(aceType)
+                .setPrincipal(who)
+                .setPermissions(aceMask).setFlags(aceFlags).build();
+            acl.add(ace);
+        }
+
+        return acl;
+    }
+
+    // Retrns true if NFSv4 ACLs not enabled on file system
+    private static boolean isAclsEnabled(int fd) {
+        try {
+            long enabled = fpathconf(fd, _PC_ACL_ENABLED);
+            if (enabled == _ACL_ACE_ENABLED)
+                return true;
+        } catch (UnixException x) {
+        }
+        return false;
+    }
+
+    @Override
+    public List<AclEntry> getAcl()
+        throws IOException
+    {
+        // permission check
+        checkAccess(file, true, false);
+
+        // open file (will fail if file is a link and not following links)
+        int fd = file.openForAttributeAccess(followLinks);
+        try {
+            long address = unsafe.allocateMemory(SIZEOF_ACE_T * MAX_ACL_ENTRIES);
+            try {
+                // read ACL and decode it
+                int n = facl(fd, ACE_GETACL, MAX_ACL_ENTRIES, address);
+                assert n >= 0;
+                return decode(address, n);
+            } catch (UnixException x) {
+                if ((x.errno() == ENOSYS) || !isAclsEnabled(fd)) {
+                    throw new FileSystemException(file.getPathForExecptionMessage(),
+                        null, x.getMessage() + " (file system does not support NFSv4 ACLs)");
+                }
+                x.rethrowAsIOException(file);
+                return null;    // keep compiler happy
+            } finally {
+                unsafe.freeMemory(address);
+            }
+        } finally {
+            close(fd);
+        }
+    }
+
+    @Override
+    public void setAcl(List<AclEntry> acl) throws IOException {
+        // permission check
+        checkAccess(file, false, true);
+
+        // open file (will fail if file is a link and not following links)
+        int fd = file.openForAttributeAccess(followLinks);
+        try {
+            // SECURITY: need to copy list as can change during processing
+            acl = new ArrayList<AclEntry>(acl);
+            int n = acl.size();
+
+            long address = unsafe.allocateMemory(SIZEOF_ACE_T * n);
+            try {
+                encode(acl, address);
+                facl(fd, ACE_SETACL, n, address);
+            } catch (UnixException x) {
+                if ((x.errno() == ENOSYS) || !isAclsEnabled(fd)) {
+                    throw new FileSystemException(file.getPathForExecptionMessage(),
+                        null, x.getMessage() + " (file system does not support NFSv4 ACLs)");
+                }
+                if (x.errno() == EINVAL && (n < 3))
+                    throw new IOException("ACL must contain at least 3 entries");
+                x.rethrowAsIOException(file);
+            } finally {
+                unsafe.freeMemory(address);
+            }
+        } finally {
+            close(fd);
+        }
+    }
+
+    @Override
+    public UserPrincipal getOwner()
+        throws IOException
+    {
+        checkAccess(file, true, false);
+
+        try {
+            UnixFileAttributes attrs =
+                UnixFileAttributes.get(file, followLinks);
+            return UnixUserPrincipals.fromUid(attrs.uid());
+        } catch (UnixException x) {
+            x.rethrowAsIOException(file);
+            return null; // keep compile happy
+        }
+    }
+
+    @Override
+    public void setOwner(UserPrincipal owner) throws IOException {
+        checkAccess(file, true, false);
+
+        if (!(owner instanceof UnixUserPrincipals.User))
+            throw new ProviderMismatchException();
+        if (owner instanceof UnixUserPrincipals.Group)
+            throw new IOException("'owner' parameter is a group");
+        int uid = ((UnixUserPrincipals.User)owner).uid();
+
+        try {
+            if (followLinks) {
+                lchown(file, uid, -1);
+            } else {
+                chown(file, uid, -1);
+            }
+        } catch (UnixException x) {
+            x.rethrowAsIOException(file);
+        }
+    }
+}
diff --git a/jdk/src/solaris/classes/sun/nio/fs/SolarisFileStore.java b/jdk/src/solaris/classes/sun/nio/fs/SolarisFileStore.java
new file mode 100644
index 0000000..bdf71a5
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/fs/SolarisFileStore.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.io.IOException;
+
+import static sun.nio.fs.UnixNativeDispatcher.*;
+import static sun.nio.fs.SolarisConstants.*;
+
+/**
+ * Solaris implementation of FileStore
+ */
+
+class SolarisFileStore
+    extends UnixFileStore
+{
+    private final boolean xattrEnabled;
+
+    SolarisFileStore(UnixPath file) throws IOException {
+        super(file);
+        this.xattrEnabled = xattrEnabled();
+    }
+
+    SolarisFileStore(UnixFileSystem fs, UnixMountEntry entry) throws IOException {
+        super(fs, entry);
+        this.xattrEnabled = xattrEnabled();
+    }
+
+    // returns true if extended attributes enabled
+    private boolean xattrEnabled() {
+        long res = 0L;
+        try {
+            res = pathconf(file(), _PC_XATTR_ENABLED);
+        } catch (UnixException x) {
+            // ignore
+        }
+        return (res != 0L);
+    }
+
+    @Override
+    UnixMountEntry findMountEntry() throws IOException {
+        // On Solaris iterate over the entries in the mount table to find device
+        for (UnixMountEntry entry: file().getFileSystem().getMountEntries()) {
+            if (entry.dev() == dev()) {
+                return entry;
+            }
+        }
+        throw new IOException("Device not found in mnttab");
+    }
+
+    @Override
+    public boolean supportsFileAttributeView(String name) {
+        if (name.equals("acl")) {
+            // lookup fstypes.properties
+            FeatureStatus status = checkIfFeaturePresent("nfsv4acl");
+            if (status == FeatureStatus.PRESENT)
+                return true;
+            if (status == FeatureStatus.NOT_PRESENT)
+                return false;
+            // AclFileAttributeView available on ZFS
+            return (type().equals("zfs"));
+        }
+        if (name.equals("xattr")) {
+            // lookup fstypes.properties
+            FeatureStatus status = checkIfFeaturePresent("xattr");
+            if (status == FeatureStatus.PRESENT)
+                return true;
+            if (status == FeatureStatus.NOT_PRESENT)
+                return false;
+            return xattrEnabled;
+        }
+
+        return super.supportsFileAttributeView(name);
+    }
+
+    @Override
+    boolean isLoopback() {
+        return type().equals("lofs");
+    }
+}
diff --git a/jdk/src/solaris/classes/sun/nio/fs/SolarisFileSystem.java b/jdk/src/solaris/classes/sun/nio/fs/SolarisFileSystem.java
new file mode 100644
index 0000000..fa7f34f
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/fs/SolarisFileSystem.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.io.IOException;
+import java.util.*;
+import java.security.AccessController;
+import sun.security.action.GetPropertyAction;
+import static sun.nio.fs.UnixNativeDispatcher.*;
+
+/**
+ * Solaris implementation of FileSystem
+ */
+
+class SolarisFileSystem extends UnixFileSystem {
+    private final boolean hasSolaris11Features;
+
+    SolarisFileSystem(UnixFileSystemProvider provider, String dir) {
+        super(provider, dir);
+
+        // check os.version
+        String osversion = AccessController
+            .doPrivileged(new GetPropertyAction("os.version"));
+        String[] vers = osversion.split("\\.", 0);
+        assert vers.length >= 2;
+        int majorVersion = Integer.parseInt(vers[0]);
+        int minorVersion = Integer.parseInt(vers[1]);
+        this.hasSolaris11Features =
+            (majorVersion > 5 || (majorVersion == 5 && minorVersion >= 11));
+    }
+
+    @Override
+    boolean isSolaris() {
+        return true;
+    }
+
+    @Override
+    public WatchService newWatchService()
+        throws IOException
+    {
+        // FEN available since Solaris 11
+        if (hasSolaris11Features) {
+            return new SolarisWatchService(this);
+        } else {
+            return new PollingWatchService();
+        }
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public <V extends FileAttributeView> V newFileAttributeView(Class<V> view,
+                                                                UnixPath file, LinkOption... options)
+    {
+        if (view == AclFileAttributeView.class)
+            return (V) new SolarisAclFileAttributeView(file, followLinks(options));
+        if (view == UserDefinedFileAttributeView.class) {
+            return(V) new SolarisUserDefinedFileAttributeView(file, followLinks(options));
+        }
+        return super.newFileAttributeView(view, file, options);
+    }
+
+    @Override
+    protected FileAttributeView newFileAttributeView(String name,
+                                                     UnixPath file,
+                                                     LinkOption... options)
+    {
+        if (name.equals("acl"))
+            return new SolarisAclFileAttributeView(file, followLinks(options));
+        if (name.equals("xattr"))
+            return new SolarisUserDefinedFileAttributeView(file, followLinks(options));
+        return super.newFileAttributeView(name, file, options);
+    }
+
+    // lazy initialization of the list of supported attribute views
+    private static class SupportedFileFileAttributeViewsHolder {
+        static final Set<String> supportedFileAttributeViews =
+            supportedFileAttributeViews();
+        private static Set<String> supportedFileAttributeViews() {
+            Set<String> result = new HashSet<String>();
+            result.addAll(UnixFileSystem.standardFileAttributeViews());
+            // additional Solaris-specific views
+            result.add("acl");
+            result.add("xattr");
+            return Collections.unmodifiableSet(result);
+        }
+    }
+
+    @Override
+    public Set<String> supportedFileAttributeViews() {
+        return SupportedFileFileAttributeViewsHolder.supportedFileAttributeViews;
+    }
+
+    @Override
+    void copyNonPosixAttributes(int ofd, int nfd) {
+        SolarisUserDefinedFileAttributeView.copyExtendedAttributes(ofd, nfd);
+        // TDB: copy ACL from source to target
+    }
+
+    @Override
+    boolean supportsSecureDirectoryStreams() {
+        return true;
+    }
+
+    /**
+     * Returns object to iterate over entries in /etc/mnttab
+     */
+    @Override
+    Iterable<UnixMountEntry> getMountEntries() {
+        ArrayList<UnixMountEntry> entries = new ArrayList<UnixMountEntry>();
+        try {
+            UnixPath mnttab = new UnixPath(this, "/etc/mnttab");
+            long fp = fopen(mnttab, "r");
+            try {
+                for (;;) {
+                    UnixMountEntry entry = new UnixMountEntry();
+                    int res = getextmntent(fp, entry);
+                    if (res < 0)
+                        break;
+                    entries.add(entry);
+                }
+            } finally {
+                fclose(fp);
+            }
+        } catch (UnixException x) {
+            // nothing we can do
+        }
+        return entries;
+    }
+
+    @Override
+    FileStore getFileStore(UnixPath path) throws IOException {
+        return new SolarisFileStore(path);
+    }
+
+    @Override
+    FileStore getFileStore(UnixMountEntry entry) throws IOException {
+        return new SolarisFileStore(this, entry);
+    }
+}
diff --git a/jdk/src/solaris/classes/sun/nio/fs/SolarisFileSystemProvider.java b/jdk/src/solaris/classes/sun/nio/fs/SolarisFileSystemProvider.java
new file mode 100644
index 0000000..9d3c084
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/fs/SolarisFileSystemProvider.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+/**
+ * Solaris implementation of FileSystemProvider
+ */
+
+public class SolarisFileSystemProvider extends UnixFileSystemProvider {
+    public SolarisFileSystemProvider() {
+        super();
+    }
+
+    @Override
+    SolarisFileSystem newFileSystem(String dir) {
+        return new SolarisFileSystem(this, dir);
+    }
+}
diff --git a/jdk/src/solaris/classes/sun/nio/fs/SolarisNativeDispatcher.java b/jdk/src/solaris/classes/sun/nio/fs/SolarisNativeDispatcher.java
new file mode 100644
index 0000000..36f2326
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/fs/SolarisNativeDispatcher.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * Solaris specific system calls.
+ */
+
+class SolarisNativeDispatcher extends UnixNativeDispatcher {
+    private SolarisNativeDispatcher() { }
+
+    /**
+     * int facl(int filedes, int cmd, int nentries, void aclbufp)
+     */
+    static native int facl(int fd, int cmd, int nentries, long aclbufp)
+        throws UnixException;
+
+
+    // initialize
+    private static native void init();
+
+    static {
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+            public Void run() {
+                System.loadLibrary("nio");
+                return null;
+        }});
+        init();
+    }
+}
diff --git a/jdk/src/solaris/classes/sun/nio/fs/SolarisUserDefinedFileAttributeView.java b/jdk/src/solaris/classes/sun/nio/fs/SolarisUserDefinedFileAttributeView.java
new file mode 100644
index 0000000..040628f
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/fs/SolarisUserDefinedFileAttributeView.java
@@ -0,0 +1,293 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.*;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.io.IOException;
+import java.util.*;
+
+import static sun.nio.fs.UnixNativeDispatcher.*;
+import static sun.nio.fs.UnixConstants.*;
+import static sun.nio.fs.SolarisConstants.*;
+
+/**
+ * Solaris emulation of NamedAttributeView using extended attributes.
+ */
+
+class SolarisUserDefinedFileAttributeView
+    extends AbstractUserDefinedFileAttributeView
+{
+    private byte[] nameAsBytes(UnixPath file, String name) throws IOException {
+        byte[] bytes = name.getBytes();
+        //  "", "." and ".." not allowed
+        if (bytes.length == 0 || bytes[0] == '.') {
+            if (bytes.length <= 1 ||
+                (bytes.length == 2 && bytes[1] == '.'))
+            {
+                throw new FileSystemException(file.getPathForExecptionMessage(),
+                    null, "'" + name + "' is not a valid name");
+            }
+        }
+        return bytes;
+    }
+
+    private final UnixPath file;
+    private final boolean followLinks;
+
+    SolarisUserDefinedFileAttributeView(UnixPath file, boolean followLinks) {
+        this.file = file;
+        this.followLinks = followLinks;
+    }
+
+    @Override
+    public List<String> list() throws IOException  {
+        if (System.getSecurityManager() != null)
+            checkAccess(file.getPathForPermissionCheck(), true, false);
+
+        int fd = file.openForAttributeAccess(followLinks);
+        try {
+            try {
+                // open extended attribute directory
+                int dfd = openat(fd, ".".getBytes(), (O_RDONLY|O_XATTR), 0);
+                long dp;
+                try {
+                    dp = fdopendir(dfd);
+                } catch (UnixException x) {
+                    close(dfd);
+                    throw x;
+                }
+
+                // read list of extended attributes
+                final List<String> list = new ArrayList<String>();
+                try {
+                    byte[] name;
+                    while ((name = readdir(dp)) != null) {
+                        String s = new String(name);
+                        if (!s.equals(".") && !s.equals(".."))
+                            list.add(s);
+                    }
+                } finally {
+                    closedir(dp);
+                }
+                return Collections.unmodifiableList(list);
+            } catch (UnixException x) {
+                throw new FileSystemException(file.getPathForExecptionMessage(),
+                    null, "Unable to get list of extended attributes: " +
+                    x.getMessage());
+            }
+        } finally {
+            close(fd);
+        }
+    }
+
+    @Override
+    public int size(String name) throws IOException  {
+        if (System.getSecurityManager() != null)
+            checkAccess(file.getPathForPermissionCheck(), true, false);
+
+        int fd = file.openForAttributeAccess(followLinks);
+        try {
+            try {
+                // open attribute file
+                int afd = openat(fd, nameAsBytes(file,name), (O_RDONLY|O_XATTR), 0);
+                try {
+                    // read attribute's attributes
+                    UnixFileAttributes attrs = UnixFileAttributes.get(afd);
+                    long size = attrs.size();
+                    if (size > Integer.MAX_VALUE)
+                        throw new ArithmeticException("Extended attribute value too large");
+                    return (int)size;
+                } finally {
+                    close(afd);
+                }
+            } catch (UnixException x) {
+                throw new FileSystemException(file.getPathForExecptionMessage(),
+                    null, "Unable to get size of extended attribute '" + name +
+                    "': " + x.getMessage());
+            }
+        } finally {
+            close(fd);
+        }
+    }
+
+    @Override
+    public int read(String name, ByteBuffer dst) throws IOException {
+        if (System.getSecurityManager() != null)
+            checkAccess(file.getPathForPermissionCheck(), true, false);
+
+        int fd = file.openForAttributeAccess(followLinks);
+        try {
+            try {
+                // open attribute file
+                int afd = openat(fd, nameAsBytes(file,name), (O_RDONLY|O_XATTR), 0);
+
+                // wrap with channel
+                FileChannel fc = UnixChannelFactory.newFileChannel(afd, true, false);
+
+                // read to EOF (nothing we can do if I/O error occurs)
+                try {
+                    if (fc.size() > dst.remaining())
+                        throw new IOException("Extended attribute file too large");
+                    int total = 0;
+                    while (dst.hasRemaining()) {
+                        int n = fc.read(dst);
+                        if (n < 0)
+                            break;
+                        total += n;
+                    }
+                    return total;
+                } finally {
+                    fc.close();
+                }
+            } catch (UnixException x) {
+                throw new FileSystemException(file.getPathForExecptionMessage(),
+                    null, "Unable to read extended attribute '" + name +
+                    "': " + x.getMessage());
+            }
+        } finally {
+            close(fd);
+        }
+    }
+
+    @Override
+    public int write(String name, ByteBuffer src) throws IOException {
+        if (System.getSecurityManager() != null)
+            checkAccess(file.getPathForPermissionCheck(), false, true);
+
+        int fd = file.openForAttributeAccess(followLinks);
+        try {
+            try {
+                // open/create attribute file
+                int afd = openat(fd, nameAsBytes(file,name),
+                                 (O_CREAT|O_WRONLY|O_TRUNC|O_XATTR),
+                                 UnixFileModeAttribute.ALL_PERMISSIONS);
+
+                // wrap with channel
+                FileChannel fc = UnixChannelFactory.newFileChannel(afd, false, true);
+
+                // write value (nothing we can do if I/O error occurs)
+                try {
+                    int rem = src.remaining();
+                    while (src.hasRemaining()) {
+                        fc.write(src);
+                    }
+                    return rem;
+                } finally {
+                    fc.close();
+                }
+            } catch (UnixException x) {
+                throw new FileSystemException(file.getPathForExecptionMessage(),
+                    null, "Unable to write extended attribute '" + name +
+                    "': " + x.getMessage());
+            }
+        } finally {
+            close(fd);
+        }
+    }
+
+    @Override
+    public void delete(String name) throws IOException {
+        if (System.getSecurityManager() != null)
+            checkAccess(file.getPathForPermissionCheck(), false, true);
+
+        int fd = file.openForAttributeAccess(followLinks);
+        try {
+            int dfd = openat(fd, ".".getBytes(), (O_RDONLY|O_XATTR), 0);
+            try {
+                unlinkat(dfd, nameAsBytes(file,name), 0);
+            } finally {
+                close(dfd);
+            }
+        } catch (UnixException x) {
+            throw new FileSystemException(file.getPathForExecptionMessage(),
+                null, "Unable to delete extended attribute '" + name +
+                "': " + x.getMessage());
+        } finally {
+            close(fd);
+        }
+    }
+
+    /**
+     * Used by copyTo/moveTo to copy extended attributes from source to target.
+     *
+     * @param   ofd
+     *          file descriptor for source file
+     * @param   nfd
+     *          file descriptor for target file
+     */
+    static void copyExtendedAttributes(int ofd, int nfd) {
+        try {
+            // open extended attribute directory
+            int dfd = openat(ofd, ".".getBytes(), (O_RDONLY|O_XATTR), 0);
+            long dp = 0L;
+            try {
+                dp = fdopendir(dfd);
+            } catch (UnixException x) {
+                close(dfd);
+                throw x;
+            }
+
+            // copy each extended attribute
+            try {
+                byte[] name;
+                while ((name = readdir(dp)) != null) {
+                    // ignore "." and ".."
+                    if (name[0] == '.') {
+                        if (name.length == 1)
+                            continue;
+                        if (name.length == 2 && name[1] == '.')
+                            continue;
+                    }
+                    copyExtendedAttribute(ofd, name, nfd);
+                }
+            } finally {
+                closedir(dp);
+            }
+        } catch (UnixException ignore) {
+        }
+    }
+
+    private static void copyExtendedAttribute(int ofd, byte[] name, int nfd)
+        throws UnixException
+    {
+        // open source attribute file
+        int src = openat(ofd, name, (O_RDONLY|O_XATTR), 0);
+        try {
+            // create target attribute file
+            int dst = openat(nfd, name, (O_CREAT|O_WRONLY|O_TRUNC|O_XATTR),
+                UnixFileModeAttribute.ALL_PERMISSIONS);
+            try {
+                UnixCopyFile.transfer(dst, src, 0L);
+            } finally {
+                close(dst);
+            }
+        } finally {
+            close(src);
+        }
+    }
+}
diff --git a/jdk/src/solaris/classes/sun/nio/fs/SolarisWatchService.java b/jdk/src/solaris/classes/sun/nio/fs/SolarisWatchService.java
new file mode 100644
index 0000000..6a11ebd
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/fs/SolarisWatchService.java
@@ -0,0 +1,770 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.*;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.*;
+import java.io.IOException;
+import sun.misc.Unsafe;
+
+import static sun.nio.fs.UnixConstants.*;
+
+/**
+ * Solaris implementation of WatchService based on file events notification
+ * facility.
+ */
+
+class SolarisWatchService
+    extends AbstractWatchService
+{
+    private static final Unsafe unsafe = Unsafe.getUnsafe();
+    private static int addressSize = unsafe.addressSize();
+
+    private static int dependsArch(int value32, int value64) {
+        return (addressSize == 4) ? value32 : value64;
+    }
+
+    /*
+     * typedef struct port_event {
+     *     int             portev_events;
+     *     ushort_t        portev_source;
+     *     ushort_t        portev_pad;
+     *     uintptr_t       portev_object;
+     *     void            *portev_user;
+     * } port_event_t;
+     */
+    private static final int SIZEOF_PORT_EVENT  = dependsArch(16, 24);
+    private static final int OFFSETOF_EVENTS    = 0;
+    private static final int OFFSETOF_SOURCE    = 4;
+    private static final int OFFSETOF_OBJECT    = 8;
+
+    /*
+     * typedef struct file_obj {
+     *     timestruc_t     fo_atime;
+     *     timestruc_t     fo_mtime;
+     *     timestruc_t     fo_ctime;
+     *     uintptr_t       fo_pad[3];
+     *     char            *fo_name;
+     * } file_obj_t;
+     */
+    private static final int SIZEOF_FILEOBJ    = dependsArch(40, 80);
+    private static final int OFFSET_FO_NAME    = dependsArch(36, 72);
+
+    // port sources
+    private static final short PORT_SOURCE_USER     = 3;
+    private static final short PORT_SOURCE_FILE     = 7;
+
+    // user-watchable events
+    private static final int FILE_MODIFIED      = 0x00000002;
+    private static final int FILE_ATTRIB        = 0x00000004;
+    private static final int FILE_NOFOLLOW      = 0x10000000;
+
+    // exception events
+    private static final int FILE_DELETE        = 0x00000010;
+    private static final int FILE_RENAME_TO     = 0x00000020;
+    private static final int FILE_RENAME_FROM   = 0x00000040;
+    private static final int UNMOUNTED          = 0x20000000;
+    private static final int MOUNTEDOVER        = 0x40000000;
+
+    // background thread to read change events
+    private final Poller poller;
+
+    SolarisWatchService(UnixFileSystem fs) throws IOException {
+        int port = -1;
+        try {
+            port = portCreate();
+        } catch (UnixException x) {
+            throw new IOException(x.errorString());
+        }
+
+        this.poller = new Poller(fs, this, port);
+        this.poller.start();
+    }
+
+    @Override
+    WatchKey register(Path dir,
+                      WatchEvent.Kind<?>[] events,
+                      WatchEvent.Modifier... modifiers)
+         throws IOException
+    {
+        // delegate to poller
+        return poller.register(dir, events, modifiers);
+    }
+
+    @Override
+    void implClose() throws IOException {
+        // delegate to poller
+        poller.close();
+    }
+
+    /**
+     * WatchKey implementation
+     */
+    private class SolarisWatchKey extends AbstractWatchKey
+        implements DirectoryNode
+    {
+        private final UnixPath dir;
+        private final UnixFileKey fileKey;
+
+        // pointer to native file_obj object
+        private final long object;
+
+        // events (may be changed). set to null when watch key is invalid
+        private volatile Set<? extends WatchEvent.Kind<?>> events;
+
+        // map of entries in directory; created lazily; accessed only by
+        // poller thread.
+        private Map<Path,EntryNode> children;
+
+        SolarisWatchKey(SolarisWatchService watcher,
+                        UnixPath dir,
+                        UnixFileKey fileKey,
+                        long object,
+                        Set<? extends WatchEvent.Kind<?>> events)
+        {
+            super(watcher);
+            this.dir = dir;
+            this.fileKey = fileKey;
+            this.object = object;
+            this.events = events;
+        }
+
+        UnixPath getFileRef() {
+            return dir;
+        }
+
+        UnixFileKey getFileKey() {
+            return fileKey;
+        }
+
+        @Override
+        public long object() {
+            return object;
+        }
+
+        void invalidate() {
+            events = null;
+        }
+
+        Set<? extends WatchEvent.Kind<?>> events() {
+            return events;
+        }
+
+        void setEvents(Set<? extends WatchEvent.Kind<?>> events) {
+            this.events = events;
+        }
+
+        @Override
+        public boolean isValid() {
+            return events != null;
+        }
+
+        @Override
+        public void cancel() {
+            if (isValid()) {
+                // delegate to poller
+                poller.cancel(this);
+            }
+        }
+
+        @Override
+        public void addChild(Path name, EntryNode node) {
+            if (children == null)
+                children = new HashMap<Path,EntryNode>();
+            children.put(name, node);
+        }
+
+        @Override
+        public void removeChild(Path name) {
+            children.remove(name);
+        }
+
+        @Override
+        public EntryNode getChild(Path name) {
+            if (children != null)
+                return children.get(name);
+            return null;
+        }
+    }
+
+    /**
+     * Background thread to read from port
+     */
+    private class Poller extends AbstractPoller {
+
+        // maximum number of events to read per call to port_getn
+        private static final int MAX_EVENT_COUNT            = 128;
+
+        // events that map to ENTRY_DELETE
+        private static final int FILE_REMOVED =
+            (FILE_DELETE|FILE_RENAME_TO|FILE_RENAME_FROM);
+
+        // events that tell us not to re-associate the object
+        private static final int FILE_EXCEPTION =
+            (FILE_REMOVED|UNMOUNTED|MOUNTEDOVER);
+
+        // address of event buffers (used to receive events with port_getn)
+        private final long bufferAddress;
+
+        private final SolarisWatchService watcher;
+
+        // the I/O port
+        private final int port;
+
+        // maps file key (dev/inode) to WatchKey
+        private final Map<UnixFileKey,SolarisWatchKey> fileKey2WatchKey;
+
+        // maps file_obj object to Node
+        private final Map<Long,Node> object2Node;
+
+        /**
+         * Create a new instance
+         */
+        Poller(UnixFileSystem fs, SolarisWatchService watcher, int port) {
+            this.watcher = watcher;
+            this.port = port;
+            this.bufferAddress =
+                unsafe.allocateMemory(SIZEOF_PORT_EVENT * MAX_EVENT_COUNT);
+            this.fileKey2WatchKey = new HashMap<UnixFileKey,SolarisWatchKey>();
+            this.object2Node = new HashMap<Long,Node>();
+        }
+
+        @Override
+        void wakeup() throws IOException {
+            // write to port to wakeup polling thread
+            try {
+                portSend(port, 0);
+            } catch (UnixException x) {
+                throw new IOException(x.errorString());
+            }
+        }
+
+        @Override
+        Object implRegister(Path obj,
+                            Set<? extends WatchEvent.Kind<?>> events,
+                            WatchEvent.Modifier... modifiers)
+        {
+            // no modifiers supported at this time
+            if (modifiers.length > 0) {
+                for (WatchEvent.Modifier modifier: modifiers) {
+                    if (modifier == null)
+                        return new NullPointerException();
+                    if (modifier instanceof com.sun.nio.file.SensitivityWatchEventModifier)
+                        continue; // ignore
+                    return new UnsupportedOperationException("Modifier not supported");
+                }
+            }
+
+            UnixPath dir = (UnixPath)obj;
+
+            // check file is directory
+            UnixFileAttributes attrs = null;
+            try {
+                attrs = UnixFileAttributes.get(dir, true);
+            } catch (UnixException x) {
+                return x.asIOException(dir);
+            }
+            if (!attrs.isDirectory()) {
+                return new NotDirectoryException(dir.getPathForExecptionMessage());
+            }
+
+            // return existing watch key after updating events if already
+            // registered
+            UnixFileKey fileKey = attrs.fileKey();
+            SolarisWatchKey watchKey = fileKey2WatchKey.get(fileKey);
+            if (watchKey != null) {
+                updateEvents(watchKey, events);
+                return watchKey;
+            }
+
+            // register directory
+            long object = 0L;
+            try {
+                object = registerImpl(dir, (FILE_MODIFIED | FILE_ATTRIB));
+            } catch (UnixException x) {
+                return x.asIOException(dir);
+            }
+
+            // create watch key and insert it into maps
+            watchKey = new SolarisWatchKey(watcher, dir, fileKey, object, events);
+            object2Node.put(object, watchKey);
+            fileKey2WatchKey.put(fileKey, watchKey);
+
+            // register all entries in directory
+            registerChildren(dir, watchKey, false);
+
+            return watchKey;
+        }
+
+        // cancel single key
+        @Override
+        void implCancelKey(WatchKey obj) {
+           SolarisWatchKey key = (SolarisWatchKey)obj;
+           if (key.isValid()) {
+               fileKey2WatchKey.remove(key.getFileKey());
+
+               // release resources for entries in directory
+               if (key.children != null) {
+                   for (Map.Entry<Path,EntryNode> entry: key.children.entrySet()) {
+                       EntryNode node = entry.getValue();
+                       long object = node.object();
+                       object2Node.remove(object);
+                       releaseObject(object, true);
+                   }
+               }
+
+               // release resources for directory
+               long object = key.object();
+               object2Node.remove(object);
+               releaseObject(object, true);
+
+               // and finally invalidate the key
+               key.invalidate();
+           }
+        }
+
+        // close watch service
+        @Override
+        void implCloseAll() {
+            // release all native resources
+            for (Long object: object2Node.keySet()) {
+                releaseObject(object, true);
+            }
+
+            // invalidate all keys
+            for (Map.Entry<UnixFileKey,SolarisWatchKey> entry: fileKey2WatchKey.entrySet()) {
+                entry.getValue().invalidate();
+            }
+
+            // clean-up
+            object2Node.clear();
+            fileKey2WatchKey.clear();
+
+            // free global resources
+            unsafe.freeMemory(bufferAddress);
+            UnixNativeDispatcher.close(port);
+        }
+
+        /**
+         * Poller main loop. Blocks on port_getn waiting for events and then
+         * processes them.
+         */
+        @Override
+        public void run() {
+            try {
+                for (;;) {
+                    int n = portGetn(port, bufferAddress, MAX_EVENT_COUNT);
+                    assert n > 0;
+
+                    long address = bufferAddress;
+                    for (int i=0; i<n; i++) {
+                        boolean shutdown = processEvent(address);
+                        if (shutdown)
+                            return;
+                        address += SIZEOF_PORT_EVENT;
+                    }
+                }
+            } catch (UnixException x) {
+                x.printStackTrace();
+            }
+        }
+
+        /**
+         * Process a single port_event
+         *
+         * Returns true if poller thread is requested to shutdown.
+         */
+        boolean processEvent(long address) {
+            // pe->portev_source
+            short source = unsafe.getShort(address + OFFSETOF_SOURCE);
+            // pe->portev_object
+            long object = unsafe.getAddress(address + OFFSETOF_OBJECT);
+            // pe->portev_events
+            int events = unsafe.getInt(address + OFFSETOF_EVENTS);
+
+            // user event is trigger to process pending requests
+            if (source != PORT_SOURCE_FILE) {
+                if (source == PORT_SOURCE_USER) {
+                    // process any pending requests
+                    boolean shutdown = processRequests();
+                    if (shutdown)
+                        return true;
+                }
+                return false;
+            }
+
+            // lookup object to get Node
+            Node node = object2Node.get(object);
+            if (node == null) {
+                // should not happen
+                return false;
+            }
+
+            // As a workaround for 6642290 and 6636438/6636412 we don't use
+            // FILE_EXCEPTION events to tell use not to register the file.
+            // boolean reregister = (events & FILE_EXCEPTION) == 0;
+            boolean reregister = true;
+
+            // If node is EntryNode then event relates to entry in directory
+            // If node is a SolarisWatchKey (DirectoryNode) then event relates
+            // to a watched directory.
+            boolean isDirectory = (node instanceof SolarisWatchKey);
+            if (isDirectory) {
+                processDirectoryEvents((SolarisWatchKey)node, events);
+            } else {
+                boolean ignore = processEntryEvents((EntryNode)node, events);
+                if (ignore)
+                    reregister = false;
+            }
+
+            // need to re-associate to get further events
+            if (reregister) {
+                try {
+                    events = FILE_MODIFIED | FILE_ATTRIB;
+                    if (!isDirectory) events |= FILE_NOFOLLOW;
+                    portAssociate(port,
+                                  PORT_SOURCE_FILE,
+                                  object,
+                                  events);
+                } catch (UnixException x) {
+                    // unable to re-register
+                    reregister = false;
+                }
+            }
+
+            // object is not re-registered so release resources. If
+            // object is a watched directory then signal key
+            if (!reregister) {
+                // release resources
+                object2Node.remove(object);
+                releaseObject(object, false);
+
+                // if watch key then signal it
+                if (isDirectory) {
+                    SolarisWatchKey key = (SolarisWatchKey)node;
+                    fileKey2WatchKey.remove( key.getFileKey() );
+                    key.invalidate();
+                    key.signal();
+                } else {
+                    // if entry then remove it from parent
+                    EntryNode entry = (EntryNode)node;
+                    SolarisWatchKey key = (SolarisWatchKey)entry.parent();
+                    key.removeChild(entry.name());
+                }
+            }
+
+            return false;
+        }
+
+        /**
+         * Process directory events. If directory is modified then re-scan
+         * directory to register any new entries
+         */
+        void processDirectoryEvents(SolarisWatchKey key, int mask) {
+            if ((mask & (FILE_MODIFIED | FILE_ATTRIB)) != 0) {
+                registerChildren(key.getFileRef(), key,
+                    key.events().contains(StandardWatchEventKind.ENTRY_CREATE));
+            }
+        }
+
+        /**
+         * Process events for entries in registered directories. Returns {@code
+         * true} if events are ignored because the watch key has been cancelled.
+         */
+        boolean processEntryEvents(EntryNode node, int mask) {
+            SolarisWatchKey key = (SolarisWatchKey)node.parent();
+            Set<? extends WatchEvent.Kind<?>> events = key.events();
+            if (events == null) {
+                // key has been cancelled so ignore event
+                return true;
+            }
+
+            // entry modified
+            if (((mask & (FILE_MODIFIED | FILE_ATTRIB)) != 0) &&
+                events.contains(StandardWatchEventKind.ENTRY_MODIFY))
+            {
+                key.signalEvent(StandardWatchEventKind.ENTRY_MODIFY, node.name());
+            }
+
+            // entry removed
+            if (((mask & (FILE_REMOVED)) != 0) &&
+                events.contains(StandardWatchEventKind.ENTRY_DELETE))
+            {
+                // Due to 6636438/6636412 we may get a remove event for cases
+                // where a rmdir/unlink/rename is attempted but fails. Until
+                // this issue is resolved we re-lstat the file to check if it
+                // exists. If it exists then we ignore the event. To keep the
+                // workaround simple we don't check the st_ino so it isn't
+                // effective when the file is replaced.
+                boolean removed = true;
+                try {
+                    UnixFileAttributes
+                        .get(key.getFileRef().resolve(node.name()), false);
+                    removed = false;
+                } catch (UnixException x) { }
+
+                if (removed)
+                    key.signalEvent(StandardWatchEventKind.ENTRY_DELETE, node.name());
+            }
+            return false;
+        }
+
+        /**
+         * Registers all entries in the given directory
+         *
+         * The {@code sendEvents} parameter indicates if ENTRY_CREATE events
+         * should be queued when new entries are found. When initially
+         * registering a directory then will always be false. When re-scanning
+         * a directory then it depends on if the event is enabled or not.
+         */
+        void registerChildren(UnixPath dir,
+                              SolarisWatchKey parent,
+                              boolean sendEvents)
+        {
+            // if the ENTRY_MODIFY event is not enabled then we don't need
+            // modification events for entries in the directory
+            int events = FILE_NOFOLLOW;
+            if (parent.events().contains(StandardWatchEventKind.ENTRY_MODIFY))
+                events |= (FILE_MODIFIED | FILE_ATTRIB);
+
+            DirectoryStream<Path> stream = null;
+            try {
+                stream = dir.newDirectoryStream();
+            } catch (IOException x) {
+                // nothing we can do
+                return;
+            }
+            try {
+                for (Path entry: stream) {
+                    Path name = entry.getName();
+
+                    // skip entry if already registered
+                    if (parent.getChild(name) != null)
+                        continue;
+
+                    // send ENTRY_CREATE if enabled
+                    if (sendEvents) {
+                        parent.signalEvent(StandardWatchEventKind.ENTRY_CREATE, name);
+                    }
+
+                    // register it
+                    long object = 0L;
+                    try {
+                        object = registerImpl((UnixPath)entry, events);
+                    } catch (UnixException x) {
+                        // can't register so ignore for now.
+                        continue;
+                    }
+
+                    // create node
+                    EntryNode node = new EntryNode(object, entry.getName(), parent);
+                    // tell the parent about it
+                    parent.addChild(entry.getName(), node);
+                    object2Node.put(object, node);
+                }
+            } catch (ConcurrentModificationException x) {
+                // error during iteration which we ignore for now
+            } finally {
+                try {
+                    stream.close();
+                } catch (IOException x) { }
+            }
+        }
+
+        /**
+         * Update watch key's events. Where the ENTRY_MODIFY changes then we
+         * need to update the events of registered children.
+         */
+        void updateEvents(SolarisWatchKey key, Set<? extends WatchEvent.Kind<?>> events) {
+            // update events, rembering if ENTRY_MODIFY was previously
+            // enabled or disabled.
+            boolean wasModifyEnabled = key.events()
+                .contains(StandardWatchEventKind.ENTRY_MODIFY);
+            key.setEvents(events);
+
+            // check if ENTRY_MODIFY has changed
+            boolean isModifyEnabled = events
+                .contains(StandardWatchEventKind.ENTRY_MODIFY);
+            if (wasModifyEnabled == isModifyEnabled) {
+                return;
+            }
+
+            // if changed then update events of children
+            if (key.children != null) {
+                int ev = FILE_NOFOLLOW;
+                if (isModifyEnabled)
+                    ev |= (FILE_MODIFIED | FILE_ATTRIB);
+
+                for (Map.Entry<Path,EntryNode> entry: key.children.entrySet()) {
+                    long object = entry.getValue().object();
+                    try {
+                        portAssociate(port,
+                                      PORT_SOURCE_FILE,
+                                      object,
+                                      ev);
+                    } catch (UnixException x) {
+                        // nothing we can do.
+                    }
+                }
+            }
+        }
+
+        /**
+         * Calls port_associate to register the given path.
+         * Returns pointer to fileobj structure that is allocated for
+         * the registration.
+         */
+        long registerImpl(UnixPath dir, int events)
+            throws UnixException
+        {
+            // allocate memory for the path (file_obj->fo_name field)
+            byte[] path = dir.getByteArrayForSysCalls();
+            int len = path.length;
+            long name = unsafe.allocateMemory(len+1);
+            unsafe.copyMemory(path, Unsafe.ARRAY_BYTE_BASE_OFFSET, null,
+                name, (long)len);
+            unsafe.putByte(name + len, (byte)0);
+
+            // allocate memory for filedatanode structure - this is the object
+            // to port_associate
+            long object = unsafe.allocateMemory(SIZEOF_FILEOBJ);
+            unsafe.setMemory(null, object, SIZEOF_FILEOBJ, (byte)0);
+            unsafe.putAddress(object + OFFSET_FO_NAME, name);
+
+            // associate the object with the port
+            try {
+                portAssociate(port,
+                              PORT_SOURCE_FILE,
+                              object,
+                              events);
+            } catch (UnixException x) {
+                // debugging
+                if (x.errno() == EAGAIN) {
+                    System.err.println("The maximum number of objects associated "+
+                        "with the port has been reached");
+                }
+
+                unsafe.freeMemory(name);
+                unsafe.freeMemory(object);
+                throw x;
+            }
+            return object;
+        }
+
+        /**
+         * Frees all resources for an file_obj object; optionally remove
+         * association from port
+         */
+        void releaseObject(long object, boolean dissociate) {
+            // remove association
+            if (dissociate) {
+                try {
+                    portDissociate(port, PORT_SOURCE_FILE, object);
+                } catch (UnixException x) {
+                    // ignore
+                }
+            }
+
+            // free native memory
+            long name = unsafe.getAddress(object + OFFSET_FO_NAME);
+            unsafe.freeMemory(name);
+            unsafe.freeMemory(object);
+        }
+    }
+
+    /**
+     * A node with native (file_obj) resources
+     */
+    private static interface Node {
+        long object();
+    }
+
+    /**
+     * A directory node with a map of the entries in the directory
+     */
+    private static interface DirectoryNode extends Node {
+        void addChild(Path name, EntryNode node);
+        void removeChild(Path name);
+        EntryNode getChild(Path name);
+    }
+
+    /**
+     * An implementation of a node that is an entry in a directory.
+     */
+    private static class EntryNode implements Node {
+        private final long object;
+        private final Path name;
+        private final DirectoryNode parent;
+
+        EntryNode(long object, Path name, DirectoryNode parent) {
+            this.object = object;
+            this.name = name;
+            this.parent = parent;
+        }
+
+        @Override
+        public long object() {
+            return object;
+        }
+
+        Path name() {
+            return name;
+        }
+
+        DirectoryNode parent() {
+            return parent;
+        }
+    }
+
+    // -- native methods --
+
+    private static native void init();
+
+    private static native int portCreate() throws UnixException;
+
+    private static native void portAssociate(int port, int source, long object, int events)
+        throws UnixException;
+
+    private static native void portDissociate(int port, int source, long object)
+        throws UnixException;
+
+    private static native void portSend(int port, int events)
+        throws UnixException;
+
+    private static native int portGetn(int port, long address, int max)
+        throws UnixException;
+
+    static {
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+            public Void run() {
+                System.loadLibrary("nio");
+                return null;
+        }});
+        init();
+    }
+}
diff --git a/jdk/src/solaris/classes/sun/nio/fs/UnixChannelFactory.java b/jdk/src/solaris/classes/sun/nio/fs/UnixChannelFactory.java
new file mode 100644
index 0000000..a8265dc
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixChannelFactory.java
@@ -0,0 +1,286 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.*;
+import java.nio.channels.*;
+import java.io.FileDescriptor;
+import java.util.Set;
+
+import sun.nio.ch.FileChannelImpl;
+import sun.nio.ch.ThreadPool;
+import sun.nio.ch.SimpleAsynchronousFileChannelImpl;
+import sun.misc.SharedSecrets;
+import sun.misc.JavaIOFileDescriptorAccess;
+
+import com.sun.nio.file.ExtendedOpenOption;
+
+import static sun.nio.fs.UnixNativeDispatcher.*;
+import static sun.nio.fs.UnixConstants.*;
+
+/**
+ * Factory for FileChannels and AsynchronousFileChannels
+ */
+
+class UnixChannelFactory {
+    private static final JavaIOFileDescriptorAccess fdAccess =
+        SharedSecrets.getJavaIOFileDescriptorAccess();
+
+    private UnixChannelFactory() {
+    }
+
+    /**
+     * Represents the flags from a user-supplied set of open options.
+     */
+    private static class Flags {
+        boolean read;
+        boolean write;
+        boolean append;
+        boolean truncateExisting;
+        boolean noFollowLinks;
+        boolean create;
+        boolean createNew;
+        boolean deleteOnClose;
+        boolean sync;
+        boolean dsync;
+
+        static Flags toFlags(Set<? extends OpenOption> options) {
+            Flags flags = new Flags();
+            for (OpenOption option: options) {
+                if (option instanceof StandardOpenOption) {
+                    switch ((StandardOpenOption)option) {
+                        case READ : flags.read = true; break;
+                        case WRITE : flags.write = true; break;
+                        case APPEND : flags.append = true; break;
+                        case TRUNCATE_EXISTING : flags.truncateExisting = true; break;
+                        case CREATE : flags.create = true; break;
+                        case CREATE_NEW : flags.createNew = true; break;
+                        case DELETE_ON_CLOSE : flags.deleteOnClose = true; break;
+                        case SPARSE : /* ignore */ break;
+                        case SYNC : flags.sync = true; break;
+                        case DSYNC : flags.dsync = true; break;
+                        default: throw new UnsupportedOperationException();
+                    }
+                    continue;
+                }
+                if (option == LinkOption.NOFOLLOW_LINKS) {
+                    flags.noFollowLinks = true;
+                    continue;
+                }
+                if (option == null)
+                    throw new NullPointerException();
+               throw new UnsupportedOperationException();
+            }
+            return flags;
+        }
+    }
+
+
+    /**
+     * Constructs a file channel from an existing (open) file descriptor
+     */
+    static FileChannel newFileChannel(int fd, boolean reading, boolean writing) {
+        FileDescriptor fdObj = new FileDescriptor();
+        fdAccess.set(fdObj, fd);
+        return FileChannelImpl.open(fdObj, reading, writing, null);
+    }
+
+    /**
+     * Constructs a file channel by opening a file using a dfd/path pair
+     */
+    static FileChannel newFileChannel(int dfd,
+                                      UnixPath path,
+                                      String pathForPermissionCheck,
+                                      Set<? extends OpenOption> options,
+                                      int mode)
+        throws UnixException
+    {
+        Flags flags = Flags.toFlags(options);
+
+        // default is reading; append => writing
+        if (!flags.read && !flags.write) {
+            if (flags.append) {
+                flags.write = true;
+            } else {
+                flags.read = true;
+            }
+        }
+
+        // validation
+        if (flags.read && flags.append)
+            throw new IllegalArgumentException("READ + APPEND not allowed");
+        if (flags.append && flags.truncateExisting)
+            throw new IllegalArgumentException("APPEND + TRUNCATE_EXISTING not allowed");
+
+        FileDescriptor fdObj = open(dfd, path, pathForPermissionCheck, flags, mode);
+        return FileChannelImpl.open(fdObj, flags.read, flags.write, null);
+    }
+
+    /**
+     * Constructs a file channel by opening the given file.
+     */
+    static FileChannel newFileChannel(UnixPath path,
+                                      Set<? extends OpenOption> options,
+                                      int mode)
+        throws UnixException
+    {
+        return newFileChannel(-1, path, null, options, mode);
+    }
+
+    /**
+     * Constructs an asynchronous file channel by opening the given file.
+     */
+    static AsynchronousFileChannel newAsynchronousFileChannel(UnixPath path,
+                                                              Set<? extends OpenOption> options,
+                                                              int mode,
+                                                              ThreadPool pool)
+        throws UnixException
+    {
+        Flags flags = Flags.toFlags(options);
+
+        // default is reading
+        if (!flags.read && !flags.write) {
+            flags.read = true;
+        }
+
+        // validation
+        if (flags.append)
+            throw new UnsupportedOperationException("APPEND not allowed");
+
+        // for now use simple implementation
+        FileDescriptor fdObj = open(-1, path, null, flags, mode);
+        return SimpleAsynchronousFileChannelImpl.open(fdObj, flags.read, flags.write, pool);
+    }
+
+    /**
+     * Opens file based on parameters and options, returning a FileDescriptor
+     * encapsulating the handle to the open file.
+     */
+    static FileDescriptor open(int dfd,
+                               UnixPath path,
+                               String pathForPermissionCheck,
+                               Flags flags,
+                               int mode)
+        throws UnixException
+    {
+        // map to oflags
+        int oflags;
+        if (flags.read && flags.write) {
+            oflags = O_RDWR;
+        } else {
+            oflags = (flags.write) ? O_WRONLY : O_RDONLY;
+        }
+        if (flags.write) {
+            if (flags.truncateExisting)
+                oflags |= O_TRUNC;
+            if (flags.append)
+                oflags |= O_APPEND;
+
+            // create flags
+            if (flags.createNew) {
+                byte[] pathForSysCall = path.asByteArray();
+
+                // throw exception if file name is "." to avoid confusing error
+                if ((pathForSysCall[pathForSysCall.length-1] == '.') &&
+                    (pathForSysCall.length == 1 ||
+                    (pathForSysCall[pathForSysCall.length-2] == '/')))
+                {
+                    throw new UnixException(EEXIST);
+                }
+                oflags |= (O_CREAT | O_EXCL);
+            } else {
+                if (flags.create)
+                    oflags |= O_CREAT;
+            }
+        }
+
+        // follow links by default
+        boolean followLinks = true;
+        if (!flags.createNew && (flags.noFollowLinks || flags.deleteOnClose)) {
+            followLinks = false;
+            oflags |= O_NOFOLLOW;
+        }
+
+        if (flags.dsync)
+            oflags |= O_DSYNC;
+        if (flags.sync)
+            oflags |= O_SYNC;
+
+        // permission check before we open the file
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            if (pathForPermissionCheck == null)
+                pathForPermissionCheck = path.getPathForPermissionCheck();
+            if (flags.read)
+                sm.checkRead(pathForPermissionCheck);
+            if (flags.write)
+                sm.checkWrite(pathForPermissionCheck);
+            if (flags.deleteOnClose)
+                sm.checkDelete(pathForPermissionCheck);
+        }
+
+        int fd;
+        try {
+            if (dfd >= 0) {
+                fd = openat(dfd, path.asByteArray(), oflags, mode);
+            } else {
+                fd = UnixNativeDispatcher.open(path, oflags, mode);
+            }
+        } catch (UnixException x) {
+            // Linux error can be EISDIR or EEXIST when file exists
+            if (flags.createNew && (x.errno() == EISDIR)) {
+                x.setError(EEXIST);
+            }
+
+            // handle ELOOP to avoid confusing message
+            if (!followLinks && (x.errno() == ELOOP)) {
+                x = new UnixException(x.getMessage() + " (NOFOLLOW_LINKS specified)");
+            }
+
+            throw x;
+        }
+
+        // unlink file immediately if delete on close. The spec is clear that
+        // an implementation cannot guarantee to unlink the correct file when
+        // replaced by an attacker after it is opened.
+        if (flags.deleteOnClose) {
+            try {
+                if (dfd >= 0) {
+                    unlinkat(dfd, path.asByteArray(), 0);
+                } else {
+                    unlink(path);
+                }
+            } catch (UnixException ignore) {
+                // best-effort
+            }
+        }
+
+        // create java.io.FileDescriptor
+        FileDescriptor fdObj = new FileDescriptor();
+        fdAccess.set(fdObj, fd);
+        return fdObj;
+    }
+}
diff --git a/jdk/src/solaris/classes/sun/nio/fs/UnixCopyFile.java b/jdk/src/solaris/classes/sun/nio/fs/UnixCopyFile.java
new file mode 100644
index 0000000..808cc1e
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixCopyFile.java
@@ -0,0 +1,608 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.*;
+import java.io.IOException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.concurrent.ExecutionException;
+import com.sun.nio.file.ExtendedCopyOption;
+
+import static sun.nio.fs.UnixNativeDispatcher.*;
+import static sun.nio.fs.UnixConstants.*;
+
+
+/**
+ * Unix implementation of Path#copyTo and Path#moveTo methods.
+ */
+
+class UnixCopyFile {
+    private UnixCopyFile() {  }
+
+    // The flags that control how a file is copied or moved
+    private static class Flags {
+        boolean replaceExisting;
+        boolean atomicMove;
+        boolean followLinks;
+        boolean interruptible;
+
+        // the attributes to copy
+        boolean copyBasicAttributes;
+        boolean copyPosixAttributes;
+        boolean copyNonPosixAttributes;
+
+        // flags that indicate if we should fail if attributes cannot be copied
+        boolean failIfUnableToCopyBasic;
+        boolean failIfUnableToCopyPosix;
+        boolean failIfUnableToCopyNonPosix;
+
+        static Flags fromCopyOptions(CopyOption... options) {
+            Flags flags = new Flags();
+            flags.followLinks = true;
+            for (CopyOption option: options) {
+                if (option == StandardCopyOption.REPLACE_EXISTING) {
+                    flags.replaceExisting = true;
+                    continue;
+                }
+                if (option == LinkOption.NOFOLLOW_LINKS) {
+                    flags.followLinks = false;
+                    continue;
+                }
+                if (option == StandardCopyOption.COPY_ATTRIBUTES) {
+                    // copy all attributes but only fail if basic attributes
+                    // cannot be copied
+                    flags.copyBasicAttributes = true;
+                    flags.copyPosixAttributes = true;
+                    flags.copyNonPosixAttributes = true;
+                    flags.failIfUnableToCopyBasic = true;
+                    continue;
+                }
+                if (option == ExtendedCopyOption.INTERRUPTIBLE) {
+                    flags.interruptible = true;
+                    continue;
+                }
+                if (option == null)
+                    throw new NullPointerException();
+                throw new UnsupportedOperationException("Unsupported copy option");
+            }
+            return flags;
+        }
+
+        static Flags fromMoveOptions(CopyOption... options) {
+            Flags flags = new Flags();
+            for (CopyOption option: options) {
+                if (option == StandardCopyOption.ATOMIC_MOVE) {
+                    flags.atomicMove = true;
+                    continue;
+                }
+                if (option == StandardCopyOption.REPLACE_EXISTING) {
+                    flags.replaceExisting = true;
+                    continue;
+                }
+                if (option == LinkOption.NOFOLLOW_LINKS) {
+                    // ignore
+                    continue;
+                }
+                if (option == null)
+                    throw new NullPointerException();
+                throw new UnsupportedOperationException("Unsupported copy option");
+            }
+
+            // a move requires that all attributes be copied but only fail if
+            // the basic attributes cannot be copied
+            flags.copyBasicAttributes = true;
+            flags.copyPosixAttributes = true;
+            flags.copyNonPosixAttributes = true;
+            flags.failIfUnableToCopyBasic = true;
+            return flags;
+        }
+    }
+
+    // copy directory from source to target
+    private static void copyDirectory(UnixPath source,
+                                      UnixFileAttributes attrs,
+                                      UnixPath target,
+                                      Flags flags)
+        throws IOException
+    {
+        try {
+            mkdir(target, attrs.mode());
+        } catch (UnixException x) {
+            x.rethrowAsIOException(target);
+        }
+
+        // no attributes to copy
+        if (!flags.copyBasicAttributes &&
+            !flags.copyPosixAttributes &&
+            !flags.copyNonPosixAttributes) return;
+
+        // open target directory if possible (this can fail when copying a
+        // directory for which we don't have read access).
+        int dfd = -1;
+        try {
+            dfd = open(target, O_RDONLY, 0);
+        } catch (UnixException x) {
+            // access to target directory required to copy named attributes
+            if (flags.copyNonPosixAttributes && flags.failIfUnableToCopyNonPosix) {
+                try { rmdir(target); } catch (UnixException ignore) { }
+                x.rethrowAsIOException(target);
+            }
+        }
+
+        boolean done = false;
+        try {
+            // copy owner/group/permissions
+            if (flags.copyPosixAttributes){
+                try {
+                    if (dfd >= 0) {
+                        fchown(dfd, attrs.uid(), attrs.gid());
+                        fchmod(dfd, attrs.mode());
+                    } else {
+                        chown(target, attrs.uid(), attrs.gid());
+                        chmod(target, attrs.mode());
+                    }
+                } catch (UnixException x) {
+                    // unable to set owner/group
+                    if (flags.failIfUnableToCopyPosix)
+                        x.rethrowAsIOException(target);
+                }
+            }
+            // copy other attributes
+            if (flags.copyNonPosixAttributes && (dfd >= 0)) {
+                int sfd = -1;
+                try {
+                    sfd = open(source, O_RDONLY, 0);
+                } catch (UnixException x) {
+                    if (flags.failIfUnableToCopyNonPosix)
+                        x.rethrowAsIOException(source);
+                }
+                if (sfd >= 0) {
+                    source.getFileSystem().copyNonPosixAttributes(sfd, dfd);
+                    close(sfd);
+                }
+            }
+            // copy time stamps last
+            if (flags.copyBasicAttributes) {
+                try {
+                    if (dfd >= 0) {
+                        futimes(dfd, attrs.lastAccessTime(),
+                            attrs.lastModifiedTime());
+                    } else {
+                        utimes(target, attrs.lastAccessTime(),
+                            attrs.lastModifiedTime());
+                    }
+                } catch (UnixException x) {
+                    // unable to set times
+                    if (flags.failIfUnableToCopyBasic)
+                        x.rethrowAsIOException(target);
+                }
+            }
+            done = true;
+        } finally {
+            if (dfd >= 0)
+                close(dfd);
+            if (!done) {
+                // rollback
+                try { rmdir(target); } catch (UnixException ignore) { }
+            }
+        }
+    }
+
+    // copy regular file from source to target
+    private static void copyFile(UnixPath source,
+                                 UnixFileAttributes attrs,
+                                 UnixPath  target,
+                                 Flags flags,
+                                 long addressToPollForCancel)
+        throws IOException
+    {
+        int fi = -1;
+        try {
+            fi = open(source, O_RDONLY, 0);
+        } catch (UnixException x) {
+            x.rethrowAsIOException(source);
+        }
+
+        try {
+            // open new file
+            int fo = -1;
+            try {
+                fo = open(target,
+                           (O_WRONLY |
+                            O_CREAT |
+                            O_TRUNC),
+                           attrs.mode());
+            } catch (UnixException x) {
+                x.rethrowAsIOException(target);
+            }
+
+            // set to true when file and attributes copied
+            boolean complete = false;
+            try {
+                // transfer bytes to target file
+                try {
+                    transfer(fo, fi, addressToPollForCancel);
+                } catch (UnixException x) {
+                    x.rethrowAsIOException(source, target);
+                }
+                // copy owner/permissions
+                if (flags.copyPosixAttributes) {
+                    try {
+                        fchown(fo, attrs.uid(), attrs.gid());
+                        fchmod(fo, attrs.mode());
+                    } catch (UnixException x) {
+                        if (flags.failIfUnableToCopyPosix)
+                            x.rethrowAsIOException(target);
+                    }
+                }
+                // copy non POSIX attributes (depends on file system)
+                if (flags.copyNonPosixAttributes) {
+                    source.getFileSystem().copyNonPosixAttributes(fi, fo);
+                }
+                // copy time attributes
+                if (flags.copyBasicAttributes) {
+                    try {
+                        futimes(fo, attrs.lastAccessTime(), attrs.lastModifiedTime());
+                    } catch (UnixException x) {
+                        if (flags.failIfUnableToCopyBasic)
+                            x.rethrowAsIOException(target);
+                    }
+                }
+                complete = true;
+            } finally {
+                close(fo);
+
+                // copy of file or attributes failed so rollback
+                if (!complete) {
+                    try {
+                        unlink(target);
+                    } catch (UnixException ignore) { }
+                }
+            }
+        } finally {
+            close(fi);
+        }
+    }
+
+    // copy symbolic link from source to target
+    private static void copyLink(UnixPath source,
+                                 UnixFileAttributes attrs,
+                                 UnixPath  target,
+                                 Flags flags)
+        throws IOException
+    {
+        byte[] linktarget = null;
+        try {
+            linktarget = readlink(source);
+        } catch (UnixException x) {
+            x.rethrowAsIOException(source);
+        }
+        try {
+            symlink(linktarget, target);
+
+            if (flags.copyPosixAttributes) {
+                try {
+                    lchown(target, attrs.uid(), attrs.gid());
+                } catch (UnixException x) {
+                    // ignore since link attributes not required to be copied
+                }
+            }
+        } catch (UnixException x) {
+            x.rethrowAsIOException(target);
+        }
+    }
+
+    // copy special file from source to target
+    private static void copySpecial(UnixPath source,
+                                    UnixFileAttributes attrs,
+                                    UnixPath  target,
+                                    Flags flags)
+        throws IOException
+    {
+        try {
+            mknod(target, attrs.mode(), attrs.rdev());
+        } catch (UnixException x) {
+            x.rethrowAsIOException(target);
+        }
+        boolean done = false;
+        try {
+            if (flags.copyPosixAttributes) {
+                try {
+                    chown(target, attrs.uid(), attrs.gid());
+                    chmod(target, attrs.mode());
+                } catch (UnixException x) {
+                    if (flags.failIfUnableToCopyPosix)
+                        x.rethrowAsIOException(target);
+                }
+            }
+            if (flags.copyBasicAttributes) {
+                try {
+                    utimes(target, attrs.lastAccessTime(), attrs.lastModifiedTime());
+                } catch (UnixException x) {
+                    if (flags.failIfUnableToCopyBasic)
+                        x.rethrowAsIOException(target);
+                }
+            }
+            done = true;
+        } finally {
+            if (!done) {
+                try { unlink(target); } catch (UnixException ignore) { }
+            }
+        }
+    }
+
+    // move file from source to target
+    static void move(UnixPath source, UnixPath target, CopyOption... options)
+        throws IOException
+    {
+        // permission check
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            source.checkWrite();
+            target.checkWrite();
+        }
+
+        // translate options into flags
+        Flags flags = Flags.fromMoveOptions(options);
+
+        // handle atomic rename case
+        if (flags.atomicMove) {
+            try {
+                rename(source, target);
+            } catch (UnixException x) {
+                if (x.errno() == EXDEV) {
+                    throw new AtomicMoveNotSupportedException(
+                        source.getPathForExecptionMessage(),
+                        target.getPathForExecptionMessage(),
+                        x.errorString());
+                }
+                x.rethrowAsIOException(source, target);
+            }
+            return;
+        }
+
+        // move using rename or copy+delete
+        UnixFileAttributes sourceAttrs = null;
+        UnixFileAttributes targetAttrs = null;
+
+        // get attributes of source file (don't follow links)
+        try {
+            sourceAttrs = UnixFileAttributes.get(source, false);
+        } catch (UnixException x) {
+            x.rethrowAsIOException(source);
+        }
+
+        // get attributes of target file (don't follow links)
+        try {
+            targetAttrs = UnixFileAttributes.get(target, false);
+        } catch (UnixException x) {
+            // ignore
+        }
+        boolean targetExists = (targetAttrs != null);
+
+        // if the target exists:
+        // 1. check if source and target are the same file
+        // 2. throw exception if REPLACE_EXISTING option is not set
+        // 3. delete target if REPLACE_EXISTING option set
+        if (targetExists) {
+            if (sourceAttrs.isSameFile(targetAttrs))
+                return;  // nothing to do as files are identical
+            if (!flags.replaceExisting) {
+                throw new FileAlreadyExistsException(
+                    target.getPathForExecptionMessage());
+            }
+
+            // attempt to delete target
+            try {
+                if (targetAttrs.isDirectory()) {
+                    rmdir(target);
+                } else {
+                    unlink(target);
+                }
+            } catch (UnixException x) {
+                // target is non-empty directory that can't be replaced.
+                if (targetAttrs.isDirectory() &&
+                   (x.errno() == EEXIST || x.errno() == ENOTEMPTY))
+                {
+                    throw new FileAlreadyExistsException(
+                        source.getPathForExecptionMessage(),
+                        target.getPathForExecptionMessage(),
+                        x.getMessage());
+                }
+                x.rethrowAsIOException(target);
+            }
+        }
+
+        // first try rename
+        try {
+            rename(source, target);
+            return;
+        } catch (UnixException x) {
+            if (x.errno() != EXDEV && x.errno() != EISDIR) {
+                x.rethrowAsIOException(source, target);
+            }
+        }
+
+        // copy source to target
+        if (sourceAttrs.isDirectory()) {
+            copyDirectory(source, sourceAttrs, target, flags);
+        } else {
+            if (sourceAttrs.isSymbolicLink()) {
+                copyLink(source, sourceAttrs, target, flags);
+            } else {
+                if (sourceAttrs.isDevice()) {
+                    copySpecial(source, sourceAttrs, target, flags);
+                } else {
+                    copyFile(source, sourceAttrs, target, flags, 0L);
+                }
+            }
+        }
+
+        // delete source
+        try {
+            if (sourceAttrs.isDirectory()) {
+                rmdir(source);
+            } else {
+                unlink(source);
+            }
+        } catch (UnixException x) {
+            // file was copied but unable to unlink the source file so attempt
+            // to remove the target and throw a reasonable exception
+            try {
+                if (sourceAttrs.isDirectory()) {
+                    rmdir(target);
+                } else {
+                    unlink(target);
+                }
+            } catch (UnixException ignore) { }
+
+            if (sourceAttrs.isDirectory() &&
+                (x.errno() == EEXIST || x.errno() == ENOTEMPTY))
+            {
+                throw new DirectoryNotEmptyException(
+                    source.getPathForExecptionMessage());
+            }
+            x.rethrowAsIOException(source);
+        }
+    }
+
+    // copy file from source to target
+    static void copy(final UnixPath source,
+                     final UnixPath target,
+                     CopyOption... options) throws IOException
+    {
+        // permission checks
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            source.checkRead();
+            target.checkWrite();
+        }
+
+        // translate options into flags
+        final Flags flags = Flags.fromCopyOptions(options);
+
+        UnixFileAttributes sourceAttrs = null;
+        UnixFileAttributes targetAttrs = null;
+
+        // get attributes of source file
+        try {
+            sourceAttrs = UnixFileAttributes.get(source, flags.followLinks);
+        } catch (UnixException x) {
+            x.rethrowAsIOException(source);
+        }
+
+        // if source file is symbolic link then we must check LinkPermission
+        if (sm != null && sourceAttrs.isSymbolicLink()) {
+            sm.checkPermission(new LinkPermission("symbolic"));
+        }
+
+        // get attributes of target file (don't follow links)
+        try {
+            targetAttrs = UnixFileAttributes.get(target, false);
+        } catch (UnixException x) {
+            // ignore
+        }
+        boolean targetExists = (targetAttrs != null);
+
+        // if the target exists:
+        // 1. check if source and target are the same file
+        // 2. throw exception if REPLACE_EXISTING option is not set
+        // 3. try to unlink the target
+        if (targetExists) {
+            if (sourceAttrs.isSameFile(targetAttrs))
+                return;  // nothing to do as files are identical
+            if (!flags.replaceExisting)
+                throw new FileAlreadyExistsException(
+                    target.getPathForExecptionMessage());
+            try {
+                if (targetAttrs.isDirectory()) {
+                    rmdir(target);
+                } else {
+                    unlink(target);
+                }
+            } catch (UnixException x) {
+                // target is non-empty directory that can't be replaced.
+                if (targetAttrs.isDirectory() &&
+                   (x.errno() == EEXIST || x.errno() == ENOTEMPTY))
+                {
+                    throw new FileAlreadyExistsException(
+                        source.getPathForExecptionMessage(),
+                        target.getPathForExecptionMessage(),
+                        x.getMessage());
+                }
+                x.rethrowAsIOException(target);
+            }
+        }
+
+        // do the copy
+        if (sourceAttrs.isDirectory()) {
+            copyDirectory(source, sourceAttrs, target, flags);
+            return;
+        }
+        if (sourceAttrs.isSymbolicLink()) {
+            copyLink(source, sourceAttrs, target, flags);
+            return;
+        }
+        if (!flags.interruptible) {
+            // non-interruptible file copy
+            copyFile(source, sourceAttrs, target, flags, 0L);
+            return;
+        }
+
+        // interruptible file copy
+        final UnixFileAttributes attrsToCopy = sourceAttrs;
+        Cancellable copyTask = new Cancellable() {
+            @Override public void implRun() throws IOException {
+                copyFile(source, attrsToCopy, target, flags,
+                    addressToPollForCancel());
+            }
+        };
+        try {
+            Cancellable.runInterruptibly(copyTask);
+        } catch (ExecutionException e) {
+            Throwable t = e.getCause();
+            if (t instanceof IOException)
+                throw (IOException)t;
+            throw new IOException(t);
+        }
+    }
+
+    // -- native methods --
+
+    static native void transfer(int dst, int src, long addressToPollForCancel)
+        throws UnixException;
+
+    static {
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+            @Override
+            public Void run() {
+                System.loadLibrary("nio");
+                return null;
+            }});
+    }
+
+}
diff --git a/jdk/src/solaris/classes/sun/nio/fs/UnixDirectoryStream.java b/jdk/src/solaris/classes/sun/nio/fs/UnixDirectoryStream.java
new file mode 100644
index 0000000..a723d71
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixDirectoryStream.java
@@ -0,0 +1,267 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.*;
+import java.util.Iterator;
+import java.util.ConcurrentModificationException;
+import java.util.NoSuchElementException;
+import java.util.concurrent.locks.*;
+import java.io.IOException;
+import static sun.nio.fs.UnixNativeDispatcher.*;
+
+/**
+ * Unix implementation of java.nio.file.DirectoryStream
+ */
+
+class UnixDirectoryStream
+    implements DirectoryStream<Path>
+{
+    // path to directory when originally opened
+    private final UnixPath dir;
+
+    // directory pointer (returned by opendir)
+    private final long dp;
+
+    // filter (may be null)
+    private final DirectoryStream.Filter<? super Path> filter;
+
+    // used to coorindate closing of directory stream
+    private final ReentrantReadWriteLock streamLock =
+        new ReentrantReadWriteLock(true);
+
+    // indicates if directory stream is open (synchronize on closeLock)
+    private volatile boolean isClosed;
+
+    // directory iterator
+    private Iterator<Path> iterator;
+
+    /**
+     * Initializes a new instance
+     */
+    UnixDirectoryStream(UnixPath dir, long dp, DirectoryStream.Filter<? super Path> filter) {
+        this.dir = dir;
+        this.dp = dp;
+        this.filter = filter;
+    }
+
+    protected final UnixPath directory() {
+        return dir;
+    }
+
+    protected final Lock readLock() {
+        return streamLock.readLock();
+    }
+
+    protected final Lock writeLock() {
+        return streamLock.writeLock();
+    }
+
+    protected final boolean isOpen() {
+        return !isClosed;
+    }
+
+    protected final boolean closeImpl() throws IOException {
+        if (!isClosed) {
+            isClosed = true;
+            try {
+                closedir(dp);
+            } catch (UnixException x) {
+                throw new IOException(x.errorString());
+            }
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    @Override
+    public void close()
+        throws IOException
+    {
+        writeLock().lock();
+        try {
+            closeImpl();
+        } finally {
+            writeLock().unlock();
+        }
+    }
+
+    protected final Iterator<Path> iterator(DirectoryStream<Path> ds) {
+        if (isClosed) {
+            throw new IllegalStateException("Directory stream is closed");
+        }
+        synchronized (this) {
+            if (iterator != null)
+                throw new IllegalStateException("Iterator already obtained");
+            iterator = new UnixDirectoryIterator(ds);
+            return iterator;
+        }
+    }
+
+    @Override
+    public Iterator<Path> iterator() {
+        return iterator(this);
+    }
+
+    /**
+     * Iterator implementation
+     */
+    private class UnixDirectoryIterator implements Iterator<Path> {
+        private final DirectoryStream<Path> stream;
+
+        // true when at EOF
+        private boolean atEof;
+
+        // next entry to return
+        private Path nextEntry;
+
+        // previous entry returned by next method (needed by remove method)
+        private Path prevEntry;
+
+        UnixDirectoryIterator(DirectoryStream<Path> stream) {
+            atEof = false;
+            this.stream = stream;
+        }
+
+        // Return true if file name is "." or ".."
+        private boolean isSelfOrParent(byte[] nameAsBytes) {
+            if (nameAsBytes[0] == '.') {
+                if ((nameAsBytes.length == 1) ||
+                    (nameAsBytes.length == 2 && nameAsBytes[1] == '.')) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        // Returns next entry (or null)
+        private Path readNextEntry() {
+            assert Thread.holdsLock(this);
+
+            for (;;) {
+                byte[] nameAsBytes = null;
+
+                // prevent close while reading
+                readLock().lock();
+                try {
+                    if (isClosed)
+                        throwAsConcurrentModificationException(new
+                            ClosedDirectoryStreamException());
+                    try {
+                        nameAsBytes = readdir(dp);
+                    } catch (UnixException x) {
+                        try {
+                            x.rethrowAsIOException(dir);
+                        } catch (IOException ioe) {
+                            throwAsConcurrentModificationException(ioe);
+                        }
+                    }
+                } finally {
+                    readLock().unlock();
+                }
+
+                // EOF
+                if (nameAsBytes == null) {
+                    return null;
+                }
+
+                // ignore "." and ".."
+                if (!isSelfOrParent(nameAsBytes)) {
+                    Path entry = dir.resolve(nameAsBytes);
+
+                    // return entry if no filter or filter accepts it
+                    if (filter.accept(entry)) {
+                        return entry;
+                    }
+                }
+            }
+        }
+
+        @Override
+        public synchronized boolean hasNext() {
+            if (nextEntry == null && !atEof) {
+                nextEntry = readNextEntry();
+
+                // at EOF?
+                if (nextEntry == null)
+                    atEof = true;
+            }
+            return nextEntry != null;
+        }
+
+        @Override
+        public synchronized Path next() {
+            if (nextEntry == null) {
+                if (!atEof) {
+                    nextEntry = readNextEntry();
+                }
+                if (nextEntry == null) {
+                    atEof = true;
+                    throw new NoSuchElementException();
+                }
+            }
+            prevEntry = nextEntry;
+            nextEntry = null;
+            return prevEntry;
+        }
+
+        @Override
+        public void remove() {
+            if (isClosed) {
+                throw new ClosedDirectoryStreamException();
+            }
+            Path entry;
+            synchronized (this) {
+                if (prevEntry == null)
+                    throw new IllegalStateException("No previous entry to remove");
+                entry = prevEntry;
+                prevEntry = null;
+            }
+
+            // use (race-free) unlinkat if available
+            try {
+                if (stream instanceof UnixSecureDirectoryStream) {
+                    ((UnixSecureDirectoryStream)stream)
+                        .implDelete(entry.getName(), false, 0);
+                } else {
+                    entry.delete(true);
+                }
+            } catch (IOException ioe) {
+                throwAsConcurrentModificationException(ioe);
+            } catch (SecurityException se) {
+                throwAsConcurrentModificationException(se);
+            }
+        }
+    }
+
+    private static void throwAsConcurrentModificationException(Throwable t) {
+        ConcurrentModificationException cme = new ConcurrentModificationException();
+        cme.initCause(t);
+        throw cme;
+    }
+
+}
diff --git a/jdk/src/solaris/classes/sun/nio/fs/UnixException.java b/jdk/src/solaris/classes/sun/nio/fs/UnixException.java
new file mode 100644
index 0000000..3a99675
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixException.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.*;
+import java.io.IOException;
+
+/**
+ * Internal exception thrown by native methods when error detected.
+ */
+
+class UnixException extends Exception {
+    static final long serialVersionUID = 7227016794320723218L;
+
+    private int errno;
+    private String msg;
+
+    UnixException(int errno) {
+        this.errno = errno;
+        this.msg = null;
+    }
+
+    UnixException(String msg) {
+        this.errno = 0;
+        this.msg = msg;
+    }
+
+    int errno() {
+        return errno;
+    }
+
+    void setError(int errno) {
+        this.errno = errno;
+        this.msg = null;
+    }
+
+    String errorString() {
+        if (msg != null) {
+            return msg;
+        } else {
+            return new String(UnixNativeDispatcher.strerror(errno()));
+        }
+    }
+
+    @Override
+    public String getMessage() {
+        return errorString();
+    }
+
+    /**
+     * Map well known errors to specific exceptions where possible; otherwise
+     * return more general FileSystemException.
+     */
+    private IOException translateToIOException(String file, String other) {
+        // created with message rather than errno
+        if (msg != null)
+            return new IOException(msg);
+
+        // handle specific cases
+        if (errno() == UnixConstants.EACCES)
+            return new AccessDeniedException(file, other, null);
+        if (errno() == UnixConstants.ENOENT)
+            return new NoSuchFileException(file, other, null);
+        if (errno() == UnixConstants.EEXIST)
+            return new FileAlreadyExistsException(file, other, null);
+
+        // fallback to the more general exception
+        return new FileSystemException(file, other, errorString());
+    }
+
+    void rethrowAsIOException(String file) throws IOException {
+        IOException x = translateToIOException(file, null);
+        throw x;
+    }
+
+    void rethrowAsIOException(UnixPath file, UnixPath other) throws IOException {
+        String a = (file == null) ? null : file.getPathForExecptionMessage();
+        String b = (other == null) ? null : other.getPathForExecptionMessage();
+        IOException x = translateToIOException(a, b);
+        throw x;
+    }
+
+    void rethrowAsIOException(UnixPath file) throws IOException {
+        rethrowAsIOException(file, null);
+    }
+
+    IOException asIOException(UnixPath file) {
+        return translateToIOException(file.getPathForExecptionMessage(), null);
+    }
+}
diff --git a/jdk/src/solaris/classes/sun/nio/fs/UnixFileAttributeViews.java b/jdk/src/solaris/classes/sun/nio/fs/UnixFileAttributeViews.java
new file mode 100644
index 0000000..7bbf925
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixFileAttributeViews.java
@@ -0,0 +1,392 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import java.io.IOException;
+
+import static sun.nio.fs.UnixNativeDispatcher.*;
+
+class UnixFileAttributeViews {
+
+    static class Basic extends AbstractBasicFileAttributeView {
+        protected final UnixPath file;
+        protected final boolean followLinks;
+
+        Basic(UnixPath file, boolean followLinks) {
+            this.file = file;
+            this.followLinks = followLinks;
+        }
+
+        @Override
+        public BasicFileAttributes readAttributes() throws IOException {
+            file.checkRead();
+            try {
+                 UnixFileAttributes attrs =
+                     UnixFileAttributes.get(file, followLinks);
+                 return attrs.asBasicFileAttributes();
+            } catch (UnixException x) {
+                x.rethrowAsIOException(file);
+                return null;    // keep compiler happy
+            }
+        }
+        @Override
+        public void setTimes(Long lastModifiedTime,
+                             Long lastAccessTime,
+                             Long createTime,
+                             TimeUnit unit) throws IOException
+        {
+            // null => don't change
+            if (lastModifiedTime == null && lastAccessTime == null) {
+                // no effect
+                return;
+            }
+
+            file.checkWrite();
+
+            int fd = file.openForAttributeAccess(followLinks);
+            try {
+                UnixFileAttributes attrs = null;
+
+                // if not changing both attributes then need existing attributes
+                if (lastModifiedTime == null || lastAccessTime == null) {
+                    try {
+                        attrs = UnixFileAttributes.get(fd);
+                    } catch (UnixException x) {
+                        x.rethrowAsIOException(file);
+                    }
+                }
+
+                // modified time = existing, now, or new value
+                long modTime;
+                if (lastModifiedTime == null) {
+                    modTime = attrs.lastModifiedTime();
+                } else {
+                    if (lastModifiedTime >= 0L) {
+                        modTime = TimeUnit.MILLISECONDS.convert(lastModifiedTime, unit);
+                    } else {
+                        if (lastModifiedTime != -1L)
+                            throw new IllegalArgumentException();
+                        modTime = System.currentTimeMillis();
+                    }
+                }
+
+                // access time = existing, now, or new value
+                long accTime;
+                if (lastAccessTime == null) {
+                    accTime = attrs.lastAccessTime();
+                } else {
+                    if (lastAccessTime >= 0L) {
+                        accTime = TimeUnit.MILLISECONDS.convert(lastAccessTime, unit);
+                    } else {
+                        if (lastAccessTime != -1L)
+                            throw new IllegalArgumentException();
+                        accTime = System.currentTimeMillis();
+                    }
+                }
+
+                try {
+                    futimes(fd, accTime, modTime);
+                } catch (UnixException x) {
+                    x.rethrowAsIOException(file);
+                }
+            } finally {
+                close(fd);
+            }
+        }
+    }
+
+    private static class Posix extends Basic implements PosixFileAttributeView {
+        private static final String PERMISSIONS_NAME = "permissions";
+        private static final String OWNER_NAME = "owner";
+        private static final String GROUP_NAME = "group";
+
+        Posix(UnixPath file, boolean followLinks) {
+            super(file, followLinks);
+        }
+
+        final void checkReadExtended() {
+            SecurityManager sm = System.getSecurityManager();
+            if (sm != null) {
+                file.checkRead();
+                sm.checkPermission(new RuntimePermission("accessUserInformation"));
+            }
+        }
+
+        final void checkWriteExtended() {
+            SecurityManager sm = System.getSecurityManager();
+            if (sm != null) {
+                file.checkWrite();
+                sm.checkPermission(new RuntimePermission("accessUserInformation"));
+            }
+        }
+
+        @Override
+        public String name() {
+            return "posix";
+        }
+
+        @Override
+        public Object getAttribute(String attribute) throws IOException {
+            if (attribute.equals(PERMISSIONS_NAME))
+                return readAttributes().permissions();
+            if (attribute.equals(OWNER_NAME))
+                return readAttributes().owner();
+            if (attribute.equals(GROUP_NAME))
+                return readAttributes().group();
+            return super.getAttribute(attribute);
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public void setAttribute(String attribute, Object value)
+            throws IOException
+        {
+            if (attribute.equals(PERMISSIONS_NAME)) {
+                setPermissions((Set<PosixFilePermission>)value);
+                return;
+            }
+            if (attribute.equals(OWNER_NAME)) {
+                setOwner((UserPrincipal)value);
+                return;
+            }
+            if (attribute.equals(GROUP_NAME)) {
+                setGroup((GroupPrincipal)value);
+                return;
+            }
+            super.setAttribute(attribute, value);
+        }
+
+        /**
+         * Invoked by readAttributes or sub-classes to add all matching posix
+         * attributes to the builder
+         */
+        final void addPosixAttributesToBuilder(PosixFileAttributes attrs,
+                                               AttributesBuilder builder)
+        {
+            if (builder.match(PERMISSIONS_NAME))
+                builder.add(PERMISSIONS_NAME, attrs.permissions());
+            if (builder.match(OWNER_NAME))
+                 builder.add(OWNER_NAME, attrs.owner());
+            if (builder.match(GROUP_NAME))
+                builder.add(GROUP_NAME, attrs.group());
+        }
+
+        @Override
+        public Map<String,?> readAttributes(String first, String[] rest)
+            throws IOException
+        {
+            AttributesBuilder builder = AttributesBuilder.create(first, rest);
+            PosixFileAttributes attrs = readAttributes();
+            addBasicAttributesToBuilder(attrs, builder);
+            addPosixAttributesToBuilder(attrs, builder);
+            return builder.unmodifiableMap();
+        }
+
+        @Override
+        public UnixFileAttributes readAttributes() throws IOException {
+            checkReadExtended();
+            try {
+                 return UnixFileAttributes.get(file, followLinks);
+            } catch (UnixException x) {
+                x.rethrowAsIOException(file);
+                return null;    // keep compiler happy
+            }
+        }
+
+        // chmod
+        final void setMode(int mode) throws IOException {
+            checkWriteExtended();
+            try {
+                if (followLinks) {
+                    chmod(file, mode);
+                } else {
+                    int fd = file.openForAttributeAccess(false);
+                    try {
+                        fchmod(fd, mode);
+                    } finally {
+                        close(fd);
+                    }
+                }
+            } catch (UnixException x) {
+                x.rethrowAsIOException(file);
+            }
+        }
+
+        // chown
+        final void setOwners(int uid, int gid) throws IOException {
+            checkWriteExtended();
+            try {
+                if (followLinks) {
+                    chown(file, uid, gid);
+                } else {
+                    lchown(file, uid, gid);
+                }
+            } catch (UnixException x) {
+                x.rethrowAsIOException(file);
+            }
+        }
+
+        @Override
+        public void setPermissions(Set<PosixFilePermission> perms)
+            throws IOException
+        {
+            setMode(UnixFileModeAttribute.toUnixMode(perms));
+        }
+
+        @Override
+        public void setOwner(UserPrincipal owner)
+            throws IOException
+        {
+            if (owner == null)
+                throw new NullPointerException("'owner' is null");
+            if (!(owner instanceof UnixUserPrincipals.User))
+                throw new ProviderMismatchException();
+            if (owner instanceof UnixUserPrincipals.Group)
+                throw new IOException("'owner' parameter can't be a group");
+            int uid = ((UnixUserPrincipals.User)owner).uid();
+            setOwners(uid, -1);
+        }
+
+        @Override
+        public UserPrincipal getOwner() throws IOException {
+            return readAttributes().owner();
+        }
+
+        @Override
+        public void setGroup(GroupPrincipal group)
+            throws IOException
+        {
+            if (group == null)
+                throw new NullPointerException("'owner' is null");
+            if (!(group instanceof UnixUserPrincipals.Group))
+                throw new ProviderMismatchException();
+            int gid = ((UnixUserPrincipals.Group)group).gid();
+            setOwners(-1, gid);
+        }
+    }
+
+    private static class Unix extends Posix {
+        private static final String MODE_NAME = "mode";
+        private static final String INO_NAME = "ino";
+        private static final String DEV_NAME = "dev";
+        private static final String RDEV_NAME = "rdev";
+        private static final String UID_NAME = "uid";
+        private static final String GID_NAME = "gid";
+        private static final String CTIME_NAME = "ctime";
+
+        Unix(UnixPath file, boolean followLinks) {
+            super(file, followLinks);
+        }
+
+        @Override
+        public String name() {
+            return "unix";
+        }
+
+        @Override
+        public Object getAttribute(String attribute) throws IOException {
+            if (attribute.equals(MODE_NAME))
+                return readAttributes().mode();
+            if (attribute.equals(INO_NAME))
+                return readAttributes().ino();
+            if (attribute.equals(DEV_NAME))
+                return readAttributes().dev();
+            if (attribute.equals(RDEV_NAME))
+                return readAttributes().rdev();
+            if (attribute.equals(UID_NAME))
+                return readAttributes().uid();
+            if (attribute.equals(GID_NAME))
+                return readAttributes().gid();
+            if (attribute.equals(CTIME_NAME))
+                return readAttributes().ctime();
+            return super.getAttribute(attribute);
+        }
+
+        @Override
+        public void setAttribute(String attribute, Object value)
+            throws IOException
+        {
+            if (attribute.equals(MODE_NAME)) {
+                setMode((Integer)value);
+                return;
+            }
+            if (attribute.equals(UID_NAME)) {
+                setOwners((Integer)value, -1);
+                return;
+            }
+            if (attribute.equals(GID_NAME)) {
+                setOwners(-1, (Integer)value);
+                return;
+            }
+            super.setAttribute(attribute, value);
+        }
+
+        @Override
+        public Map<String,?> readAttributes(String first, String[] rest)
+            throws IOException
+        {
+            AttributesBuilder builder = AttributesBuilder.create(first, rest);
+            UnixFileAttributes attrs = readAttributes();
+            addBasicAttributesToBuilder(attrs, builder);
+            addPosixAttributesToBuilder(attrs, builder);
+            if (builder.match(MODE_NAME))
+                builder.add(MODE_NAME, attrs.mode());
+            if (builder.match(INO_NAME))
+                builder.add(INO_NAME, attrs.ino());
+            if (builder.match(DEV_NAME))
+                builder.add(DEV_NAME, attrs.dev());
+            if (builder.match(RDEV_NAME))
+                builder.add(RDEV_NAME, attrs.rdev());
+            if (builder.match(UID_NAME))
+                builder.add(UID_NAME, attrs.uid());
+            if (builder.match(GID_NAME))
+                builder.add(GID_NAME, attrs.gid());
+            if (builder.match(CTIME_NAME))
+                builder.add(CTIME_NAME, attrs.ctime());
+            return builder.unmodifiableMap();
+        }
+    }
+
+    static BasicFileAttributeView createBasicView(UnixPath file, boolean followLinks) {
+        return new Basic(file, followLinks);
+    }
+
+    static PosixFileAttributeView createPosixView(UnixPath file, boolean followLinks) {
+        return new Posix(file, followLinks);
+    }
+
+    static PosixFileAttributeView createUnixView(UnixPath file, boolean followLinks) {
+        return new Unix(file, followLinks);
+    }
+
+    static FileOwnerAttributeView createOwnerView(UnixPath file, boolean followLinks) {
+        return new FileOwnerAttributeViewImpl(createPosixView(file, followLinks));
+    }
+}
diff --git a/jdk/src/solaris/classes/sun/nio/fs/UnixFileAttributes.java b/jdk/src/solaris/classes/sun/nio/fs/UnixFileAttributes.java
new file mode 100644
index 0000000..c1882d7
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixFileAttributes.java
@@ -0,0 +1,307 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.attribute.*;
+import java.util.concurrent.TimeUnit;
+import java.util.Set;
+import java.util.HashSet;
+
+/**
+ * Unix implementation of PosixFileAttributes.
+ */
+
+class UnixFileAttributes
+    implements PosixFileAttributes
+{
+    private int     st_mode;
+    private long    st_ino;
+    private long    st_dev;
+    private long    st_rdev;
+    private int     st_nlink;
+    private int     st_uid;
+    private int     st_gid;
+    private long    st_size;
+    private long    st_atime;
+    private long    st_mtime;
+    private long    st_ctime;
+
+    // created lazily
+    private volatile UserPrincipal owner;
+    private volatile GroupPrincipal group;
+    private volatile UnixFileKey key;
+
+    private UnixFileAttributes() {
+    }
+
+    // get the UnixFileAttributes for a given file
+    static UnixFileAttributes get(UnixPath path, boolean followLinks)
+        throws UnixException
+    {
+        UnixFileAttributes attrs = new UnixFileAttributes();
+        if (followLinks) {
+            UnixNativeDispatcher.stat(path, attrs);
+        } else {
+            UnixNativeDispatcher.lstat(path, attrs);
+        }
+        return attrs;
+    }
+
+    // get the UnixFileAttributes for an open file
+    static UnixFileAttributes get(int fd) throws UnixException {
+        UnixFileAttributes attrs = new UnixFileAttributes();
+        UnixNativeDispatcher.fstat(fd, attrs);
+        return attrs;
+    }
+
+    // get the UnixFileAttributes for a given file, relative to open directory
+    static UnixFileAttributes get(int dfd, UnixPath path, boolean followLinks)
+        throws UnixException
+    {
+        UnixFileAttributes attrs = new UnixFileAttributes();
+        int flag = (followLinks) ? 0 : UnixConstants.AT_SYMLINK_NOFOLLOW;
+        UnixNativeDispatcher.fstatat(dfd, path.asByteArray(), flag, attrs);
+        return attrs;
+    }
+
+    // package-private
+    boolean isSameFile(UnixFileAttributes attrs) {
+        return ((st_ino == attrs.st_ino) && (st_dev == attrs.st_dev));
+    }
+
+    // package-private
+    int mode()  { return st_mode; }
+    long ino()  { return st_ino; }
+    long dev()  { return st_dev; }
+    long rdev() { return st_rdev; }
+    int uid()   { return st_uid; }
+    int gid()   { return st_gid; }
+    long ctime() { return st_ctime; }
+
+    boolean isDevice() {
+        int type = st_mode & UnixConstants.S_IFMT;
+        return (type == UnixConstants.S_IFCHR ||
+                type == UnixConstants.S_IFBLK  ||
+                type == UnixConstants.S_IFIFO);
+    }
+
+    @Override
+    public long lastModifiedTime() {
+        return st_mtime;
+    }
+
+    @Override
+    public long lastAccessTime() {
+        return st_atime;
+    }
+
+    @Override
+    public long creationTime() {
+        return -1L;
+    }
+
+    @Override
+    public TimeUnit resolution() {
+        return TimeUnit.MILLISECONDS;
+    }
+
+    @Override
+    public boolean isRegularFile() {
+       return ((st_mode & UnixConstants.S_IFMT) == UnixConstants.S_IFREG);
+    }
+
+    @Override
+    public boolean isDirectory() {
+        return ((st_mode & UnixConstants.S_IFMT) == UnixConstants.S_IFDIR);
+    }
+
+    @Override
+    public boolean isSymbolicLink() {
+        return ((st_mode & UnixConstants.S_IFMT) == UnixConstants.S_IFLNK);
+    }
+
+    @Override
+    public boolean isOther() {
+        int type = st_mode & UnixConstants.S_IFMT;
+        return (type != UnixConstants.S_IFREG &&
+                type != UnixConstants.S_IFDIR &&
+                type != UnixConstants.S_IFLNK);
+    }
+
+    @Override
+    public long size() {
+        return st_size;
+    }
+
+    @Override
+    public int linkCount() {
+        return st_nlink;
+    }
+
+    @Override
+    public UnixFileKey fileKey() {
+        if (key == null) {
+            synchronized (this) {
+                if (key == null) {
+                    key = new UnixFileKey(st_dev, st_ino);
+                }
+            }
+        }
+        return key;
+    }
+
+    @Override
+    public UserPrincipal owner() {
+        if (owner == null) {
+            synchronized (this) {
+                if (owner == null) {
+                    owner = UnixUserPrincipals.fromUid(st_uid);
+                }
+            }
+        }
+        return owner;
+    }
+
+    @Override
+    public GroupPrincipal group() {
+        if (group == null) {
+            synchronized (this) {
+                if (group == null) {
+                    group = UnixUserPrincipals.fromGid(st_gid);
+                }
+            }
+        }
+        return group;
+    }
+
+    @Override
+    public Set<PosixFilePermission> permissions() {
+        int bits = (st_mode & UnixConstants.S_IAMB);
+        HashSet<PosixFilePermission> perms = new HashSet<PosixFilePermission>();
+
+        if ((bits & UnixConstants.S_IRUSR) > 0)
+            perms.add(PosixFilePermission.OWNER_READ);
+        if ((bits & UnixConstants.S_IWUSR) > 0)
+            perms.add(PosixFilePermission.OWNER_WRITE);
+        if ((bits & UnixConstants.S_IXUSR) > 0)
+            perms.add(PosixFilePermission.OWNER_EXECUTE);
+
+        if ((bits & UnixConstants.S_IRGRP) > 0)
+            perms.add(PosixFilePermission.GROUP_READ);
+        if ((bits & UnixConstants.S_IWGRP) > 0)
+            perms.add(PosixFilePermission.GROUP_WRITE);
+        if ((bits & UnixConstants.S_IXGRP) > 0)
+            perms.add(PosixFilePermission.GROUP_EXECUTE);
+
+        if ((bits & UnixConstants.S_IROTH) > 0)
+            perms.add(PosixFilePermission.OTHERS_READ);
+        if ((bits & UnixConstants.S_IWOTH) > 0)
+            perms.add(PosixFilePermission.OTHERS_WRITE);
+        if ((bits & UnixConstants.S_IXOTH) > 0)
+            perms.add(PosixFilePermission.OTHERS_EXECUTE);
+
+        return perms;
+    }
+
+    // wrap this object with BasicFileAttributes object to prevent leaking of
+    // user information
+    BasicFileAttributes asBasicFileAttributes() {
+        return UnixAsBasicFileAttributes.wrap(this);
+    }
+
+    // unwrap BasicFileAttributes to get the underlying UnixFileAttributes
+    // object. Returns null is not wrapped.
+    static UnixFileAttributes toUnixFileAttributes(BasicFileAttributes attrs) {
+        if (attrs instanceof UnixFileAttributes)
+            return (UnixFileAttributes)attrs;
+        if (attrs instanceof UnixAsBasicFileAttributes) {
+            return ((UnixAsBasicFileAttributes)attrs).unwrap();
+        }
+        return null;
+    }
+
+    // wrap a UnixFileAttributes object as a BasicFileAttributes
+    private static class UnixAsBasicFileAttributes implements BasicFileAttributes {
+        private final UnixFileAttributes attrs;
+
+        private UnixAsBasicFileAttributes(UnixFileAttributes attrs) {
+            this.attrs = attrs;
+        }
+
+        static UnixAsBasicFileAttributes wrap(UnixFileAttributes attrs) {
+            return new UnixAsBasicFileAttributes(attrs);
+        }
+
+        UnixFileAttributes unwrap() {
+            return attrs;
+        }
+
+        @Override
+        public long lastModifiedTime() {
+            return attrs.lastModifiedTime();
+        }
+        @Override
+        public long lastAccessTime() {
+            return attrs.lastAccessTime();
+        }
+        @Override
+        public long creationTime() {
+            return attrs.creationTime();
+        }
+        @Override
+        public TimeUnit resolution() {
+            return attrs.resolution();
+        }
+        @Override
+        public boolean isRegularFile() {
+            return attrs.isRegularFile();
+        }
+        @Override
+        public boolean isDirectory() {
+            return attrs.isDirectory();
+        }
+        @Override
+        public boolean isSymbolicLink() {
+            return attrs.isSymbolicLink();
+        }
+        @Override
+        public boolean isOther() {
+            return attrs.isOther();
+        }
+        @Override
+        public long size() {
+            return attrs.size();
+        }
+        @Override
+        public int linkCount() {
+            return attrs.linkCount();
+        }
+        @Override
+        public Object fileKey() {
+            return attrs.fileKey();
+        }
+    }
+}
diff --git a/jdk/src/solaris/classes/sun/nio/fs/UnixFileKey.java b/jdk/src/solaris/classes/sun/nio/fs/UnixFileKey.java
new file mode 100644
index 0000000..4ab3aec
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixFileKey.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+/**
+ * Container for device/inode to uniquely identify file.
+ */
+
+class UnixFileKey {
+    private final long st_dev;
+    private final long st_ino;
+
+    UnixFileKey(long st_dev, long st_ino) {
+        this.st_dev = st_dev;
+        this.st_ino = st_ino;
+    }
+
+    @Override
+    public int hashCode() {
+        return (int)(st_dev ^ (st_dev >>> 32)) +
+               (int)(st_ino ^ (st_ino >>> 32));
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this)
+            return true;
+        if (!(obj instanceof UnixFileKey))
+            return false;
+        UnixFileKey other = (UnixFileKey)obj;
+        return (this.st_dev == other.st_dev) && (this.st_ino == other.st_ino);
+    }
+}
diff --git a/jdk/src/solaris/classes/sun/nio/fs/UnixFileModeAttribute.java b/jdk/src/solaris/classes/sun/nio/fs/UnixFileModeAttribute.java
new file mode 100644
index 0000000..67ea59e
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixFileModeAttribute.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.attribute.*;
+import java.util.*;
+
+class UnixFileModeAttribute {
+    static final int ALL_PERMISSIONS =
+        UnixConstants.S_IRUSR | UnixConstants.S_IWUSR | UnixConstants.S_IXUSR |
+        UnixConstants.S_IRGRP | UnixConstants.S_IWGRP | UnixConstants.S_IXGRP |
+        UnixConstants.S_IROTH | UnixConstants.S_IWOTH | UnixConstants. S_IXOTH;
+
+    static final int ALL_READWRITE =
+        UnixConstants.S_IRUSR | UnixConstants.S_IWUSR |
+        UnixConstants.S_IRGRP | UnixConstants.S_IWGRP |
+        UnixConstants.S_IROTH | UnixConstants.S_IWOTH;
+
+    static final int TEMPFILE_PERMISSIONS =
+        UnixConstants.S_IRUSR | UnixConstants.S_IWUSR | UnixConstants.S_IXUSR;
+
+    private Set<PosixFilePermission> perms;
+
+    UnixFileModeAttribute() {
+        perms = Collections.emptySet();
+    }
+
+    static int toUnixMode(Set<PosixFilePermission> perms) {
+        int mode = 0;
+        for (PosixFilePermission perm: perms) {
+            if (perm == null)
+                throw new NullPointerException();
+            switch (perm) {
+                case OWNER_READ :     mode |= UnixConstants.S_IRUSR; break;
+                case OWNER_WRITE :    mode |= UnixConstants.S_IWUSR; break;
+                case OWNER_EXECUTE :  mode |= UnixConstants.S_IXUSR; break;
+                case GROUP_READ :     mode |= UnixConstants.S_IRGRP; break;
+                case GROUP_WRITE :    mode |= UnixConstants.S_IWGRP; break;
+                case GROUP_EXECUTE :  mode |= UnixConstants.S_IXGRP; break;
+                case OTHERS_READ :    mode |= UnixConstants.S_IROTH; break;
+                case OTHERS_WRITE :   mode |= UnixConstants.S_IWOTH; break;
+                case OTHERS_EXECUTE : mode |= UnixConstants.S_IXOTH; break;
+            }
+        }
+        return mode;
+    }
+
+    @SuppressWarnings("unchecked")
+    static int toUnixMode(int defaultMode, FileAttribute<?>... attrs) {
+        int mode = defaultMode;
+        for (FileAttribute<?> attr: attrs) {
+            String name = attr.name();
+            if (!name.equals("posix:permissions") && !name.equals("unix:permissions")) {
+                throw new UnsupportedOperationException("'" + attr.name() +
+                   "' not supported as initial attribute");
+            }
+            mode = toUnixMode((Set<PosixFilePermission>)attr.value());
+        }
+        return mode;
+    }
+}
diff --git a/jdk/src/solaris/classes/sun/nio/fs/UnixFileStore.java b/jdk/src/solaris/classes/sun/nio/fs/UnixFileStore.java
new file mode 100644
index 0000000..483a4ea
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixFileStore.java
@@ -0,0 +1,290 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.nio.channels.*;
+import java.util.*;
+import java.io.IOException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * Base implementation of FileStore for Unix/like implementations.
+ */
+
+abstract class UnixFileStore
+    extends FileStore
+{
+    // original path of file that identified file system
+    private final UnixPath file;
+
+    // device ID
+    private final long dev;
+
+    // entry in the mount tab
+    private final UnixMountEntry entry;
+
+    // return the device ID where the given file resides
+    private static long devFor(UnixPath file) throws IOException {
+        try {
+            return UnixFileAttributes.get(file, true).dev();
+        } catch (UnixException x) {
+            x.rethrowAsIOException(file);
+            return 0L;  // keep compiler happy
+        }
+    }
+
+    UnixFileStore(UnixPath file) throws IOException {
+        this.file = file;
+        this.dev = devFor(file);
+        this.entry = findMountEntry();
+    }
+
+    UnixFileStore(UnixFileSystem fs, UnixMountEntry entry) throws IOException {
+        this.file = new UnixPath(fs, entry.dir());
+        this.dev = (entry.dev() == 0L) ? devFor(this.file) : entry.dev();
+        this.entry = entry;
+    }
+
+    /**
+     * Find the mount entry for the file store
+     */
+    abstract UnixMountEntry findMountEntry() throws IOException;
+
+    /**
+     * Returns true if this file store represents a loopback file system that
+     * will have the same device ID as undelrying file system.
+     */
+    abstract boolean isLoopback();
+
+    UnixPath file() {
+        return file;
+    }
+
+    long dev() {
+        return dev;
+    }
+
+    UnixMountEntry entry() {
+        return entry;
+    }
+
+    @Override
+    public String name() {
+        return entry.name();
+    }
+
+    @Override
+    public String type() {
+        return entry.fstype();
+    }
+
+    @Override
+    public boolean isReadOnly() {
+        return entry.isReadOnly();
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public <V extends FileStoreAttributeView> V getFileStoreAttributeView(Class<V> viewType)
+    {
+        if (viewType == FileStoreSpaceAttributeView.class)
+            return (V) new UnixFileStoreSpaceAttributeView(this);
+        return (V) null;
+    }
+
+    @Override
+    public FileStoreAttributeView getFileStoreAttributeView(String name) {
+        if (name.equals("space"))
+            return new UnixFileStoreSpaceAttributeView(this);
+        return  null;
+    }
+
+    @Override
+    public boolean supportsFileAttributeView(Class<? extends FileAttributeView> type) {
+        if (type == BasicFileAttributeView.class)
+            return true;
+        if (type == PosixFileAttributeView.class ||
+            type == FileOwnerAttributeView.class)
+        {
+            // lookup fstypes.properties
+            FeatureStatus status = checkIfFeaturePresent("posix");
+            if (status == FeatureStatus.NOT_PRESENT)
+                return false;
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean supportsFileAttributeView(String name) {
+        if (name.equals("basic") || name.equals("unix"))
+            return true;
+        if (name.equals("posix"))
+            return supportsFileAttributeView(PosixFileAttributeView.class);
+        if (name.equals("owner"))
+            return supportsFileAttributeView(FileOwnerAttributeView.class);
+        return false;
+    }
+
+    @Override
+    public boolean equals(Object ob) {
+        if (ob == this)
+            return true;
+        if (!(ob instanceof UnixFileStore))
+            return false;
+        UnixFileStore other = (UnixFileStore)ob;
+        if (dev != other.dev)
+            return false;
+        // deviceIDs are equal but they may not be equal if one or both of
+        // them is a loopback file system
+        boolean thisIsLoopback = isLoopback();
+        if (thisIsLoopback != other.isLoopback())
+            return false;  // one, but not both, are lofs
+        if (!thisIsLoopback)
+            return true;    // neither is lofs
+        // both are lofs so compare mount points
+        return Arrays.equals(this.entry.dir(), other.entry.dir());
+    }
+
+    @Override
+    public int hashCode() {
+        return (int)(dev ^ (dev >>> 32));
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder(new String(entry.dir()));
+        sb.append(" (");
+        sb.append(entry.name());
+        sb.append(")");
+        return sb.toString();
+    }
+
+    private static class UnixFileStoreSpaceAttributeView
+        extends AbstractFileStoreSpaceAttributeView
+    {
+        private final UnixFileStore fs;
+
+        UnixFileStoreSpaceAttributeView(UnixFileStore fs) {
+            this.fs = fs;
+        }
+
+        @Override
+        public FileStoreSpaceAttributes readAttributes()
+            throws IOException
+        {
+            UnixPath file = fs.file();
+            final UnixFileStoreAttributes attrs;
+            try {
+                attrs = UnixFileStoreAttributes.get(file);
+            } catch (UnixException x) {
+                x.rethrowAsIOException(file);
+                return null;    // keep compile happy
+            }
+
+            return new FileStoreSpaceAttributes() {
+                @Override
+                public long totalSpace() {
+                    return attrs.blockSize() * attrs.totalBlocks();
+                }
+                @Override
+                public long usableSpace() {
+                    return attrs.blockSize() * attrs.availableBlocks();
+                }
+                @Override
+                public long unallocatedSpace() {
+                    return attrs.blockSize() * attrs.freeBlocks();
+                }
+            };
+        }
+    }
+
+    // -- fstypes.properties --
+
+    private static final Object loadLock = new Object();
+    private static volatile Properties props;
+
+    enum FeatureStatus {
+        PRESENT,
+        NOT_PRESENT,
+        UNKNOWN;
+    }
+
+    /**
+     * Returns status to indicate if file system supports a given feature
+     */
+    FeatureStatus checkIfFeaturePresent(String feature) {
+        if (props == null) {
+            synchronized (loadLock) {
+                if (props == null) {
+                    props = AccessController.doPrivileged(
+                        new PrivilegedAction<Properties>() {
+                            @Override
+                            public Properties run() {
+                                return loadProperties();
+                            }});
+                }
+            }
+        }
+
+        String value = props.getProperty(type());
+        if (value != null) {
+            String[] values = value.split("\\s");
+            for (String s: values) {
+                s = s.trim().toLowerCase();
+                if (s.equals(feature)) {
+                    return FeatureStatus.PRESENT;
+                }
+                if (s.startsWith("no")) {
+                    s = s.substring(2);
+                    if (s.equals(feature)) {
+                        return FeatureStatus.NOT_PRESENT;
+                    }
+                }
+            }
+        }
+        return FeatureStatus.UNKNOWN;
+    }
+
+    private static Properties loadProperties() {
+        Properties result = new Properties();
+        String fstypes = System.getProperty("java.home") + "/lib/fstypes.properties";
+        FileRef file = Paths.get(fstypes);
+        try {
+            ReadableByteChannel rbc = file.newByteChannel();
+            try {
+                result.load(Channels.newReader(rbc, "UTF-8"));
+            } finally {
+                rbc.close();
+            }
+        } catch (IOException x) {
+        }
+        return result;
+    }
+}
diff --git a/jdk/src/solaris/classes/sun/nio/fs/UnixFileStoreAttributes.java b/jdk/src/solaris/classes/sun/nio/fs/UnixFileStoreAttributes.java
new file mode 100644
index 0000000..f2cbd17
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixFileStoreAttributes.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+class UnixFileStoreAttributes {
+    private long f_frsize;          // block size
+    private long f_blocks;          // total
+    private long f_bfree;           // free
+    private long f_bavail;          // usable
+
+    private UnixFileStoreAttributes() {
+    }
+
+    static UnixFileStoreAttributes get(UnixPath path) throws UnixException {
+        UnixFileStoreAttributes attrs = new UnixFileStoreAttributes();
+        UnixNativeDispatcher.statvfs(path, attrs);
+        return attrs;
+    }
+
+    long blockSize() {
+        return f_frsize;
+    }
+
+    long totalBlocks() {
+        return f_blocks;
+    }
+
+    long freeBlocks() {
+        return f_bfree;
+    }
+
+    long availableBlocks() {
+        return f_bavail;
+    }
+
+}
diff --git a/jdk/src/solaris/classes/sun/nio/fs/UnixFileSystem.java b/jdk/src/solaris/classes/sun/nio/fs/UnixFileSystem.java
new file mode 100644
index 0000000..6e46b26
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixFileSystem.java
@@ -0,0 +1,380 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.nio.file.spi.*;
+import java.io.IOException;
+import java.util.*;
+import java.util.regex.Pattern;
+import java.security.AccessController;
+import sun.security.action.GetPropertyAction;
+
+/**
+ * Base implementation of FileSystem for Unix-like implementations.
+ */
+
+abstract class UnixFileSystem
+    extends FileSystem
+{
+    private final UnixFileSystemProvider provider;
+    private final byte[] defaultDirectory;
+    private final boolean needToResolveAgainstDefaultDirectory;
+    private final UnixPath rootDirectory;
+
+    // package-private
+    UnixFileSystem(UnixFileSystemProvider provider, String dir) {
+        this.provider = provider;
+        this.defaultDirectory = UnixPath.normalizeAndCheck(dir).getBytes();
+        if (this.defaultDirectory[0] != '/') {
+            throw new RuntimeException("default directory must be absolute");
+        }
+
+        // if process-wide chdir is allowed or default directory is not the
+        // process working directory then paths must be resolved against the
+        // default directory.
+        String propValue = AccessController.doPrivileged(
+            new GetPropertyAction("sun.nio.fs.chdirAllowed", "false"));
+        boolean chdirAllowed = (propValue.length() == 0) ?
+            true : Boolean.valueOf(propValue);
+        if (chdirAllowed) {
+            this.needToResolveAgainstDefaultDirectory = true;
+        } else {
+            byte[] cwd = UnixNativeDispatcher.getcwd();
+            boolean defaultIsCwd = (cwd.length == defaultDirectory.length);
+            if (defaultIsCwd) {
+                for (int i=0; i<cwd.length; i++) {
+                    if (cwd[i] != defaultDirectory[i]) {
+                        defaultIsCwd = false;
+                        break;
+                    }
+                }
+            }
+            this.needToResolveAgainstDefaultDirectory = !defaultIsCwd;
+        }
+
+        // the root directory
+        this.rootDirectory = new UnixPath(this, "/");
+    }
+
+    // package-private
+    byte[] defaultDirectory() {
+        return defaultDirectory;
+    }
+
+    boolean needToResolveAgainstDefaultDirectory() {
+        return needToResolveAgainstDefaultDirectory;
+    }
+
+    UnixPath rootDirectory() {
+        return rootDirectory;
+    }
+
+    boolean isSolaris() {
+        return false;
+    }
+
+    @Override
+    public final FileSystemProvider provider() {
+        return provider;
+    }
+
+    @Override
+    public final String getSeparator() {
+        return "/";
+    }
+
+    @Override
+    public final boolean isOpen() {
+        return true;
+    }
+
+    @Override
+    public final boolean isReadOnly() {
+        return false;
+    }
+
+    @Override
+    public final void close() throws IOException {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Copies non-POSIX attributes from the source to target file.
+     *
+     * Copying a file preserving attributes, or moving a file, will preserve
+     * the file owner/group/permissions/timestamps but it does not preserve
+     * other non-POSIX attributes. This method is invoked by the
+     * copy or move operation to preserve these attributes. It should copy
+     * extended attributes, ACLs, or other attributes.
+     *
+     * @param   sfd
+     *          Open file descriptor to source file
+     * @param   tfd
+     *          Open file descriptor to target file
+     */
+    abstract void copyNonPosixAttributes(int sfd, int tfd);
+
+    /**
+     * Tells if directory relative system calls (openat, etc.) are available
+     * on this operating system.
+     */
+    abstract boolean supportsSecureDirectoryStreams();
+
+    /**
+     * Unix systems only have a single root directory (/)
+     */
+    @Override
+    public final Iterable<Path> getRootDirectories() {
+        final List<Path> allowedList =
+           Collections.unmodifiableList(Arrays.asList((Path)rootDirectory));
+        return new Iterable<Path>() {
+            public Iterator<Path> iterator() {
+                try {
+                    SecurityManager sm = System.getSecurityManager();
+                    if (sm != null)
+                        sm.checkRead(rootDirectory.toString());
+                    return allowedList.iterator();
+                } catch (SecurityException x) {
+                    List<Path> disallowed = Collections.emptyList();
+                    return disallowed.iterator();
+                }
+            }
+        };
+    }
+
+    /**
+     * Returns object to iterate over entries in mounttab or equivalent
+     */
+    abstract Iterable<UnixMountEntry> getMountEntries();
+
+    /**
+     * Returns a FileStore to represent the file system where the given file
+     * reside.
+     */
+    abstract FileStore getFileStore(UnixPath path) throws IOException;
+
+    /**
+     * Returns a FileStore to represent the file system for the given mount
+     * mount.
+     */
+    abstract FileStore getFileStore(UnixMountEntry entry) throws IOException;
+
+    /**
+     * Iterator returned by getFileStores method.
+     */
+    private class FileStoreIterator implements Iterator<FileStore> {
+        private final Iterator<UnixMountEntry> entries;
+        private FileStore next;
+
+        FileStoreIterator() {
+            this.entries = getMountEntries().iterator();
+        }
+
+        private FileStore readNext() {
+            assert Thread.holdsLock(this);
+            for (;;) {
+                if (!entries.hasNext())
+                    return null;
+                UnixMountEntry entry = entries.next();
+
+                // skip entries with the "ignore" option
+                if (entry.isIgnored())
+                    continue;
+
+                // check permission to read mount point
+                SecurityManager sm = System.getSecurityManager();
+                if (sm != null) {
+                    try {
+                        sm.checkRead(new String(entry.dir()));
+                    } catch (SecurityException x) {
+                        continue;
+                    }
+                }
+                try {
+                    return getFileStore(entry);
+                } catch (IOException ignore) {
+                    // ignore as per spec
+                }
+            }
+        }
+
+        @Override
+        public synchronized boolean hasNext() {
+            if (next != null)
+                return true;
+            next = readNext();
+            return next != null;
+        }
+
+        @Override
+        public synchronized FileStore next() {
+            if (next == null)
+                next = readNext();
+            if (next == null) {
+                throw new NoSuchElementException();
+            } else {
+                FileStore result = next;
+                next = null;
+                return result;
+            }
+        }
+
+        @Override
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    @Override
+    public final Iterable<FileStore> getFileStores() {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            try {
+                sm.checkPermission(new RuntimePermission("getFileStoreAttributes"));
+            } catch (SecurityException se) {
+                return Collections.emptyList();
+            }
+        }
+        return new Iterable<FileStore>() {
+            public Iterator<FileStore> iterator() {
+                return new FileStoreIterator();
+            }
+        };
+    }
+
+    @Override
+    public final UnixPath getPath(String path) {
+        return new UnixPath(this, path);
+    }
+
+    @Override
+    public PathMatcher getPathMatcher(String syntaxAndInput) {
+        int pos = syntaxAndInput.indexOf(':');
+        if (pos <= 0 || pos == syntaxAndInput.length())
+            throw new IllegalArgumentException();
+        String syntax = syntaxAndInput.substring(0, pos);
+        String input = syntaxAndInput.substring(pos+1);
+
+        String expr;
+        if (syntax.equals(GLOB_SYNTAX)) {
+            expr = Globs.toUnixRegexPattern(input);
+        } else {
+            if (syntax.equals(REGEX_SYNTAX)) {
+                expr = input;
+            } else {
+                throw new UnsupportedOperationException("Syntax '" + syntax +
+                    "' not recognized");
+            }
+        }
+
+        // return matcher
+        final Pattern pattern = Pattern.compile(expr);
+        return new PathMatcher() {
+            @Override
+            public boolean matches(Path path) {
+                return pattern.matcher(path.toString()).matches();
+            }
+        };
+    }
+    private static final String GLOB_SYNTAX = "glob";
+    private static final String REGEX_SYNTAX = "regex";
+
+    protected boolean followLinks(LinkOption... options) {
+        boolean followLinks = true;
+        for (LinkOption option: options) {
+            if (option == LinkOption.NOFOLLOW_LINKS) {
+                followLinks = false;
+                continue;
+            }
+            if (option == null)
+                throw new NullPointerException();
+            throw new AssertionError("Should not get here");
+        }
+        return followLinks;
+    }
+
+    @SuppressWarnings("unchecked")
+    protected <V extends FileAttributeView> V newFileAttributeView(Class<V> view,
+                                                                   UnixPath file,
+                                                                   LinkOption... options)
+    {
+        if (view == null)
+            throw new NullPointerException();
+        boolean followLinks = followLinks(options);
+        Class<?> c = view;
+        if (c == BasicFileAttributeView.class)
+            return (V) UnixFileAttributeViews.createBasicView(file, followLinks);
+        if (c == PosixFileAttributeView.class)
+            return (V) UnixFileAttributeViews.createPosixView(file, followLinks);
+        if (c == FileOwnerAttributeView.class)
+            return (V) UnixFileAttributeViews.createOwnerView(file, followLinks);
+        return (V) null;
+    }
+
+    static List<String> standardFileAttributeViews() {
+        return Arrays.asList("basic", "posix", "unix", "owner");
+    }
+
+    protected FileAttributeView newFileAttributeView(String name,
+                                                     UnixPath file,
+                                                     LinkOption... options)
+    {
+        boolean followLinks = followLinks(options);
+        if (name.equals("basic"))
+            return UnixFileAttributeViews.createBasicView(file, followLinks);
+        if (name.equals("posix"))
+            return UnixFileAttributeViews.createPosixView(file, followLinks);
+        if (name.equals("unix"))
+            return UnixFileAttributeViews.createUnixView(file, followLinks);
+        if (name.equals("owner"))
+            return UnixFileAttributeViews.createOwnerView(file, followLinks);
+        return null;
+    }
+
+    @Override
+    public final UserPrincipalLookupService getUserPrincipalLookupService() {
+        return theLookupService;
+    }
+
+    private static final UserPrincipalLookupService theLookupService =
+        new UserPrincipalLookupService() {
+            @Override
+            public UserPrincipal lookupPrincipalByName(String name)
+                throws IOException
+            {
+                return UnixUserPrincipals.lookupUser(name);
+            }
+
+            @Override
+            public GroupPrincipal lookupPrincipalByGroupName(String group)
+                throws IOException
+            {
+                return UnixUserPrincipals.lookupGroup(group);
+            }
+        };
+}
diff --git a/jdk/src/solaris/classes/sun/nio/fs/UnixFileSystemProvider.java b/jdk/src/solaris/classes/sun/nio/fs/UnixFileSystemProvider.java
new file mode 100644
index 0000000..878fe25
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixFileSystemProvider.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.nio.file.spi.FileSystemProvider;
+import java.nio.channels.*;
+import java.net.URI;
+import java.util.concurrent.ExecutorService;
+import java.io.IOException;
+import java.util.*;
+
+import sun.nio.ch.ThreadPool;
+
+/**
+ * Base implementation of FileSystemProvider
+ */
+
+public abstract class UnixFileSystemProvider
+    extends FileSystemProvider
+{
+    private static final String USER_DIR = "user.dir";
+    private final UnixFileSystem theFileSystem;
+
+    public UnixFileSystemProvider() {
+        String userDir = System.getProperty(USER_DIR);
+        theFileSystem = newFileSystem(userDir);
+    }
+
+    /**
+     * Constructs a new file system using the given default directory.
+     */
+    abstract UnixFileSystem newFileSystem(String dir);
+
+    @Override
+    public final String getScheme() {
+        return "file";
+    }
+
+    private void checkUri(URI uri) {
+        if (!uri.getScheme().equalsIgnoreCase(getScheme()))
+            throw new IllegalArgumentException("URI does not match this provider");
+        if (uri.getAuthority() != null)
+            throw new IllegalArgumentException("Authority component present");
+        if (uri.getPath() == null)
+            throw new IllegalArgumentException("Path component is undefined");
+        if (!uri.getPath().equals("/"))
+            throw new IllegalArgumentException("Path component should be '/'");
+        if (uri.getQuery() != null)
+            throw new IllegalArgumentException("Query component present");
+        if (uri.getFragment() != null)
+            throw new IllegalArgumentException("Fragment component present");
+    }
+
+    @Override
+    public final FileSystem newFileSystem(URI uri, Map<String,?> env) {
+        checkUri(uri);
+        throw new FileSystemAlreadyExistsException();
+    }
+
+    @Override
+    public final FileSystem getFileSystem(URI uri) {
+        checkUri(uri);
+        return theFileSystem;
+    }
+
+    @Override
+    public Path getPath(URI uri) {
+        return UnixUriUtils.fromUri(theFileSystem, uri);
+    }
+
+    private UnixPath checkPath(Path obj) {
+        if (obj == null)
+            throw new NullPointerException();
+        if (!(obj instanceof UnixPath))
+            throw new ProviderMismatchException();
+        return (UnixPath)obj;
+    }
+
+    @Override
+    public final FileChannel newFileChannel(Path obj,
+                                            Set<? extends OpenOption> options,
+                                            FileAttribute<?>... attrs)
+        throws IOException
+    {
+        UnixPath file = checkPath(obj);
+        int mode = UnixFileModeAttribute
+            .toUnixMode(UnixFileModeAttribute.ALL_READWRITE, attrs);
+        try {
+            return UnixChannelFactory.newFileChannel(file, options, mode);
+        } catch (UnixException x) {
+            x.rethrowAsIOException(file);
+            return null;
+        }
+    }
+
+    @Override
+    public final AsynchronousFileChannel newAsynchronousFileChannel(Path obj,
+                                                                    Set<? extends OpenOption> options,
+                                                                    ExecutorService executor,
+                                                                    FileAttribute<?>... attrs) throws IOException
+    {
+        UnixPath file = checkPath(obj);
+        int mode = UnixFileModeAttribute
+            .toUnixMode(UnixFileModeAttribute.ALL_READWRITE, attrs);
+        ThreadPool pool = (executor == null) ? null : ThreadPool.wrap(executor, 0);
+        try {
+            return UnixChannelFactory
+                .newAsynchronousFileChannel(file, options, mode, pool);
+        } catch (UnixException x) {
+            x.rethrowAsIOException(file);
+            return null;
+        }
+    }
+}
diff --git a/jdk/src/solaris/classes/sun/nio/fs/UnixMountEntry.java b/jdk/src/solaris/classes/sun/nio/fs/UnixMountEntry.java
new file mode 100644
index 0000000..c4769e7
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixMountEntry.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+/**
+ * Represents an entry in the mount table.
+ */
+
+class UnixMountEntry {
+    private byte[] name;        // file system name
+    private byte[] dir;         // directory (mount point)
+    private byte[] fstype;      // ufs, nfs, ...
+    private byte[] opts;        // mount options
+    private long dev;           // device ID
+
+    private volatile String fstypeAsString;
+    private volatile String optionsAsString;
+
+    UnixMountEntry() {
+    }
+
+    String name() {
+        return new String(name);
+    }
+
+    String fstype() {
+        if (fstypeAsString == null)
+            fstypeAsString = new String(fstype);
+        return fstypeAsString;
+    }
+
+    byte[] dir() {
+        return dir;
+    }
+
+    long dev() {
+        return dev;
+    }
+
+    /**
+     * Tells whether the mount entry has the given option.
+     */
+    boolean hasOption(String requested) {
+        if (optionsAsString == null)
+            optionsAsString = new String(opts);
+        for (String opt: optionsAsString.split("\\,", 0)) {
+            if (opt.equals(requested))
+                return true;
+        }
+        return false;
+    }
+
+    // generic option
+    boolean isIgnored() {
+        return hasOption("ignore");
+    }
+
+    // generic option
+    boolean isReadOnly() {
+        return hasOption("ro");
+    }
+}
diff --git a/jdk/src/solaris/classes/sun/nio/fs/UnixNativeDispatcher.java b/jdk/src/solaris/classes/sun/nio/fs/UnixNativeDispatcher.java
new file mode 100644
index 0000000..29140e3
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixNativeDispatcher.java
@@ -0,0 +1,556 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * Unix system and library calls.
+ */
+
+class UnixNativeDispatcher {
+    protected UnixNativeDispatcher() { }
+
+    // returns a NativeBuffer containing the given path
+    private static NativeBuffer copyToNativeBuffer(UnixPath path) {
+        byte[] cstr = path.getByteArrayForSysCalls();
+        int size = cstr.length + 1;
+        NativeBuffer buffer = NativeBuffers.getNativeBufferFromCache(size);
+        if (buffer == null) {
+            buffer = NativeBuffers.allocNativeBuffer(size);
+        } else {
+            // buffer already contains the path
+            if (buffer.owner() == path)
+                return buffer;
+        }
+        NativeBuffers.copyCStringToNativeBuffer(cstr, buffer);
+        buffer.setOwner(path);
+        return buffer;
+    }
+
+    /**
+     * char *getcwd(char *buf, size_t size);
+     */
+    static native byte[] getcwd();
+
+    /**
+     * int dup(int filedes)
+     */
+    static native int dup(int filedes) throws UnixException;
+
+    /**
+     * int open(const char* path, int oflag, mode_t mode)
+     */
+    static int open(UnixPath path, int flags, int mode) throws UnixException {
+        NativeBuffer buffer = copyToNativeBuffer(path);
+        try {
+            return open0(buffer.address(), flags, mode);
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native int open0(long pathAddress, int flags, int mode)
+        throws UnixException;
+
+    /**
+     * int openat(int dfd, const char* path, int oflag, mode_t mode)
+     */
+    static int openat(int dfd, byte[] path, int flags, int mode) throws UnixException {
+        NativeBuffer buffer = NativeBuffers.asNativeBuffer(path);
+        try {
+            return openat0(dfd, buffer.address(), flags, mode);
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native int openat0(int dfd, long pathAddress, int flags, int mode)
+        throws UnixException;
+
+    /**
+     * close(int filedes)
+     */
+    static native void close(int fd);
+
+    /**
+     * FILE* fopen(const char *filename, const char* mode);
+     */
+    static long fopen(UnixPath filename, String mode) throws UnixException {
+        NativeBuffer pathBuffer = copyToNativeBuffer(filename);
+        NativeBuffer modeBuffer = NativeBuffers.asNativeBuffer(mode.getBytes());
+        try {
+            return fopen0(pathBuffer.address(), modeBuffer.address());
+        } finally {
+            modeBuffer.release();
+            pathBuffer.release();
+        }
+    }
+    private static native long fopen0(long pathAddress, long modeAddress)
+        throws UnixException;
+
+    /**
+     * fclose(FILE* stream)
+     */
+    static native void fclose(long stream) throws UnixException;
+
+    /**
+     * link(const char* existing, const char* new)
+     */
+    static void link(UnixPath existing, UnixPath newfile) throws UnixException {
+        NativeBuffer existingBuffer = copyToNativeBuffer(existing);
+        NativeBuffer newBuffer = copyToNativeBuffer(newfile);
+        try {
+            link0(existingBuffer.address(), newBuffer.address());
+        } finally {
+            newBuffer.release();
+            existingBuffer.release();
+        }
+    }
+    private static native void link0(long existingAddress, long newAddress)
+        throws UnixException;
+
+    /**
+     * unlink(const char* path)
+     */
+    static void unlink(UnixPath path) throws UnixException {
+        NativeBuffer buffer = copyToNativeBuffer(path);
+        try {
+            unlink0(buffer.address());
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native void unlink0(long pathAddress) throws UnixException;
+
+    /**
+     * unlinkat(int dfd, const char* path, int flag)
+     */
+    static void unlinkat(int dfd, byte[] path, int flag) throws UnixException {
+        NativeBuffer buffer = NativeBuffers.asNativeBuffer(path);
+        try {
+            unlinkat0(dfd, buffer.address(), flag);
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native void unlinkat0(int dfd, long pathAddress, int flag)
+        throws UnixException;
+
+    /**
+     * mknod(const char* path, mode_t mode, dev_t dev)
+     */
+    static void mknod(UnixPath path, int mode, long dev) throws UnixException {
+        NativeBuffer buffer = copyToNativeBuffer(path);
+        try {
+            mknod0(buffer.address(), mode, dev);
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native void mknod0(long pathAddress, int mode, long dev)
+        throws UnixException;
+
+    /**
+     *  rename(const char* old, const char* new)
+     */
+    static void rename(UnixPath from, UnixPath to) throws UnixException {
+        NativeBuffer fromBuffer = copyToNativeBuffer(from);
+        NativeBuffer toBuffer = copyToNativeBuffer(to);
+        try {
+            rename0(fromBuffer.address(), toBuffer.address());
+        } finally {
+            toBuffer.release();
+            fromBuffer.release();
+        }
+    }
+    private static native void rename0(long fromAddress, long toAddress)
+        throws UnixException;
+
+    /**
+     *  renameat(int fromfd, const char* old, int tofd, const char* new)
+     */
+    static void renameat(int fromfd, byte[] from, int tofd, byte[] to) throws UnixException {
+        NativeBuffer fromBuffer = NativeBuffers.asNativeBuffer(from);
+        NativeBuffer toBuffer = NativeBuffers.asNativeBuffer(to);
+        try {
+            renameat0(fromfd, fromBuffer.address(), tofd, toBuffer.address());
+        } finally {
+            toBuffer.release();
+            fromBuffer.release();
+        }
+    }
+    private static native void renameat0(int fromfd, long fromAddress, int tofd, long toAddress)
+        throws UnixException;
+
+    /**
+     * mkdir(const char* path, mode_t mode)
+     */
+    static void mkdir(UnixPath path, int mode) throws UnixException {
+        NativeBuffer buffer = copyToNativeBuffer(path);
+        try {
+            mkdir0(buffer.address(), mode);
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native void mkdir0(long pathAddress, int mode) throws UnixException;
+
+    /**
+     * rmdir(const char* path)
+     */
+    static void rmdir(UnixPath path) throws UnixException {
+        NativeBuffer buffer = copyToNativeBuffer(path);
+        try {
+            rmdir0(buffer.address());
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native void rmdir0(long pathAddress) throws UnixException;
+
+    /**
+     * readlink(const char* path, char* buf, size_t bufsize)
+     *
+     * @return  link target
+     */
+    static byte[] readlink(UnixPath path) throws UnixException {
+        NativeBuffer buffer = copyToNativeBuffer(path);
+        try {
+            return readlink0(buffer.address());
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native byte[] readlink0(long pathAddress) throws UnixException;
+
+    /**
+     * realpath(const char* path, char* resolved_name)
+     *
+     * @return  resolved path
+     */
+    static byte[] realpath(UnixPath path) throws UnixException {
+        NativeBuffer buffer = copyToNativeBuffer(path);
+        try {
+            return realpath0(buffer.address());
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native byte[] realpath0(long pathAddress) throws UnixException;
+
+    /**
+     * symlink(const char* name1, const char* name2)
+     */
+    static void symlink(byte[] name1, UnixPath name2) throws UnixException {
+        NativeBuffer targetBuffer = NativeBuffers.asNativeBuffer(name1);
+        NativeBuffer linkBuffer = copyToNativeBuffer(name2);
+        try {
+            symlink0(targetBuffer.address(), linkBuffer.address());
+        } finally {
+            linkBuffer.release();
+            targetBuffer.release();
+        }
+    }
+    private static native void symlink0(long name1, long name2)
+        throws UnixException;
+
+    /**
+     * stat(const char* path, struct stat* buf)
+     */
+    static void stat(UnixPath path, UnixFileAttributes attrs) throws UnixException {
+        NativeBuffer buffer = copyToNativeBuffer(path);
+        try {
+            stat0(buffer.address(), attrs);
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native void stat0(long pathAddress, UnixFileAttributes attrs)
+        throws UnixException;
+
+    /**
+     * lstat(const char* path, struct stat* buf)
+     */
+    static void lstat(UnixPath path, UnixFileAttributes attrs) throws UnixException {
+        NativeBuffer buffer = copyToNativeBuffer(path);
+        try {
+            lstat0(buffer.address(), attrs);
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native void lstat0(long pathAddress, UnixFileAttributes attrs)
+        throws UnixException;
+
+    /**
+     * fstat(int filedes, struct stat* buf)
+     */
+    static native void fstat(int fd, UnixFileAttributes attrs) throws UnixException;
+
+    /**
+     * fstatat(int filedes,const char* path,  struct stat* buf, int flag)
+     */
+    static void fstatat(int dfd, byte[] path, int flag, UnixFileAttributes attrs)
+        throws UnixException
+    {
+        NativeBuffer buffer = NativeBuffers.asNativeBuffer(path);
+        try {
+            fstatat0(dfd, buffer.address(), flag, attrs);
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native void fstatat0(int dfd, long pathAddress, int flag,
+        UnixFileAttributes attrs) throws UnixException;
+
+    /**
+     * chown(const char* path, uid_t owner, gid_t group)
+     */
+    static void chown(UnixPath path, int uid, int gid) throws UnixException {
+        NativeBuffer buffer = copyToNativeBuffer(path);
+        try {
+            chown0(buffer.address(), uid, gid);
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native void chown0(long pathAddress, int uid, int gid)
+        throws UnixException;
+
+    /**
+     * lchown(const char* path, uid_t owner, gid_t group)
+     */
+    static void lchown(UnixPath path, int uid, int gid) throws UnixException {
+        NativeBuffer buffer = copyToNativeBuffer(path);
+        try {
+            lchown0(buffer.address(), uid, gid);
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native void lchown0(long pathAddress, int uid, int gid)
+        throws UnixException;
+
+    /**
+     * fchown(int filedes, uid_t owner, gid_t group)
+     */
+    static native void fchown(int fd, int uid, int gid) throws UnixException;
+
+    /**
+     * chmod(const char* path, mode_t mode)
+     */
+    static void chmod(UnixPath path, int mode) throws UnixException {
+        NativeBuffer buffer = copyToNativeBuffer(path);
+        try {
+            chmod0(buffer.address(), mode);
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native void chmod0(long pathAddress, int mode)
+        throws UnixException;
+
+    /**
+     * fchmod(int fildes, mode_t mode)
+     */
+    static native void fchmod(int fd, int mode) throws UnixException;
+
+    /**
+     * utimes(conar char* path, const struct timeval times[2])
+     */
+    static void utimes(UnixPath path, long times0, long times1)
+        throws UnixException
+    {
+        NativeBuffer buffer = copyToNativeBuffer(path);
+        try {
+            utimes0(buffer.address(), times0, times1);
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native void utimes0(long pathAddress, long times0, long times1)
+        throws UnixException;
+
+    /**
+     * futimes(int fildes,, const struct timeval times[2])
+     */
+    static native void futimes(int fd, long times0, long times1) throws UnixException;
+
+    /**
+     * DIR *opendir(const char* dirname)
+     */
+    static long opendir(UnixPath path) throws UnixException {
+        NativeBuffer buffer = copyToNativeBuffer(path);
+        try {
+            return opendir0(buffer.address());
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native long opendir0(long pathAddress) throws UnixException;
+
+    /**
+     * DIR* fdopendir(int filedes)
+     */
+    static native long fdopendir(int dfd) throws UnixException;
+
+
+    /**
+     * closedir(DIR* dirp)
+     */
+    static native void closedir(long dir) throws UnixException;
+
+    /**
+     * struct dirent* readdir(DIR *dirp)
+     *
+     * @return  dirent->d_name
+     */
+    static native byte[] readdir(long dir) throws UnixException;
+
+    /**
+     * size_t read(int fildes, void* buf, size_t nbyte)
+     */
+    static native int read(int fildes, long buf, int nbyte) throws UnixException;
+
+    /**
+     * size_t writeint fildes, void* buf, size_t nbyte)
+     */
+    static native int write(int fildes, long buf, int nbyte) throws UnixException;
+
+    /**
+     * access(const char* path, int amode);
+     */
+    static void access(UnixPath path, int amode) throws UnixException {
+        NativeBuffer buffer = copyToNativeBuffer(path);
+        try {
+            access0(buffer.address(), amode);
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native void access0(long pathAddress, int amode) throws UnixException;
+
+    /**
+     * struct passwd *getpwuid(uid_t uid);
+     *
+     * @return  passwd->pw_name
+     */
+    static native byte[] getpwuid(int uid) throws UnixException;
+
+    /**
+     * struct group *getgrgid(gid_t gid);
+     *
+     * @return  group->gr_name
+     */
+    static native byte[] getgrgid(int gid) throws UnixException;
+
+    /**
+     * struct passwd *getpwnam(const char *name);
+     *
+     * @return  passwd->pw_uid
+     */
+    static int getpwnam(String name) throws UnixException {
+        NativeBuffer buffer = NativeBuffers.asNativeBuffer(name.getBytes());
+        try {
+            return getpwnam0(buffer.address());
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native int getpwnam0(long nameAddress) throws UnixException;
+
+    /**
+     * struct group *getgrnam(const char *name);
+     *
+     * @return  group->gr_name
+     */
+    static int getgrnam(String name) throws UnixException {
+        NativeBuffer buffer = NativeBuffers.asNativeBuffer(name.getBytes());
+        try {
+            return getgrnam0(buffer.address());
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native int getgrnam0(long nameAddress) throws UnixException;
+
+    /**
+     * int getextmntent(FILE *fp, struct extmnttab *mp, int len);
+     */
+    static native int getextmntent(long fp, UnixMountEntry entry) throws UnixException;
+
+    /**
+     * statvfs(const char* path, struct statvfs *buf)
+     */
+    static void statvfs(UnixPath path, UnixFileStoreAttributes attrs)
+        throws UnixException
+    {
+        NativeBuffer buffer = copyToNativeBuffer(path);
+        try {
+            statvfs0(buffer.address(), attrs);
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native void statvfs0(long pathAddress, UnixFileStoreAttributes attrs)
+        throws UnixException;
+
+    /**
+     * long int pathconf(const char *path, int name);
+     */
+    static long pathconf(UnixPath path, int name) throws UnixException {
+        NativeBuffer buffer = copyToNativeBuffer(path);
+        try {
+            return pathconf0(buffer.address(), name);
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native long pathconf0(long pathAddress, int name)
+        throws UnixException;
+
+    /**
+     * long fpathconf(int fildes, int name);
+     */
+    static native long fpathconf(int filedes, int name) throws UnixException;
+
+    /**
+     * char* strerror(int errnum)
+     */
+    static native byte[] strerror(int errnum);
+
+    // initialize field IDs
+    private static native void initIDs();
+
+    static {
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+            public Void run() {
+                System.loadLibrary("nio");
+                return null;
+        }});
+        initIDs();
+    }
+}
diff --git a/jdk/src/solaris/classes/sun/nio/fs/UnixPath.java b/jdk/src/solaris/classes/sun/nio/fs/UnixPath.java
new file mode 100644
index 0000000..c1330f0
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixPath.java
@@ -0,0 +1,1228 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.*;
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.nio.file.spi.AbstractPath;
+import java.nio.charset.*;
+import java.nio.channels.*;
+import java.security.AccessController;
+import java.io.*;
+import java.net.URI;
+import java.util.*;
+import java.lang.ref.SoftReference;
+import sun.security.util.SecurityConstants;
+
+import static sun.nio.fs.UnixNativeDispatcher.*;
+import static sun.nio.fs.UnixConstants.*;
+
+/**
+ * Solaris/Linux implementation of java.nio.file.Path
+ */
+
+class UnixPath
+    extends AbstractPath
+{
+    private static ThreadLocal<SoftReference<CharsetEncoder>> encoder =
+        new ThreadLocal<SoftReference<CharsetEncoder>>();
+
+    // FIXME - eliminate this reference to reduce space
+    private final UnixFileSystem fs;
+
+    // internal representation
+    private final byte[] path;
+
+    // String representation (created lazily)
+    private volatile String stringValue;
+
+    // cached hashcode (created lazily, no need to be volatile)
+    private int hash;
+
+    // array of offsets of elements in path (created lazily)
+    private volatile int[] offsets;
+
+    // file permissions (created lazily)
+    private volatile FilePermission[] perms;
+
+    UnixPath(UnixFileSystem fs, byte[] path) {
+        this.fs = fs;
+        this.path = path;
+    }
+
+    UnixPath(UnixFileSystem fs, String input) {
+        // removes redundant slashes and checks for invalid characters
+        this(fs, encode(normalizeAndCheck(input)));
+    }
+
+    // package-private
+    // removes redundant slashes and check input for invalid characters
+    static String normalizeAndCheck(String input) {
+        int n = input.length();
+        if (n == 0)
+            throw new InvalidPathException(input, "Path is empty");
+        char prevChar = 0;
+        for (int i=0; i < n; i++) {
+            char c = input.charAt(i);
+            if (c == '\u0000')
+                throw new InvalidPathException(input, "Nul character not allowed");
+            if ((c == '/') && (prevChar == '/'))
+                return normalize(input, n, i - 1);
+            prevChar = c;
+        }
+        if (prevChar == '/')
+            return normalize(input, n, n - 1);
+        return input;
+    }
+
+    private static String normalize(String input, int len, int off) {
+        if (len == 0)
+            return input;
+        int n = len;
+        while ((n > 0) && (input.charAt(n - 1) == '/')) n--;
+        if (n == 0)
+            return "/";
+        StringBuilder sb = new StringBuilder(input.length());
+        if (off > 0)
+            sb.append(input.substring(0, off));
+        char prevChar = 0;
+        for (int i=off; i < n; i++) {
+            char c = input.charAt(i);
+            if ((c == '/') && (prevChar == '/'))
+                continue;
+            sb.append(c);
+            prevChar = c;
+        }
+        return sb.toString();
+    }
+
+    // encodes the given path-string into a sequence of bytes
+    private static byte[] encode(String input) {
+        SoftReference<CharsetEncoder> ref = encoder.get();
+        CharsetEncoder ce = (ref != null) ? ref.get() : null;
+        if (ce == null) {
+            ce = Charset.defaultCharset().newEncoder()
+                .onMalformedInput(CodingErrorAction.REPORT)
+                .onUnmappableCharacter(CodingErrorAction.REPORT);
+            encoder.set(new SoftReference<CharsetEncoder>(ce));
+        }
+
+        char[] ca = input.toCharArray();
+
+        // size output buffer for worse-case size
+        byte[] ba = new byte[(int)(ca.length * (double)ce.maxBytesPerChar())];
+
+        // encode
+        ByteBuffer bb = ByteBuffer.wrap(ba);
+        CharBuffer cb = CharBuffer.wrap(ca);
+        ce.reset();
+        CoderResult cr = ce.encode(cb, bb, true);
+        boolean error;
+        if (!cr.isUnderflow()) {
+            error = true;
+        } else {
+            cr = ce.flush(bb);
+            error = !cr.isUnderflow();
+        }
+        if (error) {
+            throw new InvalidPathException(input,
+                "Malformed input or input contains unmappable chacraters");
+        }
+
+        // trim result to actual length if required
+        int len = bb.position();
+        if (len != ba.length)
+            ba = Arrays.copyOf(ba, len);
+
+        return ba;
+    }
+
+    // package-private
+    byte[] asByteArray() {
+        return path;
+    }
+
+    // use this path when making system/library calls
+    byte[] getByteArrayForSysCalls() {
+        // resolve against default directory if required (chdir allowed or
+        // file system default directory is not working directory)
+        if (getFileSystem().needToResolveAgainstDefaultDirectory()) {
+            return resolve(getFileSystem().defaultDirectory(), path);
+        } else {
+            return path;
+        }
+    }
+
+    // use this message when throwing exceptions
+    String getPathForExecptionMessage() {
+        return toString();
+    }
+
+    // use this path for permission checks
+    String getPathForPermissionCheck() {
+        if (getFileSystem().needToResolveAgainstDefaultDirectory()) {
+            return new String(getByteArrayForSysCalls());
+        } else {
+            return toString();
+        }
+    }
+
+    // Checks that the given file is a UnixPath
+    private UnixPath checkPath(FileRef obj) {
+        if (obj == null)
+            throw new NullPointerException();
+        if (!(obj instanceof UnixPath))
+            throw new ProviderMismatchException();
+        return (UnixPath)obj;
+    }
+
+    // create offset list if not already created
+    private void initOffsets() {
+        if (offsets == null) {
+            int count, index;
+
+            // count names
+            count = 0;
+            index = 0;
+            while (index < path.length) {
+                byte c = path[index++];
+                if (c != '/') {
+                    count++;
+                    while (index < path.length && path[index] != '/')
+                        index++;
+                }
+            }
+
+            // populate offsets
+            int[] result = new int[count];
+            count = 0;
+            index = 0;
+            while (index < path.length) {
+                byte c = path[index];
+                if (c == '/') {
+                    index++;
+                } else {
+                    result[count++] = index++;
+                    while (index < path.length && path[index] != '/')
+                        index++;
+                }
+            }
+            synchronized (this) {
+                if (offsets == null)
+                    offsets = result;
+            }
+        }
+    }
+
+    @Override
+    public UnixFileSystem getFileSystem() {
+        return fs;
+    }
+
+    @Override
+    public UnixPath getRoot() {
+        if (path[0] == '/') {
+            return getFileSystem().rootDirectory();
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public UnixPath getName() {
+        initOffsets();
+
+        int count = offsets.length;
+        if (count == 0)
+            return null;  // no elements so no name
+
+        if (count == 1 && path[0] != '/')
+            return this;
+
+        int lastOffset = offsets[count-1];
+        int len = path.length - lastOffset;
+        byte[] result = new byte[len];
+        System.arraycopy(path, lastOffset, result, 0, len);
+        return new UnixPath(getFileSystem(), result);
+    }
+
+    @Override
+    public UnixPath getParent() {
+        initOffsets();
+
+        int count = offsets.length;
+        if (count == 0) {
+            // no elements so no parent
+            return null;
+        }
+        int len = offsets[count-1] - 1;
+        if (len <= 0) {
+            // parent is root only (may be null)
+            return getRoot();
+        }
+        byte[] result = new byte[len];
+        System.arraycopy(path, 0, result, 0, len);
+        return new UnixPath(getFileSystem(), result);
+    }
+
+    @Override
+    public int getNameCount() {
+        initOffsets();
+        return offsets.length;
+    }
+
+    @Override
+    public UnixPath getName(int index) {
+        initOffsets();
+        if (index < 0)
+            throw new IllegalArgumentException();
+        if (index >= offsets.length)
+            throw new IllegalArgumentException();
+
+        int begin = offsets[index];
+        int len;
+        if (index == (offsets.length-1)) {
+            len = path.length - begin;
+        } else {
+            len = offsets[index+1] - begin - 1;
+        }
+
+        // construct result
+        byte[] result = new byte[len];
+        System.arraycopy(path, begin, result, 0, len);
+        return new UnixPath(getFileSystem(), result);
+    }
+
+    @Override
+    public UnixPath subpath(int beginIndex, int endIndex) {
+        initOffsets();
+
+        if (beginIndex < 0)
+            throw new IllegalArgumentException();
+        if (beginIndex >= offsets.length)
+            throw new IllegalArgumentException();
+        if (endIndex > offsets.length)
+            throw new IllegalArgumentException();
+        if (beginIndex >= endIndex) {
+            throw new IllegalArgumentException();
+        }
+
+        // starting offset and length
+        int begin = offsets[beginIndex];
+        int len;
+        if (endIndex == offsets.length) {
+            len = path.length - begin;
+        } else {
+            len = offsets[endIndex] - begin - 1;
+        }
+
+        // construct result
+        byte[] result = new byte[len];
+        System.arraycopy(path, begin, result, 0, len);
+        return new UnixPath(getFileSystem(), result);
+    }
+
+    @Override
+    public boolean isAbsolute() {
+        return (path[0] == '/');
+    }
+
+    // Resolve child against given base
+    private static byte[] resolve(byte[] base, byte[] child) {
+        if (child[0] == '/')
+            return child;
+        byte[] result;
+        if (base.length == 1 && base[0] == '/') {
+            result = new byte[child.length + 1];
+            result[0] = '/';
+            System.arraycopy(child, 0, result, 1, child.length);
+        } else {
+            result = new byte[base.length + 1 + child.length];
+            System.arraycopy(base, 0, result, 0, base.length);
+            result[base.length] = '/';
+            System.arraycopy(child, 0, result,  base.length+1, child.length);
+        }
+        return result;
+    }
+
+    @Override
+    public UnixPath resolve(Path obj) {
+        if (obj == null)
+            return this;
+        byte[] other = checkPath(obj).path;
+        if (other[0] == '/')
+            return ((UnixPath)obj);
+        byte[] result = resolve(path, other);
+        return new UnixPath(getFileSystem(), result);
+    }
+
+    @Override
+    public UnixPath resolve(String other) {
+        return resolve(new UnixPath(getFileSystem(), other));
+    }
+
+    UnixPath resolve(byte[] other) {
+        return resolve(new UnixPath(getFileSystem(), other));
+    }
+
+    @Override
+    public UnixPath relativize(Path obj) {
+        UnixPath other = checkPath(obj);
+        if (other.equals(this))
+            return null;
+
+        // can only relativize paths of the same type
+        if (this.isAbsolute() != other.isAbsolute())
+            throw new IllegalArgumentException("'other' is different type of Path");
+
+        int bn = this.getNameCount();
+        int cn = other.getNameCount();
+
+        // skip matching names
+        int n = (bn > cn) ? cn : bn;
+        int i = 0;
+        while (i < n) {
+            if (!this.getName(i).equals(other.getName(i)))
+                break;
+            i++;
+        }
+
+        int dotdots = bn - i;
+        if (i < cn) {
+            // remaining name components in other
+            UnixPath remainder = other.subpath(i, cn);
+            if (dotdots == 0)
+                return remainder;
+
+            // result is a  "../" for each remaining name in base
+            // followed by the remaining names in other
+            byte[] result = new byte[dotdots*3 + remainder.path.length];
+            int pos = 0;
+            while (dotdots > 0) {
+                result[pos++] = (byte)'.';
+                result[pos++] = (byte)'.';
+                result[pos++] = (byte)'/';
+                dotdots--;
+            }
+            System.arraycopy(remainder.path, 0, result, pos, remainder.path.length);
+            return new UnixPath(getFileSystem(), result);
+        } else {
+            // no remaining names in other so result is simply a sequence of ".."
+            byte[] result = new byte[dotdots*3 - 1];
+            int pos = 0;
+            while (dotdots > 0) {
+                result[pos++] = (byte)'.';
+                result[pos++] = (byte)'.';
+                // no tailing slash at the end
+                if (dotdots > 1)
+                    result[pos++] = (byte)'/';
+                dotdots--;
+            }
+            return new UnixPath(getFileSystem(), result);
+        }
+    }
+
+    @Override
+    public Path normalize() {
+        final int count = getNameCount();
+        if (count == 0)
+            return this;
+
+        boolean[] ignore = new boolean[count];      // true => ignore name
+        int[] size = new int[count];                // length of name
+        int remaining = count;                      // number of names remaining
+        boolean hasDotDot = false;                  // has at least one ..
+        boolean isAbsolute = path[0] == '/';
+
+        // first pass:
+        //   1. compute length of names
+        //   2. mark all occurences of "." to ignore
+        //   3. and look for any occurences of ".."
+        for (int i=0; i<count; i++) {
+            int begin = offsets[i];
+            int len;
+            if (i == (offsets.length-1)) {
+                len = path.length - begin;
+            } else {
+                len = offsets[i+1] - begin - 1;
+            }
+            size[i] = len;
+
+            if (path[begin] == '.') {
+                if (len == 1) {
+                    ignore[i] = true;  // ignore  "."
+                    remaining--;
+                }
+                else {
+                    if (path[begin+1] == '.')   // ".." found
+                        hasDotDot = true;
+                }
+            }
+        }
+
+        // multiple passes to eliminate all occurences of name/..
+        if (hasDotDot) {
+            int prevRemaining;
+            do {
+                prevRemaining = remaining;
+                int prevName = -1;
+                for (int i=0; i<count; i++) {
+                    if (ignore[i])
+                        continue;
+
+                    // not a ".."
+                    if (size[i] != 2) {
+                        prevName = i;
+                        continue;
+                    }
+
+                    int begin = offsets[i];
+                    if (path[begin] != '.' || path[begin+1] != '.') {
+                        prevName = i;
+                        continue;
+                    }
+
+                    // ".." found
+                    if (prevName >= 0) {
+                        // name/<ignored>/.. found so mark name and ".." to be
+                        // ignored
+                        ignore[prevName] = true;
+                        ignore[i] = true;
+                        remaining = remaining - 2;
+                        prevName = -1;
+                    } else {
+                        // Case: /<ignored>/.. so mark ".." as ignored
+                        if (isAbsolute) {
+                            boolean hasPrevious = false;
+                            for (int j=0; j<i; j++) {
+                                if (!ignore[j]) {
+                                    hasPrevious = true;
+                                    break;
+                                }
+                            }
+                            if (!hasPrevious) {
+                                // all proceeding names are ignored
+                                ignore[i] = true;
+                                remaining--;
+                            }
+                        }
+                    }
+                }
+            } while (prevRemaining > remaining);
+        }
+
+        // no redundant names
+        if (remaining == count)
+            return this;
+
+        // corner case - all names removed
+        if (remaining == 0) {
+            return isAbsolute ? getFileSystem().rootDirectory() : null;
+        }
+
+        // compute length of result
+        int len = remaining - 1;
+        if (isAbsolute)
+            len++;
+
+        for (int i=0; i<count; i++) {
+            if (!ignore[i])
+                len += size[i];
+        }
+        byte[] result = new byte[len];
+
+        // copy names into result
+        int pos = 0;
+        if (isAbsolute)
+            result[pos++] = '/';
+        for (int i=0; i<count; i++) {
+            if (!ignore[i]) {
+                System.arraycopy(path, offsets[i], result, pos, size[i]);
+                pos += size[i];
+                if (--remaining > 0) {
+                    result[pos++] = '/';
+                }
+            }
+        }
+        return new UnixPath(getFileSystem(), result);
+    }
+
+    @Override
+    public boolean startsWith(Path other) {
+        UnixPath that = checkPath(other);
+
+        // other path is longer
+        if (that.path.length > path.length)
+            return false;
+
+        int thisOffsetCount = getNameCount();
+        int thatOffsetCount = that.getNameCount();
+
+        // other path has no name elements
+        if (thatOffsetCount == 0 && this.isAbsolute())
+            return true;
+
+        // given path has more elements that this path
+        if (thatOffsetCount > thisOffsetCount)
+            return false;
+
+        // same number of elements so must be exact match
+        if ((thatOffsetCount == thisOffsetCount) &&
+            (path.length != that.path.length)) {
+            return false;
+        }
+
+        // check offsets of elements match
+        for (int i=0; i<thatOffsetCount; i++) {
+            Integer o1 = offsets[i];
+            Integer o2 = that.offsets[i];
+            if (!o1.equals(o2))
+                return false;
+        }
+
+        // offsets match so need to compare bytes
+        int i=0;
+        while (i < that.path.length) {
+            if (this.path[i] != that.path[i])
+                return false;
+            i++;
+        }
+
+        // final check that match is on name boundary
+        if (i < path.length && this.path[i] != '/')
+            return false;
+
+        return true;
+    }
+
+    @Override
+    public boolean endsWith(Path other) {
+        UnixPath that = checkPath(other);
+
+        // other path is longer
+        if (that.path.length > path.length)
+            return false;
+
+        // other path is absolute so this path must be absolute
+        if (that.isAbsolute() && !this.isAbsolute())
+            return false;
+
+        int thisOffsetCount = getNameCount();
+        int thatOffsetCount = that.getNameCount();
+
+        // given path has more elements that this path
+        if (thatOffsetCount > thisOffsetCount) {
+            return false;
+        } else {
+            // same number of elements
+            if (thatOffsetCount == thisOffsetCount) {
+                if (thisOffsetCount == 0)
+                    return true;
+                int expectedLen = path.length;
+                if (this.isAbsolute() && !that.isAbsolute())
+                    expectedLen--;
+                if (that.path.length != expectedLen)
+                    return false;
+            } else {
+                // this path has more elements so given path must be relative
+                if (that.isAbsolute())
+                    return false;
+            }
+        }
+
+        // compare bytes
+        int thisPos = offsets[thisOffsetCount - thatOffsetCount];
+        int thatPos = that.offsets[0];
+        while (thatPos < that.path.length) {
+            if (this.path[thisPos++] != that.path[thatPos++])
+                return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int compareTo(Path other) {
+        int len1 = path.length;
+        int len2 = ((UnixPath) other).path.length;
+
+        int n = Math.min(len1, len2);
+        byte v1[] = path;
+        byte v2[] = ((UnixPath) other).path;
+
+        int k = 0;
+        while (k < n) {
+            int c1 = v1[k] & 0xff;
+            int c2 = v2[k] & 0xff;
+            if (c1 != c2) {
+                return c1 - c2;
+            }
+            k++;
+        }
+        return len1 - len2;
+    }
+
+    @Override
+    public boolean equals(Object ob) {
+        if ((ob != null) && (ob instanceof UnixPath)) {
+            return compareTo((Path)ob) == 0;
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        // OK if two or more threads compute hash
+        int h = hash;
+        if (h == 0) {
+            for (int i = 0; i< path.length; i++) {
+                h = 31*h + (path[i] & 0xff);
+            }
+            hash = h;
+        }
+        return h;
+    }
+
+    @Override
+    public String toString() {
+        // OK if two or more threads create a String
+        if (stringValue == null)
+            stringValue = new String(path);     // platform encoding
+        return stringValue;
+    }
+
+    @Override
+    public Iterator<Path> iterator() {
+        initOffsets();
+        return new Iterator<Path>() {
+            int i = 0;
+            @Override
+            public boolean hasNext() {
+                return (i < offsets.length);
+            }
+            @Override
+            public Path next() {
+                if (i < offsets.length) {
+                    Path result = getName(i);
+                    i++;
+                    return result;
+                } else {
+                    throw new NoSuchElementException();
+                }
+            }
+            @Override
+            public void remove() {
+                throw new UnsupportedOperationException();
+            }
+        };
+    }
+
+    // -- file operations --
+
+    // package-private
+    int openForAttributeAccess(boolean followLinks) throws IOException {
+        int flags = O_RDONLY;
+        if (!followLinks)
+            flags |= O_NOFOLLOW;
+        try {
+            return open(this, flags, 0);
+        } catch (UnixException x) {
+            // HACK: EINVAL instead of ELOOP on Solaris 10 prior to u4 (see 6460380)
+            if (getFileSystem().isSolaris() && x.errno() == EINVAL)
+                x.setError(ELOOP);
+
+            if (x.errno() == ELOOP)
+                throw new FileSystemException(getPathForExecptionMessage(), null,
+                    x.getMessage() + " or unable to access attributes of symbolic link");
+
+            x.rethrowAsIOException(this);
+            return -1; // keep compile happy
+        }
+    }
+
+    // create file permissions used for read and write checks
+    private void checkReadOrWrite(boolean checkRead) {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm == null)
+            return;
+        if (perms == null) {
+            synchronized (this) {
+                if (perms == null) {
+                    FilePermission[] p = new FilePermission[2];
+                    String pathForPermCheck = getPathForPermissionCheck();
+                    p[0] = new FilePermission(pathForPermCheck,
+                        SecurityConstants.FILE_READ_ACTION);
+                    p[1] = new FilePermission(pathForPermCheck,
+                        SecurityConstants.FILE_WRITE_ACTION);
+                    perms = p;
+                }
+            }
+        }
+        if (checkRead) {
+            sm.checkPermission(perms[0]);
+        } else {
+            sm.checkPermission(perms[1]);
+        }
+    }
+
+    void checkRead() {
+        checkReadOrWrite(true);
+    }
+
+    void checkWrite() {
+        checkReadOrWrite(false);
+    }
+
+    void checkDelete() {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            // permission not cached
+            sm.checkDelete(getPathForPermissionCheck());
+        }
+    }
+
+    @Override
+    public FileStore getFileStore()
+        throws IOException
+    {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(new RuntimePermission("getFileStoreAttributes"));
+            checkRead();
+        }
+        return getFileSystem().getFileStore(this);
+    }
+
+    @Override
+    public void checkAccess(AccessMode... modes) throws IOException {
+        boolean e = false;
+        boolean r = false;
+        boolean w = false;
+        boolean x = false;
+
+        if (modes.length == 0) {
+            e = true;
+        } else {
+            for (AccessMode mode: modes) {
+                switch (mode) {
+                    case READ : r = true; break;
+                    case WRITE : w = true; break;
+                    case EXECUTE : x = true; break;
+                    default: throw new AssertionError("Should not get here");
+                }
+            }
+        }
+
+        int mode = 0;
+        if (e || r) {
+            checkRead();
+            mode |= (r) ? R_OK : F_OK;
+        }
+        if (w) {
+            checkWrite();
+            mode |= W_OK;
+        }
+        if (x) {
+            SecurityManager sm = System.getSecurityManager();
+            if (sm != null) {
+                // not cached
+                sm.checkExec(getPathForPermissionCheck());
+            }
+            mode |= X_OK;
+        }
+        try {
+            access(this, mode);
+        } catch (UnixException exc) {
+            exc.rethrowAsIOException(this);
+        }
+    }
+
+    @Override
+    public void delete(boolean failIfNotExists) throws IOException {
+        checkDelete();
+
+        // need file attributes to know if file is directory
+        UnixFileAttributes attrs = null;
+        try {
+            attrs = UnixFileAttributes.get(this, false);
+            if (attrs.isDirectory()) {
+                rmdir(this);
+            } else {
+                unlink(this);
+            }
+        } catch (UnixException x) {
+            // no-op if file does not exist
+            if (!failIfNotExists && x.errno() == ENOENT)
+                return;
+
+            // DirectoryNotEmptyException if not empty
+            if (attrs != null && attrs.isDirectory() &&
+                (x.errno() == EEXIST || x.errno() == ENOTEMPTY))
+                throw new DirectoryNotEmptyException(getPathForExecptionMessage());
+
+            x.rethrowAsIOException(this);
+        }
+    }
+
+    @Override
+    public DirectoryStream<Path> newDirectoryStream(DirectoryStream.Filter<? super Path> filter)
+        throws IOException
+    {
+        if (filter == null)
+            throw new NullPointerException();
+        checkRead();
+
+        // can't return SecureDirectoryStream on older kernels.
+        if (!getFileSystem().supportsSecureDirectoryStreams()) {
+            try {
+                long ptr = opendir(this);
+                return new UnixDirectoryStream(this, ptr, filter);
+            } catch (UnixException x) {
+                if (x.errno() == UnixConstants.ENOTDIR)
+                    throw new NotDirectoryException(getPathForExecptionMessage());
+                x.rethrowAsIOException(this);
+            }
+        }
+
+        // open directory and dup file descriptor for use by
+        // opendir/readdir/closedir
+        int dfd1 = -1;
+        int dfd2 = -1;
+        long dp = 0L;
+        try {
+            dfd1 = open(this, O_RDONLY, 0);
+            dfd2 = dup(dfd1);
+            dp = fdopendir(dfd1);
+        } catch (UnixException x) {
+            if (dfd1 != -1)
+                close(dfd1);
+            if (dfd2 != -1)
+                close(dfd2);
+            if (x.errno() == UnixConstants.ENOTDIR)
+                throw new NotDirectoryException(getPathForExecptionMessage());
+            x.rethrowAsIOException(this);
+        }
+        return new UnixSecureDirectoryStream(this, dp, dfd2, filter);
+    }
+
+    // invoked by AbstractPath#copyTo
+    @Override
+    public void implCopyTo(Path obj, CopyOption... options)
+        throws IOException
+    {
+        UnixPath target = (UnixPath)obj;
+        UnixCopyFile.copy(this, target, options);
+    }
+
+    @Override
+    public void implMoveTo(Path obj, CopyOption... options)
+        throws IOException
+    {
+        UnixPath target = (UnixPath)obj;
+        UnixCopyFile.move(this, target, options);
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public <V extends FileAttributeView> V
+        getFileAttributeView(Class<V> type, LinkOption... options)
+    {
+        FileAttributeView view = getFileSystem()
+            .newFileAttributeView(type, this, options);
+        if (view == null)
+            return null;
+        return (V) view;
+    }
+
+    @Override
+    public FileAttributeView getFileAttributeView(String name, LinkOption... options) {
+        return getFileSystem().newFileAttributeView(name, this, options);
+    }
+
+    @Override
+    public Path createDirectory(FileAttribute<?>... attrs)
+        throws IOException
+    {
+        checkWrite();
+
+        int mode = UnixFileModeAttribute
+            .toUnixMode(UnixFileModeAttribute.ALL_PERMISSIONS, attrs);
+        try {
+            mkdir(this, mode);
+        } catch (UnixException x) {
+            x.rethrowAsIOException(this);
+        }
+        return this;
+    }
+
+    @Override
+    public InputStream newInputStream()throws IOException {
+        try {
+            Set<OpenOption> options = Collections.emptySet();
+            FileChannel fc = UnixChannelFactory.newFileChannel(this, options, 0);
+            return Channels.newInputStream(fc);
+        } catch (UnixException x) {
+            x.rethrowAsIOException(this);
+            return null;  // keep compiler happy
+        }
+    }
+
+    @Override
+    public SeekableByteChannel newByteChannel(Set<? extends OpenOption> options,
+                                                      FileAttribute<?>... attrs)
+         throws IOException
+    {
+        int mode = UnixFileModeAttribute
+            .toUnixMode(UnixFileModeAttribute.ALL_READWRITE, attrs);
+        try {
+            return UnixChannelFactory.newFileChannel(this, options, mode);
+        } catch (UnixException x) {
+            x.rethrowAsIOException(this);
+            return null;  // keep compiler happy
+        }
+    }
+
+    @Override
+    public OutputStream newOutputStream(Set<? extends OpenOption> options,
+                                        FileAttribute<?>... attrs)
+        throws IOException
+    {
+        // need to copy options to add WRITE
+        Set<OpenOption> opts = new HashSet<OpenOption>(options);
+        if (opts.contains(StandardOpenOption.READ))
+            throw new IllegalArgumentException("READ not allowed");
+        opts.add(StandardOpenOption.WRITE);
+
+        int mode = UnixFileModeAttribute
+            .toUnixMode(UnixFileModeAttribute.ALL_READWRITE, attrs);
+        try {
+            FileChannel fc = UnixChannelFactory.newFileChannel(this, opts, mode);
+            return Channels.newOutputStream(fc);
+        } catch (UnixException x) {
+            x.rethrowAsIOException(this);
+            return null;  // keep compiler happy
+        }
+    }
+
+    @Override
+    public boolean isSameFile(FileRef obj) throws IOException {
+        if (this.equals(obj))
+            return true;
+        if (!(obj instanceof UnixPath))  // includes null check
+            return false;
+        UnixPath other = (UnixPath)obj;
+
+        // check security manager access to both files
+        this.checkRead();
+        other.checkRead();
+
+        UnixFileAttributes thisAttrs;
+        UnixFileAttributes otherAttrs;
+        try {
+             thisAttrs = UnixFileAttributes.get(this, true);
+        } catch (UnixException x) {
+            x.rethrowAsIOException(this);
+            return false;    // keep compiler happy
+        }
+        try {
+            otherAttrs = UnixFileAttributes.get(other, true);
+        } catch (UnixException x) {
+            x.rethrowAsIOException(other);
+            return false;    // keep compiler happy
+        }
+        return thisAttrs.isSameFile(otherAttrs);
+    }
+
+    @Override
+    public Path createSymbolicLink(Path obj, FileAttribute<?>... attrs)
+        throws IOException
+    {
+        UnixPath target = checkPath(obj);
+
+        // no attributes supported when creating links
+        if (attrs.length > 0) {
+            UnixFileModeAttribute.toUnixMode(0, attrs);  // may throw NPE or UOE
+            throw new UnsupportedOperationException("Initial file attributes" +
+                "not supported when creating symbolic link");
+        }
+
+        // permission check
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(new LinkPermission("symbolic"));
+            checkWrite();
+        }
+
+        // create link
+        try {
+            symlink(target.asByteArray(), this);
+        } catch (UnixException x) {
+            x.rethrowAsIOException(this);
+        }
+
+        return this;
+    }
+
+    @Override
+    public Path createLink(Path obj) throws IOException {
+        UnixPath existing = checkPath(obj);
+
+        // permission check
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(new LinkPermission("hard"));
+            this.checkWrite();
+            existing.checkWrite();
+        }
+        try {
+            link(existing, this);
+        } catch (UnixException x) {
+            x.rethrowAsIOException(this, existing);
+        }
+        return this;
+    }
+
+    @Override
+    public Path readSymbolicLink() throws IOException {
+        // permission check
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            FilePermission perm = new FilePermission(getPathForPermissionCheck(),
+                SecurityConstants.FILE_READLINK_ACTION);
+            AccessController.checkPermission(perm);
+        }
+        try {
+            byte[] target = readlink(this);
+            return new UnixPath(getFileSystem(), target);
+        } catch (UnixException x) {
+           if (x.errno() == UnixConstants.EINVAL)
+                throw new NotLinkException(getPathForExecptionMessage());
+            x.rethrowAsIOException(this);
+            return null;    // keep compiler happy
+        }
+    }
+
+    @Override
+    public UnixPath toAbsolutePath() {
+        if (isAbsolute()) {
+            return this;
+        }
+        // The path is relative so need to resolve against default directory,
+        // taking care not to reveal the user.dir
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPropertyAccess("user.dir");
+        }
+        return new UnixPath(getFileSystem(),
+            resolve(getFileSystem().defaultDirectory(), path));
+    }
+
+    @Override
+    public UnixPath toRealPath(boolean resolveLinks) throws IOException {
+        checkRead();
+
+        UnixPath absolute = toAbsolutePath();
+
+        // if resolveLinks is true then use realpath
+        if (resolveLinks) {
+            try {
+                byte[] rp = realpath(absolute);
+                return new UnixPath(getFileSystem(), rp);
+            } catch (UnixException x) {
+                x.rethrowAsIOException(this);
+            }
+        }
+
+        // if resolveLinks is false then eliminate "." and also ".."
+        // where the previous element is not a link.
+        UnixPath root = getFileSystem().rootDirectory();
+        UnixPath result = root;
+        for (int i=0; i<absolute.getNameCount(); i++) {
+            UnixPath element = absolute.getName(i);
+
+            // eliminate "."
+            if ((element.asByteArray().length == 1) && (element.asByteArray()[0] == '.'))
+                continue;
+
+            // cannot eliminate ".." if previous element is a link
+            if ((element.asByteArray().length == 2) && (element.asByteArray()[0] == '.') &&
+                (element.asByteArray()[1] == '.'))
+            {
+                UnixFileAttributes attrs = null;
+                try {
+                    attrs = UnixFileAttributes.get(result, false);
+                } catch (UnixException x) {
+                    x.rethrowAsIOException(result);
+                }
+                if (!attrs.isSymbolicLink()) {
+                    result = result.getParent();
+                    if (result == null) {
+                        result = root;
+                    }
+                    continue;
+                }
+            }
+            result = result.resolve(element);
+        }
+
+        // finally check that file exists
+        try {
+            UnixFileAttributes.get(result, true);
+        } catch (UnixException x) {
+            x.rethrowAsIOException(result);
+        }
+        return result;
+    }
+
+    @Override
+    public boolean isHidden() {
+        checkRead();
+        UnixPath name = getName();
+        if (name == null)
+            return false;
+        return (name.asByteArray()[0] == '.');
+    }
+
+    @Override
+    public URI toUri() {
+        return UnixUriUtils.toUri(this);
+    }
+
+    @Override
+    public WatchKey register(WatchService watcher,
+                             WatchEvent.Kind<?>[] events,
+                             WatchEvent.Modifier... modifiers)
+        throws IOException
+    {
+        if (watcher == null)
+            throw new NullPointerException();
+        if (!(watcher instanceof AbstractWatchService))
+            throw new ProviderMismatchException();
+        checkRead();
+        return ((AbstractWatchService)watcher).register(this, events, modifiers);
+    }
+}
diff --git a/jdk/src/solaris/classes/sun/nio/fs/UnixSecureDirectoryStream.java b/jdk/src/solaris/classes/sun/nio/fs/UnixSecureDirectoryStream.java
new file mode 100644
index 0000000..e589487
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixSecureDirectoryStream.java
@@ -0,0 +1,643 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.nio.channels.SeekableByteChannel;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import java.io.IOException;
+
+import static sun.nio.fs.UnixNativeDispatcher.*;
+import static sun.nio.fs.UnixConstants.*;
+
+/**
+ * Unix implementation of SecureDirectoryStream.
+ */
+
+class UnixSecureDirectoryStream
+    extends SecureDirectoryStream
+{
+    private final UnixDirectoryStream ds;
+    private final int dfd;
+
+    UnixSecureDirectoryStream(UnixPath dir,
+                              long dp,
+                              int dfd,
+                              DirectoryStream.Filter<? super Path> filter)
+    {
+        this.ds = new UnixDirectoryStream(dir, dp, filter);
+        this.dfd = dfd;
+    }
+
+    @Override
+    public void close()
+        throws IOException
+    {
+        ds.writeLock().lock();
+        try {
+            if (ds.closeImpl()) {
+                UnixNativeDispatcher.close(dfd);
+            }
+        } finally {
+            ds.writeLock().unlock();
+        }
+    }
+
+    @Override
+    public Iterator<Path> iterator() {
+        return ds.iterator(this);
+    }
+
+    private UnixPath getName(Path obj) {
+        if (obj == null)
+            throw new NullPointerException();
+        if (!(obj instanceof UnixPath))
+            throw new ProviderMismatchException();
+        return (UnixPath)obj;
+    }
+
+    /**
+     * Opens sub-directory in this directory
+     */
+    @Override
+    public SecureDirectoryStream newDirectoryStream(Path obj,
+                                                    boolean followLinks,
+                                                    DirectoryStream.Filter<? super Path> filter)
+        throws IOException
+    {
+        UnixPath file = getName(obj);
+        UnixPath child = ds.directory().resolve(file);
+
+        // permission check using name resolved against original path of directory
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            child.checkRead();
+        }
+
+        ds.readLock().lock();
+        try {
+            if (!ds.isOpen())
+                throw new ClosedDirectoryStreamException();
+
+            // open directory and create new secure directory stream
+            int newdfd1 = -1;
+            int newdfd2 = -1;
+            long ptr = 0L;
+            try {
+                int flags = O_RDONLY;
+                if (!followLinks)
+                    flags |= O_NOFOLLOW;
+                newdfd1 = openat(dfd, file.asByteArray(), flags , 0);
+                newdfd2 = dup(newdfd1);
+                ptr = fdopendir(newdfd1);
+            } catch (UnixException x) {
+                if (newdfd1 != -1)
+                    UnixNativeDispatcher.close(newdfd1);
+                if (newdfd2 != -1)
+                    UnixNativeDispatcher.close(newdfd2);
+                if (x.errno() == UnixConstants.ENOTDIR)
+                    throw new NotDirectoryException(file.toString());
+                x.rethrowAsIOException(file);
+            }
+            return new UnixSecureDirectoryStream(child, ptr, newdfd2, filter);
+        } finally {
+            ds.readLock().unlock();
+        }
+    }
+
+    /**
+     * Opens file in this directory
+     */
+    @Override
+    public SeekableByteChannel newByteChannel(Path obj,
+                                              Set<? extends OpenOption> options,
+                                              FileAttribute<?>... attrs)
+        throws IOException
+    {
+        UnixPath file = getName(obj);
+
+        int mode = UnixFileModeAttribute
+            .toUnixMode(UnixFileModeAttribute.ALL_READWRITE, attrs);
+
+        // path for permission check
+        String pathToCheck = ds.directory().resolve(file).getPathForPermissionCheck();
+
+        ds.readLock().lock();
+        try {
+            if (!ds.isOpen())
+                throw new ClosedDirectoryStreamException();
+            try {
+                return UnixChannelFactory.newFileChannel(dfd, file, pathToCheck, options, mode);
+            } catch (UnixException x) {
+                x.rethrowAsIOException(file);
+                return null; // keep compiler happy
+            }
+        } finally {
+            ds.readLock().unlock();
+        }
+    }
+
+    /**
+     * Deletes file/directory in this directory. Works in a race-free manner
+     * when invoked with flags.
+     */
+    void implDelete(Path obj, boolean haveFlags, int flags)
+        throws IOException
+    {
+        UnixPath file = getName(obj);
+
+        // permission check using name resolved against original path of directory
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            ds.directory().resolve(file).checkDelete();
+        }
+
+        ds.readLock().lock();
+        try {
+            if (!ds.isOpen())
+                throw new ClosedDirectoryStreamException();
+
+            if (!haveFlags) {
+                // need file attribute to know if file is directory. This creates
+                // a race in that the file may be replaced by a directory or a
+                // directory replaced by a file between the time we query the
+                // file type and unlink it.
+                UnixFileAttributes attrs = null;
+                try {
+                    attrs = UnixFileAttributes.get(dfd, file, false);
+                } catch (UnixException x) {
+                    x.rethrowAsIOException(file);
+                }
+                flags = (attrs.isDirectory()) ? AT_REMOVEDIR : 0;
+            }
+
+            try {
+                unlinkat(dfd, file.asByteArray(), flags);
+            } catch (UnixException x) {
+                if ((flags & AT_REMOVEDIR) != 0) {
+                    if (x.errno() == EEXIST || x.errno() == ENOTEMPTY) {
+                        throw new DirectoryNotEmptyException(null);
+                    }
+                }
+                x.rethrowAsIOException(file);
+            }
+        } finally {
+            ds.readLock().unlock();
+        }
+    }
+
+    @Override
+    public void deleteFile(Path file) throws IOException {
+        implDelete(file, true, 0);
+    }
+
+    @Override
+    public void deleteDirectory(Path dir) throws IOException {
+        implDelete(dir, true, AT_REMOVEDIR);
+    }
+
+    /**
+     * Rename/move file in this directory to another (open) directory
+     */
+    @Override
+    public void move(Path fromObj, SecureDirectoryStream dir, Path toObj)
+        throws IOException
+    {
+        UnixPath from = getName(fromObj);
+        UnixPath to = getName(toObj);
+        if (dir == null)
+            throw new NullPointerException();
+        if (!(dir instanceof UnixSecureDirectoryStream))
+            throw new ProviderMismatchException();
+        UnixSecureDirectoryStream that = (UnixSecureDirectoryStream)dir;
+
+        // permission check
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            this.ds.directory().resolve(from).checkWrite();
+            that.ds.directory().resolve(to).checkWrite();
+        }
+
+        // lock ordering doesn't matter
+        this.ds.readLock().lock();
+        try {
+            that.ds.readLock().lock();
+            try {
+                if (!this.ds.isOpen() || !that.ds.isOpen())
+                    throw new ClosedDirectoryStreamException();
+                try {
+                    renameat(this.dfd, from.asByteArray(), that.dfd, to.asByteArray());
+                } catch (UnixException x) {
+                    if (x.errno() == EXDEV) {
+                        throw new AtomicMoveNotSupportedException(
+                            from.toString(), to.toString(), x.errorString());
+                    }
+                    x.rethrowAsIOException(from, to);
+                }
+            } finally {
+                that.ds.readLock().unlock();
+            }
+        } finally {
+            this.ds.readLock().unlock();
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private <V extends FileAttributeView> V getFileAttributeViewImpl(UnixPath file,
+                                                                     Class<V> type,
+                                                                     boolean followLinks)
+    {
+        if (type == null)
+            throw new NullPointerException();
+        Class<?> c = type;
+        if (c == BasicFileAttributeView.class) {
+            return (V) new BasicFileAttributeViewImpl(file, followLinks);
+        }
+        if (c == PosixFileAttributeView.class || c == FileOwnerAttributeView.class) {
+            return (V) new PosixFileAttributeViewImpl(file, followLinks);
+        }
+        // TBD - should also support AclFileAttributeView
+        return (V) null;
+    }
+
+    /**
+     * Returns file attribute view bound to this directory
+     */
+    @Override
+    public <V extends FileAttributeView> V getFileAttributeView(Class<V> type) {
+        return getFileAttributeViewImpl(null, type, false);
+    }
+
+    /**
+     * Returns file attribute view bound to dfd/filename.
+     */
+    @Override
+    public <V extends FileAttributeView> V getFileAttributeView(Path obj,
+                                                                Class<V> type,
+                                                                LinkOption... options)
+    {
+        UnixPath file = getName(obj);
+        boolean followLinks = file.getFileSystem().followLinks(options);
+        return getFileAttributeViewImpl(file, type, followLinks);
+    }
+
+    /**
+     * A BasicFileAttributeView implementation that using a dfd/name pair.
+     */
+    private class BasicFileAttributeViewImpl
+        extends AbstractBasicFileAttributeView
+    {
+        final UnixPath file;
+        final boolean followLinks;
+
+        // set to true when binding to another object
+        volatile boolean forwarding;
+
+        BasicFileAttributeViewImpl(UnixPath file, boolean followLinks)
+        {
+            this.file = file;
+            this.followLinks = followLinks;
+        }
+
+        int open() throws IOException {
+            int oflags = O_RDONLY;
+            if (!followLinks)
+                oflags |= O_NOFOLLOW;
+            try {
+                return openat(dfd, file.asByteArray(), oflags, 0);
+            } catch (UnixException x) {
+                x.rethrowAsIOException(file);
+                return -1; // keep compiler happy
+            }
+        }
+
+        private void checkWriteAccess() {
+            SecurityManager sm = System.getSecurityManager();
+            if (sm != null) {
+                ds.directory().resolve(file).checkWrite();
+            }
+        }
+
+        @Override
+        public String name() {
+            return "basic";
+        }
+
+        @Override
+        public BasicFileAttributes readAttributes() throws IOException {
+            ds.readLock().lock();
+            try {
+                if (!ds.isOpen())
+                    throw new ClosedDirectoryStreamException();
+
+                SecurityManager sm = System.getSecurityManager();
+                if (sm != null) {
+                    if (file == null) {
+                        ds.directory().checkRead();
+                    } else {
+                        ds.directory().resolve(file).checkRead();
+                    }
+                }
+                try {
+                     UnixFileAttributes attrs = (file == null) ?
+                         UnixFileAttributes.get(dfd) :
+                         UnixFileAttributes.get(dfd, file, followLinks);
+
+                     // SECURITY: must return as BasicFileAttribute
+                     return attrs.asBasicFileAttributes();
+                } catch (UnixException x) {
+                    x.rethrowAsIOException(file);
+                    return null;    // keep compiler happy
+                }
+            } finally {
+                ds.readLock().unlock();
+            }
+        }
+
+        @Override
+        public void setTimes(Long lastModifiedTime,
+                             Long lastAccessTime,
+                             Long createTime, // ignore
+                             TimeUnit unit)
+            throws IOException
+        {
+            // no effect
+            if (lastModifiedTime == null && lastAccessTime == null) {
+                return;
+            }
+
+            checkWriteAccess();
+
+            ds.readLock().lock();
+            try {
+                if (!ds.isOpen())
+                    throw new ClosedDirectoryStreamException();
+
+                int fd = (file == null) ? dfd : open();
+                try {
+                    UnixFileAttributes attrs = null;
+
+                    // if not changing both attributes then need existing attributes
+                    if (lastModifiedTime == null || lastAccessTime == null) {
+                        try {
+                            attrs = UnixFileAttributes.get(fd);
+                        } catch (UnixException x) {
+                            x.rethrowAsIOException(file);
+                        }
+                    }
+
+                    // modified time = existing, now, or new value
+                    long modTime;
+                    if (lastModifiedTime == null) {
+                        modTime = attrs.lastModifiedTime();
+                    } else {
+                        if (lastModifiedTime >= 0L) {
+                            modTime = TimeUnit.MILLISECONDS.convert(lastModifiedTime, unit);
+                        } else {
+                            if (lastModifiedTime != -1L)
+                                throw new IllegalArgumentException();
+                            modTime = System.currentTimeMillis();
+                        }
+                    }
+
+                    // access time = existing, now, or new value
+                    long accTime;
+                    if (lastAccessTime == null) {
+                        accTime = attrs.lastAccessTime();
+                    } else {
+                        if (lastAccessTime >= 0L) {
+                            accTime = TimeUnit.MILLISECONDS.convert(lastAccessTime, unit);
+                        } else {
+                            if (lastAccessTime != -1L)
+                                throw new IllegalArgumentException();
+                            accTime = System.currentTimeMillis();
+                        }
+                    }
+
+                    try {
+                        futimes(fd, accTime, modTime);
+                    } catch (UnixException x) {
+                        x.rethrowAsIOException(file);
+                    }
+                } finally {
+                    if (file != null)
+                        UnixNativeDispatcher.close(fd);
+                }
+            } finally {
+                ds.readLock().unlock();
+            }
+        }
+    }
+
+    /**
+     * A PosixFileAttributeView implementation that using a dfd/name pair.
+     */
+    private class PosixFileAttributeViewImpl
+        extends BasicFileAttributeViewImpl implements PosixFileAttributeView
+    {
+        private static final String PERMISSIONS_NAME = "permissions";
+        private static final String OWNER_NAME = "owner";
+        private static final String GROUP_NAME = "group";
+
+        PosixFileAttributeViewImpl(UnixPath file, boolean followLinks) {
+            super(file, followLinks);
+        }
+
+        private void checkWriteAndUserAccess() {
+            SecurityManager sm = System.getSecurityManager();
+            if (sm != null) {
+                super.checkWriteAccess();
+                sm.checkPermission(new RuntimePermission("accessUserInformation"));
+            }
+        }
+
+        @Override
+        public String name() {
+            return "posix";
+        }
+
+        @Override
+        public Object getAttribute(String attribute) throws IOException {
+            if (attribute.equals(PERMISSIONS_NAME))
+                return readAttributes().permissions();
+            if (attribute.equals(OWNER_NAME))
+                return readAttributes().owner();
+            if (attribute.equals(GROUP_NAME))
+                return readAttributes().group();
+            return super.getAttribute(attribute);
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public void setAttribute(String attribute, Object value)
+            throws IOException
+        {
+            if (attribute.equals(PERMISSIONS_NAME)) {
+                setPermissions((Set<PosixFilePermission>)value);
+                return;
+            }
+            if (attribute.equals(OWNER_NAME)) {
+                setOwner((UserPrincipal)value);
+                return;
+            }
+            if (attribute.equals(GROUP_NAME)) {
+                setGroup((GroupPrincipal)value);
+                return;
+            }
+            super.setAttribute(attribute, value);
+        }
+
+        final void addPosixAttributesToBuilder(PosixFileAttributes attrs,
+                                               AttributesBuilder builder)
+        {
+            if (builder.match(PERMISSIONS_NAME))
+                builder.add(PERMISSIONS_NAME, attrs.permissions());
+            if (builder.match(OWNER_NAME))
+                builder.add(OWNER_NAME, attrs.owner());
+            if (builder.match(GROUP_NAME))
+                builder.add(GROUP_NAME, attrs.group());
+        }
+
+        @Override
+        public Map<String,?> readAttributes(String first, String[] rest)
+            throws IOException
+        {
+            AttributesBuilder builder = AttributesBuilder.create(first, rest);
+            PosixFileAttributes attrs = readAttributes();
+            addBasicAttributesToBuilder(attrs, builder);
+            addPosixAttributesToBuilder(attrs, builder);
+            return builder.unmodifiableMap();
+        }
+
+        @Override
+        public PosixFileAttributes readAttributes() throws IOException {
+            SecurityManager sm = System.getSecurityManager();
+            if (sm != null) {
+                if (file == null)
+                    ds.directory().checkRead();
+                else
+                    ds.directory().resolve(file).checkRead();
+                sm.checkPermission(new RuntimePermission("accessUserInformation"));
+            }
+
+            ds.readLock().lock();
+            try {
+                if (!ds.isOpen())
+                    throw new ClosedDirectoryStreamException();
+
+                try {
+                     UnixFileAttributes attrs = (file == null) ?
+                         UnixFileAttributes.get(dfd) :
+                         UnixFileAttributes.get(dfd, file, followLinks);
+                     return attrs;
+                } catch (UnixException x) {
+                    x.rethrowAsIOException(file);
+                    return null;    // keep compiler happy
+                }
+            } finally {
+                ds.readLock().unlock();
+            }
+        }
+
+        @Override
+        public void setPermissions(Set<PosixFilePermission> perms)
+            throws IOException
+        {
+            // permission check
+            checkWriteAndUserAccess();
+
+            ds.readLock().lock();
+            try {
+                if (!ds.isOpen())
+                    throw new ClosedDirectoryStreamException();
+
+                int fd = (file == null) ? dfd : open();
+                try {
+                    fchmod(fd, UnixFileModeAttribute.toUnixMode(perms));
+                } catch (UnixException x) {
+                    x.rethrowAsIOException(file);
+                } finally {
+                    if (file != null && fd >= 0)
+                        UnixNativeDispatcher.close(fd);
+                }
+            } finally {
+                ds.readLock().unlock();
+            }
+        }
+
+        private void setOwners(int uid, int gid) throws IOException {
+            // permission check
+            checkWriteAndUserAccess();
+
+            ds.readLock().lock();
+            try {
+                if (!ds.isOpen())
+                    throw new ClosedDirectoryStreamException();
+
+                int fd = (file == null) ? dfd : open();
+                try {
+                    fchown(fd, uid, gid);
+                } catch (UnixException x) {
+                    x.rethrowAsIOException(file);
+                } finally {
+                    if (file != null && fd >= 0)
+                        UnixNativeDispatcher.close(fd);
+                }
+            } finally {
+                ds.readLock().unlock();
+            }
+        }
+
+        @Override
+        public UserPrincipal getOwner() throws IOException {
+            return readAttributes().owner();
+        }
+
+        @Override
+        public void setOwner(UserPrincipal owner)
+            throws IOException
+        {
+            if (!(owner instanceof UnixUserPrincipals.User))
+                throw new ProviderMismatchException();
+            if (owner instanceof UnixUserPrincipals.Group)
+                throw new IOException("'owner' parameter can't be a group");
+            int uid = ((UnixUserPrincipals.User)owner).uid();
+            setOwners(uid, -1);
+        }
+
+        @Override
+        public void setGroup(GroupPrincipal group)
+            throws IOException
+        {
+            if (!(group instanceof UnixUserPrincipals.Group))
+                throw new ProviderMismatchException();
+            int gid = ((UnixUserPrincipals.Group)group).gid();
+            setOwners(-1, gid);
+        }
+    }
+}
diff --git a/jdk/src/solaris/classes/sun/nio/fs/UnixUriUtils.java b/jdk/src/solaris/classes/sun/nio/fs/UnixUriUtils.java
new file mode 100644
index 0000000..bf3c78d
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixUriUtils.java
@@ -0,0 +1,216 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+/**
+ * Unix specific Path <--> URI conversion
+ */
+
+class UnixUriUtils {
+    private UnixUriUtils() { }
+
+    /**
+     * Converts URI to Path
+     */
+    static UnixPath fromUri(UnixFileSystem fs, URI uri) {
+        if (!uri.isAbsolute())
+            throw new IllegalArgumentException("URI is not absolute");
+        if (uri.isOpaque())
+            throw new IllegalArgumentException("URI is not hierarchical");
+        String scheme = uri.getScheme();
+        if ((scheme == null) || !scheme.equalsIgnoreCase("file"))
+            throw new IllegalArgumentException("URI scheme is not \"file\"");
+        if (uri.getAuthority() != null)
+            throw new IllegalArgumentException("URI has an authority component");
+        if (uri.getFragment() != null)
+            throw new IllegalArgumentException("URI has a fragment component");
+        if (uri.getQuery() != null)
+            throw new IllegalArgumentException("URI has a query component");
+
+        String path = uri.getPath();
+        if (path.equals(""))
+            throw new IllegalArgumentException("URI path component is empty");
+        if (path.endsWith("/") && (path.length() > 1)) {
+            // "/foo/" --> "/foo", but "/" --> "/"
+            path = path.substring(0, path.length() - 1);
+        }
+
+        // preserve bytes
+        byte[] result = new byte[path.length()];
+        for (int i=0; i<path.length(); i++) {
+            byte v = (byte)(path.charAt(i));
+            if (v == 0)
+                throw new IllegalArgumentException("Nul character not allowed");
+            result[i] = v;
+        }
+        return new UnixPath(fs, result);
+    }
+
+    /**
+     * Converts Path to URI
+     */
+    static URI toUri(UnixPath up) {
+        byte[] path = up.toAbsolutePath().asByteArray();
+        StringBuilder sb = new StringBuilder("file:///");
+        assert path[0] == '/';
+        for (int i=1; i<path.length; i++) {
+            char c = (char)(path[i] & 0xff);
+            if (match(c, L_PATH, H_PATH)) {
+                sb.append(c);
+            } else {
+               sb.append('%');
+               sb.append(hexDigits[(c >> 4) & 0x0f]);
+               sb.append(hexDigits[(c >> 0) & 0x0f]);
+            }
+        }
+
+        // trailing slash if directory
+        if (sb.charAt(sb.length()-1) != '/') {
+            try {
+                 if (UnixFileAttributes.get(up, true).isDirectory())
+                     sb.append('/');
+            } catch (UnixException x) {
+                // ignore
+            }
+        }
+
+        try {
+            return new URI(sb.toString());
+        } catch (URISyntaxException x) {
+            throw new AssertionError(x);  // should not happen
+        }
+    }
+
+    // The following is copied from java.net.URI
+
+    // Compute the low-order mask for the characters in the given string
+    private static long lowMask(String chars) {
+        int n = chars.length();
+        long m = 0;
+        for (int i = 0; i < n; i++) {
+            char c = chars.charAt(i);
+            if (c < 64)
+                m |= (1L << c);
+        }
+        return m;
+    }
+
+    // Compute the high-order mask for the characters in the given string
+    private static long highMask(String chars) {
+        int n = chars.length();
+        long m = 0;
+        for (int i = 0; i < n; i++) {
+            char c = chars.charAt(i);
+            if ((c >= 64) && (c < 128))
+                m |= (1L << (c - 64));
+        }
+        return m;
+    }
+
+    // Compute a low-order mask for the characters
+    // between first and last, inclusive
+    private static long lowMask(char first, char last) {
+        long m = 0;
+        int f = Math.max(Math.min(first, 63), 0);
+        int l = Math.max(Math.min(last, 63), 0);
+        for (int i = f; i <= l; i++)
+            m |= 1L << i;
+        return m;
+    }
+
+    // Compute a high-order mask for the characters
+    // between first and last, inclusive
+    private static long highMask(char first, char last) {
+        long m = 0;
+        int f = Math.max(Math.min(first, 127), 64) - 64;
+        int l = Math.max(Math.min(last, 127), 64) - 64;
+        for (int i = f; i <= l; i++)
+            m |= 1L << i;
+        return m;
+    }
+
+    // Tell whether the given character is permitted by the given mask pair
+    private static boolean match(char c, long lowMask, long highMask) {
+        if (c < 64)
+            return ((1L << c) & lowMask) != 0;
+        if (c < 128)
+            return ((1L << (c - 64)) & highMask) != 0;
+        return false;
+    }
+
+    // digit    = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" |
+    //            "8" | "9"
+    private static final long L_DIGIT = lowMask('0', '9');
+    private static final long H_DIGIT = 0L;
+
+    // upalpha  = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" |
+    //            "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" |
+    //            "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z"
+    private static final long L_UPALPHA = 0L;
+    private static final long H_UPALPHA = highMask('A', 'Z');
+
+    // lowalpha = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" |
+    //            "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" |
+    //            "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z"
+    private static final long L_LOWALPHA = 0L;
+    private static final long H_LOWALPHA = highMask('a', 'z');
+
+    // alpha         = lowalpha | upalpha
+    private static final long L_ALPHA = L_LOWALPHA | L_UPALPHA;
+    private static final long H_ALPHA = H_LOWALPHA | H_UPALPHA;
+
+    // alphanum      = alpha | digit
+    private static final long L_ALPHANUM = L_DIGIT | L_ALPHA;
+    private static final long H_ALPHANUM = H_DIGIT | H_ALPHA;
+
+    // mark          = "-" | "_" | "." | "!" | "~" | "*" | "'" |
+    //                 "(" | ")"
+    private static final long L_MARK = lowMask("-_.!~*'()");
+    private static final long H_MARK = highMask("-_.!~*'()");
+
+    // unreserved    = alphanum | mark
+    private static final long L_UNRESERVED = L_ALPHANUM | L_MARK;
+    private static final long H_UNRESERVED = H_ALPHANUM | H_MARK;
+
+    // pchar         = unreserved | escaped |
+    //                 ":" | "@" | "&" | "=" | "+" | "$" | ","
+    private static final long L_PCHAR
+        = L_UNRESERVED | lowMask(":@&=+$,");
+    private static final long H_PCHAR
+        = H_UNRESERVED | highMask(":@&=+$,");
+
+   // All valid path characters
+   private static final long L_PATH = L_PCHAR | lowMask(";/");
+   private static final long H_PATH = H_PCHAR | highMask(";/");
+
+   private final static char[] hexDigits = {
+        '0', '1', '2', '3', '4', '5', '6', '7',
+        '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
+    };
+}
diff --git a/jdk/src/solaris/classes/sun/nio/fs/UnixUserPrincipals.java b/jdk/src/solaris/classes/sun/nio/fs/UnixUserPrincipals.java
new file mode 100644
index 0000000..88dfe9c
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixUserPrincipals.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.attribute.*;
+import java.io.IOException;
+import static sun.nio.fs.UnixNativeDispatcher.*;
+
+/**
+ * Unix implementation of java.nio.file.attribute.UserPrincipal
+ */
+
+class UnixUserPrincipals {
+    private static User createSpecial(String name) { return new User(-1, name); }
+
+    static final User SPECIAL_OWNER = createSpecial("OWNER@");
+    static final User SPECIAL_GROUP = createSpecial("GROUP@");
+    static final User SPECIAL_EVERYONE = createSpecial("EVERYONE@");
+
+    static class User implements UserPrincipal {
+        private final int id;             // uid or gid
+        private final boolean isGroup;
+        private final String name;
+
+        private User(int id, boolean isGroup, String name) {
+            this.id = id;
+            this.isGroup = isGroup;
+            this.name = name;
+        }
+
+        User(int id, String name) {
+            this(id, false, name);
+        }
+
+        int uid() {
+            if (isGroup)
+                throw new AssertionError();
+            return id;
+        }
+
+        int gid() {
+            if (isGroup)
+                return id;
+            throw new AssertionError();
+        }
+
+        boolean isSpecial() {
+            return id == -1;
+        }
+
+        @Override
+        public String getName() {
+            return name;
+        }
+
+        @Override
+        public String toString() {
+            return name;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj == this)
+                return true;
+            if (!(obj instanceof User))
+                return false;
+            User other = (User)obj;
+            if ((this.id != other.id) ||
+                (this.isGroup != other.isGroup)) {
+                return false;
+            }
+            // specials
+            if (this.id == -1 && other.id == -1)
+                return this.name.equals(other.name);
+
+            return true;
+        }
+
+        @Override
+        public int hashCode() {
+            return (id != -1) ? id : name.hashCode();
+        }
+    }
+
+    static class Group extends User implements GroupPrincipal {
+        Group(int id, String name) {
+            super(id, true, name);
+        }
+    }
+
+    // return UserPrincipal representing given uid
+    static User fromUid(int uid) {
+        String name = null;
+        try {
+            name = new String(getpwuid(uid));
+        } catch (UnixException x) {
+            name = Integer.toString(uid);
+        }
+        return new User(uid, name);
+    }
+
+    // return GroupPrincipal representing given gid
+    static Group fromGid(int gid) {
+        String name = null;
+        try {
+            name = new String(getgrgid(gid));
+        } catch (UnixException x) {
+            name = Integer.toString(gid);
+        }
+        return new Group(gid, name);
+    }
+
+    // lookup user or group name
+    private static int lookupName(String name, boolean isGroup)
+        throws IOException
+    {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(new RuntimePermission("lookupUserInformation"));
+        }
+        int id = -1;
+        try {
+            id = (isGroup) ? getgrnam(name) : getpwnam(name);
+        } catch (UnixException x) {
+            throw new IOException(name + ": " + x.errorString());
+        }
+        if (id == -1)
+            throw new UserPrincipalNotFoundException(name);
+        return id;
+
+    }
+
+    // lookup user name
+    static UserPrincipal lookupUser(String name) throws IOException {
+        if (name.equals(SPECIAL_OWNER.getName()))
+            return SPECIAL_OWNER;
+        if (name.equals(SPECIAL_GROUP.getName()))
+            return SPECIAL_GROUP;
+        if (name.equals(SPECIAL_EVERYONE.getName()))
+            return SPECIAL_EVERYONE;
+        int uid = lookupName(name, false);
+        return new User(uid, name);
+    }
+
+    // lookup group name
+    static GroupPrincipal lookupGroup(String group)
+        throws IOException
+    {
+        int gid = lookupName(group, true);
+        return new Group(gid, group);
+    }
+}
diff --git a/jdk/src/solaris/native/java/net/Inet4AddressImpl.c b/jdk/src/solaris/native/java/net/Inet4AddressImpl.c
index a41aa96..9e3cca4 100644
--- a/jdk/src/solaris/native/java/net/Inet4AddressImpl.c
+++ b/jdk/src/solaris/native/java/net/Inet4AddressImpl.c
@@ -165,16 +165,18 @@
     hostname = JNU_GetStringPlatformChars(env, host, JNI_FALSE);
     CHECK_NULL_RETURN(hostname, NULL);
 
+#ifdef __solaris__
     /*
      * Workaround for Solaris bug 4160367 - if a hostname contains a
      * white space then 0.0.0.0 is returned
      */
-    if (isspace(hostname[0])) {
+    if (isspace((unsigned char)hostname[0])) {
         JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException",
                         (char *)hostname);
         JNU_ReleaseStringPlatformChars(env, host, hostname);
         return NULL;
     }
+#endif
 
     /* Try once, with our static buffer. */
 #ifdef __GLIBC__
@@ -325,7 +327,8 @@
 ping4(JNIEnv *env, jint fd, struct sockaddr_in* him, jint timeout,
       struct sockaddr_in* netif, jint ttl) {
     jint size;
-    jint n, len, hlen1, icmplen;
+    jint n, hlen1, icmplen;
+    socklen_t len;
     char sendbuf[1500];
     char recvbuf[1500];
     struct icmp *icmp;
diff --git a/jdk/src/solaris/native/java/net/Inet6AddressImpl.c b/jdk/src/solaris/native/java/net/Inet6AddressImpl.c
index 181307f..5ecedbc 100644
--- a/jdk/src/solaris/native/java/net/Inet6AddressImpl.c
+++ b/jdk/src/solaris/native/java/net/Inet6AddressImpl.c
@@ -196,16 +196,18 @@
         hints.ai_flags = AI_CANONNAME;
         hints.ai_family = AF_UNSPEC;
 
+#ifdef __solaris__
         /*
          * Workaround for Solaris bug 4160367 - if a hostname contains a
          * white space then 0.0.0.0 is returned
          */
-        if (isspace(hostname[0])) {
+        if (isspace((unsigned char)hostname[0])) {
             JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException",
                             (char *)hostname);
             JNU_ReleaseStringPlatformChars(env, host, hostname);
             return NULL;
         }
+#endif
 
         error = (*getaddrinfo_ptr)(hostname, NULL, &hints, &res);
 
@@ -455,7 +457,8 @@
 ping6(JNIEnv *env, jint fd, struct sockaddr_in6* him, jint timeout,
       struct sockaddr_in6* netif, jint ttl) {
     jint size;
-    jint n, len;
+    jint n;
+    socklen_t len;
     char sendbuf[1500];
     unsigned char recvbuf[1500];
     struct icmp6_hdr *icmp6;
diff --git a/jdk/src/solaris/native/java/net/NetworkInterface.c b/jdk/src/solaris/native/java/net/NetworkInterface.c
index 14273f5..a741f86 100644
--- a/jdk/src/solaris/native/java/net/NetworkInterface.c
+++ b/jdk/src/solaris/native/java/net/NetworkInterface.c
@@ -969,13 +969,39 @@
            // Got access to parent, so create it if necessary.
            strcpy(vname, name);
            *unit = '\0';
-        }
-        else {
+        } else {
+#if defined(__solaris__) && defined(AF_INET6)
+          struct   lifreq lifr;
+          memset((char *) &lifr, 0, sizeof(lifr));
+          strcpy(lifr.lifr_name, vname);
+
+          /* Try with an IPv6 socket in case the interface has only IPv6
+           * addresses assigned to it */
+          close(sock);
+          sock = JVM_Socket(AF_INET6, SOCK_DGRAM, 0);
+
+          if (sock < 0) {
+            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                         "Socket creation failed");
+            return ifs; /* return untouched list */
+          }
+
+          if (ioctl(sock, SIOCGLIFFLAGS, (char *)&lifr) >= 0) {
+            // Got access to parent, so create it if necessary.
+            strcpy(vname, name);
+            *unit = '\0';
+          } else {
+            // failed to access parent interface do not create parent.
+            // We are a virtual interface with no parent.
+            isVirtual = 1;
+            vname[0] = 0;
+          }
+#else
           // failed to access parent interface do not create parent.
           // We are a virtual interface with no parent.
           isVirtual = 1;
-
           vname[0] = 0;
+#endif
         }
       }
       close(sock);
diff --git a/jdk/src/solaris/native/sun/nio/ch/EPoll.c b/jdk/src/solaris/native/sun/nio/ch/EPoll.c
new file mode 100644
index 0000000..fc9cab7
--- /dev/null
+++ b/jdk/src/solaris/native/sun/nio/ch/EPoll.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+#include "jni.h"
+#include "jni_util.h"
+#include "jvm.h"
+#include "jlong.h"
+#include "nio_util.h"
+
+#include "sun_nio_ch_EPoll.h"
+
+#include <dlfcn.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* epoll_wait(2) man page */
+
+typedef union epoll_data {
+    void *ptr;
+    int fd;
+    __uint32_t u32;
+    __uint64_t u64;
+} epoll_data_t;
+
+struct epoll_event {
+    __uint32_t events;  /* Epoll events */
+    epoll_data_t data;  /* User data variable */
+} __attribute__ ((__packed__));
+
+#ifdef  __cplusplus
+}
+#endif
+
+/*
+ * epoll event notification is new in 2.6 kernel. As the offical build
+ * platform for the JDK is on a 2.4-based distribution then we must
+ * obtain the addresses of the epoll functions dynamically.
+ */
+typedef int (*epoll_create_t)(int size);
+typedef int (*epoll_ctl_t)   (int epfd, int op, int fd, struct epoll_event *event);
+typedef int (*epoll_wait_t)  (int epfd, struct epoll_event *events, int maxevents, int timeout);
+
+static epoll_create_t epoll_create_func;
+static epoll_ctl_t    epoll_ctl_func;
+static epoll_wait_t   epoll_wait_func;
+
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_EPoll_init(JNIEnv *env, jclass this)
+{
+    epoll_create_func = (epoll_create_t) dlsym(RTLD_DEFAULT, "epoll_create");
+    epoll_ctl_func    = (epoll_ctl_t)    dlsym(RTLD_DEFAULT, "epoll_ctl");
+    epoll_wait_func   = (epoll_wait_t)   dlsym(RTLD_DEFAULT, "epoll_wait");
+
+    if ((epoll_create_func == NULL) || (epoll_ctl_func == NULL) ||
+        (epoll_wait_func == NULL)) {
+        JNU_ThrowInternalError(env, "unable to get address of epoll functions, pre-2.6 kernel?");
+    }
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_ch_EPoll_eventSize(JNIEnv* env, jclass this)
+{
+    return sizeof(struct epoll_event);
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_ch_EPoll_eventsOffset(JNIEnv* env, jclass this)
+{
+    return offsetof(struct epoll_event, events);
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_ch_EPoll_dataOffset(JNIEnv* env, jclass this)
+{
+    return offsetof(struct epoll_event, data);
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_ch_EPoll_epollCreate(JNIEnv *env, jclass c) {
+    /*
+     * epoll_create expects a size as a hint to the kernel about how to
+     * dimension internal structures. We can't predict the size in advance.
+     */
+    int epfd = (*epoll_create_func)(256);
+    if (epfd < 0) {
+       JNU_ThrowIOExceptionWithLastError(env, "epoll_create failed");
+    }
+    return epfd;
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_ch_EPoll_epollCtl(JNIEnv *env, jclass c, jint epfd,
+                                   jint opcode, jint fd, jint events)
+{
+    struct epoll_event event;
+    int res;
+
+    event.events = events;
+    event.data.fd = fd;
+
+    RESTARTABLE((*epoll_ctl_func)(epfd, (int)opcode, (int)fd, &event), res);
+
+    return (res == 0) ? 0 : errno;
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_ch_EPoll_epollWait(JNIEnv *env, jclass c,
+                                    jint epfd, jlong address, jint numfds)
+{
+    struct epoll_event *events = jlong_to_ptr(address);
+    int res;
+
+    RESTARTABLE((*epoll_wait_func)(epfd, events, numfds, -1), res);
+    if (res < 0) {
+        JNU_ThrowIOExceptionWithLastError(env, "epoll_wait failed");
+    }
+    return res;
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_EPoll_close0(JNIEnv *env, jclass c, jint epfd) {
+    int res;
+    RESTARTABLE(close(epfd), res);
+}
diff --git a/jdk/src/solaris/native/sun/nio/ch/EPollPort.c b/jdk/src/solaris/native/sun/nio/ch/EPollPort.c
new file mode 100644
index 0000000..8d34dd8
--- /dev/null
+++ b/jdk/src/solaris/native/sun/nio/ch/EPollPort.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+#include "jni.h"
+#include "jni_util.h"
+#include "jvm.h"
+#include "jlong.h"
+#include "nio_util.h"
+
+#include "sun_nio_ch_EPollPort.h"
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_EPollPort_socketpair(JNIEnv* env, jclass clazz, jintArray sv) {
+    int sp[2];
+    if (socketpair(PF_UNIX, SOCK_STREAM, 0, sp) == -1) {
+        JNU_ThrowIOExceptionWithLastError(env, "socketpair failed");
+    } else {
+        jint res[2];
+        res[0] = (jint)sp[0];
+        res[1] = (jint)sp[1];
+        (*env)->SetIntArrayRegion(env, sv, 0, 2, &res[0]);
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_EPollPort_interrupt(JNIEnv *env, jclass c, jint fd) {
+    int res;
+    int buf[1];
+    buf[0] = 1;
+    RESTARTABLE(write(fd, buf, 1), res);
+    if (res < 0) {
+        JNU_ThrowIOExceptionWithLastError(env, "write failed");
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_EPollPort_drain1(JNIEnv *env, jclass cl, jint fd) {
+    int res;
+    char buf[1];
+    RESTARTABLE(read(fd, buf, 1), res);
+    if (res < 0) {
+        JNU_ThrowIOExceptionWithLastError(env, "drain1 failed");
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_EPollPort_close0(JNIEnv *env, jclass c, jint fd) {
+    int res;
+    RESTARTABLE(close(fd), res);
+}
diff --git a/jdk/src/solaris/native/sun/nio/ch/FileChannelImpl.c b/jdk/src/solaris/native/sun/nio/ch/FileChannelImpl.c
index b42c899..7b37e61 100644
--- a/jdk/src/solaris/native/sun/nio/ch/FileChannelImpl.c
+++ b/jdk/src/solaris/native/sun/nio/ch/FileChannelImpl.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2009 Sun Microsystems, Inc.  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
@@ -31,7 +31,6 @@
 #include <sys/stat.h>
 #include "sun_nio_ch_FileChannelImpl.h"
 #include "java_lang_Integer.h"
-#include "java_lang_Long.h"
 #include "nio.h"
 #include "nio_util.h"
 #include <dlfcn.h>
@@ -145,32 +144,6 @@
 }
 
 
-JNIEXPORT jint JNICALL
-Java_sun_nio_ch_FileChannelImpl_truncate0(JNIEnv *env, jobject this,
-                                          jobject fdo, jlong size)
-{
-    return handle(env,
-                  ftruncate64(fdval(env, fdo), size),
-                  "Truncation failed");
-}
-
-
-JNIEXPORT jint JNICALL
-Java_sun_nio_ch_FileChannelImpl_force0(JNIEnv *env, jobject this,
-                                       jobject fdo, jboolean md)
-{
-    jint fd = fdval(env, fdo);
-    int result = 0;
-
-    if (md == JNI_FALSE) {
-        result = fdatasync(fd);
-    } else {
-        result = fsync(fd);
-    }
-    return handle(env, result, "Force failed");
-}
-
-
 JNIEXPORT jlong JNICALL
 Java_sun_nio_ch_FileChannelImpl_position0(JNIEnv *env, jobject this,
                                           jobject fdo, jlong offset)
@@ -187,17 +160,6 @@
 }
 
 
-JNIEXPORT jlong JNICALL
-Java_sun_nio_ch_FileChannelImpl_size0(JNIEnv *env, jobject this, jobject fdo)
-{
-    struct stat64 fbuf;
-
-    if (fstat64(fdval(env, fdo), &fbuf) < 0)
-        return handle(env, -1, "Size failed");
-    return fbuf.st_size;
-}
-
-
 JNIEXPORT void JNICALL
 Java_sun_nio_ch_FileChannelImpl_close0(JNIEnv *env, jobject this, jobject fdo)
 {
@@ -280,65 +242,3 @@
     }
 #endif
 }
-
-JNIEXPORT jint JNICALL
-Java_sun_nio_ch_FileChannelImpl_lock0(JNIEnv *env, jobject this, jobject fdo,
-                                      jboolean block, jlong pos, jlong size,
-                                      jboolean shared)
-{
-    jint fd = fdval(env, fdo);
-    jint lockResult = 0;
-    int cmd = 0;
-    struct flock64 fl;
-
-    fl.l_whence = SEEK_SET;
-    if (size == (jlong)java_lang_Long_MAX_VALUE) {
-        fl.l_len = (off64_t)0;
-    } else {
-        fl.l_len = (off64_t)size;
-    }
-    fl.l_start = (off64_t)pos;
-    if (shared == JNI_TRUE) {
-        fl.l_type = F_RDLCK;
-    } else {
-        fl.l_type = F_WRLCK;
-    }
-    if (block == JNI_TRUE) {
-        cmd = F_SETLKW64;
-    } else {
-        cmd = F_SETLK64;
-    }
-    lockResult = fcntl(fd, cmd, &fl);
-    if (lockResult < 0) {
-        if ((cmd == F_SETLK64) && (errno == EAGAIN))
-            return sun_nio_ch_FileChannelImpl_NO_LOCK;
-        if (errno == EINTR)
-            return sun_nio_ch_FileChannelImpl_INTERRUPTED;
-        JNU_ThrowIOExceptionWithLastError(env, "Lock failed");
-    }
-    return 0;
-}
-
-
-JNIEXPORT void JNICALL
-Java_sun_nio_ch_FileChannelImpl_release0(JNIEnv *env, jobject this,
-                                         jobject fdo, jlong pos, jlong size)
-{
-    jint fd = fdval(env, fdo);
-    jint lockResult = 0;
-    struct flock64 fl;
-    int cmd = F_SETLK64;
-
-    fl.l_whence = SEEK_SET;
-    if (size == (jlong)java_lang_Long_MAX_VALUE) {
-        fl.l_len = (off64_t)0;
-    } else {
-        fl.l_len = (off64_t)size;
-    }
-    fl.l_start = (off64_t)pos;
-    fl.l_type = F_UNLCK;
-    lockResult = fcntl(fd, cmd, &fl);
-    if (lockResult < 0) {
-        JNU_ThrowIOExceptionWithLastError(env, "Release failed");
-    }
-}
diff --git a/jdk/src/solaris/native/sun/nio/ch/FileDispatcher.c b/jdk/src/solaris/native/sun/nio/ch/FileDispatcher.c
deleted file mode 100644
index fd3c0e3..0000000
--- a/jdk/src/solaris/native/sun/nio/ch/FileDispatcher.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright 2000-2002 Sun Microsystems, Inc.  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.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-#include "jni.h"
-#include "jni_util.h"
-#include "jvm.h"
-#include "jlong.h"
-#include "sun_nio_ch_FileDispatcher.h"
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <fcntl.h>
-#include <sys/uio.h>
-#include "nio_util.h"
-
-
-static int preCloseFD = -1;     /* File descriptor to which we dup other fd's
-                                   before closing them for real */
-
-
-JNIEXPORT void JNICALL
-Java_sun_nio_ch_FileDispatcher_init(JNIEnv *env, jclass cl)
-{
-    int sp[2];
-    if (socketpair(PF_UNIX, SOCK_STREAM, 0, sp) < 0) {
-        JNU_ThrowIOExceptionWithLastError(env, "socketpair failed");
-        return;
-    }
-    preCloseFD = sp[0];
-    close(sp[1]);
-}
-
-JNIEXPORT jint JNICALL
-Java_sun_nio_ch_FileDispatcher_read0(JNIEnv *env, jclass clazz,
-                             jobject fdo, jlong address, jint len)
-{
-    jint fd = fdval(env, fdo);
-    void *buf = (void *)jlong_to_ptr(address);
-
-    return convertReturnVal(env, read(fd, buf, len), JNI_TRUE);
-}
-
-JNIEXPORT jint JNICALL
-Java_sun_nio_ch_FileDispatcher_pread0(JNIEnv *env, jclass clazz, jobject fdo,
-                            jlong address, jint len, jlong offset)
-{
-    jint fd = fdval(env, fdo);
-    void *buf = (void *)jlong_to_ptr(address);
-
-    return convertReturnVal(env, pread64(fd, buf, len, offset), JNI_TRUE);
-}
-
-JNIEXPORT jlong JNICALL
-Java_sun_nio_ch_FileDispatcher_readv0(JNIEnv *env, jclass clazz,
-                              jobject fdo, jlong address, jint len)
-{
-    jint fd = fdval(env, fdo);
-    struct iovec *iov = (struct iovec *)jlong_to_ptr(address);
-    if (len > 16) {
-        len = 16;
-    }
-    return convertLongReturnVal(env, readv(fd, iov, len), JNI_TRUE);
-}
-
-JNIEXPORT jint JNICALL
-Java_sun_nio_ch_FileDispatcher_write0(JNIEnv *env, jclass clazz,
-                              jobject fdo, jlong address, jint len)
-{
-    jint fd = fdval(env, fdo);
-    void *buf = (void *)jlong_to_ptr(address);
-
-    return convertReturnVal(env, write(fd, buf, len), JNI_FALSE);
-}
-
-JNIEXPORT jint JNICALL
-Java_sun_nio_ch_FileDispatcher_pwrite0(JNIEnv *env, jclass clazz, jobject fdo,
-                            jlong address, jint len, jlong offset)
-{
-    jint fd = fdval(env, fdo);
-    void *buf = (void *)jlong_to_ptr(address);
-
-    return convertReturnVal(env, pwrite64(fd, buf, len, offset), JNI_FALSE);
-}
-
-JNIEXPORT jlong JNICALL
-Java_sun_nio_ch_FileDispatcher_writev0(JNIEnv *env, jclass clazz,
-                                       jobject fdo, jlong address, jint len)
-{
-    jint fd = fdval(env, fdo);
-    struct iovec *iov = (struct iovec *)jlong_to_ptr(address);
-    if (len > 16) {
-        len = 16;
-    }
-    return convertLongReturnVal(env, writev(fd, iov, len), JNI_FALSE);
-}
-
-static void closeFileDescriptor(JNIEnv *env, int fd) {
-    if (fd != -1) {
-        int result = close(fd);
-        if (result < 0)
-            JNU_ThrowIOExceptionWithLastError(env, "Close failed");
-    }
-}
-
-JNIEXPORT void JNICALL
-Java_sun_nio_ch_FileDispatcher_close0(JNIEnv *env, jclass clazz, jobject fdo)
-{
-    jint fd = fdval(env, fdo);
-    closeFileDescriptor(env, fd);
-}
-
-JNIEXPORT void JNICALL
-Java_sun_nio_ch_FileDispatcher_preClose0(JNIEnv *env, jclass clazz, jobject fdo)
-{
-    jint fd = fdval(env, fdo);
-    if (preCloseFD >= 0) {
-        if (dup2(preCloseFD, fd) < 0)
-            JNU_ThrowIOExceptionWithLastError(env, "dup2 failed");
-    }
-}
-
-JNIEXPORT void JNICALL
-Java_sun_nio_ch_FileDispatcher_closeIntFD(JNIEnv *env, jclass clazz, jint fd)
-{
-    closeFileDescriptor(env, fd);
-}
diff --git a/jdk/src/solaris/native/sun/nio/ch/FileDispatcherImpl.c b/jdk/src/solaris/native/sun/nio/ch/FileDispatcherImpl.c
new file mode 100644
index 0000000..ed65889
--- /dev/null
+++ b/jdk/src/solaris/native/sun/nio/ch/FileDispatcherImpl.c
@@ -0,0 +1,256 @@
+/*
+ * Copyright 2000-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+#include "jni.h"
+#include "jni_util.h"
+#include "jvm.h"
+#include "jlong.h"
+#include "sun_nio_ch_FileDispatcherImpl.h"
+#include "java_lang_Long.h"
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <fcntl.h>
+#include <sys/uio.h>
+#include "nio.h"
+#include "nio_util.h"
+
+
+static int preCloseFD = -1;     /* File descriptor to which we dup other fd's
+                                   before closing them for real */
+
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_FileDispatcherImpl_init(JNIEnv *env, jclass cl)
+{
+    int sp[2];
+    if (socketpair(PF_UNIX, SOCK_STREAM, 0, sp) < 0) {
+        JNU_ThrowIOExceptionWithLastError(env, "socketpair failed");
+        return;
+    }
+    preCloseFD = sp[0];
+    close(sp[1]);
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_ch_FileDispatcherImpl_read0(JNIEnv *env, jclass clazz,
+                             jobject fdo, jlong address, jint len)
+{
+    jint fd = fdval(env, fdo);
+    void *buf = (void *)jlong_to_ptr(address);
+
+    return convertReturnVal(env, read(fd, buf, len), JNI_TRUE);
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_ch_FileDispatcherImpl_pread0(JNIEnv *env, jclass clazz, jobject fdo,
+                            jlong address, jint len, jlong offset)
+{
+    jint fd = fdval(env, fdo);
+    void *buf = (void *)jlong_to_ptr(address);
+
+    return convertReturnVal(env, pread64(fd, buf, len, offset), JNI_TRUE);
+}
+
+JNIEXPORT jlong JNICALL
+Java_sun_nio_ch_FileDispatcherImpl_readv0(JNIEnv *env, jclass clazz,
+                              jobject fdo, jlong address, jint len)
+{
+    jint fd = fdval(env, fdo);
+    struct iovec *iov = (struct iovec *)jlong_to_ptr(address);
+    if (len > 16) {
+        len = 16;
+    }
+    return convertLongReturnVal(env, readv(fd, iov, len), JNI_TRUE);
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_ch_FileDispatcherImpl_write0(JNIEnv *env, jclass clazz,
+                              jobject fdo, jlong address, jint len)
+{
+    jint fd = fdval(env, fdo);
+    void *buf = (void *)jlong_to_ptr(address);
+
+    return convertReturnVal(env, write(fd, buf, len), JNI_FALSE);
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_ch_FileDispatcherImpl_pwrite0(JNIEnv *env, jclass clazz, jobject fdo,
+                            jlong address, jint len, jlong offset)
+{
+    jint fd = fdval(env, fdo);
+    void *buf = (void *)jlong_to_ptr(address);
+
+    return convertReturnVal(env, pwrite64(fd, buf, len, offset), JNI_FALSE);
+}
+
+JNIEXPORT jlong JNICALL
+Java_sun_nio_ch_FileDispatcherImpl_writev0(JNIEnv *env, jclass clazz,
+                                       jobject fdo, jlong address, jint len)
+{
+    jint fd = fdval(env, fdo);
+    struct iovec *iov = (struct iovec *)jlong_to_ptr(address);
+    if (len > 16) {
+        len = 16;
+    }
+    return convertLongReturnVal(env, writev(fd, iov, len), JNI_FALSE);
+}
+
+static jlong
+handle(JNIEnv *env, jlong rv, char *msg)
+{
+    if (rv >= 0)
+        return rv;
+    if (errno == EINTR)
+        return IOS_INTERRUPTED;
+    JNU_ThrowIOExceptionWithLastError(env, msg);
+    return IOS_THROWN;
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_ch_FileDispatcherImpl_force0(JNIEnv *env, jobject this,
+                                          jobject fdo, jboolean md)
+{
+    jint fd = fdval(env, fdo);
+    int result = 0;
+
+    if (md == JNI_FALSE) {
+        result = fdatasync(fd);
+    } else {
+        result = fsync(fd);
+    }
+    return handle(env, result, "Force failed");
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_ch_FileDispatcherImpl_truncate0(JNIEnv *env, jobject this,
+                                             jobject fdo, jlong size)
+{
+    return handle(env,
+                  ftruncate64(fdval(env, fdo), size),
+                  "Truncation failed");
+}
+
+JNIEXPORT jlong JNICALL
+Java_sun_nio_ch_FileDispatcherImpl_size0(JNIEnv *env, jobject this, jobject fdo)
+{
+    struct stat64 fbuf;
+
+    if (fstat64(fdval(env, fdo), &fbuf) < 0)
+        return handle(env, -1, "Size failed");
+    return fbuf.st_size;
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_ch_FileDispatcherImpl_lock0(JNIEnv *env, jobject this, jobject fdo,
+                                      jboolean block, jlong pos, jlong size,
+                                      jboolean shared)
+{
+    jint fd = fdval(env, fdo);
+    jint lockResult = 0;
+    int cmd = 0;
+    struct flock64 fl;
+
+    fl.l_whence = SEEK_SET;
+    if (size == (jlong)java_lang_Long_MAX_VALUE) {
+        fl.l_len = (off64_t)0;
+    } else {
+        fl.l_len = (off64_t)size;
+    }
+    fl.l_start = (off64_t)pos;
+    if (shared == JNI_TRUE) {
+        fl.l_type = F_RDLCK;
+    } else {
+        fl.l_type = F_WRLCK;
+    }
+    if (block == JNI_TRUE) {
+        cmd = F_SETLKW64;
+    } else {
+        cmd = F_SETLK64;
+    }
+    lockResult = fcntl(fd, cmd, &fl);
+    if (lockResult < 0) {
+        if ((cmd == F_SETLK64) && (errno == EAGAIN))
+            return sun_nio_ch_FileDispatcherImpl_NO_LOCK;
+        if (errno == EINTR)
+            return sun_nio_ch_FileDispatcherImpl_INTERRUPTED;
+        JNU_ThrowIOExceptionWithLastError(env, "Lock failed");
+    }
+    return 0;
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_FileDispatcherImpl_release0(JNIEnv *env, jobject this,
+                                         jobject fdo, jlong pos, jlong size)
+{
+    jint fd = fdval(env, fdo);
+    jint lockResult = 0;
+    struct flock64 fl;
+    int cmd = F_SETLK64;
+
+    fl.l_whence = SEEK_SET;
+    if (size == (jlong)java_lang_Long_MAX_VALUE) {
+        fl.l_len = (off64_t)0;
+    } else {
+        fl.l_len = (off64_t)size;
+    }
+    fl.l_start = (off64_t)pos;
+    fl.l_type = F_UNLCK;
+    lockResult = fcntl(fd, cmd, &fl);
+    if (lockResult < 0) {
+        JNU_ThrowIOExceptionWithLastError(env, "Release failed");
+    }
+}
+
+
+static void closeFileDescriptor(JNIEnv *env, int fd) {
+    if (fd != -1) {
+        int result = close(fd);
+        if (result < 0)
+            JNU_ThrowIOExceptionWithLastError(env, "Close failed");
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_FileDispatcherImpl_close0(JNIEnv *env, jclass clazz, jobject fdo)
+{
+    jint fd = fdval(env, fdo);
+    closeFileDescriptor(env, fd);
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_FileDispatcherImpl_preClose0(JNIEnv *env, jclass clazz, jobject fdo)
+{
+    jint fd = fdval(env, fdo);
+    if (preCloseFD >= 0) {
+        if (dup2(preCloseFD, fd) < 0)
+            JNU_ThrowIOExceptionWithLastError(env, "dup2 failed");
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_FileDispatcherImpl_closeIntFD(JNIEnv *env, jclass clazz, jint fd)
+{
+    closeFileDescriptor(env, fd);
+}
diff --git a/jdk/src/solaris/native/sun/nio/ch/SocketDispatcher.c b/jdk/src/solaris/native/sun/nio/ch/SocketDispatcher.c
index 1524326..812ff4b 100644
--- a/jdk/src/solaris/native/sun/nio/ch/SocketDispatcher.c
+++ b/jdk/src/solaris/native/sun/nio/ch/SocketDispatcher.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2001 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2009 Sun Microsystems, Inc.  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
@@ -27,7 +27,6 @@
 #include "jni_util.h"
 #include "jvm.h"
 #include "jlong.h"
-#include "sun_nio_ch_FileDispatcher.h"
 
 /* this is a fake c file to make the build happy since there is no
    real SocketDispatcher.c file on Solaris but there is on windows. */
diff --git a/jdk/src/solaris/native/sun/nio/ch/SolarisEventPort.c b/jdk/src/solaris/native/sun/nio/ch/SolarisEventPort.c
new file mode 100644
index 0000000..6494759
--- /dev/null
+++ b/jdk/src/solaris/native/sun/nio/ch/SolarisEventPort.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+#include "jni.h"
+#include "jni_util.h"
+#include "jvm.h"
+#include "jlong.h"
+#include "nio_util.h"
+
+#include <stdlib.h>
+#include <dlfcn.h>
+#include <sys/types.h>
+#include <port.h>       // Solaris 10
+
+#include "sun_nio_ch_SolarisEventPort.h"
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_SolarisEventPort_init(JNIEnv *env, jclass clazz)
+{
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_ch_SolarisEventPort_portCreate
+    (JNIEnv* env, jclass clazz)
+{
+    int port = port_create();
+    if (port == -1) {
+        JNU_ThrowIOExceptionWithLastError(env, "port_create");
+    }
+    return (jint)port;
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_SolarisEventPort_portClose
+    (JNIEnv* env, jclass clazz, jint port)
+{
+    int res;
+    RESTARTABLE(close(port), res);
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_SolarisEventPort_portAssociate
+    (JNIEnv* env, jclass clazz, jint port, jint source, jlong objectAddress, jint events)
+{
+    uintptr_t object = (uintptr_t)jlong_to_ptr(objectAddress);
+
+    if (port_associate((int)port, (int)source, object, (int)events, NULL) == -1) {
+        JNU_ThrowIOExceptionWithLastError(env, "port_associate");
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_SolarisEventPort_portDissociate
+    (JNIEnv* env, jclass clazz, jint port, jint source, jlong objectAddress)
+{
+    uintptr_t object = (uintptr_t)jlong_to_ptr(objectAddress);
+
+    if (port_dissociate((int)port, (int)source, object) == -1) {
+        JNU_ThrowIOExceptionWithLastError(env, "port_dissociate");
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_SolarisEventPort_portSend(JNIEnv* env, jclass clazz,
+    jint port, jint events)
+{
+    if (port_send((int)port, (int)events, NULL) == -1) {
+        JNU_ThrowIOExceptionWithLastError(env, "port_send");
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_SolarisEventPort_portGet(JNIEnv* env, jclass clazz,
+    jint port, jlong eventAddress)
+{
+    int res;
+    port_event_t* ev = (port_event_t*)jlong_to_ptr(eventAddress);
+
+    RESTARTABLE(port_get((int)port, ev, NULL), res);
+    if (res == -1) {
+        JNU_ThrowIOExceptionWithLastError(env, "port_get");
+    }
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_ch_SolarisEventPort_portGetn(JNIEnv* env, jclass clazz,
+    jint port, jlong arrayAddress, jint max)
+{
+    int res;
+    uint_t n = 1;
+    port_event_t* list = (port_event_t*)jlong_to_ptr(arrayAddress);
+
+    RESTARTABLE(port_getn((int)port, list, (uint_t)max, &n, NULL), res);
+    if (res == -1) {
+        JNU_ThrowIOExceptionWithLastError(env, "port_getn");
+    }
+    return (jint)n;
+}
diff --git a/jdk/src/solaris/native/sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.c b/jdk/src/solaris/native/sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.c
new file mode 100644
index 0000000..9c92cc2
--- /dev/null
+++ b/jdk/src/solaris/native/sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+#include "sun_nio_ch_UnixAsynchronousServerSocketChannelImpl.h"
+
+extern void Java_sun_nio_ch_ServerSocketChannelImpl_initIDs(JNIEnv* env,
+    jclass c);
+
+extern jint Java_sun_nio_ch_ServerSocketChannelImpl_accept0(JNIEnv* env,
+    jobject this, jobject ssfdo, jobject newfdo, jobjectArray isaa);
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_UnixAsynchronousServerSocketChannelImpl_initIDs(JNIEnv* env,
+    jclass c)
+{
+    Java_sun_nio_ch_ServerSocketChannelImpl_initIDs(env, c);
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_ch_UnixAsynchronousServerSocketChannelImpl_accept0(JNIEnv* env,
+    jobject this, jobject ssfdo, jobject newfdo, jobjectArray isaa)
+{
+    return Java_sun_nio_ch_ServerSocketChannelImpl_accept0(env, this,
+        ssfdo, newfdo, isaa);
+}
diff --git a/jdk/src/solaris/native/sun/nio/ch/UnixAsynchronousSocketChannelImpl.c b/jdk/src/solaris/native/sun/nio/ch/UnixAsynchronousSocketChannelImpl.c
new file mode 100644
index 0000000..461d97f
--- /dev/null
+++ b/jdk/src/solaris/native/sun/nio/ch/UnixAsynchronousSocketChannelImpl.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include "jni.h"
+#include "jni_util.h"
+#include "net_util.h"
+#include "jlong.h"
+#include "sun_nio_ch_UnixAsynchronousSocketChannelImpl.h"
+#include "nio_util.h"
+#include "nio.h"
+
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_UnixAsynchronousSocketChannelImpl_checkConnect(JNIEnv *env,
+    jobject this, int fd)
+{
+    int error = 0;
+    int n = sizeof(error);
+    int result;
+
+    result = getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &n);
+    if (result < 0) {
+        JNU_ThrowIOExceptionWithLastError(env, "getsockopt");
+    } else {
+        if (error)
+            handleSocketError(env, error);
+    }
+}
diff --git a/jdk/src/solaris/native/sun/nio/fs/GnomeFileTypeDetector.c b/jdk/src/solaris/native/sun/nio/fs/GnomeFileTypeDetector.c
new file mode 100644
index 0000000..0a169a9
--- /dev/null
+++ b/jdk/src/solaris/native/sun/nio/fs/GnomeFileTypeDetector.c
@@ -0,0 +1,205 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+#include "jni.h"
+#include "jni_util.h"
+#include "jvm.h"
+#include "jlong.h"
+
+#include <stdlib.h>
+#include <dlfcn.h>
+#include <link.h>
+
+#ifdef __solaris__
+#include <strings.h>
+#endif
+
+#ifdef __linux__
+#include <string.h>
+#endif
+
+/* Definitions for GIO */
+
+#define G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE "standard::content-type"
+
+typedef void* gpointer;
+typedef struct _GFile GFile;
+typedef struct _GFileInfo GFileInfo;
+typedef struct _GCancellable GCancellable;
+typedef struct _GError GError;
+
+typedef enum {
+  G_FILE_QUERY_INFO_NONE = 0
+} GFileQueryInfoFlags;
+
+typedef void (*g_type_init_func)(void);
+typedef void (*g_object_unref_func)(gpointer object);
+typedef GFile* (*g_file_new_for_path_func)(const char* path);
+typedef GFileInfo* (*g_file_query_info_func)(GFile *file,
+    const char *attributes, GFileQueryInfoFlags flags,
+    GCancellable *cancellable, GError **error);
+typedef char* (*g_file_info_get_content_type_func)(GFileInfo *info);
+
+static g_type_init_func g_type_init;
+static g_object_unref_func g_object_unref;
+static g_file_new_for_path_func g_file_new_for_path;
+static g_file_query_info_func g_file_query_info;
+static g_file_info_get_content_type_func g_file_info_get_content_type;
+
+
+/* Definitions for GNOME VFS */
+
+typedef int gboolean;
+
+typedef gboolean (*gnome_vfs_init_function)(void);
+typedef const char* (*gnome_vfs_mime_type_from_name_function)
+    (const char* filename);
+
+static gnome_vfs_init_function gnome_vfs_init;
+static gnome_vfs_mime_type_from_name_function gnome_vfs_mime_type_from_name;
+
+
+#include "sun_nio_fs_GnomeFileTypeDetector.h"
+
+
+JNIEXPORT jboolean JNICALL
+Java_sun_nio_fs_GnomeFileTypeDetector_initializeGio
+    (JNIEnv* env, jclass this)
+{
+    void* gio_handle;
+
+    gio_handle = dlopen("libgio-2.0.so", RTLD_LAZY);
+    if (gio_handle == NULL) {
+        gio_handle = dlopen("libgio-2.0.so.0", RTLD_LAZY);
+        if (gio_handle == NULL) {
+            return JNI_FALSE;
+        }
+    }
+
+    g_type_init = (g_type_init_func)dlsym(gio_handle, "g_type_init");
+    (*g_type_init)();
+
+    g_object_unref = (g_object_unref_func)dlsym(gio_handle, "g_object_unref");
+
+    g_file_new_for_path =
+        (g_file_new_for_path_func)dlsym(gio_handle, "g_file_new_for_path");
+
+    g_file_query_info =
+        (g_file_query_info_func)dlsym(gio_handle, "g_file_query_info");
+
+    g_file_info_get_content_type = (g_file_info_get_content_type_func)
+        dlsym(gio_handle, "g_file_info_get_content_type");
+
+
+    if (g_type_init == NULL ||
+        g_object_unref == NULL ||
+        g_file_new_for_path == NULL ||
+        g_file_query_info == NULL ||
+        g_file_info_get_content_type == NULL)
+    {
+        dlclose(gio_handle);
+        return JNI_FALSE;
+    }
+
+    (*g_type_init)();
+    return JNI_TRUE;
+}
+
+JNIEXPORT jbyteArray JNICALL
+Java_sun_nio_fs_GnomeFileTypeDetector_probeUsingGio
+    (JNIEnv* env, jclass this, jlong pathAddress)
+{
+    char* path = (char*)jlong_to_ptr(pathAddress);
+    GFile* gfile;
+    GFileInfo* gfileinfo;
+    jbyteArray result = NULL;
+
+    gfile = (*g_file_new_for_path)(path);
+    gfileinfo = (*g_file_query_info)(gfile, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
+        G_FILE_QUERY_INFO_NONE, NULL, NULL);
+    if (gfileinfo != NULL) {
+        const char* mime = (*g_file_info_get_content_type)(gfileinfo);
+        if (mime != NULL) {
+            jsize len = strlen(mime);
+            result = (*env)->NewByteArray(env, len);
+            if (result != NULL) {
+                (*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)mime);
+            }
+        }
+        (*g_object_unref)(gfileinfo);
+    }
+    (*g_object_unref)(gfile);
+
+    return result;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_sun_nio_fs_GnomeFileTypeDetector_initializeGnomeVfs
+    (JNIEnv* env, jclass this)
+{
+    void* vfs_handle;
+
+    vfs_handle = dlopen("libgnomevfs-2.so", RTLD_LAZY);
+    if (vfs_handle == NULL) {
+        vfs_handle = dlopen("libgnomevfs-2.so.0", RTLD_LAZY);
+    }
+    if (vfs_handle == NULL) {
+        return JNI_FALSE;
+    }
+
+    gnome_vfs_init = (gnome_vfs_init_function)dlsym(vfs_handle, "gnome_vfs_init");
+    gnome_vfs_mime_type_from_name = (gnome_vfs_mime_type_from_name_function)
+        dlsym(vfs_handle, "gnome_vfs_mime_type_from_name");
+
+    if (gnome_vfs_init == NULL ||
+        gnome_vfs_mime_type_from_name == NULL)
+    {
+        dlclose(vfs_handle);
+        return JNI_FALSE;
+    }
+
+    (*gnome_vfs_init)();
+    return JNI_TRUE;
+}
+
+JNIEXPORT jbyteArray JNICALL
+Java_sun_nio_fs_GnomeFileTypeDetector_probeUsingGnomeVfs
+    (JNIEnv* env, jclass this, jlong pathAddress)
+{
+    char* path = (char*)jlong_to_ptr(pathAddress);
+    const char* mime = (*gnome_vfs_mime_type_from_name)(path);
+
+    if (mime == NULL) {
+        return NULL;
+    } else {
+        jbyteArray result;
+        jsize len = strlen(mime);
+        result = (*env)->NewByteArray(env, len);
+        if (result != NULL) {
+            (*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)mime);
+        }
+        return result;
+    }
+}
diff --git a/jdk/src/solaris/native/sun/nio/fs/LinuxNativeDispatcher.c b/jdk/src/solaris/native/sun/nio/fs/LinuxNativeDispatcher.c
new file mode 100644
index 0000000..8e4fa66
--- /dev/null
+++ b/jdk/src/solaris/native/sun/nio/fs/LinuxNativeDispatcher.c
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+#include "jni.h"
+#include "jni_util.h"
+#include "jvm.h"
+#include "jlong.h"
+
+#include <stdio.h>
+#include <dlfcn.h>
+#include <errno.h>
+#include <mntent.h>
+
+#include "sun_nio_fs_LinuxNativeDispatcher.h"
+
+typedef size_t fgetxattr_func(int fd, const char* name, void* value, size_t size);
+typedef int fsetxattr_func(int fd, const char* name, void* value, size_t size, int flags);
+typedef int fremovexattr_func(int fd, const char* name);
+typedef int flistxattr_func(int fd, char* list, size_t size);
+
+fgetxattr_func* my_fgetxattr_func = NULL;
+fsetxattr_func* my_fsetxattr_func = NULL;
+fremovexattr_func* my_fremovexattr_func = NULL;
+flistxattr_func* my_flistxattr_func = NULL;
+
+static void throwUnixException(JNIEnv* env, int errnum) {
+    jobject x = JNU_NewObjectByName(env, "sun/nio/fs/UnixException",
+        "(I)V", errnum);
+    if (x != NULL) {
+        (*env)->Throw(env, x);
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_LinuxNativeDispatcher_init(JNIEnv *env, jclass clazz)
+{
+    my_fgetxattr_func = (fgetxattr_func*)dlsym(RTLD_DEFAULT, "fgetxattr");
+    my_fsetxattr_func = (fsetxattr_func*)dlsym(RTLD_DEFAULT, "fsetxattr");
+    my_fremovexattr_func = (fremovexattr_func*)dlsym(RTLD_DEFAULT, "fremovexattr");
+    my_flistxattr_func = (flistxattr_func*)dlsym(RTLD_DEFAULT, "flistxattr");
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_fs_LinuxNativeDispatcher_fgetxattr0(JNIEnv* env, jclass clazz,
+    jint fd, jlong nameAddress, jlong valueAddress, jint valueLen)
+{
+    size_t res = -1;
+    const char* name = jlong_to_ptr(nameAddress);
+    void* value = jlong_to_ptr(valueAddress);
+
+    if (my_fgetxattr_func == NULL) {
+        errno = ENOTSUP;
+    } else {
+        /* EINTR not documented */
+        res = (*my_fgetxattr_func)(fd, name, value, valueLen);
+    }
+    if (res == (size_t)-1)
+        throwUnixException(env, errno);
+    return (jint)res;
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_LinuxNativeDispatcher_fsetxattr0(JNIEnv* env, jclass clazz,
+    jint fd, jlong nameAddress, jlong valueAddress, jint valueLen)
+{
+    int res = -1;
+    const char* name = jlong_to_ptr(nameAddress);
+    void* value = jlong_to_ptr(valueAddress);
+
+    if (my_fsetxattr_func == NULL) {
+        errno = ENOTSUP;
+    } else {
+        /* EINTR not documented */
+        res = (*my_fsetxattr_func)(fd, name, value, valueLen, 0);
+    }
+    if (res == -1)
+        throwUnixException(env, errno);
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_LinuxNativeDispatcher_fremovexattr0(JNIEnv* env, jclass clazz,
+    jint fd, jlong nameAddress)
+{
+    int res = -1;
+    const char* name = jlong_to_ptr(nameAddress);
+
+    if (my_fremovexattr_func == NULL) {
+        errno = ENOTSUP;
+    } else {
+        /* EINTR not documented */
+        res = (*my_fremovexattr_func)(fd, name);
+    }
+    if (res == -1)
+        throwUnixException(env, errno);
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_fs_LinuxNativeDispatcher_flistxattr(JNIEnv* env, jclass clazz,
+    jint fd, jlong listAddress, jint size)
+{
+    size_t res = -1;
+    char* list = jlong_to_ptr(listAddress);
+
+    if (my_flistxattr_func == NULL) {
+        errno = ENOTSUP;
+    } else {
+        /* EINTR not documented */
+        res = (*my_flistxattr_func)(fd, list, (size_t)size);
+    }
+    if (res == (size_t)-1)
+        throwUnixException(env, errno);
+    return (jint)res;
+}
+
+JNIEXPORT jlong JNICALL
+Java_sun_nio_fs_LinuxNativeDispatcher_setmntent0(JNIEnv* env, jclass this, jlong pathAddress,
+                                                 jlong modeAddress)
+{
+    FILE* fp = NULL;
+    const char* path = (const char*)jlong_to_ptr(pathAddress);
+    const char* mode = (const char*)jlong_to_ptr(modeAddress);
+
+    do {
+        fp = setmntent(path, mode);
+    } while (fp == NULL && errno == EINTR);
+    if (fp == NULL) {
+        throwUnixException(env, errno);
+    }
+    return ptr_to_jlong(fp);
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_LinuxNativeDispatcher_endmntent(JNIEnv* env, jclass this, jlong stream)
+{
+    FILE* fp = jlong_to_ptr(stream);
+    /* FIXME - man page doesn't explain how errors are returned */
+    endmntent(fp);
+}
diff --git a/jdk/src/solaris/native/sun/nio/fs/LinuxWatchService.c b/jdk/src/solaris/native/sun/nio/fs/LinuxWatchService.c
new file mode 100644
index 0000000..74a1540
--- /dev/null
+++ b/jdk/src/solaris/native/sun/nio/fs/LinuxWatchService.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+#include "jni.h"
+#include "jni_util.h"
+#include "jvm.h"
+#include "jlong.h"
+
+#include <stdlib.h>
+#include <dlfcn.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/poll.h>
+
+#include "sun_nio_fs_LinuxWatchService.h"
+
+/* inotify.h may not be available at build time */
+#ifdef  __cplusplus
+extern "C" {
+#endif
+struct inotify_event
+{
+  int wd;
+  uint32_t mask;
+  uint32_t cookie;
+  uint32_t len;
+  char name __flexarr;
+};
+#ifdef  __cplusplus
+}
+#endif
+
+typedef int inotify_init_func(void);
+typedef int inotify_add_watch_func(int fd, const char* path, uint32_t mask);
+typedef int inotify_rm_watch_func(int fd, uint32_t wd);
+
+inotify_init_func* my_inotify_init_func = NULL;
+inotify_add_watch_func* my_inotify_add_watch_func = NULL;
+inotify_rm_watch_func* my_inotify_rm_watch_func = NULL;
+
+static void throwUnixException(JNIEnv* env, int errnum) {
+    jobject x = JNU_NewObjectByName(env, "sun/nio/fs/UnixException",
+        "(I)V", errnum);
+    if (x != NULL) {
+        (*env)->Throw(env, x);
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_LinuxWatchService_init(JNIEnv *env, jclass clazz)
+{
+    my_inotify_init_func = (inotify_init_func*)
+        dlsym(RTLD_DEFAULT, "inotify_init");
+    my_inotify_add_watch_func =
+        (inotify_add_watch_func*) dlsym(RTLD_DEFAULT, "inotify_add_watch");
+    my_inotify_rm_watch_func =
+        (inotify_rm_watch_func*) dlsym(RTLD_DEFAULT, "inotify_rm_watch");
+
+    if ((my_inotify_init_func == NULL) || (my_inotify_add_watch_func == NULL) ||
+        (my_inotify_rm_watch_func == NULL)) {
+        JNU_ThrowInternalError(env, "unable to get address of inotify functions");
+    }
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_fs_LinuxWatchService_eventSize(JNIEnv *env, jclass clazz)
+{
+    return (jint)sizeof(struct inotify_event);
+}
+
+JNIEXPORT jintArray JNICALL
+Java_sun_nio_fs_LinuxWatchService_eventOffsets(JNIEnv *env, jclass clazz)
+{
+    jintArray result = (*env)->NewIntArray(env, 5);
+    if (result != NULL) {
+        jint arr[5];
+        arr[0] = (jint)offsetof(struct inotify_event, wd);
+        arr[1] = (jint)offsetof(struct inotify_event, mask);
+        arr[2] = (jint)offsetof(struct inotify_event, cookie);
+        arr[3] = (jint)offsetof(struct inotify_event, len);
+        arr[4] = (jint)offsetof(struct inotify_event, name);
+        (*env)->SetIntArrayRegion(env, result, 0, 5, arr);
+    }
+    return result;
+}
+
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_fs_LinuxWatchService_inotifyInit
+    (JNIEnv* env, jclass clazz)
+{
+    int ifd = (*my_inotify_init_func)();
+    if (ifd == -1) {
+        throwUnixException(env, errno);
+    }
+    return (jint)ifd;
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_fs_LinuxWatchService_inotifyAddWatch
+    (JNIEnv* env, jclass clazz, jint fd, jlong address, jint mask)
+{
+    int wfd = -1;
+    const char* path = (const char*)jlong_to_ptr(address);
+
+    wfd = (*my_inotify_add_watch_func)((int)fd, path, mask);
+    if (wfd == -1) {
+        throwUnixException(env, errno);
+    }
+    return (jint)wfd;
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_LinuxWatchService_inotifyRmWatch
+    (JNIEnv* env, jclass clazz, jint fd, jint wd)
+{
+    int err = (*my_inotify_rm_watch_func)((int)fd, (int)wd);
+    if (err == -1)
+        throwUnixException(env, errno);
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_LinuxWatchService_configureBlocking
+    (JNIEnv* env, jclass clazz, jint fd, jboolean blocking)
+{
+    int flags = fcntl(fd, F_GETFL);
+
+    if ((blocking == JNI_FALSE) && !(flags & O_NONBLOCK))
+        fcntl(fd, F_SETFL, flags | O_NONBLOCK);
+    else if ((blocking == JNI_TRUE) && (flags & O_NONBLOCK))
+        fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_LinuxWatchService_socketpair
+    (JNIEnv* env, jclass clazz, jintArray sv)
+{
+    int sp[2];
+    if (socketpair(PF_UNIX, SOCK_STREAM, 0, sp) == -1) {
+        throwUnixException(env, errno);
+    } else {
+        jint res[2];
+        res[0] = (jint)sp[0];
+        res[1] = (jint)sp[1];
+        (*env)->SetIntArrayRegion(env, sv, 0, 2, &res[0]);
+    }
+
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_fs_LinuxWatchService_poll
+    (JNIEnv* env, jclass clazz, jint fd1, jint fd2)
+{
+    struct pollfd ufds[2];
+    int n;
+
+    ufds[0].fd = fd1;
+    ufds[0].events = POLLIN;
+    ufds[1].fd = fd2;
+    ufds[1].events = POLLIN;
+
+    n = poll(&ufds[0], 2, -1);
+    if (n == -1) {
+        if (errno == EINTR) {
+            n = 0;
+        } else {
+            throwUnixException(env, errno);
+        }
+     }
+    return (jint)n;
+
+
+}
diff --git a/jdk/src/solaris/native/sun/nio/fs/SolarisNativeDispatcher.c b/jdk/src/solaris/native/sun/nio/fs/SolarisNativeDispatcher.c
new file mode 100644
index 0000000..a57009c
--- /dev/null
+++ b/jdk/src/solaris/native/sun/nio/fs/SolarisNativeDispatcher.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+#include "jni.h"
+#include "jni_util.h"
+#include "jvm.h"
+#include "jlong.h"
+
+#include <dlfcn.h>
+#include <errno.h>
+#include <sys/acl.h>
+
+#include "sun_nio_fs_SolarisNativeDispatcher.h"
+
+static void throwUnixException(JNIEnv* env, int errnum) {
+    jobject x = JNU_NewObjectByName(env, "sun/nio/fs/UnixException",
+        "(I)V", errnum);
+    if (x != NULL) {
+        (*env)->Throw(env, x);
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_SolarisNativeDispatcher_init(JNIEnv *env, jclass clazz) {
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_fs_SolarisNativeDispatcher_facl(JNIEnv* env, jclass this, jint fd,
+    jint cmd, jint nentries, jlong address)
+{
+    void* aclbufp = jlong_to_ptr(address);
+    int n = -1;
+
+    n = facl((int)fd, (int)cmd, (int)nentries, aclbufp);
+    if (n == -1) {
+        throwUnixException(env, errno);
+    }
+    return (jint)n;
+}
diff --git a/jdk/src/solaris/native/sun/nio/fs/SolarisWatchService.c b/jdk/src/solaris/native/sun/nio/fs/SolarisWatchService.c
new file mode 100644
index 0000000..776227f
--- /dev/null
+++ b/jdk/src/solaris/native/sun/nio/fs/SolarisWatchService.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+#include "jni.h"
+#include "jni_util.h"
+#include "jvm.h"
+#include "jlong.h"
+
+#include <stdlib.h>
+#include <dlfcn.h>
+#include <sys/types.h>
+#include <port.h>       // Solaris 10
+
+#include "sun_nio_fs_SolarisWatchService.h"
+
+static void throwUnixException(JNIEnv* env, int errnum) {
+    jobject x = JNU_NewObjectByName(env, "sun/nio/fs/UnixException",
+        "(I)V", errnum);
+    if (x != NULL) {
+        (*env)->Throw(env, x);
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_SolarisWatchService_init(JNIEnv *env, jclass clazz)
+{
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_fs_SolarisWatchService_portCreate
+    (JNIEnv* env, jclass clazz)
+{
+    int port = port_create();
+    if (port == -1) {
+        throwUnixException(env, errno);
+    }
+    return (jint)port;
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_SolarisWatchService_portAssociate
+    (JNIEnv* env, jclass clazz, jint port, jint source, jlong objectAddress, jint events)
+{
+    uintptr_t object = (uintptr_t)jlong_to_ptr(objectAddress);
+
+    if (port_associate((int)port, (int)source, object, (int)events, NULL) == -1) {
+        throwUnixException(env, errno);
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_SolarisWatchService_portDissociate
+    (JNIEnv* env, jclass clazz, jint port, jint source, jlong objectAddress)
+{
+    uintptr_t object = (uintptr_t)jlong_to_ptr(objectAddress);
+
+    if (port_dissociate((int)port, (int)source, object) == -1) {
+        throwUnixException(env, errno);
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_SolarisWatchService_portSend(JNIEnv* env, jclass clazz,
+    jint port, jint events)
+{
+    if (port_send((int)port, (int)events, NULL) == -1) {
+        throwUnixException(env, errno);
+    }
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_fs_SolarisWatchService_portGetn(JNIEnv* env, jclass clazz,
+    jint port, jlong arrayAddress, jint max)
+{
+    uint_t n = 1;
+    port_event_t* list = (port_event_t*)jlong_to_ptr(arrayAddress);
+
+    if (port_getn((int)port, list, (uint_t)max, &n, NULL) == -1) {
+        throwUnixException(env, errno);
+    }
+    return (jint)n;
+}
diff --git a/jdk/src/solaris/native/sun/nio/fs/UnixCopyFile.c b/jdk/src/solaris/native/sun/nio/fs/UnixCopyFile.c
new file mode 100644
index 0000000..526ccba
--- /dev/null
+++ b/jdk/src/solaris/native/sun/nio/fs/UnixCopyFile.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+#include "jni.h"
+#include "jni_util.h"
+#include "jlong.h"
+
+#include <unistd.h>
+#include <errno.h>
+
+#include "sun_nio_fs_UnixCopyFile.h"
+
+#define RESTARTABLE(_cmd, _result) do { \
+  do { \
+    _result = _cmd; \
+  } while((_result == -1) && (errno == EINTR)); \
+} while(0)
+
+static void throwUnixException(JNIEnv* env, int errnum) {
+    jobject x = JNU_NewObjectByName(env, "sun/nio/fs/UnixException",
+        "(I)V", errnum);
+    if (x != NULL) {
+        (*env)->Throw(env, x);
+    }
+}
+
+/**
+ * Transfer all bytes from src to dst via user-space buffers
+ */
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_UnixCopyFile_transfer
+    (JNIEnv* env, jclass this, jint dst, jint src, jlong cancelAddress)
+{
+    char buf[8192];
+    volatile jint* cancel = (jint*)jlong_to_ptr(cancelAddress);
+
+    for (;;) {
+        ssize_t n, pos, len;
+        RESTARTABLE(read((int)src, &buf, sizeof(buf)), n);
+        if (n <= 0) {
+            if (n < 0)
+                throwUnixException(env, errno);
+            return;
+        }
+        if (cancel != NULL && *cancel != 0) {
+            throwUnixException(env, ECANCELED);
+            return;
+        }
+        pos = 0;
+        len = n;
+        do {
+            char* bufp = buf;
+            bufp += pos;
+            RESTARTABLE(write((int)dst, bufp, len), n);
+            if (n == -1) {
+                throwUnixException(env, errno);
+                return;
+            }
+            pos += n;
+            len -= n;
+        } while (len > 0);
+    }
+}
diff --git a/jdk/src/solaris/native/sun/nio/fs/UnixNativeDispatcher.c b/jdk/src/solaris/native/sun/nio/fs/UnixNativeDispatcher.c
new file mode 100644
index 0000000..13a1a3a
--- /dev/null
+++ b/jdk/src/solaris/native/sun/nio/fs/UnixNativeDispatcher.c
@@ -0,0 +1,1080 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <grp.h>
+#include <errno.h>
+#include <dlfcn.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/statvfs.h>
+#include <sys/time.h>
+
+#ifdef __solaris__
+#include <strings.h>
+#include <sys/mnttab.h>
+#include <sys/mkdev.h>
+#endif
+
+#ifdef __linux__
+#include <string.h>
+#include <mntent.h>
+#endif
+
+#include "jni.h"
+#include "jni_util.h"
+#include "jlong.h"
+
+#include "sun_nio_fs_UnixNativeDispatcher.h"
+
+#define RESTARTABLE(_cmd, _result) do { \
+  do { \
+    _result = _cmd; \
+  } while((_result == -1) && (errno == EINTR)); \
+} while(0)
+
+static jfieldID attrs_st_mode;
+static jfieldID attrs_st_ino;
+static jfieldID attrs_st_dev;
+static jfieldID attrs_st_rdev;
+static jfieldID attrs_st_nlink;
+static jfieldID attrs_st_uid;
+static jfieldID attrs_st_gid;
+static jfieldID attrs_st_size;
+static jfieldID attrs_st_atime;
+static jfieldID attrs_st_mtime;
+static jfieldID attrs_st_ctime;
+
+static jfieldID attrs_f_frsize;
+static jfieldID attrs_f_blocks;
+static jfieldID attrs_f_bfree;
+static jfieldID attrs_f_bavail;
+
+static jfieldID entry_name;
+static jfieldID entry_dir;
+static jfieldID entry_fstype;
+static jfieldID entry_options;
+static jfieldID entry_dev;
+
+/**
+ * System calls that may not be available at build time.
+ */
+typedef int openat64_func(int, const char *, int, ...);
+typedef int fstatat64_func(int, const char *, struct stat64 *, int);
+typedef int unlinkat_func(int, const char*, int);
+typedef int renameat_func(int, const char*, int, const char*);
+typedef int futimesat_func(int, const char *, const struct timeval *);
+typedef DIR* fdopendir_func(int);
+
+static openat64_func* my_openat64_func = NULL;
+static fstatat64_func* my_fstatat64_func = NULL;
+static unlinkat_func* my_unlinkat_func = NULL;
+static renameat_func* my_renameat_func = NULL;
+static futimesat_func* my_futimesat_func = NULL;
+static fdopendir_func* my_fdopendir_func = NULL;
+
+/**
+ * fstatat missing from glibc on Linux. Temporary workaround
+ * for x86/x64.
+ */
+#if defined(__linux__) && defined(__i386)
+#define FSTATAT64_SYSCALL_AVAILABLE
+static int fstatat64_wrapper(int dfd, const char *path,
+                             struct stat64 *statbuf, int flag)
+{
+    #ifndef __NR_fstatat64
+    #define __NR_fstatat64  300
+    #endif
+    return syscall(__NR_fstatat64, dfd, path, statbuf, flag);
+}
+#endif
+
+#if defined(__linux__) && defined(__x86_64__)
+#define FSTATAT64_SYSCALL_AVAILABLE
+static int fstatat64_wrapper(int dfd, const char *path,
+                             struct stat64 *statbuf, int flag)
+{
+    #ifndef __NR_newfstatat
+    #define __NR_newfstatat  262
+    #endif
+    return syscall(__NR_newfstatat, dfd, path, statbuf, flag);
+}
+#endif
+
+/**
+ * Call this to throw an internal UnixException when a system/library
+ * call fails
+ */
+static void throwUnixException(JNIEnv* env, int errnum) {
+    jobject x = JNU_NewObjectByName(env, "sun/nio/fs/UnixException",
+        "(I)V", errnum);
+    if (x != NULL) {
+        (*env)->Throw(env, x);
+    }
+}
+
+/**
+ * Initialize jfieldIDs
+ */
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_initIDs(JNIEnv* env, jclass this)
+{
+    jclass clazz;
+
+    clazz = (*env)->FindClass(env, "sun/nio/fs/UnixFileAttributes");
+    if (clazz == NULL) {
+        return;
+    }
+    attrs_st_mode = (*env)->GetFieldID(env, clazz, "st_mode", "I");
+    attrs_st_ino = (*env)->GetFieldID(env, clazz, "st_ino", "J");
+    attrs_st_dev = (*env)->GetFieldID(env, clazz, "st_dev", "J");
+    attrs_st_rdev = (*env)->GetFieldID(env, clazz, "st_rdev", "J");
+    attrs_st_nlink = (*env)->GetFieldID(env, clazz, "st_nlink", "I");
+    attrs_st_uid = (*env)->GetFieldID(env, clazz, "st_uid", "I");
+    attrs_st_gid = (*env)->GetFieldID(env, clazz, "st_gid", "I");
+    attrs_st_size = (*env)->GetFieldID(env, clazz, "st_size", "J");
+    attrs_st_atime = (*env)->GetFieldID(env, clazz, "st_atime", "J");
+    attrs_st_mtime = (*env)->GetFieldID(env, clazz, "st_mtime", "J");
+    attrs_st_ctime = (*env)->GetFieldID(env, clazz, "st_ctime", "J");
+
+    clazz = (*env)->FindClass(env, "sun/nio/fs/UnixFileStoreAttributes");
+    if (clazz == NULL) {
+        return;
+    }
+    attrs_f_frsize = (*env)->GetFieldID(env, clazz, "f_frsize", "J");
+    attrs_f_blocks = (*env)->GetFieldID(env, clazz, "f_blocks", "J");
+    attrs_f_bfree = (*env)->GetFieldID(env, clazz, "f_bfree", "J");
+    attrs_f_bavail = (*env)->GetFieldID(env, clazz, "f_bavail", "J");
+
+    clazz = (*env)->FindClass(env, "sun/nio/fs/UnixMountEntry");
+    if (clazz == NULL) {
+        return;
+    }
+    entry_name = (*env)->GetFieldID(env, clazz, "name", "[B");
+    entry_dir = (*env)->GetFieldID(env, clazz, "dir", "[B");
+    entry_fstype = (*env)->GetFieldID(env, clazz, "fstype", "[B");
+    entry_options = (*env)->GetFieldID(env, clazz, "opts", "[B");
+    entry_dev = (*env)->GetFieldID(env, clazz, "dev", "J");
+
+    /* system calls that might not be available at build time */
+
+#if defined(__solaris__) && defined(_LP64)
+    /* Solaris 64-bit does not have openat64/fstatat64 */
+    my_openat64_func = (openat64_func*)dlsym(RTLD_DEFAULT, "openat");
+    my_fstatat64_func = (fstatat64_func*)dlsym(RTLD_DEFAULT, "fstatat");
+#else
+    my_openat64_func = (openat64_func*) dlsym(RTLD_DEFAULT, "openat64");
+    my_fstatat64_func = (fstatat64_func*) dlsym(RTLD_DEFAULT, "fstatat64");
+#endif
+    my_unlinkat_func = (unlinkat_func*) dlsym(RTLD_DEFAULT, "unlinkat");
+    my_renameat_func = (renameat_func*) dlsym(RTLD_DEFAULT, "renameat");
+    my_futimesat_func = (futimesat_func*) dlsym(RTLD_DEFAULT, "futimesat");
+    my_fdopendir_func = (fdopendir_func*) dlsym(RTLD_DEFAULT, "fdopendir");
+
+#if defined(FSTATAT64_SYSCALL_AVAILABLE)
+    /* fstatat64 missing from glibc */
+    if (my_fstatat64_func == NULL)
+        my_fstatat64_func = (fstatat64_func*)&fstatat64_wrapper;
+#endif
+}
+
+JNIEXPORT jbyteArray JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_getcwd(JNIEnv* env, jclass this) {
+    jbyteArray result = NULL;
+    char buf[PATH_MAX+1];
+
+    /* EINTR not listed as a possible error */
+    char* cwd = getcwd(buf, sizeof(buf));
+    if (cwd == NULL) {
+        throwUnixException(env, errno);
+    } else {
+        jsize len = (jsize)strlen(buf);
+        result = (*env)->NewByteArray(env, len);
+        if (result != NULL) {
+            (*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)buf);
+        }
+    }
+    return result;
+}
+
+JNIEXPORT jbyteArray
+Java_sun_nio_fs_UnixNativeDispatcher_strerror(JNIEnv* env, jclass this, jint error)
+{
+    char* msg;
+    jsize len;
+    jbyteArray bytes;
+
+    msg = strerror((int)error);
+    len = strlen(msg);
+    bytes = (*env)->NewByteArray(env, len);
+    if (bytes != NULL) {
+        (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)msg);
+    }
+    return bytes;
+}
+
+JNIEXPORT jint
+Java_sun_nio_fs_UnixNativeDispatcher_dup(JNIEnv* env, jclass this, jint fd) {
+
+    int res = -1;
+
+    RESTARTABLE(dup((int)fd), res);
+    if (fd == -1) {
+        throwUnixException(env, errno);
+    }
+    return (jint)res;
+}
+
+JNIEXPORT jlong JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_fopen0(JNIEnv* env, jclass this,
+    jlong pathAddress, jlong modeAddress)
+{
+    FILE* fp = NULL;
+    const char* path = (const char*)jlong_to_ptr(pathAddress);
+    const char* mode = (const char*)jlong_to_ptr(modeAddress);
+
+    do {
+        fp = fopen(path, mode);
+    } while (fp == NULL && errno == EINTR);
+
+    if (fp == NULL) {
+        throwUnixException(env, errno);
+    }
+
+    return ptr_to_jlong(fp);
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_fclose(JNIEnv* env, jclass this, jlong stream)
+{
+    int res;
+    FILE* fp = jlong_to_ptr(stream);
+
+    do {
+        res = fclose(fp);
+    } while (res == EOF && errno == EINTR);
+    if (res == EOF) {
+        throwUnixException(env, errno);
+    }
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_open0(JNIEnv* env, jclass this,
+    jlong pathAddress, jint oflags, jint mode)
+{
+    jint fd;
+    const char* path = (const char*)jlong_to_ptr(pathAddress);
+
+    RESTARTABLE(open64(path, (int)oflags, (mode_t)mode), fd);
+    if (fd == -1) {
+        throwUnixException(env, errno);
+    }
+    return fd;
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_openat0(JNIEnv* env, jclass this, jint dfd,
+    jlong pathAddress, jint oflags, jint mode)
+{
+    jint fd;
+    const char* path = (const char*)jlong_to_ptr(pathAddress);
+
+    if (my_openat64_func == NULL) {
+        JNU_ThrowInternalError(env, "should not reach here");
+        return -1;
+    }
+
+    RESTARTABLE((*my_openat64_func)(dfd, path, (int)oflags, (mode_t)mode), fd);
+    if (fd == -1) {
+        throwUnixException(env, errno);
+    }
+    return fd;
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_close(JNIEnv* env, jclass this, jint fd) {
+    int err;
+    /* TDB - need to decide if EIO and other errors should cause exception */
+    RESTARTABLE(close((int)fd), err);
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_read(JNIEnv* env, jclass this, jint fd,
+    jlong address, jint nbytes)
+{
+    ssize_t n;
+    void* bufp = jlong_to_ptr(address);
+    RESTARTABLE(read((int)fd, bufp, (size_t)nbytes), n);
+    if (n == -1) {
+        throwUnixException(env, errno);
+    }
+    return (jint)n;
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_write(JNIEnv* env, jclass this, jint fd,
+    jlong address, jint nbytes)
+{
+    ssize_t n;
+    void* bufp = jlong_to_ptr(address);
+    RESTARTABLE(write((int)fd, bufp, (size_t)nbytes), n);
+    if (n == -1) {
+        throwUnixException(env, errno);
+    }
+    return (jint)n;
+}
+
+/**
+ * Copy stat64 members into sun.nio.fs.UnixFileAttributes
+ */
+static void prepAttributes(JNIEnv* env, struct stat64* buf, jobject attrs) {
+    (*env)->SetIntField(env, attrs, attrs_st_mode, (jint)buf->st_mode);
+    (*env)->SetLongField(env, attrs, attrs_st_ino, (jlong)buf->st_ino);
+    (*env)->SetLongField(env, attrs, attrs_st_dev, (jlong)buf->st_dev);
+    (*env)->SetLongField(env, attrs, attrs_st_rdev, (jlong)buf->st_rdev);
+    (*env)->SetIntField(env, attrs, attrs_st_nlink, (jint)buf->st_nlink);
+    (*env)->SetIntField(env, attrs, attrs_st_uid, (jint)buf->st_uid);
+    (*env)->SetIntField(env, attrs, attrs_st_gid, (jint)buf->st_gid);
+    (*env)->SetLongField(env, attrs, attrs_st_size, (jlong)buf->st_size);
+    (*env)->SetLongField(env, attrs, attrs_st_atime, (jlong)buf->st_atime * 1000);
+    (*env)->SetLongField(env, attrs, attrs_st_mtime, (jlong)buf->st_mtime * 1000);
+    (*env)->SetLongField(env, attrs, attrs_st_ctime, (jlong)buf->st_ctime * 1000);
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_stat0(JNIEnv* env, jclass this,
+    jlong pathAddress, jobject attrs)
+{
+    int err;
+    struct stat64 buf;
+    const char* path = (const char*)jlong_to_ptr(pathAddress);
+
+    RESTARTABLE(stat64(path, &buf), err);
+    if (err == -1) {
+        throwUnixException(env, errno);
+    } else {
+        prepAttributes(env, &buf, attrs);
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_lstat0(JNIEnv* env, jclass this,
+    jlong pathAddress, jobject attrs)
+{
+    int err;
+    struct stat64 buf;
+    const char* path = (const char*)jlong_to_ptr(pathAddress);
+
+    RESTARTABLE(lstat64(path, &buf), err);
+    if (err == -1) {
+        throwUnixException(env, errno);
+    } else {
+        prepAttributes(env, &buf, attrs);
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_fstat(JNIEnv* env, jclass this, jint fd,
+    jobject attrs)
+{
+    int err;
+    struct stat64 buf;
+
+    RESTARTABLE(fstat64((int)fd, &buf), err);
+    if (err == -1) {
+        throwUnixException(env, errno);
+    } else {
+        prepAttributes(env, &buf, attrs);
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_fstatat0(JNIEnv* env, jclass this, jint dfd,
+    jlong pathAddress, jint flag, jobject attrs)
+{
+    int err;
+    struct stat64 buf;
+    const char* path = (const char*)jlong_to_ptr(pathAddress);
+
+    if (my_fstatat64_func == NULL) {
+        JNU_ThrowInternalError(env, "should not reach here");
+        return;
+    }
+    RESTARTABLE((*my_fstatat64_func)((int)dfd, path, &buf, (int)flag), err);
+    if (err == -1) {
+        throwUnixException(env, errno);
+    } else {
+        prepAttributes(env, &buf, attrs);
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_chmod0(JNIEnv* env, jclass this,
+    jlong pathAddress, jint mode)
+{
+    int err;
+    const char* path = (const char*)jlong_to_ptr(pathAddress);
+
+    RESTARTABLE(chmod(path, (mode_t)mode), err);
+    if (err == -1) {
+        throwUnixException(env, errno);
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_fchmod(JNIEnv* env, jclass this, jint filedes,
+    jint mode)
+{
+    int err;
+
+    RESTARTABLE(fchmod((int)filedes, (mode_t)mode), err);
+    if (err == -1) {
+        throwUnixException(env, errno);
+    }
+}
+
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_chown0(JNIEnv* env, jclass this,
+    jlong pathAddress, jint uid, jint gid)
+{
+    int err;
+    const char* path = (const char*)jlong_to_ptr(pathAddress);
+
+    RESTARTABLE(chown(path, (uid_t)uid, (gid_t)gid), err);
+    if (err == -1) {
+        throwUnixException(env, errno);
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_lchown0(JNIEnv* env, jclass this, jlong pathAddress, jint uid, jint gid)
+{
+    int err;
+    const char* path = (const char*)jlong_to_ptr(pathAddress);
+
+    RESTARTABLE(lchown(path, (uid_t)uid, (gid_t)gid), err);
+    if (err == -1) {
+        throwUnixException(env, errno);
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_fchown(JNIEnv* env, jclass this, jint filedes, jint uid, jint gid)
+{
+    int err;
+
+    RESTARTABLE(fchown(filedes, (uid_t)uid, (gid_t)gid), err);
+    if (err == -1) {
+        throwUnixException(env, errno);
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_utimes0(JNIEnv* env, jclass this,
+    jlong pathAddress, jlong accessTime, jlong modificationTime)
+{
+    int err;
+    struct timeval times[2];
+    const char* path = (const char*)jlong_to_ptr(pathAddress);
+
+    times[0].tv_sec = accessTime / 1000;
+    times[0].tv_usec = (accessTime % 1000) * 1000;
+
+    times[1].tv_sec = modificationTime / 1000;
+    times[1].tv_usec = (modificationTime % 1000) * 1000;
+
+    RESTARTABLE(utimes(path, &times[0]), err);
+    if (err == -1) {
+        throwUnixException(env, errno);
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_futimes(JNIEnv* env, jclass this, jint filedes,
+    jlong accessTime, jlong modificationTime)
+{
+    struct timeval times[2];
+    int err = 0;
+
+    times[0].tv_sec = accessTime / 1000;
+    times[0].tv_usec = (accessTime % 1000) * 1000;
+
+    times[1].tv_sec = modificationTime / 1000;
+    times[1].tv_usec = (modificationTime % 1000) * 1000;
+
+    if (my_futimesat_func != NULL) {
+        RESTARTABLE((*my_futimesat_func)(filedes, NULL, &times[0]), err);
+        if (err == -1) {
+            throwUnixException(env, errno);
+        }
+    }
+}
+
+JNIEXPORT jlong JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_opendir0(JNIEnv* env, jclass this,
+    jlong pathAddress)
+{
+    DIR* dir;
+    const char* path = (const char*)jlong_to_ptr(pathAddress);
+
+    /* EINTR not listed as a possible error */
+    dir = opendir(path);
+    if (dir == NULL) {
+        throwUnixException(env, errno);
+    }
+    return ptr_to_jlong(dir);
+}
+
+JNIEXPORT jlong JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_fdopendir(JNIEnv* env, jclass this, int dfd) {
+    DIR* dir;
+
+    if (my_fdopendir_func == NULL) {
+        JNU_ThrowInternalError(env, "should not reach here");
+        return (jlong)-1;
+    }
+
+    /* EINTR not listed as a possible error */
+    dir = (*my_fdopendir_func)((int)dfd);
+    if (dir == NULL) {
+        throwUnixException(env, errno);
+    }
+    return ptr_to_jlong(dir);
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_closedir(JNIEnv* env, jclass this, jlong dir) {
+    int err;
+    DIR* dirp = jlong_to_ptr(dir);
+
+    RESTARTABLE(closedir(dirp), err);
+    if (errno == -1) {
+        throwUnixException(env, errno);
+    }
+}
+
+JNIEXPORT jbyteArray JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_readdir(JNIEnv* env, jclass this, jlong value) {
+    char entry[sizeof(struct dirent64) + PATH_MAX + 1];
+    struct dirent64* ptr = (struct dirent64*)&entry;
+    struct dirent64* result;
+    int res;
+    DIR* dirp = jlong_to_ptr(value);
+
+    /* EINTR not listed as a possible error */
+    /* TDB: reentrant version probably not required here */
+    res = readdir64_r(dirp, ptr, &result);
+    if (res != 0) {
+        throwUnixException(env, res);
+        return NULL;
+    } else {
+        if (result == NULL) {
+            return NULL;
+        } else {
+            jsize len = strlen(ptr->d_name);
+            jbyteArray bytes = (*env)->NewByteArray(env, len);
+            if (bytes != NULL) {
+                (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)(ptr->d_name));
+            }
+            return bytes;
+        }
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_mkdir0(JNIEnv* env, jclass this,
+    jlong pathAddress, jint mode)
+{
+    const char* path = (const char*)jlong_to_ptr(pathAddress);
+
+    /* EINTR not listed as a possible error */
+    if (mkdir(path, (mode_t)mode) == -1) {
+        throwUnixException(env, errno);
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_rmdir0(JNIEnv* env, jclass this,
+    jlong pathAddress)
+{
+    const char* path = (const char*)jlong_to_ptr(pathAddress);
+
+    /* EINTR not listed as a possible error */
+    if (rmdir(path) == -1) {
+        throwUnixException(env, errno);
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_link0(JNIEnv* env, jclass this,
+    jlong existingAddress, jlong newAddress)
+{
+    int err;
+    const char* existing = (const char*)jlong_to_ptr(existingAddress);
+    const char* newname = (const char*)jlong_to_ptr(newAddress);
+
+    RESTARTABLE(link(existing, newname), err);
+    if (err == -1) {
+        throwUnixException(env, errno);
+    }
+}
+
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_unlink0(JNIEnv* env, jclass this,
+    jlong pathAddress)
+{
+    const char* path = (const char*)jlong_to_ptr(pathAddress);
+
+    /* EINTR not listed as a possible error */
+    if (unlink(path) == -1) {
+        throwUnixException(env, errno);
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_unlinkat0(JNIEnv* env, jclass this, jint dfd,
+                                               jlong pathAddress, jint flags)
+{
+    const char* path = (const char*)jlong_to_ptr(pathAddress);
+
+    if (my_unlinkat_func == NULL) {
+        JNU_ThrowInternalError(env, "should not reach here");
+        return;
+    }
+
+    /* EINTR not listed as a possible error */
+    if ((*my_unlinkat_func)((int)dfd, path, (int)flags) == -1) {
+        throwUnixException(env, errno);
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_rename0(JNIEnv* env, jclass this,
+    jlong fromAddress, jlong toAddress)
+{
+    const char* from = (const char*)jlong_to_ptr(fromAddress);
+    const char* to = (const char*)jlong_to_ptr(toAddress);
+
+    /* EINTR not listed as a possible error */
+    if (rename(from, to) == -1) {
+        throwUnixException(env, errno);
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_renameat0(JNIEnv* env, jclass this,
+    jint fromfd, jlong fromAddress, jint tofd, jlong toAddress)
+{
+    const char* from = (const char*)jlong_to_ptr(fromAddress);
+    const char* to = (const char*)jlong_to_ptr(toAddress);
+
+    if (my_renameat_func == NULL) {
+        JNU_ThrowInternalError(env, "should not reach here");
+        return;
+    }
+
+    /* EINTR not listed as a possible error */
+    if ((*my_renameat_func)((int)fromfd, from, (int)tofd, to) == -1) {
+        throwUnixException(env, errno);
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_symlink0(JNIEnv* env, jclass this,
+    jlong targetAddress, jlong linkAddress)
+{
+    const char* target = (const char*)jlong_to_ptr(targetAddress);
+    const char* link = (const char*)jlong_to_ptr(linkAddress);
+
+    /* EINTR not listed as a possible error */
+    if (symlink(target, link) == -1) {
+        throwUnixException(env, errno);
+    }
+}
+
+JNIEXPORT jbyteArray JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_readlink0(JNIEnv* env, jclass this,
+    jlong pathAddress)
+{
+    jbyteArray result = NULL;
+    char target[PATH_MAX+1];
+    const char* path = (const char*)jlong_to_ptr(pathAddress);
+
+    /* EINTR not listed as a possible error */
+    int n = readlink(path, target, sizeof(target));
+    if (n == -1) {
+        throwUnixException(env, errno);
+    } else {
+        jsize len;
+        if (n == sizeof(target)) {
+            n--;
+        }
+        target[n] = '\0';
+        len = (jsize)strlen(target);
+        result = (*env)->NewByteArray(env, len);
+        if (result != NULL) {
+            (*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)target);
+        }
+    }
+    return result;
+}
+
+JNIEXPORT jbyteArray JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_realpath0(JNIEnv* env, jclass this,
+    jlong pathAddress)
+{
+    jbyteArray result = NULL;
+    char resolved[PATH_MAX+1];
+    const char* path = (const char*)jlong_to_ptr(pathAddress);
+
+    /* EINTR not listed as a possible error */
+    if (realpath(path, resolved) == NULL) {
+        throwUnixException(env, errno);
+    } else {
+        jsize len = (jsize)strlen(resolved);
+        result = (*env)->NewByteArray(env, len);
+        if (result != NULL) {
+            (*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)resolved);
+        }
+    }
+    return result;
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_access0(JNIEnv* env, jclass this,
+    jlong pathAddress, jint amode)
+{
+    int err;
+    const char* path = (const char*)jlong_to_ptr(pathAddress);
+
+    RESTARTABLE(access(path, (int)amode), err);
+    if (err == -1) {
+        throwUnixException(env, errno);
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_statvfs0(JNIEnv* env, jclass this,
+    jlong pathAddress, jobject attrs)
+{
+    int err;
+    struct statvfs64 buf;
+    const char* path = (const char*)jlong_to_ptr(pathAddress);
+
+
+    RESTARTABLE(statvfs64(path, &buf), err);
+    if (err == -1) {
+        throwUnixException(env, errno);
+    } else {
+        (*env)->SetLongField(env, attrs, attrs_f_frsize, long_to_jlong(buf.f_frsize));
+        (*env)->SetLongField(env, attrs, attrs_f_blocks, long_to_jlong(buf.f_blocks));
+        (*env)->SetLongField(env, attrs, attrs_f_bfree,  long_to_jlong(buf.f_bfree));
+        (*env)->SetLongField(env, attrs, attrs_f_bavail, long_to_jlong(buf.f_bavail));
+    }
+}
+
+JNIEXPORT jlong JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_pathconf0(JNIEnv* env, jclass this,
+    jlong pathAddress, jint name)
+{
+    long err;
+    const char* path = (const char*)jlong_to_ptr(pathAddress);
+
+    err = pathconf(path, (int)name);
+    if (err == -1) {
+        throwUnixException(env, errno);
+    }
+    return (jlong)err;
+}
+
+JNIEXPORT jlong JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_fpathconf(JNIEnv* env, jclass this,
+    jint fd, jint name)
+{
+    long err;
+
+    err = fpathconf((int)fd, (int)name);
+    if (err == -1) {
+        throwUnixException(env, errno);
+    }
+    return (jlong)err;
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_mknod0(JNIEnv* env, jclass this,
+    jlong pathAddress, jint mode, jlong dev)
+{
+    int err;
+    const char* path = (const char*)jlong_to_ptr(pathAddress);
+
+    RESTARTABLE(mknod(path, (mode_t)mode, (dev_t)dev), err);
+    if (err == -1) {
+        throwUnixException(env, errno);
+    }
+}
+
+JNIEXPORT jbyteArray JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_getpwuid(JNIEnv* env, jclass this, jint uid)
+{
+    jbyteArray result = NULL;
+    int buflen;
+
+    buflen = (int)sysconf(_SC_GETPW_R_SIZE_MAX);
+    if (buflen == -1) {
+        throwUnixException(env, errno);
+    } else {
+        char* pwbuf = (char*)malloc(buflen);
+        if (pwbuf == NULL) {
+            JNU_ThrowOutOfMemoryError(env, "native heap");
+        } else {
+            struct passwd pwent;
+            struct passwd* p;
+            int res = 0;
+
+#ifdef __solaris__
+            p = getpwuid_r((uid_t)uid, &pwent, pwbuf, (size_t)buflen);
+#else
+            res = getpwuid_r((uid_t)uid, &pwent, pwbuf, (size_t)buflen, &p);
+#endif
+
+            if (res != 0 || p == NULL || p->pw_name == NULL || *(p->pw_name) == '\0') {
+                throwUnixException(env, errno);
+            } else {
+                jsize len = strlen(p->pw_name);
+                result = (*env)->NewByteArray(env, len);
+                if (result != NULL) {
+                    (*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)(p->pw_name));
+                }
+            }
+            free(pwbuf);
+        }
+    }
+    return result;
+}
+
+
+JNIEXPORT jbyteArray JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_getgrgid(JNIEnv* env, jclass this, jint gid)
+{
+    jbyteArray result = NULL;
+    int buflen;
+
+    buflen = (int)sysconf(_SC_GETGR_R_SIZE_MAX);
+    if (buflen == -1) {
+        throwUnixException(env, errno);
+    } else {
+        char* grbuf = (char*)malloc(buflen);
+        if (grbuf == NULL) {
+            JNU_ThrowOutOfMemoryError(env, "native heap");
+        } else {
+            struct group grent;
+            struct group* g;
+            int res = 0;
+
+#ifdef __solaris__
+            g = getgrgid_r((gid_t)gid, &grent, grbuf, (size_t)buflen);
+#else
+            res = getgrgid_r((gid_t)gid, &grent, grbuf, (size_t)buflen, &g);
+#endif
+            if (res != 0 || g == NULL || g->gr_name == NULL || *(g->gr_name) == '\0') {
+                throwUnixException(env, errno);
+            } else {
+                jsize len = strlen(g->gr_name);
+                result = (*env)->NewByteArray(env, len);
+                if (result != NULL) {
+                    (*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)(g->gr_name));
+                }
+            }
+            free(grbuf);
+        }
+    }
+    return result;
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_getpwnam0(JNIEnv* env, jclass this,
+    jlong nameAddress)
+{
+    jint uid = -1;
+    int buflen;
+    char* pwbuf;
+    struct passwd pwent;
+    struct passwd* p;
+    int res = 0;
+    const char* name = (const char*)jlong_to_ptr(nameAddress);
+
+    buflen = (int)sysconf(_SC_GETPW_R_SIZE_MAX);
+    if (buflen == -1) {
+        throwUnixException(env, errno);
+        return -1;
+    }
+    pwbuf = (char*)malloc(buflen);
+    if (pwbuf == NULL) {
+        JNU_ThrowOutOfMemoryError(env, "native heap");
+        return -1;
+    }
+
+#ifdef __solaris__
+    p = getpwnam_r(name, &pwent, pwbuf, (size_t)buflen);
+#else
+    res = getpwnam_r(name, &pwent, pwbuf, (size_t)buflen, &p);
+#endif
+
+    if (res != 0 || p == NULL || p->pw_name == NULL || *(p->pw_name) == '\0') {
+        /* not found or error */
+    } else {
+        uid = p->pw_uid;
+    }
+
+    free(pwbuf);
+
+    return uid;
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_getgrnam0(JNIEnv* env, jclass this,
+    jlong nameAddress)
+{
+    jint gid = -1;
+    int buflen;
+    char* grbuf;
+    struct group grent;
+    struct group* g;
+    int res = 0;
+    const char* name = (const char*)jlong_to_ptr(nameAddress);
+
+    buflen = (int)sysconf(_SC_GETGR_R_SIZE_MAX);
+    if (buflen == -1) {
+        throwUnixException(env, errno);
+        return -1;
+    }
+    grbuf = (char*)malloc(buflen);
+    if (grbuf == NULL) {
+        JNU_ThrowOutOfMemoryError(env, "native heap");
+        return -1;
+    }
+
+#ifdef __solaris__
+    g = getgrnam_r(name, &grent, grbuf, (size_t)buflen);
+#else
+    res = getgrnam_r(name, &grent, grbuf, (size_t)buflen, &g);
+#endif
+
+    if (res != 0 || g == NULL || g->gr_name == NULL || *(g->gr_name) == '\0') {
+        /* not found or error */
+    } else {
+        gid = g->gr_gid;
+    }
+    free(grbuf);
+
+    return gid;
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_getextmntent(JNIEnv* env, jclass this,
+    jlong value, jobject entry)
+{
+#ifdef __solaris__
+    struct extmnttab ent;
+#else
+    struct mntent ent;
+    char buf[1024];
+    int buflen = sizeof(buf);
+    struct mntent* m;
+#endif
+    FILE* fp = jlong_to_ptr(value);
+    jsize len;
+    jbyteArray bytes;
+    char* name;
+    char* dir;
+    char* fstype;
+    char* options;
+    dev_t dev;
+
+#ifdef __solaris__
+    if (getextmntent(fp, &ent, 0))
+        return -1;
+    name = ent.mnt_special;
+    dir = ent.mnt_mountp;
+    fstype = ent.mnt_fstype;
+    options = ent.mnt_mntopts;
+    dev = makedev(ent.mnt_major, ent.mnt_minor);
+    if (dev == NODEV) {
+        /* possible bug on Solaris 8 and 9 */
+        throwUnixException(env, errno);
+        return -1;
+    }
+#else
+    m = getmntent_r(fp, &ent, (char*)&buf, buflen);
+    if (m == NULL)
+        return -1;
+    name = m->mnt_fsname;
+    dir = m->mnt_dir;
+    fstype = m->mnt_type;
+    options = m->mnt_opts;
+    dev = 0;
+#endif
+
+    len = strlen(name);
+    bytes = (*env)->NewByteArray(env, len);
+    if (bytes == NULL)
+        return -1;
+    (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)name);
+    (*env)->SetObjectField(env, entry, entry_name, bytes);
+
+    len = strlen(dir);
+    bytes = (*env)->NewByteArray(env, len);
+    if (bytes == NULL)
+        return -1;
+    (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)dir);
+    (*env)->SetObjectField(env, entry, entry_dir, bytes);
+
+    len = strlen(fstype);
+    bytes = (*env)->NewByteArray(env, len);
+    if (bytes == NULL)
+        return -1;
+    (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)fstype);
+    (*env)->SetObjectField(env, entry, entry_fstype, bytes);
+
+    len = strlen(options);
+    bytes = (*env)->NewByteArray(env, len);
+    if (bytes == NULL)
+        return -1;
+    (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)options);
+    (*env)->SetObjectField(env, entry, entry_options, bytes);
+
+    if (dev != 0)
+        (*env)->SetLongField(env, entry, entry_dev, (jlong)dev);
+
+    return 0;
+}
diff --git a/jdk/src/solaris/native/sun/nio/fs/genSolarisConstants.c b/jdk/src/solaris/native/sun/nio/fs/genSolarisConstants.c
new file mode 100644
index 0000000..182449e
--- /dev/null
+++ b/jdk/src/solaris/native/sun/nio/fs/genSolarisConstants.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/acl.h>
+#include <sys/fcntl.h>
+#include <sys/stat.h>
+
+/**
+ * Generates sun.nio.fs.SolarisConstants
+ */
+
+static void out(char* s) {
+    printf("%s\n", s);
+}
+
+static void emit(char* name, int value) {
+    printf("    static final int %s = %d;\n", name, value);
+}
+
+static void emitX(char* name, int value) {
+    printf("    static final int %s = 0x%x;\n", name, value);
+}
+
+#define DEF(X) emit(#X, X);
+#define DEFX(X) emitX(#X, X);
+
+int main(int argc, const char* argv[]) {
+    out("// AUTOMATICALLY GENERATED FILE - DO NOT EDIT                                  ");
+    out("package sun.nio.fs;                                                            ");
+    out("class SolarisConstants {                                                       ");
+    out("    private SolarisConstants() { }                                             ");
+
+    // extended attributes
+    DEFX(O_XATTR);
+    DEF(_PC_XATTR_ENABLED);
+
+    // ACL configuration
+    DEF(_PC_ACL_ENABLED);
+    DEFX(_ACL_ACE_ENABLED);
+
+    // ACL commands
+    DEFX(ACE_GETACL);
+    DEFX(ACE_SETACL);
+
+    // ACL mask/flags/types
+    emitX("ACE_ACCESS_ALLOWED_ACE_TYPE",        0x0000);
+    emitX("ACE_ACCESS_DENIED_ACE_TYPE",         0x0001);
+    emitX("ACE_SYSTEM_AUDIT_ACE_TYPE",          0x0002);
+    emitX("ACE_SYSTEM_ALARM_ACE_TYPE",          0x0003);
+    emitX("ACE_READ_DATA",                      0x00000001);
+    emitX("ACE_LIST_DIRECTORY",                 0x00000001);
+    emitX("ACE_WRITE_DATA",                     0x00000002);
+    emitX("ACE_ADD_FILE",                       0x00000002);
+    emitX("ACE_APPEND_DATA",                    0x00000004);
+    emitX("ACE_ADD_SUBDIRECTORY",               0x00000004);
+    emitX("ACE_READ_NAMED_ATTRS",               0x00000008);
+    emitX("ACE_WRITE_NAMED_ATTRS",              0x00000010);
+    emitX("ACE_EXECUTE",                        0x00000020);
+    emitX("ACE_DELETE_CHILD",                   0x00000040);
+    emitX("ACE_READ_ATTRIBUTES",                0x00000080);
+    emitX("ACE_WRITE_ATTRIBUTES",               0x00000100);
+    emitX("ACE_DELETE",                         0x00010000);
+    emitX("ACE_READ_ACL",                       0x00020000);
+    emitX("ACE_WRITE_ACL",                      0x00040000);
+    emitX("ACE_WRITE_OWNER",                    0x00080000);
+    emitX("ACE_SYNCHRONIZE",                    0x00100000);
+    emitX("ACE_FILE_INHERIT_ACE",               0x0001);
+    emitX("ACE_DIRECTORY_INHERIT_ACE",          0x0002);
+    emitX("ACE_NO_PROPAGATE_INHERIT_ACE",       0x0004);
+    emitX("ACE_INHERIT_ONLY_ACE",               0x0008);
+    emitX("ACE_SUCCESSFUL_ACCESS_ACE_FLAG",     0x0010);
+    emitX("ACE_FAILED_ACCESS_ACE_FLAG",         0x0020);
+    emitX("ACE_IDENTIFIER_GROUP",               0x0040);
+    emitX("ACE_OWNER",                          0x1000);
+    emitX("ACE_GROUP",                          0x2000);
+    emitX("ACE_EVERYONE",                       0x4000);
+
+    out("}                                                                              ");
+    return 0;
+}
diff --git a/jdk/src/solaris/native/sun/nio/fs/genUnixConstants.c b/jdk/src/solaris/native/sun/nio/fs/genUnixConstants.c
new file mode 100644
index 0000000..c01f641
--- /dev/null
+++ b/jdk/src/solaris/native/sun/nio/fs/genUnixConstants.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/fcntl.h>
+#include <sys/stat.h>
+
+/**
+ * Generates sun.nio.fs.UnixConstants
+ */
+
+static void out(char* s) {
+    printf("%s\n", s);
+}
+
+static void emit(char* name, int value) {
+    printf("    static final int %s = %d;\n", name, value);
+}
+
+static void emitX(char* name, int value) {
+    printf("    static final int %s = 0x%x;\n", name, value);
+}
+
+#define DEF(X) emit(#X, X);
+#define DEFX(X) emitX(#X, X);
+
+int main(int argc, const char* argv[]) {
+    out("// AUTOMATICALLY GENERATED FILE - DO NOT EDIT                                  ");
+    out("package sun.nio.fs;                                                            ");
+    out("class UnixConstants {                                                          ");
+    out("    private UnixConstants() { }                                                ");
+
+    // open flags
+    DEF(O_RDONLY);
+    DEF(O_WRONLY);
+    DEF(O_RDWR);
+    DEFX(O_APPEND);
+    DEFX(O_CREAT);
+    DEFX(O_EXCL);
+    DEFX(O_TRUNC);
+    DEFX(O_SYNC);
+    DEFX(O_DSYNC);
+    DEFX(O_NOFOLLOW);
+
+    // flags used with openat/unlinkat/etc.
+#ifdef __solaris__
+    DEFX(AT_SYMLINK_NOFOLLOW);
+    DEFX(AT_REMOVEDIR);
+#endif
+#ifdef __linux__
+    emitX("AT_SYMLINK_NOFOLLOW", 0x100);        // since 2.6.16
+    emitX("AT_REMOVEDIR", 0x200);
+#endif
+
+    // mode masks
+    emitX("S_IAMB",
+         (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH));
+    DEF(S_IRUSR);
+    DEF(S_IWUSR);
+    DEF(S_IXUSR);
+    DEF(S_IRGRP);
+    DEF(S_IWGRP);
+    DEF(S_IXGRP);
+    DEF(S_IROTH);
+    DEF(S_IWOTH);
+    DEF(S_IXOTH);
+    DEFX(S_IFMT);
+    DEFX(S_IFREG);
+    DEFX(S_IFDIR);
+    DEFX(S_IFLNK);
+    DEFX(S_IFCHR);
+    DEFX(S_IFBLK);
+    DEFX(S_IFIFO);
+
+    // access modes
+    DEF(R_OK);
+    DEF(W_OK);
+    DEF(X_OK);
+    DEF(F_OK);
+
+    // errors
+    DEF(ENOENT);
+    DEF(EACCES);
+    DEF(EEXIST);
+    DEF(ENOTDIR);
+    DEF(EINVAL);
+    DEF(EXDEV);
+    DEF(EISDIR);
+    DEF(ENOTEMPTY);
+    DEF(ENOSPC);
+    DEF(EAGAIN);
+    DEF(ENOSYS);
+    DEF(ELOOP);
+    DEF(EROFS);
+    DEF(ENODATA);
+    DEF(ERANGE);
+
+    out("}                                                                              ");
+
+    return 0;
+}
diff --git a/jdk/src/windows/classes/sun/nio/ch/DefaultAsynchronousChannelProvider.java b/jdk/src/windows/classes/sun/nio/ch/DefaultAsynchronousChannelProvider.java
new file mode 100644
index 0000000..6187aa3
--- /dev/null
+++ b/jdk/src/windows/classes/sun/nio/ch/DefaultAsynchronousChannelProvider.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.ch;
+
+import java.nio.channels.spi.AsynchronousChannelProvider;
+
+/**
+ * Creates this platform's default asynchronous channel provider
+ */
+
+public class DefaultAsynchronousChannelProvider {
+    private DefaultAsynchronousChannelProvider() { }
+
+    /**
+     * Returns the default AsynchronousChannelProvider.
+     */
+    public static AsynchronousChannelProvider create() {
+        return new WindowsAsynchronousChannelProvider();
+    }
+}
diff --git a/jdk/src/windows/classes/sun/nio/ch/FileDispatcher.java b/jdk/src/windows/classes/sun/nio/ch/FileDispatcherImpl.java
similarity index 71%
rename from jdk/src/windows/classes/sun/nio/ch/FileDispatcher.java
rename to jdk/src/windows/classes/sun/nio/ch/FileDispatcherImpl.java
index 6928449..30390f7 100644
--- a/jdk/src/windows/classes/sun/nio/ch/FileDispatcher.java
+++ b/jdk/src/windows/classes/sun/nio/ch/FileDispatcherImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2003 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2009 Sun Microsystems, Inc.  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
@@ -27,13 +27,7 @@
 
 import java.io.*;
 
-
-/**
- * Allows different platforms to call different native methods
- * for read and write operations.
- */
-
-class FileDispatcher extends NativeDispatcher
+class FileDispatcherImpl extends FileDispatcher
 {
 
     static {
@@ -74,6 +68,28 @@
         return writev0(fd, address, len);
     }
 
+    int force(FileDescriptor fd, boolean metaData) throws IOException {
+        return force0(fd, metaData);
+    }
+
+    int truncate(FileDescriptor fd, long size) throws IOException {
+        return truncate0(fd, size);
+    }
+
+    long size(FileDescriptor fd) throws IOException {
+        return size0(fd);
+    }
+
+    int lock(FileDescriptor fd, boolean blocking, long pos, long size,
+             boolean shared) throws IOException
+    {
+        return lock0(fd, blocking, pos, size, shared);
+    }
+
+    void release(FileDescriptor fd, long pos, long size) throws IOException {
+        release0(fd, pos, size);
+    }
+
     void close(FileDescriptor fd) throws IOException {
         close0(fd);
     }
@@ -98,6 +114,20 @@
     static native long writev0(FileDescriptor fd, long address, int len)
         throws IOException;
 
+    static native int force0(FileDescriptor fd, boolean metaData)
+        throws IOException;
+
+    static native int truncate0(FileDescriptor fd, long size)
+        throws IOException;
+
+    static native long size0(FileDescriptor fd) throws IOException;
+
+    static native int lock0(FileDescriptor fd, boolean blocking, long pos,
+                            long size, boolean shared) throws IOException;
+
+    static native void release0(FileDescriptor fd, long pos, long size)
+        throws IOException;
+
     static native void close0(FileDescriptor fd) throws IOException;
 
     static native void closeByHandle(long fd) throws IOException;
diff --git a/jdk/src/windows/classes/sun/nio/ch/Iocp.java b/jdk/src/windows/classes/sun/nio/ch/Iocp.java
new file mode 100644
index 0000000..b4c2cde
--- /dev/null
+++ b/jdk/src/windows/classes/sun/nio/ch/Iocp.java
@@ -0,0 +1,437 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.ch;
+
+import java.nio.channels.*;
+import java.nio.channels.spi.AsynchronousChannelProvider;
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.FileDescriptor;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import sun.misc.Unsafe;
+
+/**
+ * Windows implementation of AsynchronousChannelGroup encapsulating an I/O
+ * completion port.
+ */
+
+class Iocp extends AsynchronousChannelGroupImpl {
+    private static final Unsafe unsafe = Unsafe.getUnsafe();
+    private static final long INVALID_HANDLE_VALUE  = -1L;
+
+    // maps completion key to channel
+    private final ReadWriteLock keyToChannelLock = new ReentrantReadWriteLock();
+    private final Map<Integer,OverlappedChannel> keyToChannel =
+        new HashMap<Integer,OverlappedChannel>();
+    private int nextCompletionKey;
+
+    // handle to completion port
+    private final long port;
+
+    // true if port has been closed
+    private boolean closed;
+
+    // the set of "stale" OVERLAPPED structures. These OVERLAPPED structures
+    // relate to I/O operations where the completion notification was not
+    // received in a timely manner after the channel is closed.
+    private final Set<Long> staleIoSet = new HashSet<Long>();
+
+    Iocp(AsynchronousChannelProvider provider, ThreadPool pool)
+        throws IOException
+    {
+        super(provider, pool);
+        this.port =
+          createIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, fixedThreadCount());
+        this.nextCompletionKey = 1;
+    }
+
+    Iocp start() {
+        startThreads(new EventHandlerTask());
+        return this;
+    }
+
+    /*
+     * Channels implements this interface support overlapped I/O and can be
+     * associated with a completion port.
+     */
+    static interface OverlappedChannel extends Closeable {
+        /**
+         * Returns a reference to the pending I/O result.
+         */
+        <V,A> PendingFuture<V,A> getByOverlapped(long overlapped);
+    }
+
+    // release all resources
+    void implClose() {
+        synchronized (this) {
+            if (closed)
+                return;
+            closed = true;
+        }
+        close0(port);
+        synchronized (staleIoSet) {
+            for (Long ov: staleIoSet) {
+                unsafe.freeMemory(ov);
+            }
+            staleIoSet.clear();
+        }
+    }
+
+    @Override
+    boolean isEmpty() {
+        keyToChannelLock.writeLock().lock();
+        try {
+            return keyToChannel.isEmpty();
+        } finally {
+            keyToChannelLock.writeLock().unlock();
+        }
+    }
+
+    @Override
+    final Object attachForeignChannel(final Channel channel, FileDescriptor fdObj)
+        throws IOException
+    {
+        int key = associate(new OverlappedChannel() {
+            public <V,A> PendingFuture<V,A> getByOverlapped(long overlapped) {
+                return null;
+            }
+            public void close() throws IOException {
+                channel.close();
+            }
+        }, 0L);
+        return Integer.valueOf(key);
+    }
+
+    @Override
+    final void detachForeignChannel(Object key) {
+        disassociate((Integer)key);
+    }
+
+    @Override
+    void closeAllChannels() {
+        /**
+         * On Windows the close operation will close the socket/file handle
+         * and then wait until all outstanding I/O operations have aborted.
+         * This is necessary as each channel's cache of OVERLAPPED structures
+         * can only be freed once all I/O operations have completed. As I/O
+         * completion requires a lookup of the keyToChannel then we must close
+         * the channels when not holding the write lock.
+         */
+        final int MAX_BATCH_SIZE = 32;
+        OverlappedChannel channels[] = new OverlappedChannel[MAX_BATCH_SIZE];
+        int count;
+        do {
+            // grab a batch of up to 32 channels
+            keyToChannelLock.writeLock().lock();
+            count = 0;
+            try {
+                for (Integer key: keyToChannel.keySet()) {
+                    channels[count++] = keyToChannel.get(key);
+                    if (count >= MAX_BATCH_SIZE)
+                        break;
+                }
+            } finally {
+                keyToChannelLock.writeLock().unlock();
+            }
+
+            // close them
+            for (int i=0; i<count; i++) {
+                try {
+                    channels[i].close();
+                } catch (IOException ignore) { }
+            }
+        } while (count > 0);
+    }
+
+    private void wakeup() {
+        try {
+            postQueuedCompletionStatus(port, 0);
+        } catch (IOException e) {
+            // should not happen
+            throw new AssertionError(e);
+        }
+    }
+
+    @Override
+    void executeOnHandlerTask(Runnable task) {
+        synchronized (this) {
+            if (closed)
+                throw new RejectedExecutionException();
+            offerTask(task);
+            wakeup();
+        }
+
+    }
+
+    @Override
+    void shutdownHandlerTasks() {
+        // shutdown all handler threads
+        int nThreads = threadCount();
+        while (nThreads-- > 0) {
+            wakeup();
+        }
+    }
+
+    /**
+     * Associate the given handle with this group
+     */
+    int associate(OverlappedChannel ch, long handle) throws IOException {
+        keyToChannelLock.writeLock().lock();
+
+        // generate a completion key (if not shutdown)
+        int key;
+        try {
+            if (isShutdown())
+                throw new ShutdownChannelGroupException();
+
+            // generate unique key
+            do {
+                key = nextCompletionKey++;
+            } while ((key == 0) || keyToChannel.containsKey(key));
+
+            // associate with I/O completion port
+            if (handle != 0L)
+                createIoCompletionPort(handle, port, key, 0);
+
+            // setup mapping
+            keyToChannel.put(key, ch);
+        } finally {
+            keyToChannelLock.writeLock().unlock();
+        }
+        return key;
+    }
+
+    /**
+     * Disassociate channel from the group.
+     */
+    void disassociate(int key) {
+        boolean checkForShutdown = false;
+
+        keyToChannelLock.writeLock().lock();
+        try {
+            keyToChannel.remove(key);
+
+            // last key to be removed so check if group is shutdown
+            if (keyToChannel.isEmpty())
+                checkForShutdown = true;
+
+        } finally {
+            keyToChannelLock.writeLock().unlock();
+        }
+
+        // continue shutdown
+        if (checkForShutdown && isShutdown()) {
+            try {
+                shutdownNow();
+            } catch (IOException ignore) { }
+        }
+    }
+
+    /**
+     * Invoked when a channel associated with this port is closed before
+     * notifications for all outstanding I/O operations have been received.
+     */
+    void makeStale(Long overlapped) {
+        synchronized (staleIoSet) {
+            staleIoSet.add(overlapped);
+        }
+    }
+
+    /**
+     * Checks if the given OVERLAPPED is stale and if so, releases it.
+     */
+    private void checkIfStale(long ov) {
+        synchronized (staleIoSet) {
+            boolean removed = staleIoSet.remove(ov);
+            if (removed) {
+                unsafe.freeMemory(ov);
+            }
+        }
+    }
+
+    /**
+     * The handler for consuming the result of an asynchronous I/O operation.
+     */
+    static interface ResultHandler {
+        /**
+         * Invoked if the I/O operation completes successfully.
+         */
+        public void completed(int bytesTransferred);
+
+        /**
+         * Invoked if the I/O operation fails.
+         */
+        public void failed(int error, IOException ioe);
+    }
+
+    // Creates IOException for the given I/O error.
+    private static IOException translateErrorToIOException(int error) {
+        String msg = getErrorMessage(error);
+        if (msg == null)
+            msg = "Unknown error: 0x0" + Integer.toHexString(error);
+        return new IOException(msg);
+    }
+
+    /**
+     * Long-running task servicing system-wide or per-file completion port
+     */
+    private class EventHandlerTask implements Runnable {
+        public void run() {
+            Invoker.GroupAndInvokeCount myGroupAndInvokeCount =
+                Invoker.getGroupAndInvokeCount();
+            CompletionStatus ioResult = new CompletionStatus();
+            boolean replaceMe = false;
+
+            try {
+                for (;;) {
+                    // reset invoke count
+                    if (myGroupAndInvokeCount != null)
+                        myGroupAndInvokeCount.resetInvokeCount();
+
+                    // wait for I/O completion event
+                    // A error here is fatal (thread will not be replaced)
+                    replaceMe = false;
+                    try {
+                        getQueuedCompletionStatus(port, ioResult);
+                    } catch (IOException x) {
+                        // should not happen
+                        x.printStackTrace();
+                        return;
+                    }
+
+                    // handle wakeup to execute task or shutdown
+                    if (ioResult.completionKey() == 0 &&
+                        ioResult.overlapped() == 0L)
+                    {
+                        Runnable task = pollTask();
+                        if (task == null) {
+                            // shutdown request
+                            return;
+                        }
+
+                        // run task
+                        // (if error/exception then replace thread)
+                        replaceMe = true;
+                        task.run();
+                        continue;
+                    }
+
+                    // map key to channel
+                    OverlappedChannel ch = null;
+                    keyToChannelLock.readLock().lock();
+                    try {
+                        ch = keyToChannel.get(ioResult.completionKey());
+                        if (ch == null) {
+                            checkIfStale(ioResult.overlapped());
+                            continue;
+                        }
+                    } finally {
+                        keyToChannelLock.readLock().unlock();
+                    }
+
+                    // lookup I/O request
+                    PendingFuture<?,?> result = ch.getByOverlapped(ioResult.overlapped());
+                    if (result == null) {
+                        // we get here if the OVERLAPPED structure is associated
+                        // with an I/O operation on a channel that was closed
+                        // but the I/O operation event wasn't read in a timely
+                        // manner. Alternatively, it may be related to a
+                        // tryLock operation as the OVERLAPPED structures for
+                        // these operations are not in the I/O cache.
+                        checkIfStale(ioResult.overlapped());
+                        continue;
+                    }
+
+                    // synchronize on result in case I/O completed immediately
+                    // and was handled by initiator
+                    synchronized (result) {
+                        if (result.isDone()) {
+                            continue;
+                        }
+                        // not handled by initiator
+                    }
+
+                    // invoke I/O result handler
+                    int error = ioResult.error();
+                    ResultHandler rh = (ResultHandler)result.getContext();
+                    replaceMe = true; // (if error/exception then replace thread)
+                    if (error == 0) {
+                        rh.completed(ioResult.bytesTransferred());
+                    } else {
+                        rh.failed(error, translateErrorToIOException(error));
+                    }
+                }
+            } finally {
+                // last thread to exit when shutdown releases resources
+                int remaining = threadExit(this, replaceMe);
+                if (remaining == 0 && isShutdown()) {
+                    implClose();
+                }
+            }
+        }
+    }
+
+    /**
+     * Container for data returned by GetQueuedCompletionStatus
+     */
+    private static class CompletionStatus {
+        private int error;
+        private int bytesTransferred;
+        private int completionKey;
+        private long overlapped;
+
+        private CompletionStatus() { }
+        int error() { return error; }
+        int bytesTransferred() { return bytesTransferred; }
+        int completionKey() { return completionKey; }
+        long overlapped() { return overlapped; }
+    }
+
+    // -- native methods --
+
+    private static native void initIDs();
+
+    private static native long createIoCompletionPort(long handle,
+        long existingPort, int completionKey, int concurrency) throws IOException;
+
+    private static native void close0(long handle);
+
+    private static native void getQueuedCompletionStatus(long completionPort,
+        CompletionStatus status) throws IOException;
+
+    private static native void postQueuedCompletionStatus(long completionPort,
+        int completionKey) throws IOException;
+
+    private static native String getErrorMessage(int error);
+
+    static {
+        Util.load();
+        initIDs();
+    }
+}
diff --git a/jdk/src/windows/classes/sun/nio/ch/PendingIoCache.java b/jdk/src/windows/classes/sun/nio/ch/PendingIoCache.java
new file mode 100644
index 0000000..2e3d503
--- /dev/null
+++ b/jdk/src/windows/classes/sun/nio/ch/PendingIoCache.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.ch;
+
+import java.nio.channels.*;
+import java.util.*;
+import sun.misc.Unsafe;
+
+/**
+ * Maintains a mapping of pending I/O requests (identified by the address of
+ * an OVERLAPPED structure) to Futures.
+ */
+
+class PendingIoCache {
+    private static final Unsafe unsafe = Unsafe.getUnsafe();
+    private static final int addressSize = unsafe.addressSize();
+
+    private static int dependsArch(int value32, int value64) {
+        return (addressSize == 4) ? value32 : value64;
+    }
+
+    /*
+     * typedef struct _OVERLAPPED {
+     *     DWORD  Internal;
+     *     DWORD  InternalHigh;
+     *     DWORD  Offset;
+     *     DWORD  OffsetHigh;
+     *     HANDLE hEvent;
+     * } OVERLAPPED;
+     */
+    private static final int SIZEOF_OVERLAPPED = dependsArch(20, 32);
+
+    // set to true when closed
+    private boolean closed;
+
+    // set to true when thread is waiting for all I/O operations to complete
+    private boolean closePending;
+
+    // maps OVERLAPPED to PendingFuture
+    private final Map<Long,PendingFuture> pendingIoMap =
+        new HashMap<Long,PendingFuture>();
+
+    // per-channel cache of OVERLAPPED structures
+    private long[] overlappedCache = new long[4];
+    private int overlappedCacheCount = 0;
+
+    PendingIoCache() {
+    }
+
+    long add(PendingFuture<?,?> result) {
+        synchronized (this) {
+            if (closed)
+                throw new AssertionError("Should not get here");
+            long ov;
+            if (overlappedCacheCount > 0) {
+                ov = overlappedCache[--overlappedCacheCount];
+            } else {
+                ov = unsafe.allocateMemory(SIZEOF_OVERLAPPED);
+            }
+            pendingIoMap.put(ov, result);
+            return ov;
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    <V,A> PendingFuture<V,A> remove(long overlapped) {
+        synchronized (this) {
+            PendingFuture<V,A> res = pendingIoMap.remove(overlapped);
+            if (res != null) {
+                if (overlappedCacheCount < overlappedCache.length) {
+                    overlappedCache[overlappedCacheCount++] = overlapped;
+                } else {
+                    // cache full or channel closing
+                    unsafe.freeMemory(overlapped);
+                }
+                // notify closing thread.
+                if (closePending) {
+                    this.notifyAll();
+                }
+            }
+            return res;
+        }
+    }
+
+    void close() {
+        synchronized (this) {
+            if (closed)
+                return;
+
+            // handle the case that where there are I/O operations that have
+            // not completed.
+            if (!pendingIoMap.isEmpty())
+                clearPendingIoMap();
+
+            // release memory for any cached OVERLAPPED structures
+            while (overlappedCacheCount > 0) {
+                unsafe.freeMemory( overlappedCache[--overlappedCacheCount] );
+            }
+
+            // done
+            closed = true;
+        }
+    }
+
+    private void clearPendingIoMap() {
+        assert Thread.holdsLock(this);
+
+        // wait up to 50ms for the I/O operations to complete
+        closePending = true;
+        try {
+            this.wait(50);
+        } catch (InterruptedException x) { }
+        closePending = false;
+        if (pendingIoMap.isEmpty())
+            return;
+
+        // cause all pending I/O operations to fail
+        // simulate the failure of all pending I/O operations.
+        for (Long ov: pendingIoMap.keySet()) {
+            PendingFuture<?,?> result = pendingIoMap.get(ov);
+            assert !result.isDone();
+
+            // make I/O port aware of the stale OVERLAPPED structure
+            Iocp iocp = (Iocp)((Groupable)result.channel()).group();
+            iocp.makeStale(ov);
+
+            // execute a task that invokes the result handler's failed method
+            final Iocp.ResultHandler rh = (Iocp.ResultHandler)result.getContext();
+            Runnable task = new Runnable() {
+                public void run() {
+                    rh.failed(-1, new AsynchronousCloseException());
+                }
+            };
+            iocp.executeOnPooledThread(task);
+        }
+        pendingIoMap.clear();
+    }
+}
diff --git a/jdk/src/windows/classes/sun/nio/ch/WindowsAsynchronousChannelProvider.java b/jdk/src/windows/classes/sun/nio/ch/WindowsAsynchronousChannelProvider.java
new file mode 100644
index 0000000..435b529
--- /dev/null
+++ b/jdk/src/windows/classes/sun/nio/ch/WindowsAsynchronousChannelProvider.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.ch;
+
+import java.nio.channels.*;
+import java.nio.channels.spi.AsynchronousChannelProvider;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.ThreadFactory;
+import java.net.ProtocolFamily;
+import java.io.IOException;
+
+public class WindowsAsynchronousChannelProvider
+    extends AsynchronousChannelProvider
+{
+    private static volatile Iocp defaultIocp;
+
+    public WindowsAsynchronousChannelProvider() {
+        // nothing to do
+    }
+
+    private Iocp defaultIocp() throws IOException {
+        if (defaultIocp == null) {
+            synchronized (WindowsAsynchronousChannelProvider.class) {
+                if (defaultIocp == null) {
+                    // default thread pool may be shared with AsynchronousFileChannels
+                    defaultIocp = new Iocp(this, ThreadPool.getDefault()).start();
+                }
+            }
+        }
+        return defaultIocp;
+    }
+
+    @Override
+    public AsynchronousChannelGroup openAsynchronousChannelGroup(int nThreads, ThreadFactory factory)
+        throws IOException
+    {
+        return new Iocp(this, ThreadPool.create(nThreads, factory)).start();
+    }
+
+    @Override
+    public AsynchronousChannelGroup openAsynchronousChannelGroup(ExecutorService executor, int initialSize)
+        throws IOException
+    {
+        return new Iocp(this, ThreadPool.wrap(executor, initialSize)).start();
+    }
+
+    private Iocp toIocp(AsynchronousChannelGroup group) throws IOException {
+        if (group == null) {
+            return defaultIocp();
+        } else {
+            if (!(group instanceof Iocp))
+                throw new IllegalChannelGroupException();
+            return (Iocp)group;
+        }
+    }
+
+    @Override
+    public AsynchronousServerSocketChannel openAsynchronousServerSocketChannel(AsynchronousChannelGroup group)
+        throws IOException
+    {
+        return new WindowsAsynchronousServerSocketChannelImpl(toIocp(group));
+    }
+
+    @Override
+    public AsynchronousSocketChannel openAsynchronousSocketChannel(AsynchronousChannelGroup group)
+        throws IOException
+    {
+        return new WindowsAsynchronousSocketChannelImpl(toIocp(group));
+    }
+
+    @Override
+    public AsynchronousDatagramChannel openAsynchronousDatagramChannel(ProtocolFamily family,
+                                                                       AsynchronousChannelGroup group)
+        throws IOException
+    {
+        return new SimpleAsynchronousDatagramChannelImpl(family, toIocp(group));
+    }
+}
diff --git a/jdk/src/windows/classes/sun/nio/ch/WindowsAsynchronousFileChannelImpl.java b/jdk/src/windows/classes/sun/nio/ch/WindowsAsynchronousFileChannelImpl.java
new file mode 100644
index 0000000..ef66864
--- /dev/null
+++ b/jdk/src/windows/classes/sun/nio/ch/WindowsAsynchronousFileChannelImpl.java
@@ -0,0 +1,741 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.ch;
+
+import java.nio.channels.*;
+import java.util.concurrent.*;
+import java.nio.ByteBuffer;
+import java.nio.BufferOverflowException;
+import java.io.IOException;
+import java.io.FileDescriptor;
+import sun.misc.SharedSecrets;
+import sun.misc.JavaIOFileDescriptorAccess;
+
+/**
+ * Windows implementation of AsynchronousFileChannel using overlapped I/O.
+ */
+
+public class WindowsAsynchronousFileChannelImpl
+    extends AsynchronousFileChannelImpl
+    implements Iocp.OverlappedChannel, Groupable
+{
+    private static final JavaIOFileDescriptorAccess fdAccess =
+        SharedSecrets.getJavaIOFileDescriptorAccess();
+
+    // error when EOF is detected asynchronously.
+    private static final int ERROR_HANDLE_EOF = 38;
+
+    // Lazy initialization of default I/O completion port
+    private static class DefaultIocpHolder {
+        static final Iocp defaultIocp = defaultIocp();
+        private static Iocp defaultIocp() {
+            try {
+                return new Iocp(null, ThreadPool.createDefault()).start();
+            } catch (IOException ioe) {
+                InternalError e = new InternalError();
+                e.initCause(ioe);
+                throw e;
+            }
+        }
+    }
+
+    // Used for force/truncate/size methods
+    private static final FileDispatcher nd = new FileDispatcherImpl();
+
+    // The handle is extracted for use in native methods invoked from this class.
+    private final long handle;
+
+    // The key that identifies the channel's association with the I/O port
+    private final int completionKey;
+
+    // I/O completion port (group)
+    private final Iocp iocp;
+
+    private final boolean isDefaultIocp;
+
+    // Caches OVERLAPPED structure for each outstanding I/O operation
+    private final PendingIoCache ioCache;
+
+
+    private WindowsAsynchronousFileChannelImpl(FileDescriptor fdObj,
+                                               boolean reading,
+                                               boolean writing,
+                                               Iocp iocp,
+                                               boolean isDefaultIocp)
+        throws IOException
+    {
+        super(fdObj, reading, writing, iocp.executor());
+        this.handle = fdAccess.getHandle(fdObj);
+        this.iocp = iocp;
+        this.isDefaultIocp = isDefaultIocp;
+        this.ioCache = new PendingIoCache();
+        this.completionKey = iocp.associate(this, handle);
+    }
+
+    public static AsynchronousFileChannel open(FileDescriptor fdo,
+                                               boolean reading,
+                                               boolean writing,
+                                               ThreadPool pool)
+        throws IOException
+    {
+        Iocp iocp;
+        boolean isDefaultIocp;
+        if (pool == null) {
+            iocp = DefaultIocpHolder.defaultIocp;
+            isDefaultIocp = true;
+        } else {
+            iocp = new Iocp(null, pool).start();
+            isDefaultIocp = false;
+        }
+        try {
+            return new
+                WindowsAsynchronousFileChannelImpl(fdo, reading, writing, iocp, isDefaultIocp);
+        } catch (IOException x) {
+            // error binding to port so need to close it (if created for this channel)
+            if (!isDefaultIocp)
+                iocp.implClose();
+            throw x;
+        }
+    }
+
+    @Override
+    public <V,A> PendingFuture<V,A> getByOverlapped(long overlapped) {
+        return ioCache.remove(overlapped);
+    }
+
+    @Override
+    public void close() throws IOException {
+        closeLock.writeLock().lock();
+        try {
+            if (closed)
+                return;     // already closed
+            closed = true;
+        } finally {
+            closeLock.writeLock().unlock();
+        }
+
+        // invalidate all locks held for this channel
+        invalidateAllLocks();
+
+        // close the file
+        close0(handle);
+
+        // waits until all I/O operations have completed
+        ioCache.close();
+
+        // disassociate from port and shutdown thread pool if not default
+        iocp.disassociate(completionKey);
+        if (!isDefaultIocp)
+            iocp.shutdown();
+    }
+
+    @Override
+    public AsynchronousChannelGroupImpl group() {
+        return iocp;
+    }
+
+    /**
+     * Translates Throwable to IOException
+     */
+    private static IOException toIOException(Throwable x) {
+        if (x instanceof IOException) {
+            if (x instanceof ClosedChannelException)
+                x = new AsynchronousCloseException();
+            return (IOException)x;
+        }
+        return new IOException(x);
+    }
+
+    @Override
+    public long size() throws IOException {
+        try {
+            begin();
+            return nd.size(fdObj);
+        } finally {
+            end();
+        }
+    }
+
+    @Override
+    public AsynchronousFileChannel truncate(long size) throws IOException {
+        if (size < 0)
+            throw new IllegalArgumentException("Negative size");
+        if (!writing)
+            throw new NonWritableChannelException();
+        try {
+            begin();
+            if (size > nd.size(fdObj))
+                return this;
+            nd.truncate(fdObj, size);
+        } finally {
+            end();
+        }
+        return this;
+    }
+
+    @Override
+    public void force(boolean metaData) throws IOException {
+        try {
+            begin();
+            nd.force(fdObj, metaData);
+        } finally {
+            end();
+        }
+    }
+
+    // -- file locking --
+
+    /**
+     * Task that initiates locking operation and handles completion result.
+     */
+    private class LockTask<A> implements Runnable, Iocp.ResultHandler {
+        private final long position;
+        private final FileLockImpl fli;
+        private final PendingFuture<FileLock,A> result;
+
+        LockTask(long position,
+                 FileLockImpl fli,
+                 PendingFuture<FileLock,A> result)
+        {
+            this.position = position;
+            this.fli = fli;
+            this.result = result;
+        }
+
+        @Override
+        public void run() {
+            long overlapped = 0L;
+            try {
+                begin();
+
+                // allocate OVERLAPPED structure
+                overlapped = ioCache.add(result);
+
+                // synchronize on result to avoid race with handler thread
+                // when lock is acquired immediately.
+                synchronized (result) {
+                    int n = lockFile(handle, position, fli.size(), fli.isShared(),
+                                     overlapped);
+                    if (n == IOStatus.UNAVAILABLE) {
+                        // I/O is pending
+                        return;
+                    }
+                    // acquired lock immediately
+                    result.setResult(fli);
+                }
+
+            } catch (Throwable x) {
+                // lock failed or channel closed
+                removeFromFileLockTable(fli);
+                if (overlapped != 0L)
+                    ioCache.remove(overlapped);
+                result.setFailure(toIOException(x));
+            } finally {
+                end();
+            }
+
+            // invoke completion handler
+            Invoker.invoke(result.handler(), result);
+        }
+
+        @Override
+        public void completed(int bytesTransferred) {
+            // release waiters and invoke completion handler
+            result.setResult(fli);
+            Invoker.invoke(result.handler(), result);
+        }
+
+        @Override
+        public void failed(int error, IOException x) {
+            // lock not acquired so remove from lock table
+            removeFromFileLockTable(fli);
+
+            // release waiters
+            if (isOpen()) {
+                result.setFailure(x);
+            } else {
+                result.setFailure(new AsynchronousCloseException());
+            }
+            Invoker.invoke(result.handler(), result);
+        }
+    }
+
+    @Override
+    public <A> Future<FileLock> lock(long position,
+                                     long size,
+                                     boolean shared,
+                                     A attachment,
+                                     CompletionHandler<FileLock,? super A> handler)
+    {
+        if (shared && !reading)
+            throw new NonReadableChannelException();
+        if (!shared && !writing)
+            throw new NonWritableChannelException();
+
+        // add to lock table
+        FileLockImpl fli = addToFileLockTable(position, size, shared);
+        if (fli == null) {
+            CompletedFuture<FileLock,A> result = CompletedFuture
+                .withFailure(this, new ClosedChannelException(), attachment);
+            Invoker.invoke(handler, result);
+            return result;
+        }
+
+        // create Future and task that will be invoked to acquire lock
+        PendingFuture<FileLock,A> result =
+            new PendingFuture<FileLock,A>(this, handler, attachment);
+        LockTask lockTask = new LockTask<A>(position, fli, result);
+        result.setContext(lockTask);
+
+        // initiate I/O (can only be done from thread in thread pool)
+        try {
+            Invoker.invokeOnThreadInThreadPool(this, lockTask);
+        } catch (ShutdownChannelGroupException e) {
+            // rollback
+            removeFromFileLockTable(fli);
+            throw e;
+        }
+        return result;
+    }
+
+    static final int NO_LOCK = -1;       // Failed to lock
+    static final int LOCKED = 0;         // Obtained requested lock
+
+    @Override
+    public FileLock tryLock(long position, long size, boolean shared)
+        throws IOException
+    {
+        if (shared && !reading)
+            throw new NonReadableChannelException();
+        if (!shared && !writing)
+            throw new NonWritableChannelException();
+
+        // add to lock table
+        final FileLockImpl fli = addToFileLockTable(position, size, shared);
+        if (fli == null)
+            throw new ClosedChannelException();
+
+        boolean gotLock = false;
+        try {
+            begin();
+            // try to acquire the lock
+            int res = nd.lock(fdObj, false, position, size, shared);
+            if (res == NO_LOCK)
+                return null;
+            gotLock = true;
+            return fli;
+        } finally {
+            if (!gotLock)
+                removeFromFileLockTable(fli);
+            end();
+        }
+    }
+
+    // invoke by FileFileImpl to release lock
+    @Override
+    void release(FileLockImpl fli) throws IOException {
+        try {
+            begin();
+            nd.release(fdObj, fli.position(), fli.size());
+            removeFromFileLockTable(fli);
+        } finally {
+            end();
+        }
+    }
+
+    /**
+     * Task that initiates read operation and handles completion result.
+     */
+    private class ReadTask<A> implements Runnable, Iocp.ResultHandler {
+        private final ByteBuffer dst;
+        private final int pos, rem;     // buffer position/remaining
+        private final long position;    // file position
+        private final PendingFuture<Integer,A> result;
+
+        // set to dst if direct; otherwise set to substituted direct buffer
+        private volatile ByteBuffer buf;
+
+        ReadTask(ByteBuffer dst,
+                 int pos,
+                 int rem,
+                 long position,
+                 PendingFuture<Integer,A> result)
+        {
+            this.dst = dst;
+            this.pos = pos;
+            this.rem = rem;
+            this.position = position;
+            this.result = result;
+        }
+
+        void releaseBufferIfSubstituted() {
+            if (buf != dst)
+                Util.releaseTemporaryDirectBuffer(buf);
+        }
+
+        void updatePosition(int bytesTransferred) {
+            // if the I/O succeeded then adjust buffer position
+            if (bytesTransferred > 0) {
+                if (buf == dst) {
+                    try {
+                        dst.position(pos + bytesTransferred);
+                    } catch (IllegalArgumentException x) {
+                        // someone has changed the position; ignore
+                    }
+                } else {
+                    // had to substitute direct buffer
+                    buf.position(bytesTransferred).flip();
+                    try {
+                        dst.put(buf);
+                    } catch (BufferOverflowException x) {
+                        // someone has changed the position; ignore
+                    }
+                }
+            }
+        }
+
+        @Override
+        public void run() {
+            int n = -1;
+            long overlapped = 0L;
+            long address;
+
+            // Substitute a native buffer if not direct
+            if (dst instanceof DirectBuffer) {
+                buf = dst;
+                address = ((DirectBuffer)dst).address() + pos;
+            } else {
+                buf = Util.getTemporaryDirectBuffer(rem);
+                address = ((DirectBuffer)buf).address();
+            }
+
+            try {
+                begin();
+
+                // allocate OVERLAPPED
+                overlapped = ioCache.add(result);
+
+                // synchronize on result to allow this thread handle the case
+                // where the read completes immediately.
+                synchronized (result) {
+                    n = readFile(handle, address, rem, position, overlapped);
+                    if (n == IOStatus.UNAVAILABLE) {
+                        // I/O is pending
+                        return;
+                    }
+                    // read completed immediately:
+                    // 1. update buffer position
+                    // 2. release waiters
+                    updatePosition(n);
+                    result.setResult(n);
+                }
+            } catch (Throwable x) {
+                // failed to initiate read
+                result.setFailure(toIOException(x));
+            } finally {
+                end();
+            }
+
+            // read failed or EOF so completion port will not be notified
+            if (n < 0 && overlapped != 0L) {
+                ioCache.remove(overlapped);
+            }
+
+            // return direct buffer to cache if substituted
+            releaseBufferIfSubstituted();
+
+            // invoke completion handler
+            Invoker.invoke(result.handler(), result);
+        }
+
+        /**
+         * Executed when the I/O has completed
+         */
+        @Override
+        public void completed(int bytesTransferred) {
+            updatePosition(bytesTransferred);
+
+            // return direct buffer to cache if substituted
+            releaseBufferIfSubstituted();
+
+            // release waiters and invoke completion handler
+            result.setResult(bytesTransferred);
+            Invoker.invoke(result.handler(), result);
+        }
+
+        @Override
+        public void failed(int error, IOException x) {
+            // if EOF detected asynchronously then it is reported as error
+            if (error == ERROR_HANDLE_EOF) {
+                completed(-1);
+            } else {
+                // return direct buffer to cache if substituted
+                releaseBufferIfSubstituted();
+
+                // release waiters
+                if (isOpen()) {
+                    result.setFailure(x);
+                } else {
+                    result.setFailure(new AsynchronousCloseException());
+                }
+                Invoker.invoke(result.handler(), result);
+            }
+        }
+    }
+
+    @Override
+    public <A> Future<Integer> read(ByteBuffer dst,
+                                    long position,
+                                    A attachment,
+                                    CompletionHandler<Integer,? super A> handler)
+    {
+        if (!reading)
+            throw new NonReadableChannelException();
+        if (position < 0)
+            throw new IllegalArgumentException("Negative position");
+        if (dst.isReadOnly())
+            throw new IllegalArgumentException("Read-only buffer");
+
+        // check if channel is closed
+        if (!isOpen()) {
+            CompletedFuture<Integer,A> result = CompletedFuture
+                .withFailure(this, new ClosedChannelException(), attachment);
+            Invoker.invoke(handler, result);
+            return result;
+        }
+
+        int pos = dst.position();
+        int lim = dst.limit();
+        assert (pos <= lim);
+        int rem = (pos <= lim ? lim - pos : 0);
+
+        // no space remaining
+        if (rem == 0) {
+            CompletedFuture<Integer,A> result =
+                CompletedFuture.withResult(this, 0, attachment);
+            Invoker.invoke(handler, result);
+            return result;
+        }
+
+        // create Future and task that initiates read
+        PendingFuture<Integer,A> result =
+            new PendingFuture<Integer,A>(this, handler, attachment);
+        ReadTask readTask = new ReadTask<A>(dst, pos, rem, position, result);
+        result.setContext(readTask);
+
+        // initiate I/O (can only be done from thread in thread pool)
+        Invoker.invokeOnThreadInThreadPool(this, readTask);
+        return result;
+    }
+
+    /**
+     * Task that initiates write operation and handles completion result.
+     */
+    private class WriteTask<A> implements Runnable, Iocp.ResultHandler {
+        private final ByteBuffer src;
+        private final int pos, rem;     // buffer position/remaining
+        private final long position;    // file position
+        private final PendingFuture<Integer,A> result;
+
+        // set to src if direct; otherwise set to substituted direct buffer
+        private volatile ByteBuffer buf;
+
+        WriteTask(ByteBuffer src,
+                  int pos,
+                  int rem,
+                  long position,
+                  PendingFuture<Integer,A> result)
+        {
+            this.src = src;
+            this.pos = pos;
+            this.rem = rem;
+            this.position = position;
+            this.result = result;
+        }
+
+        void releaseBufferIfSubstituted() {
+            if (buf != src)
+                Util.releaseTemporaryDirectBuffer(buf);
+        }
+
+        void updatePosition(int bytesTransferred) {
+            // if the I/O succeeded then adjust buffer position
+            if (bytesTransferred > 0) {
+                try {
+                    src.position(pos + bytesTransferred);
+                } catch (IllegalArgumentException x) {
+                    // someone has changed the position
+                }
+            }
+        }
+
+        @Override
+        public void run() {
+            int n = -1;
+            long overlapped = 0L;
+            long address;
+
+            // Substitute a native buffer if not direct
+            if (src instanceof DirectBuffer) {
+                buf = src;
+                address = ((DirectBuffer)src).address() + pos;
+            } else {
+                buf = Util.getTemporaryDirectBuffer(rem);
+                buf.put(src);
+                buf.flip();
+                // temporarily restore position as we don't know how many bytes
+                // will be written
+                src.position(pos);
+                address = ((DirectBuffer)buf).address();
+            }
+
+            try {
+                begin();
+
+                // allocate an OVERLAPPED structure
+                overlapped = ioCache.add(result);
+
+                // synchronize on result to allow this thread handle the case
+                // where the read completes immediately.
+                synchronized (result) {
+                    n = writeFile(handle, address, rem, position, overlapped);
+                    if (n == IOStatus.UNAVAILABLE) {
+                        // I/O is pending
+                        return;
+                    }
+                    // read completed immediately:
+                    // 1. update buffer position
+                    // 2. release waiters
+                    updatePosition(n);
+                    result.setResult(n);
+                }
+            } catch (Throwable x) {
+                // failed to initiate read:
+                result.setFailure(toIOException(x));
+
+                // release resources
+                if (overlapped != 0L)
+                    ioCache.remove(overlapped);
+                releaseBufferIfSubstituted();
+
+            } finally {
+                end();
+            }
+
+            // invoke completion handler
+            Invoker.invoke(result.handler(), result);
+        }
+
+        /**
+         * Executed when the I/O has completed
+         */
+        @Override
+        public void completed(int bytesTransferred) {
+            updatePosition(bytesTransferred);
+
+            // return direct buffer to cache if substituted
+            releaseBufferIfSubstituted();
+
+            // release waiters and invoke completion handler
+            result.setResult(bytesTransferred);
+            Invoker.invoke(result.handler(), result);
+        }
+
+        @Override
+        public void failed(int error, IOException x) {
+            // return direct buffer to cache if substituted
+            releaseBufferIfSubstituted();
+
+            // release waiters and invoker completion handler
+            if (isOpen()) {
+                result.setFailure(x);
+            } else {
+                result.setFailure(new AsynchronousCloseException());
+            }
+            Invoker.invoke(result.handler(), result);
+        }
+    }
+
+    @Override
+    public <A> Future<Integer> write(ByteBuffer src,
+                                     long position,
+                                     A attachment,
+                                     CompletionHandler<Integer,? super A> handler)
+    {
+        if (!writing)
+            throw new NonWritableChannelException();
+        if (position < 0)
+            throw new IllegalArgumentException("Negative position");
+
+        // check if channel is closed
+        if (!isOpen()) {
+            CompletedFuture<Integer,A> result = CompletedFuture
+                .withFailure(this, new ClosedChannelException(), attachment);
+            Invoker.invoke(handler, result);
+            return result;
+        }
+
+        int pos = src.position();
+        int lim = src.limit();
+        assert (pos <= lim);
+        int rem = (pos <= lim ? lim - pos : 0);
+
+        // nothing to write
+        if (rem == 0) {
+            CompletedFuture<Integer,A> result =
+                CompletedFuture.withResult(this, 0, attachment);
+            Invoker.invoke(handler, result);
+            return result;
+        }
+
+        // create Future and task to initiate write
+        PendingFuture<Integer,A> result =
+            new PendingFuture<Integer,A>(this, handler, attachment);
+        WriteTask writeTask = new WriteTask<A>(src, pos, rem, position, result);
+        result.setContext(writeTask);
+
+        // initiate I/O (can only be done from thread in thread pool)
+        Invoker.invokeOnThreadInThreadPool(this, writeTask);
+        return result;
+    }
+
+    // -- Native methods --
+
+    private static native int readFile(long handle, long address, int len,
+        long offset, long overlapped) throws IOException;
+
+    private static native int writeFile(long handle, long address, int len,
+        long offset, long overlapped) throws IOException;
+
+    private static native int lockFile(long handle, long position, long size,
+        boolean shared, long overlapped) throws IOException;
+
+    private static native void close0(long handle);
+
+    static {
+        Util.load();
+    }
+}
diff --git a/jdk/src/windows/classes/sun/nio/ch/WindowsAsynchronousServerSocketChannelImpl.java b/jdk/src/windows/classes/sun/nio/ch/WindowsAsynchronousServerSocketChannelImpl.java
new file mode 100644
index 0000000..8efb10d
--- /dev/null
+++ b/jdk/src/windows/classes/sun/nio/ch/WindowsAsynchronousServerSocketChannelImpl.java
@@ -0,0 +1,367 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.ch;
+
+import java.nio.channels.*;
+import java.net.InetSocketAddress;
+import java.util.concurrent.Future;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.io.IOException;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import sun.misc.Unsafe;
+
+/**
+ * Windows implementation of AsynchronousServerSocketChannel using overlapped I/O.
+ */
+
+class WindowsAsynchronousServerSocketChannelImpl
+    extends AsynchronousServerSocketChannelImpl implements Iocp.OverlappedChannel
+{
+    private static final Unsafe unsafe = Unsafe.getUnsafe();
+
+    // 2 * (sizeof(SOCKET_ADDRESS) + 16)
+    private static final int DATA_BUFFER_SIZE = 88;
+
+    private final long handle;
+    private final int completionKey;
+    private final Iocp iocp;
+
+    // typically there will be zero, or one I/O operations pending. In rare
+    // cases there may be more. These rare cases arise when a sequence of accept
+    // operations complete immediately and handled by the initiating thread.
+    // The corresponding OVERLAPPED cannot be reused/released until the completion
+    // event has been posted.
+    private final PendingIoCache ioCache;
+
+    // the data buffer to receive the local/remote socket address
+    private final long dataBuffer;
+
+    // flag to indicate that an accept operation is outstanding
+    private AtomicBoolean accepting = new AtomicBoolean();
+
+
+    WindowsAsynchronousServerSocketChannelImpl(Iocp iocp) throws IOException {
+        super(iocp);
+
+        // associate socket with given completion port
+        long h = IOUtil.fdVal(fd);
+        int key;
+        try {
+            key = iocp.associate(this, h);
+        } catch (IOException x) {
+            closesocket0(h);   // prevent leak
+            throw x;
+        }
+
+        this.handle = h;
+        this.completionKey = key;
+        this.iocp = iocp;
+        this.ioCache = new PendingIoCache();
+        this.dataBuffer = unsafe.allocateMemory(DATA_BUFFER_SIZE);
+    }
+
+    @Override
+    public <V,A> PendingFuture<V,A> getByOverlapped(long overlapped) {
+        return ioCache.remove(overlapped);
+    }
+
+    @Override
+    void implClose() throws IOException {
+        // close socket (which may cause outstanding accept to be aborted).
+        closesocket0(handle);
+
+        // waits until the accept operations have completed
+        ioCache.close();
+
+        // finally disassociate from the completion port
+        iocp.disassociate(completionKey);
+
+        // release other resources
+        unsafe.freeMemory(dataBuffer);
+    }
+
+    @Override
+    public AsynchronousChannelGroupImpl group() {
+        return iocp;
+    }
+
+    /**
+     * Task to initiate accept operation and to handle result.
+     */
+    private class AcceptTask<A> implements Runnable, Iocp.ResultHandler {
+        private final WindowsAsynchronousSocketChannelImpl channel;
+        private final AccessControlContext acc;
+        private final PendingFuture<AsynchronousSocketChannel,A> result;
+
+        AcceptTask(WindowsAsynchronousSocketChannelImpl channel,
+                   AccessControlContext acc,
+                   PendingFuture<AsynchronousSocketChannel,A> result)
+        {
+            this.channel = channel;
+            this.acc = acc;
+            this.result = result;
+        }
+
+        void enableAccept() {
+            accepting.set(false);
+        }
+
+        void closeChildChannel() {
+            try {
+                channel.close();
+            } catch (IOException ignore) { }
+        }
+
+        // caller must have acquired read lock for the listener and child channel.
+        void finishAccept() throws IOException {
+            /**
+             * Set local/remote addresses. This is currently very inefficient
+             * in that it requires 2 calls to getsockname and 2 calls to getpeername.
+             * (should change this to use GetAcceptExSockaddrs)
+             */
+            updateAcceptContext(handle, channel.handle());
+
+            InetSocketAddress local = Net.localAddress(channel.fd);
+            final InetSocketAddress remote = Net.remoteAddress(channel.fd);
+            channel.setConnected(local, remote);
+
+            // permission check (in context of initiating thread)
+            if (acc != null) {
+                AccessController.doPrivileged(new PrivilegedAction<Void>() {
+                    public Void run() {
+                        SecurityManager sm = System.getSecurityManager();
+                        sm.checkAccept(remote.getAddress().getHostAddress(),
+                                       remote.getPort());
+                        return null;
+                    }
+                }, acc);
+            }
+        }
+
+        /**
+         * Initiates the accept operation.
+         */
+        @Override
+        public void run() {
+            long overlapped = 0L;
+
+            try {
+                // begin usage of listener socket
+                begin();
+                try {
+                    // begin usage of child socket (as it is registered with
+                    // completion port and so may be closed in the event that
+                    // the group is forcefully closed).
+                    channel.begin();
+
+                    synchronized (result) {
+                        overlapped = ioCache.add(result);
+
+                        int n = accept0(handle, channel.handle(), overlapped, dataBuffer);
+                        if (n == IOStatus.UNAVAILABLE) {
+                            return;
+                        }
+
+                        // connection accepted immediately
+                        finishAccept();
+
+                        // allow another accept before the result is set
+                        enableAccept();
+                        result.setResult(channel);
+                    }
+                } finally {
+                    // end usage on child socket
+                    channel.end();
+                }
+            } catch (Throwable x) {
+                // failed to initiate accept so release resources
+                if (overlapped != 0L)
+                    ioCache.remove(overlapped);
+                closeChildChannel();
+                if (x instanceof ClosedChannelException)
+                    x = new AsynchronousCloseException();
+                if (!(x instanceof IOException) && !(x instanceof SecurityException))
+                    x = new IOException(x);
+                enableAccept();
+                result.setFailure(x);
+            } finally {
+                // end of usage of listener socket
+                end();
+            }
+
+            // accept completed immediately but may not have executed on
+            // initiating thread in which case the operation may have been
+            // cancelled.
+            if (result.isCancelled()) {
+                closeChildChannel();
+            }
+
+            // invoke completion handler
+            Invoker.invokeIndirectly(result.handler(), result);
+        }
+
+        /**
+         * Executed when the I/O has completed
+         */
+        @Override
+        public void completed(int bytesTransferred) {
+            try {
+                // connection accept after group has shutdown
+                if (iocp.isShutdown()) {
+                    throw new IOException(new ShutdownChannelGroupException());
+                }
+
+                // finish the accept
+                try {
+                    begin();
+                    try {
+                        channel.begin();
+                        finishAccept();
+                    } finally {
+                        channel.end();
+                    }
+                } finally {
+                    end();
+                }
+
+                // allow another accept before the result is set
+                enableAccept();
+                result.setResult(channel);
+            } catch (Throwable x) {
+                enableAccept();
+                closeChildChannel();
+                if (x instanceof ClosedChannelException)
+                    x = new AsynchronousCloseException();
+                if (!(x instanceof IOException) && !(x instanceof SecurityException))
+                    x = new IOException(x);
+                result.setFailure(x);
+            }
+
+            // if an async cancel has already cancelled the operation then
+            // close the new channel so as to free resources
+            if (result.isCancelled()) {
+                closeChildChannel();
+            }
+
+            // invoke handler (but not directly)
+            Invoker.invokeIndirectly(result.handler(), result);
+        }
+
+        @Override
+        public void failed(int error, IOException x) {
+            enableAccept();
+            closeChildChannel();
+
+            // release waiters
+            if (isOpen()) {
+                result.setFailure(x);
+            } else {
+                result.setFailure(new AsynchronousCloseException());
+            }
+            Invoker.invokeIndirectly(result.handler(), result);
+        }
+    }
+
+    @Override
+    public <A> Future<AsynchronousSocketChannel> accept(A attachment,
+        final CompletionHandler<AsynchronousSocketChannel,? super A> handler)
+    {
+        if (!isOpen()) {
+            CompletedFuture<AsynchronousSocketChannel,A> result = CompletedFuture
+                .withFailure(this, new ClosedChannelException(), attachment);
+            Invoker.invokeIndirectly(handler, result);
+            return result;
+        }
+        if (isAcceptKilled())
+            throw new RuntimeException("Accept not allowed due to cancellation");
+
+        // ensure channel is bound to local address
+        if (localAddress == null)
+            throw new NotYetBoundException();
+
+        // create the socket that will be accepted. The creation of the socket
+        // is enclosed by a begin/end for the listener socket to ensure that
+        // we check that the listener is open and also to prevent the I/O
+        // port from being closed as the new socket is registered.
+        WindowsAsynchronousSocketChannelImpl ch = null;
+        IOException ioe = null;
+        try {
+            begin();
+            ch = new WindowsAsynchronousSocketChannelImpl(iocp, false);
+        } catch (IOException x) {
+            ioe = x;
+        } finally {
+            end();
+        }
+        if (ioe != null) {
+            CompletedFuture<AsynchronousSocketChannel,A> result =
+                CompletedFuture.withFailure(this, ioe, attachment);
+            Invoker.invokeIndirectly(handler, result);
+            return result;
+        }
+
+        // need calling context when there is security manager as
+        // permission check may be done in a different thread without
+        // any application call frames on the stack
+        AccessControlContext acc = (System.getSecurityManager() == null) ?
+            null : AccessController.getContext();
+
+        PendingFuture<AsynchronousSocketChannel,A> result =
+            new PendingFuture<AsynchronousSocketChannel,A>(this, handler, attachment);
+        AcceptTask task = new AcceptTask<A>(ch, acc, result);
+        result.setContext(task);
+
+        // check and set flag to prevent concurrent accepting
+        if (!accepting.compareAndSet(false, true))
+            throw new AcceptPendingException();
+
+        // initiate accept. As I/O operations are tied to the initiating thread
+        // then it will only be invoked direcly if this thread is in the thread
+        // pool. If this thread is not in the thread pool when a task is
+        // submitted to initiate the accept.
+        Invoker.invokeOnThreadInThreadPool(this, task);
+        return result;
+    }
+
+    // -- Native methods --
+
+    private static native void initIDs();
+
+    private static native int accept0(long listenSocket, long acceptSocket,
+        long overlapped, long dataBuffer) throws IOException;
+
+    private static native void updateAcceptContext(long listenSocket,
+        long acceptSocket) throws IOException;
+
+    private static native void closesocket0(long socket) throws IOException;
+
+    static {
+        Util.load();
+        initIDs();
+    }
+}
diff --git a/jdk/src/windows/classes/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.java b/jdk/src/windows/classes/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.java
new file mode 100644
index 0000000..fe9920c
--- /dev/null
+++ b/jdk/src/windows/classes/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.java
@@ -0,0 +1,911 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 conne02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.ch;
+
+import java.nio.channels.*;
+import java.nio.ByteBuffer;
+import java.nio.BufferOverflowException;
+import java.net.*;
+import java.util.concurrent.*;
+import java.io.IOException;
+import sun.misc.Unsafe;
+
+/**
+ * Windows implementation of AsynchronousSocketChannel using overlapped I/O.
+ */
+
+class WindowsAsynchronousSocketChannelImpl
+    extends AsynchronousSocketChannelImpl implements Iocp.OverlappedChannel
+{
+    private static final Unsafe unsafe = Unsafe.getUnsafe();
+    private static int addressSize = unsafe.addressSize();
+
+    private static int dependsArch(int value32, int value64) {
+        return (addressSize == 4) ? value32 : value64;
+    }
+
+    /*
+     * typedef struct _WSABUF {
+     *     u_long      len;
+     *     char FAR *  buf;
+     * } WSABUF;
+     */
+    private static final int SIZEOF_WSABUF  = dependsArch(8, 16);
+    private static final int OFFSETOF_LEN   = 0;
+    private static final int OFFSETOF_BUF   = dependsArch(4, 8);
+
+    // maximum vector size for scatter/gather I/O
+    private static final int MAX_WSABUF     = 16;
+
+    private static final int SIZEOF_WSABUFARRAY = MAX_WSABUF * SIZEOF_WSABUF;
+
+
+    // socket handle. Use begin()/end() around each usage of this handle.
+    final long handle;
+
+    // I/O completion port that the socket is associated with
+    private final Iocp iocp;
+
+    // completion key to identify channel when I/O completes
+    private final int completionKey;
+
+    // Pending I/O operations are tied to an OVERLAPPED structure that can only
+    // be released when the I/O completion event is posted to the completion
+    // port. Where I/O operations complete immediately then it is possible
+    // there may be more than two OVERLAPPED structures in use.
+    private final PendingIoCache ioCache;
+
+    // per-channel arrays of WSABUF structures
+    private final long readBufferArray;
+    private final long writeBufferArray;
+
+
+    WindowsAsynchronousSocketChannelImpl(Iocp iocp, boolean failIfGroupShutdown)
+        throws IOException
+    {
+        super(iocp);
+
+        // associate socket with default completion port
+        long h = IOUtil.fdVal(fd);
+        int key = 0;
+        try {
+            key = iocp.associate(this, h);
+        } catch (ShutdownChannelGroupException x) {
+            if (failIfGroupShutdown) {
+                closesocket0(h);
+                throw x;
+            }
+        } catch (IOException x) {
+            closesocket0(h);
+            throw x;
+        }
+
+        this.handle = h;
+        this.iocp = iocp;
+        this.completionKey = key;
+        this.ioCache = new PendingIoCache();
+
+        // allocate WSABUF arrays
+        this.readBufferArray = unsafe.allocateMemory(SIZEOF_WSABUFARRAY);
+        this.writeBufferArray = unsafe.allocateMemory(SIZEOF_WSABUFARRAY);
+    }
+
+    WindowsAsynchronousSocketChannelImpl(Iocp iocp) throws IOException {
+        this(iocp, true);
+    }
+
+    @Override
+    public AsynchronousChannelGroupImpl group() {
+        return iocp;
+    }
+
+    /**
+     * Invoked by Iocp when an I/O operation competes.
+     */
+    @Override
+    public <V,A> PendingFuture<V,A> getByOverlapped(long overlapped) {
+        return ioCache.remove(overlapped);
+    }
+
+    // invoked by WindowsAsynchronousServerSocketChannelImpl
+    long handle() {
+        return handle;
+    }
+
+    // invoked by WindowsAsynchronousServerSocketChannelImpl when new connection
+    // accept
+    void setConnected(SocketAddress localAddress, SocketAddress remoteAddress) {
+        synchronized (stateLock) {
+            state = ST_CONNECTED;
+            this.localAddress = localAddress;
+            this.remoteAddress = remoteAddress;
+        }
+    }
+
+    @Override
+    void implClose() throws IOException {
+        // close socket (may cause outstanding async I/O operations to fail).
+        closesocket0(handle);
+
+        // waits until all I/O operations have completed
+        ioCache.close();
+
+        // release arrays of WSABUF structures
+        unsafe.freeMemory(readBufferArray);
+        unsafe.freeMemory(writeBufferArray);
+
+        // finally disassociate from the completion port (key can be 0 if
+        // channel created when group is shutdown)
+        if (completionKey != 0)
+            iocp.disassociate(completionKey);
+    }
+
+    @Override
+    public void onCancel(PendingFuture<?,?> task) {
+        if (task.getContext() instanceof ConnectTask)
+            killConnect();
+        if (task.getContext() instanceof ReadTask)
+            killReading();
+        if (task.getContext() instanceof WriteTask)
+            killWriting();
+    }
+
+    /**
+     * Implements the task to initiate a connection and the handler to
+     * consume the result when the connection is established (or fails).
+     */
+    private class ConnectTask<A> implements Runnable, Iocp.ResultHandler {
+        private final InetSocketAddress remote;
+        private final PendingFuture<Void,A> result;
+
+        ConnectTask(InetSocketAddress remote, PendingFuture<Void,A> result) {
+            this.remote = remote;
+            this.result = result;
+        }
+
+        private void closeChannel() {
+            try {
+                close();
+            } catch (IOException ignore) { }
+        }
+
+        private IOException toIOException(Throwable x) {
+            if (x instanceof IOException) {
+                if (x instanceof ClosedChannelException)
+                    x = new AsynchronousCloseException();
+                return (IOException)x;
+            }
+            return new IOException(x);
+        }
+
+        /**
+         * Invoke after a connection is successfully established.
+         */
+        private void afterConnect() throws IOException {
+            updateConnectContext(handle);
+            synchronized (stateLock) {
+                state = ST_CONNECTED;
+                remoteAddress = remote;
+            }
+        }
+
+        /**
+         * Task to initiate a connection.
+         */
+        @Override
+        public void run() {
+            long overlapped = 0L;
+            Throwable exc = null;
+            try {
+                begin();
+
+                // synchronize on result to allow this thread handle the case
+                // where the connection is established immediately.
+                synchronized (result) {
+                    overlapped = ioCache.add(result);
+                    // initiate the connection
+                    int n = connect0(handle, Net.isIPv6Available(), remote.getAddress(),
+                                     remote.getPort(), overlapped);
+                    if (n == IOStatus.UNAVAILABLE) {
+                        // connection is pending
+                        return;
+                    }
+
+                    // connection established immediately
+                    afterConnect();
+                    result.setResult(null);
+                }
+            } catch (Throwable x) {
+                exc = x;
+            } finally {
+                end();
+            }
+
+            if (exc != null) {
+                if (overlapped != 0L)
+                    ioCache.remove(overlapped);
+                closeChannel();
+                result.setFailure(toIOException(exc));
+            }
+            Invoker.invoke(result.handler(), result);
+        }
+
+        /**
+         * Invoked by handler thread when connection established.
+         */
+        @Override
+        public void completed(int bytesTransferred) {
+            Throwable exc = null;
+            try {
+                begin();
+                afterConnect();
+                result.setResult(null);
+            } catch (Throwable x) {
+                // channel is closed or unable to finish connect
+                exc = x;
+            } finally {
+                end();
+            }
+
+            // can't close channel while in begin/end block
+            if (exc != null) {
+                closeChannel();
+                result.setFailure(toIOException(exc));
+            }
+
+            Invoker.invoke(result.handler(), result);
+        }
+
+        /**
+         * Invoked by handler thread when failed to establish connection.
+         */
+        @Override
+        public void failed(int error, IOException x) {
+            if (isOpen()) {
+                closeChannel();
+                result.setFailure(x);
+            } else {
+                result.setFailure(new AsynchronousCloseException());
+            }
+            Invoker.invoke(result.handler(), result);
+        }
+    }
+
+    @Override
+    public <A> Future<Void> connect(SocketAddress remote,
+                                    A attachment,
+                                    CompletionHandler<Void,? super A> handler)
+    {
+        if (!isOpen()) {
+            CompletedFuture<Void,A> result = CompletedFuture
+                .withFailure(this, new ClosedChannelException(), attachment);
+            Invoker.invoke(handler, result);
+            return result;
+        }
+
+        InetSocketAddress isa = Net.checkAddress(remote);
+
+        // permission check
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null)
+            sm.checkConnect(isa.getAddress().getHostAddress(), isa.getPort());
+
+        // check and update state
+        // ConnectEx requires the socket to be bound to a local address
+        IOException bindException = null;
+        synchronized (stateLock) {
+            if (state == ST_CONNECTED)
+                throw new AlreadyConnectedException();
+            if (state == ST_PENDING)
+                throw new ConnectionPendingException();
+            if (localAddress == null) {
+                try {
+                    bind(new InetSocketAddress(0));
+                } catch (IOException x) {
+                    bindException = x;
+                }
+            }
+            if (bindException == null)
+                state = ST_PENDING;
+        }
+
+        // handle bind failure
+        if (bindException != null) {
+            try {
+                close();
+            } catch (IOException ignore) { }
+            CompletedFuture<Void,A> result = CompletedFuture
+                .withFailure(this, bindException, attachment);
+            Invoker.invoke(handler, result);
+            return result;
+        }
+
+        // setup task
+        PendingFuture<Void,A> result =
+            new PendingFuture<Void,A>(this, handler, attachment);
+        ConnectTask task = new ConnectTask<A>(isa, result);
+        result.setContext(task);
+
+        // initiate I/O (can only be done from thread in thread pool)
+        Invoker.invokeOnThreadInThreadPool(this, task);
+        return result;
+    }
+
+    /**
+     * Implements the task to initiate a read and the handler to consume the
+     * result when the read completes.
+     */
+    private class ReadTask<V,A> implements Runnable, Iocp.ResultHandler {
+        private final ByteBuffer[] bufs;
+        private final int numBufs;
+        private final boolean scatteringRead;
+        private final PendingFuture<V,A> result;
+
+        // set by run method
+        private ByteBuffer[] shadow;
+
+        ReadTask(ByteBuffer[] bufs,
+                 boolean scatteringRead,
+                 PendingFuture<V,A> result)
+        {
+            this.bufs = bufs;
+            this.numBufs = (bufs.length > MAX_WSABUF) ? MAX_WSABUF : bufs.length;
+            this.scatteringRead = scatteringRead;
+            this.result = result;
+        }
+
+        /**
+         * Invoked prior to read to prepare the WSABUF array. Where necessary,
+         * it substitutes non-direct buffers with direct buffers.
+         */
+        void prepareBuffers() {
+            shadow = new ByteBuffer[numBufs];
+            long address = readBufferArray;
+            for (int i=0; i<numBufs; i++) {
+                ByteBuffer dst = bufs[i];
+                int pos = dst.position();
+                int lim = dst.limit();
+                assert (pos <= lim);
+                int rem = (pos <= lim ? lim - pos : 0);
+                long a;
+                if (!(dst instanceof DirectBuffer)) {
+                    // substitute with direct buffer
+                    ByteBuffer bb = Util.getTemporaryDirectBuffer(rem);
+                    shadow[i] = bb;
+                    a = ((DirectBuffer)bb).address();
+                } else {
+                    shadow[i] = dst;
+                    a = ((DirectBuffer)dst).address() + pos;
+                }
+                unsafe.putAddress(address + OFFSETOF_BUF, a);
+                unsafe.putInt(address + OFFSETOF_LEN, rem);
+                address += SIZEOF_WSABUF;
+            }
+        }
+
+        /**
+         * Invoked after a read has completed to update the buffer positions
+         * and release any substituted buffers.
+         */
+        void updateBuffers(int bytesRead) {
+            for (int i=0; i<numBufs; i++) {
+                ByteBuffer nextBuffer = shadow[i];
+                int pos = nextBuffer.position();
+                int len = nextBuffer.remaining();
+                if (bytesRead >= len) {
+                    bytesRead -= len;
+                    int newPosition = pos + len;
+                    try {
+                        nextBuffer.position(newPosition);
+                    } catch (IllegalArgumentException x) {
+                        // position changed by another
+                    }
+                } else { // Buffers not completely filled
+                    if (bytesRead > 0) {
+                        assert(pos + bytesRead < (long)Integer.MAX_VALUE);
+                        int newPosition = pos + bytesRead;
+                        try {
+                            nextBuffer.position(newPosition);
+                        } catch (IllegalArgumentException x) {
+                            // position changed by another
+                        }
+                    }
+                    break;
+                }
+            }
+
+            // Put results from shadow into the slow buffers
+            for (int i=0; i<numBufs; i++) {
+                if (!(bufs[i] instanceof DirectBuffer)) {
+                    shadow[i].flip();
+                    try {
+                        bufs[i].put(shadow[i]);
+                    } catch (BufferOverflowException x) {
+                        // position changed by another
+                    }
+                }
+            }
+        }
+
+        void releaseBuffers() {
+            for (int i=0; i<numBufs; i++) {
+                if (!(bufs[i] instanceof DirectBuffer)) {
+                    Util.releaseTemporaryDirectBuffer(shadow[i]);
+                }
+            }
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public void run() {
+            long overlapped = 0L;
+            boolean prepared = false;
+            boolean pending = false;
+
+            try {
+                begin();
+
+                // substitute non-direct buffers
+                prepareBuffers();
+                prepared = true;
+
+                // get an OVERLAPPED structure (from the cache or allocate)
+                overlapped = ioCache.add(result);
+
+                // synchronize on result to allow this thread handle the case
+                // where the read completes immediately.
+                synchronized (result) {
+                    int n = read0(handle, numBufs, readBufferArray, overlapped);
+                    if (n == IOStatus.UNAVAILABLE) {
+                        // I/O is pending
+                        pending = true;
+                        return;
+                    }
+                    // read completed immediately:
+                    // 1. update buffer position
+                    // 2. reset read flag
+                    // 3. release waiters
+                    if (n == 0) {
+                        n = -1;
+                    } else {
+                        updateBuffers(n);
+                    }
+                    enableReading();
+
+                    if (scatteringRead) {
+                        result.setResult((V)Long.valueOf(n));
+                    } else {
+                        result.setResult((V)Integer.valueOf(n));
+                    }
+                }
+            } catch (Throwable x) {
+                // failed to initiate read:
+                // 1. reset read flag
+                // 2. free resources
+                // 3. release waiters
+                enableReading();
+                if (overlapped != 0L)
+                    ioCache.remove(overlapped);
+                if (x instanceof ClosedChannelException)
+                    x = new AsynchronousCloseException();
+                if (!(x instanceof IOException))
+                    x = new IOException(x);
+                result.setFailure(x);
+            } finally {
+                if (prepared && !pending) {
+                    // return direct buffer(s) to cache if substituted
+                    releaseBuffers();
+                }
+                end();
+            }
+
+            // invoke completion handler
+            Invoker.invoke(result.handler(), result);
+        }
+
+        /**
+         * Executed when the I/O has completed
+         */
+        @Override
+        @SuppressWarnings("unchecked")
+        public void completed(int bytesTransferred) {
+            if (bytesTransferred == 0) {
+                bytesTransferred = -1;  // EOF
+            } else {
+                updateBuffers(bytesTransferred);
+            }
+
+            // return direct buffer to cache if substituted
+            releaseBuffers();
+
+            // release waiters if not already released by timeout
+            synchronized (result) {
+                if (result.isDone())
+                    return;
+                enableReading();
+                if (scatteringRead) {
+                    result.setResult((V)Long.valueOf(bytesTransferred));
+                } else {
+                    result.setResult((V)Integer.valueOf(bytesTransferred));
+                }
+            }
+            Invoker.invoke(result.handler(), result);
+        }
+
+        @Override
+        public void failed(int error, IOException x) {
+            // return direct buffer to cache if substituted
+            releaseBuffers();
+
+            // release waiters if not already released by timeout
+            if (!isOpen())
+                x = new AsynchronousCloseException();
+
+            synchronized (result) {
+                if (result.isDone())
+                    return;
+                enableReading();
+                result.setFailure(x);
+            }
+            Invoker.invoke(result.handler(), result);
+        }
+
+        /**
+         * Invoked if timeout expires before it is cancelled
+         */
+        void timeout() {
+            // synchronize on result as the I/O could complete/fail
+            synchronized (result) {
+                if (result.isDone())
+                    return;
+
+                // kill further reading before releasing waiters
+                enableReading(true);
+                result.setFailure(new InterruptedByTimeoutException());
+            }
+
+            // invoke handler without any locks
+            Invoker.invoke(result.handler(), result);
+        }
+    }
+
+    @Override
+    <V extends Number,A> Future<V> readImpl(ByteBuffer[] bufs,
+                                            boolean scatteringRead,
+                                            long timeout,
+                                            TimeUnit unit,
+                                            A attachment,
+                                            CompletionHandler<V,? super A> handler)
+    {
+        // setup task
+        PendingFuture<V,A> result =
+            new PendingFuture<V,A>(this, handler, attachment);
+        final ReadTask readTask = new ReadTask<V,A>(bufs, scatteringRead, result);
+        result.setContext(readTask);
+
+        // schedule timeout
+        if (timeout > 0L) {
+            Future<?> timeoutTask = iocp.schedule(new Runnable() {
+                public void run() {
+                    readTask.timeout();
+                }
+            }, timeout, unit);
+            result.setTimeoutTask(timeoutTask);
+        }
+
+        // initiate I/O (can only be done from thread in thread pool)
+        Invoker.invokeOnThreadInThreadPool(this, readTask);
+        return result;
+    }
+
+    /**
+     * Implements the task to initiate a write and the handler to consume the
+     * result when the write completes.
+     */
+    private class WriteTask<V,A> implements Runnable, Iocp.ResultHandler {
+        private final ByteBuffer[] bufs;
+        private final int numBufs;
+        private final boolean gatheringWrite;
+        private final PendingFuture<V,A> result;
+
+        // set by run method
+        private ByteBuffer[] shadow;
+
+        WriteTask(ByteBuffer[] bufs,
+                  boolean gatheringWrite,
+                  PendingFuture<V,A> result)
+        {
+            this.bufs = bufs;
+            this.numBufs = (bufs.length > MAX_WSABUF) ? MAX_WSABUF : bufs.length;
+            this.gatheringWrite = gatheringWrite;
+            this.result = result;
+        }
+
+        /**
+         * Invoked prior to write to prepare the WSABUF array. Where necessary,
+         * it substitutes non-direct buffers with direct buffers.
+         */
+        void prepareBuffers() {
+            shadow = new ByteBuffer[numBufs];
+            long address = writeBufferArray;
+            for (int i=0; i<numBufs; i++) {
+                ByteBuffer src = bufs[i];
+                int pos = src.position();
+                int lim = src.limit();
+                assert (pos <= lim);
+                int rem = (pos <= lim ? lim - pos : 0);
+                long a;
+                if (!(src instanceof DirectBuffer)) {
+                    // substitute with direct buffer
+                    ByteBuffer bb = Util.getTemporaryDirectBuffer(rem);
+                    bb.put(src);
+                    bb.flip();
+                    src.position(pos);  // leave heap buffer untouched for now
+                    shadow[i] = bb;
+                    a = ((DirectBuffer)bb).address();
+                } else {
+                    shadow[i] = src;
+                    a = ((DirectBuffer)src).address() + pos;
+                }
+                unsafe.putAddress(address + OFFSETOF_BUF, a);
+                unsafe.putInt(address + OFFSETOF_LEN, rem);
+                address += SIZEOF_WSABUF;
+            }
+        }
+
+        /**
+         * Invoked after a write has completed to update the buffer positions
+         * and release any substituted buffers.
+         */
+        void updateBuffers(int bytesWritten) {
+            // Notify the buffers how many bytes were taken
+            for (int i=0; i<numBufs; i++) {
+                ByteBuffer nextBuffer = bufs[i];
+                int pos = nextBuffer.position();
+                int lim = nextBuffer.limit();
+                int len = (pos <= lim ? lim - pos : lim);
+                if (bytesWritten >= len) {
+                    bytesWritten -= len;
+                    int newPosition = pos + len;
+                    try {
+                        nextBuffer.position(newPosition);
+                    } catch (IllegalArgumentException x) {
+                        // position changed by someone else
+                    }
+                } else { // Buffers not completely filled
+                    if (bytesWritten > 0) {
+                        assert(pos + bytesWritten < (long)Integer.MAX_VALUE);
+                        int newPosition = pos + bytesWritten;
+                        try {
+                            nextBuffer.position(newPosition);
+                        } catch (IllegalArgumentException x) {
+                            // position changed by someone else
+                        }
+                    }
+                    break;
+                }
+            }
+        }
+
+        void releaseBuffers() {
+            for (int i=0; i<numBufs; i++) {
+                if (!(bufs[i] instanceof DirectBuffer)) {
+                    Util.releaseTemporaryDirectBuffer(shadow[i]);
+                }
+            }
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public void run() {
+            int n = -1;
+            long overlapped = 0L;
+            boolean prepared = false;
+            boolean pending = false;
+            boolean shutdown = false;
+
+            try {
+                begin();
+
+                // substitute non-direct buffers
+                prepareBuffers();
+                prepared = true;
+
+                // get an OVERLAPPED structure (from the cache or allocate)
+                overlapped = ioCache.add(result);
+
+                // synchronize on result to allow this thread handle the case
+                // where the read completes immediately.
+                synchronized (result) {
+                    n = write0(handle, numBufs, writeBufferArray, overlapped);
+                    if (n == IOStatus.UNAVAILABLE) {
+                        // I/O is pending
+                        pending = true;
+                        return;
+                    }
+
+                    enableWriting();
+
+                    if (n == IOStatus.EOF) {
+                        // special case for shutdown output
+                        shutdown = true;
+                        throw new ClosedChannelException();
+                    }
+
+                    // write completed immediately:
+                    // 1. enable writing
+                    // 2. update buffer position
+                    // 3. release waiters
+                    updateBuffers(n);
+
+                    // result is a Long or Integer
+                    if (gatheringWrite) {
+                        result.setResult((V)Long.valueOf(n));
+                    } else {
+                        result.setResult((V)Integer.valueOf(n));
+                    }
+                }
+            } catch (Throwable x) {
+                enableWriting();
+
+                // failed to initiate read:
+                if (!shutdown && (x instanceof ClosedChannelException))
+                    x = new AsynchronousCloseException();
+                if (!(x instanceof IOException))
+                    x = new IOException(x);
+                result.setFailure(x);
+
+                // release resources
+                if (overlapped != 0L)
+                    ioCache.remove(overlapped);
+
+            } finally {
+                if (prepared && !pending) {
+                    // return direct buffer(s) to cache if substituted
+                    releaseBuffers();
+                }
+                end();
+            }
+
+            // invoke completion handler
+            Invoker.invoke(result.handler(), result);
+        }
+
+        /**
+         * Executed when the I/O has completed
+         */
+        @Override
+        @SuppressWarnings("unchecked")
+        public void completed(int bytesTransferred) {
+            updateBuffers(bytesTransferred);
+
+            // return direct buffer to cache if substituted
+            releaseBuffers();
+
+            // release waiters if not already released by timeout
+            synchronized (result) {
+                if (result.isDone())
+                    return;
+                enableWriting();
+                if (gatheringWrite) {
+                    result.setResult((V)Long.valueOf(bytesTransferred));
+                } else {
+                    result.setResult((V)Integer.valueOf(bytesTransferred));
+                }
+            }
+            Invoker.invoke(result.handler(), result);
+        }
+
+        @Override
+        public void failed(int error, IOException x) {
+            // return direct buffer to cache if substituted
+            releaseBuffers();
+
+            // release waiters if not already released by timeout
+            if (!isOpen())
+                x = new AsynchronousCloseException();
+
+            synchronized (result) {
+                if (result.isDone())
+                    return;
+                enableWriting();
+                result.setFailure(x);
+            }
+            Invoker.invoke(result.handler(), result);
+        }
+
+        /**
+         * Invoked if timeout expires before it is cancelled
+         */
+        void timeout() {
+            // synchronize on result as the I/O could complete/fail
+            synchronized (result) {
+                if (result.isDone())
+                    return;
+
+                // kill further writing before releasing waiters
+                enableWriting(true);
+                result.setFailure(new InterruptedByTimeoutException());
+            }
+
+            // invoke handler without any locks
+            Invoker.invoke(result.handler(), result);
+        }
+    }
+
+    @Override
+    <V extends Number,A> Future<V> writeImpl(ByteBuffer[] bufs,
+                                             boolean gatheringWrite,
+                                             long timeout,
+                                             TimeUnit unit,
+                                             A attachment,
+                                             CompletionHandler<V,? super A> handler)
+    {
+        // setup task
+        PendingFuture<V,A> result =
+            new PendingFuture<V,A>(this, handler, attachment);
+        final WriteTask writeTask = new WriteTask<V,A>(bufs, gatheringWrite, result);
+        result.setContext(writeTask);
+
+        // schedule timeout
+        if (timeout > 0L) {
+            Future<?> timeoutTask = iocp.schedule(new Runnable() {
+                public void run() {
+                    writeTask.timeout();
+                }
+            }, timeout, unit);
+            result.setTimeoutTask(timeoutTask);
+        }
+
+        // initiate I/O (can only be done from thread in thread pool)
+        Invoker.invokeOnThreadInThreadPool(this, writeTask);
+        return result;
+    }
+
+    // -- Native methods --
+
+    private static native void initIDs();
+
+    private static native int connect0(long socket, boolean preferIPv6,
+        InetAddress remote, int remotePort, long overlapped) throws IOException;
+
+    private static native void updateConnectContext(long socket) throws IOException;
+
+    private static native int read0(long socket, int count, long addres, long overlapped)
+        throws IOException;
+
+    private static native int write0(long socket, int count, long address,
+        long overlapped) throws IOException;
+
+    private static native void shutdown0(long socket, int how) throws IOException;
+
+    private static native void closesocket0(long socket) throws IOException;
+
+    static {
+        Util.load();
+        initIDs();
+    }
+}
diff --git a/jdk/src/windows/classes/sun/nio/fs/DefaultFileSystemProvider.java b/jdk/src/windows/classes/sun/nio/fs/DefaultFileSystemProvider.java
new file mode 100644
index 0000000..9392310
--- /dev/null
+++ b/jdk/src/windows/classes/sun/nio/fs/DefaultFileSystemProvider.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.spi.FileSystemProvider;
+
+/**
+ * Creates default provider on Windows
+ */
+public class DefaultFileSystemProvider {
+    private DefaultFileSystemProvider() { }
+    public static FileSystemProvider create() {
+        return new WindowsFileSystemProvider();
+    }
+}
diff --git a/jdk/src/windows/classes/sun/nio/fs/DefaultFileTypeDetector.java b/jdk/src/windows/classes/sun/nio/fs/DefaultFileTypeDetector.java
new file mode 100644
index 0000000..1e775ae
--- /dev/null
+++ b/jdk/src/windows/classes/sun/nio/fs/DefaultFileTypeDetector.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.spi.FileTypeDetector;
+
+public class DefaultFileTypeDetector {
+    private DefaultFileTypeDetector() { }
+
+    public static FileTypeDetector create() {
+        return new RegistryFileTypeDetector();
+    }
+}
diff --git a/jdk/src/windows/classes/sun/nio/fs/RegistryFileTypeDetector.java b/jdk/src/windows/classes/sun/nio/fs/RegistryFileTypeDetector.java
new file mode 100644
index 0000000..dc4b9c0
--- /dev/null
+++ b/jdk/src/windows/classes/sun/nio/fs/RegistryFileTypeDetector.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.*;
+import java.io.IOException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * File type detector that does lookup of file extension using Windows Registry.
+ */
+
+public class RegistryFileTypeDetector
+    extends AbstractFileTypeDetector
+{
+    public RegistryFileTypeDetector() {
+        super();
+    }
+
+    @Override
+    public String implProbeContentType(FileRef file) throws IOException {
+        if (!(file instanceof Path))
+            return null;
+
+        // get file extension
+        Path name = ((Path)file).getName();
+        if (name == null)
+            return null;
+        String filename = name.toString();
+        int dot = filename.lastIndexOf('.');
+        if ((dot < 0) || (dot == (filename.length()-1)))
+            return null;
+
+        // query HKEY_CLASSES_ROOT\<ext>
+        String key = filename.substring(dot);
+        NativeBuffer keyBuffer = WindowsNativeDispatcher.asNativeBuffer(key);
+        NativeBuffer nameBuffer = WindowsNativeDispatcher.asNativeBuffer("Content Type");
+        try {
+            return queryStringValue(keyBuffer.address(), nameBuffer.address());
+        } finally {
+            nameBuffer.release();
+            keyBuffer.release();
+        }
+    }
+
+    private static native String queryStringValue(long subKey, long name);
+
+    static {
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+            @Override
+            public Void run() {
+                // nio.dll has dependency on net.dll
+                System.loadLibrary("net");
+                System.loadLibrary("nio");
+                return null;
+        }});
+    }
+}
diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsAclFileAttributeView.java b/jdk/src/windows/classes/sun/nio/fs/WindowsAclFileAttributeView.java
new file mode 100644
index 0000000..937aedd
--- /dev/null
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsAclFileAttributeView.java
@@ -0,0 +1,226 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.ProviderMismatchException;
+import java.nio.file.attribute.*;
+import java.util.*;
+import java.io.IOException;
+
+import static sun.nio.fs.WindowsNativeDispatcher.*;
+import static sun.nio.fs.WindowsConstants.*;
+
+/**
+ * Windows implementation of AclFileAttributeView.
+ */
+
+class WindowsAclFileAttributeView
+    extends AbstractAclFileAttributeView
+{
+    /**
+     * typedef struct _SECURITY_DESCRIPTOR {
+     *     BYTE  Revision;
+     *     BYTE  Sbz1;
+     *     SECURITY_DESCRIPTOR_CONTROL Control;
+     *     PSID Owner;
+     *     PSID Group;
+     *     PACL Sacl;
+     *     PACL Dacl;
+     * } SECURITY_DESCRIPTOR;
+     */
+    private static final short SIZEOF_SECURITY_DESCRIPTOR   = 20;
+
+    private final WindowsPath file;
+    private final boolean followLinks;
+
+    WindowsAclFileAttributeView(WindowsPath file, boolean followLinks) {
+        this.file = file;
+        this.followLinks = followLinks;
+    }
+
+    // permision check
+    private void checkAccess(WindowsPath file,
+                             boolean checkRead,
+                             boolean checkWrite)
+    {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            if (checkRead)
+                sm.checkRead(file.getPathForPermissionCheck());
+            if (checkWrite)
+                sm.checkWrite(file.getPathForPermissionCheck());
+            sm.checkPermission(new RuntimePermission("accessUserInformation"));
+        }
+    }
+
+    // invokes GetFileSecurity to get requested security information
+    static NativeBuffer getFileSecurity(String path, int request)
+        throws IOException
+    {
+        // invoke get to buffer size
+        int size = 0;
+        try {
+            size = GetFileSecurity(path, request, 0L, 0);
+        } catch (WindowsException x) {
+            x.rethrowAsIOException(path);
+        }
+        assert size > 0;
+
+        // allocate buffer and re-invoke to get security information
+        NativeBuffer buffer = NativeBuffers.getNativeBuffer(size);
+        try {
+            for (;;) {
+                int newSize = GetFileSecurity(path, request, buffer.address(), size);
+                if (newSize <= size)
+                    return buffer;
+
+                // buffer was insufficient
+                buffer.release();
+                buffer = NativeBuffers.getNativeBuffer(newSize);
+                size = newSize;
+            }
+        } catch (WindowsException x) {
+            buffer.release();
+            x.rethrowAsIOException(path);
+            return null;
+        }
+    }
+
+    @Override
+    public UserPrincipal getOwner()
+        throws IOException
+    {
+        checkAccess(file, true, false);
+
+        // GetFileSecurity does not follow links so when following links we
+        // need the final target
+        String path = WindowsLinkSupport.getFinalPath(file, followLinks);
+        NativeBuffer buffer = getFileSecurity(path, OWNER_SECURITY_INFORMATION);
+        try {
+            // get the address of the SID
+            long sidAddress = GetSecurityDescriptorOwner(buffer.address());
+            if (sidAddress == 0L)
+                throw new IOException("no owner");
+            return WindowsUserPrincipals.fromSid(sidAddress);
+        } catch (WindowsException x) {
+            x.rethrowAsIOException(file);
+            return null;
+        } finally {
+            buffer.release();
+        }
+    }
+
+    @Override
+    public List<AclEntry> getAcl()
+        throws IOException
+    {
+        checkAccess(file, true, false);
+
+        // GetFileSecurity does not follow links so when following links we
+        // need the final target
+        String path = WindowsLinkSupport.getFinalPath(file, followLinks);
+
+        // ALLOW and DENY entries in DACL;
+        // AUDIT entries in SACL (ignore for now as it requires privileges)
+        NativeBuffer buffer = getFileSecurity(path, DACL_SECURITY_INFORMATION);
+        try {
+            return WindowsSecurityDescriptor.getAcl(buffer.address());
+        } finally {
+            buffer.release();
+        }
+    }
+
+    @Override
+    public void setOwner(UserPrincipal obj)
+        throws IOException
+    {
+        if (obj == null)
+            throw new NullPointerException("'owner' is null");
+        if (!(obj instanceof WindowsUserPrincipals.User))
+            throw new ProviderMismatchException();
+        WindowsUserPrincipals.User owner = (WindowsUserPrincipals.User)obj;
+
+        // permission check
+        checkAccess(file, false, true);
+
+        // SetFileSecurity does not follow links so when following links we
+        // need the final target
+        String path = WindowsLinkSupport.getFinalPath(file, followLinks);
+
+        // ConvertStringSidToSid allocates memory for SID so must invoke
+        // LocalFree to free it when we are done
+        long pOwner = 0L;
+        try {
+            pOwner = ConvertStringSidToSid(owner.sidString());
+        } catch (WindowsException x) {
+            throw new IOException("Failed to get SID for " + owner.getName()
+                + ": " + x.errorString());
+        }
+
+        // Allocate buffer for security descriptor, initialize it, set
+        // owner information and update the file.
+        try {
+            NativeBuffer buffer = NativeBuffers.getNativeBuffer(SIZEOF_SECURITY_DESCRIPTOR);
+            try {
+                InitializeSecurityDescriptor(buffer.address());
+                SetSecurityDescriptorOwner(buffer.address(), pOwner);
+                // may need SeRestorePrivilege to set the owner
+                WindowsSecurity.Privilege priv =
+                    WindowsSecurity.enablePrivilege("SeRestorePrivilege");
+                try {
+                    SetFileSecurity(path,
+                                    OWNER_SECURITY_INFORMATION,
+                                    buffer.address());
+                } finally {
+                    priv.drop();
+                }
+            } catch (WindowsException x) {
+                x.rethrowAsIOException(file);
+            } finally {
+                buffer.release();
+            }
+        } finally {
+            LocalFree(pOwner);
+        }
+    }
+
+    @Override
+    public void setAcl(List<AclEntry> acl) throws IOException {
+        checkAccess(file, false, true);
+
+        // SetFileSecurity does not follow links so when following links we
+        // need the final target
+        String path = WindowsLinkSupport.getFinalPath(file, followLinks);
+        WindowsSecurityDescriptor sd = WindowsSecurityDescriptor.create(acl);
+        try {
+            SetFileSecurity(path, DACL_SECURITY_INFORMATION, sd.address());
+        } catch (WindowsException x) {
+             x.rethrowAsIOException(file);
+        } finally {
+            sd.release();
+        }
+    }
+}
diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsChannelFactory.java b/jdk/src/windows/classes/sun/nio/fs/WindowsChannelFactory.java
new file mode 100644
index 0000000..f559166b
--- /dev/null
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsChannelFactory.java
@@ -0,0 +1,341 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.*;
+import java.nio.channels.*;
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.util.*;
+
+import com.sun.nio.file.ExtendedOpenOption;
+
+import sun.nio.ch.FileChannelImpl;
+import sun.nio.ch.ThreadPool;
+import sun.nio.ch.WindowsAsynchronousFileChannelImpl;
+import sun.misc.SharedSecrets;
+import sun.misc.JavaIOFileDescriptorAccess;
+
+import static sun.nio.fs.WindowsNativeDispatcher.*;
+import static sun.nio.fs.WindowsConstants.*;
+
+/**
+ * Factory to create FileChannels and AsynchronousFileChannels.
+ */
+
+class WindowsChannelFactory {
+    private static final JavaIOFileDescriptorAccess fdAccess =
+        SharedSecrets.getJavaIOFileDescriptorAccess();
+
+    private WindowsChannelFactory() { }
+
+    /**
+     * Do not follow reparse points when opening an existing file. Do not fail
+     * if the file is a reparse point.
+     */
+    static final OpenOption OPEN_REPARSE_POINT = new OpenOption() { };
+
+    /**
+     * Represents the flags from a user-supplied set of open options.
+     */
+    private static class Flags {
+        boolean read;
+        boolean write;
+        boolean append;
+        boolean truncateExisting;
+        boolean create;
+        boolean createNew;
+        boolean deleteOnClose;
+        boolean sparse;
+        boolean overlapped;
+        boolean sync;
+        boolean dsync;
+
+        // non-standard
+        boolean shareRead = true;
+        boolean shareWrite = true;
+        boolean shareDelete = true;
+        boolean noFollowLinks;
+        boolean openReparsePoint;
+
+        static Flags toFlags(Set<? extends OpenOption> options) {
+            Flags flags = new Flags();
+            for (OpenOption option: options) {
+                if (option instanceof StandardOpenOption) {
+                    switch ((StandardOpenOption)option) {
+                        case READ : flags.read = true; break;
+                        case WRITE : flags.write = true; break;
+                        case APPEND : flags.append = true; break;
+                        case TRUNCATE_EXISTING : flags.truncateExisting = true; break;
+                        case CREATE : flags.create = true; break;
+                        case CREATE_NEW : flags.createNew = true; break;
+                        case DELETE_ON_CLOSE : flags.deleteOnClose = true; break;
+                        case SPARSE : flags.sparse = true; break;
+                        case SYNC : flags.sync = true; break;
+                        case DSYNC : flags.dsync = true; break;
+                        default: throw new UnsupportedOperationException();
+                    }
+                    continue;
+                }
+                if (option instanceof ExtendedOpenOption) {
+                    switch ((ExtendedOpenOption)option) {
+                        case NOSHARE_READ : flags.shareRead = false; break;
+                        case NOSHARE_WRITE : flags.shareWrite = false; break;
+                        case NOSHARE_DELETE : flags.shareDelete = false; break;
+                        default: throw new UnsupportedOperationException();
+                    }
+                    continue;
+                }
+                if (option == LinkOption.NOFOLLOW_LINKS) {
+                    flags.noFollowLinks = true;
+                    continue;
+                }
+                if (option == OPEN_REPARSE_POINT) {
+                    flags.openReparsePoint = true;
+                    continue;
+                }
+                if (option == null)
+                    throw new NullPointerException();
+                throw new UnsupportedOperationException();
+            }
+            return flags;
+        }
+    }
+
+    /**
+     * Open/creates file, returning FileChannel to access the file
+     *
+     * @param   pathForWindows
+     *          The path of the file to open/create
+     * @param   pathToCheck
+     *          The path used for permission checks (if security manager)
+     */
+    static FileChannel newFileChannel(String pathForWindows,
+                                      String pathToCheck,
+                                      Set<? extends OpenOption> options,
+                                      long pSecurityDescriptor)
+        throws WindowsException
+    {
+        Flags flags = Flags.toFlags(options);
+
+        // default is reading; append => writing
+        if (!flags.read && !flags.write) {
+            if (flags.append) {
+                flags.write = true;
+            } else {
+                flags.read = true;
+            }
+        }
+
+        // validation
+        if (flags.read && flags.append)
+            throw new IllegalArgumentException("READ + APPEND not allowed");
+        if (flags.append && flags.truncateExisting)
+            throw new IllegalArgumentException("APPEND + TRUNCATE_EXISTING not allowed");
+
+        FileDescriptor fdObj = open(pathForWindows, pathToCheck, flags, pSecurityDescriptor);
+        return FileChannelImpl.open(fdObj, flags.read, flags.write, null);
+    }
+
+    /**
+     * Open/creates file, returning AsynchronousFileChannel to access the file
+     *
+     * @param   pathForWindows
+     *          The path of the file to open/create
+     * @param   pathToCheck
+     *          The path used for permission checks (if security manager)
+     * @param   pool
+     *          The thread pool that the channel is associated with
+     */
+    static AsynchronousFileChannel newAsynchronousFileChannel(String pathForWindows,
+                                                              String pathToCheck,
+                                                              Set<? extends OpenOption> options,
+                                                              long pSecurityDescriptor,
+                                                              ThreadPool pool)
+        throws IOException
+    {
+        Flags flags = Flags.toFlags(options);
+
+        // Overlapped I/O required
+        flags.overlapped = true;
+
+        // default is reading
+        if (!flags.read && !flags.write) {
+            flags.read = true;
+        }
+
+        // validation
+        if (flags.append)
+            throw new UnsupportedOperationException("APPEND not allowed");
+
+        // open file for overlapped I/O
+        FileDescriptor fdObj;
+        try {
+            fdObj = open(pathForWindows, pathToCheck, flags, pSecurityDescriptor);
+        } catch (WindowsException x) {
+            x.rethrowAsIOException(pathForWindows);
+            return null;
+        }
+
+        // create the AsynchronousFileChannel
+        try {
+            return WindowsAsynchronousFileChannelImpl.open(fdObj, flags.read, flags.write, pool);
+        } catch (IOException x) {
+            // IOException is thrown if the file handle cannot be associated
+            // with the completion port. All we can do is close the file.
+            long handle = fdAccess.getHandle(fdObj);
+            CloseHandle(handle);
+            throw x;
+        }
+    }
+
+    /**
+     * Opens file based on parameters and options, returning a FileDescriptor
+     * encapsulating the handle to the open file.
+     */
+    private static FileDescriptor open(String pathForWindows,
+                                       String pathToCheck,
+                                       Flags flags,
+                                       long pSecurityDescriptor)
+        throws WindowsException
+    {
+        // set to true if file must be truncated after open
+        boolean truncateAfterOpen = false;
+
+        // map options
+        int dwDesiredAccess = 0;
+        if (flags.read)
+            dwDesiredAccess |= GENERIC_READ;
+        if (flags.write)
+            dwDesiredAccess |= (flags.append) ? FILE_APPEND_DATA : GENERIC_WRITE;
+
+        int dwShareMode = 0;
+        if (flags.shareRead)
+            dwShareMode |= FILE_SHARE_READ;
+        if (flags.shareWrite)
+            dwShareMode |= FILE_SHARE_WRITE;
+        if (flags.shareDelete)
+            dwShareMode |= FILE_SHARE_DELETE;
+
+        int dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
+        int dwCreationDisposition = OPEN_EXISTING;
+        if (flags.write) {
+            if (flags.createNew) {
+                dwCreationDisposition = CREATE_NEW;
+                // force create to fail if file is orphaned reparse point
+                dwFlagsAndAttributes |= FILE_FLAG_OPEN_REPARSE_POINT;
+            } else {
+                if (flags.create)
+                    dwCreationDisposition = OPEN_ALWAYS;
+                if (flags.truncateExisting) {
+                    // Windows doesn't have a creation disposition that exactly
+                    // corresponds to CREATE + TRUNCATE_EXISTING so we use
+                    // the OPEN_ALWAYS mode and then truncate the file.
+                    if (dwCreationDisposition == OPEN_ALWAYS) {
+                        truncateAfterOpen = true;
+                    } else {
+                        dwCreationDisposition = TRUNCATE_EXISTING;
+                    }
+                }
+            }
+        }
+
+        if (flags.dsync || flags.sync)
+            dwFlagsAndAttributes |= FILE_FLAG_WRITE_THROUGH;
+        if (flags.overlapped)
+            dwFlagsAndAttributes |= FILE_FLAG_OVERLAPPED;
+        if (flags.deleteOnClose)
+            dwFlagsAndAttributes |= FILE_FLAG_DELETE_ON_CLOSE;
+
+        // NOFOLLOW_LINKS and NOFOLLOW_REPARSEPOINT mean open reparse point
+        boolean okayToFollowLinks = true;
+        if (dwCreationDisposition != CREATE_NEW &&
+            (flags.noFollowLinks ||
+             flags.openReparsePoint ||
+             flags.deleteOnClose))
+        {
+            if (flags.noFollowLinks || flags.deleteOnClose)
+                okayToFollowLinks = false;
+            dwFlagsAndAttributes |= FILE_FLAG_OPEN_REPARSE_POINT;
+        }
+
+        // permission check
+        if (pathToCheck != null) {
+            SecurityManager sm = System.getSecurityManager();
+            if (sm != null) {
+                if (flags.read)
+                    sm.checkRead(pathToCheck);
+                if (flags.write)
+                    sm.checkWrite(pathToCheck);
+                if (flags.deleteOnClose)
+                    sm.checkDelete(pathToCheck);
+            }
+        }
+
+        // open file
+        long handle = CreateFile(pathForWindows,
+                                 dwDesiredAccess,
+                                 dwShareMode,
+                                 pSecurityDescriptor,
+                                 dwCreationDisposition,
+                                 dwFlagsAndAttributes);
+
+        // make sure this isn't a symbolic link.
+        if (!okayToFollowLinks) {
+            try {
+                if (WindowsFileAttributes.readAttributes(handle).isSymbolicLink())
+                    throw new WindowsException("File is symbolic link");
+            } catch (WindowsException x) {
+                CloseHandle(handle);
+                throw x;
+            }
+        }
+
+        // truncate file (for CREATE + TRUNCATE_EXISTING case)
+        if (truncateAfterOpen) {
+            try {
+                SetEndOfFile(handle);
+            } catch (WindowsException x) {
+                CloseHandle(handle);
+                throw x;
+            }
+        }
+
+        // make the file sparse if needed
+        if (dwCreationDisposition == CREATE_NEW && flags.sparse) {
+            try {
+                DeviceIoControlSetSparse(handle);
+            } catch (WindowsException x) {
+                // ignore as sparse option is hint
+            }
+        }
+
+        // create FileDescriptor and return
+        FileDescriptor fdObj = new FileDescriptor();
+        fdAccess.setHandle(fdObj, handle);
+        return fdObj;
+    }
+}
diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsConstants.java b/jdk/src/windows/classes/sun/nio/fs/WindowsConstants.java
new file mode 100644
index 0000000..f2619ac
--- /dev/null
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsConstants.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+/**
+ * Win32 APIs constants.
+ */
+
+class WindowsConstants {
+    private WindowsConstants() { }
+
+    // general
+    public static final long INVALID_HANDLE_VALUE = -1L;
+
+    // generic rights
+    public static final int GENERIC_READ        = 0x80000000;
+    public static final int GENERIC_WRITE       = 0x40000000;
+
+    // share modes
+    public static final int FILE_SHARE_READ     = 0x00000001;
+    public static final int FILE_SHARE_WRITE    = 0x00000002;
+    public static final int FILE_SHARE_DELETE   = 0x00000004;
+
+    // creation modes
+    public static final int CREATE_NEW          = 1;
+    public static final int CREATE_ALWAYS       = 2;
+    public static final int OPEN_EXISTING       = 3;
+    public static final int OPEN_ALWAYS         = 4;
+    public static final int TRUNCATE_EXISTING   = 5;
+
+    // attributes and flags
+    public static final int FILE_ATTRIBUTE_READONLY         = 0x00000001;
+    public static final int FILE_ATTRIBUTE_HIDDEN           = 0x00000002;
+    public static final int FILE_ATTRIBUTE_SYSTEM           = 0x00000004;
+    public static final int FILE_ATTRIBUTE_DIRECTORY        = 0x00000010;
+    public static final int FILE_ATTRIBUTE_ARCHIVE          = 0x00000020;
+    public static final int FILE_ATTRIBUTE_DEVICE           = 0x00000040;
+    public static final int FILE_ATTRIBUTE_NORMAL           = 0x00000080;
+    public static final int FILE_ATTRIBUTE_REPARSE_POINT    = 0x400;
+    public static final int FILE_FLAG_NO_BUFFERING          = 0x20000000;
+    public static final int FILE_FLAG_OVERLAPPED            = 0x40000000;
+    public static final int FILE_FLAG_WRITE_THROUGH         = 0x80000000;
+    public static final int FILE_FLAG_BACKUP_SEMANTICS      = 0x02000000;
+    public static final int FILE_FLAG_DELETE_ON_CLOSE       = 0x04000000;
+    public static final int FILE_FLAG_OPEN_REPARSE_POINT    = 0x00200000;
+
+    // stream ids
+    public static final int BACKUP_ALTERNATE_DATA           = 0x00000004;
+    public static final int BACKUP_SPARSE_BLOCK             = 0x00000009;
+
+    // reparse point/symbolic link related constants
+    public static final int IO_REPARSE_TAG_SYMLINK              = 0xA000000C;
+    public static final int MAXIMUM_REPARSE_DATA_BUFFER_SIZE    = 16 * 1024;
+    public static final int SYMBOLIC_LINK_FLAG_DIRECTORY        = 0x1;
+
+    // volume flags
+    public static final int FILE_CASE_SENSITIVE_SEARCH      = 0x00000001;
+    public static final int FILE_CASE_PRESERVED_NAMES       = 0x00000002;
+    public static final int FILE_PERSISTENT_ACLS            = 0x00000008;
+    public static final int FILE_VOLUME_IS_COMPRESSED       = 0x00008000;
+    public static final int FILE_NAMED_STREAMS              = 0x00040000;
+    public static final int FILE_READ_ONLY_VOLUME           = 0x00080000;
+
+    // error codes
+    public static final int ERROR_FILE_NOT_FOUND        = 2;
+    public static final int ERROR_PATH_NOT_FOUND        = 3;
+    public static final int ERROR_ACCESS_DENIED         = 5;
+    public static final int ERROR_INVALID_HANDLE        = 6;
+    public static final int ERROR_INVALID_DATA          = 13;
+    public static final int ERROR_NOT_SAME_DEVICE       = 17;
+    public static final int ERROR_NOT_READY             = 21;
+    public static final int ERROR_FILE_EXISTS           = 80;
+    public static final int ERROR_DISK_FULL             = 112;
+    public static final int ERROR_INSUFFICIENT_BUFFER   = 122;
+    public static final int ERROR_INVALID_LEVEL         = 124;
+    public static final int ERROR_DIR_NOT_EMPTY         = 145;
+    public static final int ERROR_ALREADY_EXISTS        = 183;
+    public static final int ERROR_DIRECTORY             = 267;
+    public static final int ERROR_NOTIFY_ENUM_DIR       = 1022;
+    public static final int ERROR_NONE_MAPPED           = 1332;
+    public static final int ERROR_NOT_A_REPARSE_POINT   = 4390;
+    public static final int ERROR_INVALID_REPARSE_DATA  = 4392;
+
+    // notify filters
+    public static final int FILE_NOTIFY_CHANGE_FILE_NAME   = 0x00000001;
+    public static final int FILE_NOTIFY_CHANGE_DIR_NAME    = 0x00000002;
+    public static final int FILE_NOTIFY_CHANGE_ATTRIBUTES  = 0x00000004;
+    public static final int FILE_NOTIFY_CHANGE_SIZE        = 0x00000008;
+    public static final int FILE_NOTIFY_CHANGE_LAST_WRITE  = 0x00000010;
+    public static final int FILE_NOTIFY_CHANGE_LAST_ACCESS = 0x00000020;
+    public static final int FILE_NOTIFY_CHANGE_CREATION    = 0x00000040;
+    public static final int FILE_NOTIFY_CHANGE_SECURITY    = 0x00000100;
+
+    // notify actions
+    public final static int FILE_ACTION_ADDED              = 0x00000001;
+    public final static int FILE_ACTION_REMOVED            = 0x00000002;
+    public final static int FILE_ACTION_MODIFIED           = 0x00000003;
+    public final static int FILE_ACTION_RENAMED_OLD_NAME   = 0x00000004;
+    public final static int FILE_ACTION_RENAMED_NEW_NAME   = 0x00000005;
+
+    // copy flags
+    public static final int COPY_FILE_FAIL_IF_EXISTS       = 0x00000001;
+    public static final int COPY_FILE_COPY_SYMLINK         = 0x00000800;
+
+    // move flags
+    public static final int MOVEFILE_REPLACE_EXISTING       = 0x00000001;
+    public static final int MOVEFILE_COPY_ALLOWED           = 0x00000002;
+
+    // drive types
+    public static final int DRIVE_UNKNOWN                   = 0;
+    public static final int DRIVE_NO_ROOT_DIR               = 1;
+    public static final int DRIVE_REMOVABLE                 = 2;
+    public static final int DRIVE_FIXED                     = 3;
+    public static final int DRIVE_REMOTE                    = 4;
+    public static final int DRIVE_CDROM                     = 5;
+    public static final int DRIVE_RAMDISK                   = 6;
+
+    // file security
+    public static final int OWNER_SECURITY_INFORMATION      = 0x00000001;
+    public static final int GROUP_SECURITY_INFORMATION      = 0x00000002;
+    public static final int DACL_SECURITY_INFORMATION       = 0x00000004;
+    public static final int SACL_SECURITY_INFORMATION       = 0x00000008;
+
+    public static final int SidTypeUser = 1;
+    public static final int SidTypeGroup = 2;
+    public static final int SidTypeDomain = 3;
+    public static final int SidTypeAlias = 4;
+    public static final int SidTypeWellKnownGroup = 5;
+    public static final int SidTypeDeletedAccount = 6;
+    public static final int SidTypeInvalid = 7;
+    public static final int SidTypeUnknown = 8;
+    public static final int SidTypeComputer= 9;
+
+    public static final byte ACCESS_ALLOWED_ACE_TYPE         = 0x0;
+    public static final byte ACCESS_DENIED_ACE_TYPE          = 0x1;
+
+    public static final byte OBJECT_INHERIT_ACE              = 0x1;
+    public static final byte CONTAINER_INHERIT_ACE           = 0x2;
+    public static final byte NO_PROPAGATE_INHERIT_ACE        = 0x4;
+    public static final byte INHERIT_ONLY_ACE                = 0x8;
+
+    public static final int DELETE                      = 0x00010000;
+    public static final int READ_CONTROL                = 0x00020000;
+    public static final int WRITE_DAC                   = 0x00040000;
+    public static final int WRITE_OWNER                 = 0x00080000;
+    public static final int SYNCHRONIZE                 = 0x00100000;
+
+    public static final int FILE_LIST_DIRECTORY         = 0x0001;
+    public static final int FILE_READ_DATA              = 0x0001;
+    public static final int FILE_WRITE_DATA             = 0x0002;
+    public static final int FILE_APPEND_DATA            = 0x0004;
+    public static final int FILE_READ_EA                = 0x0008;
+    public static final int FILE_WRITE_EA               = 0x0010;
+    public static final int FILE_EXECUTE                = 0x0020;
+    public static final int FILE_DELETE_CHILD           = 0x0040;
+    public static final int FILE_READ_ATTRIBUTES        = 0x0080;
+    public static final int FILE_WRITE_ATTRIBUTES       = 0x0100;
+
+    // operating system security
+    public static final int TOKEN_DUPLICATE             = 0x0002;
+    public static final int TOKEN_IMPERSONATE           = 0x0004;
+    public static final int TOKEN_QUERY                 = 0x0008;
+    public static final int TOKEN_ADJUST_PRIVILEGES     = 0x0020;
+
+    public static final int SE_PRIVILEGE_ENABLED        = 0x00000002;
+
+    public static final int TokenUser                   = 1;
+    public static final int PROCESS_QUERY_INFORMATION   = 0x0400;
+}
diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsDirectoryStream.java b/jdk/src/windows/classes/sun/nio/fs/WindowsDirectoryStream.java
new file mode 100644
index 0000000..fa0b148
--- /dev/null
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsDirectoryStream.java
@@ -0,0 +1,255 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.*;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.Iterator;
+import java.util.ConcurrentModificationException;
+import java.util.NoSuchElementException;
+import java.io.IOException;
+
+import static sun.nio.fs.WindowsNativeDispatcher.*;
+import static sun.nio.fs.WindowsConstants.*;
+
+/**
+ * Windows implementation of DirectoryStream
+ */
+
+class WindowsDirectoryStream
+    implements DirectoryStream<Path>
+{
+    private final WindowsPath dir;
+    private final DirectoryStream.Filter<? super Path> filter;
+
+    // handle to directory
+    private final long handle;
+    // first entry in the directory
+    private final String firstName;
+
+    // buffer for WIN32_FIND_DATA structure that receives information about file
+    private final NativeBuffer findDataBuffer;
+
+    private final Object closeLock = new Object();
+
+    // need closeLock to access these
+    private boolean isOpen = true;
+    private Iterator<Path> iterator;
+
+
+    WindowsDirectoryStream(WindowsPath dir, DirectoryStream.Filter<? super Path> filter)
+        throws IOException
+    {
+        this.dir = dir;
+        this.filter = filter;
+
+        try {
+            // Need to append * or \* to match entries in directory.
+            String search = dir.getPathForWin32Calls();
+            char last = search.charAt(search.length() -1);
+            if (last == ':' || last == '\\') {
+                search += "*";
+            } else {
+                search += "\\*";
+            }
+
+            FirstFile first = FindFirstFile(search);
+            this.handle = first.handle();
+            this.firstName = first.name();
+            this.findDataBuffer = WindowsFileAttributes.getBufferForFindData();
+        } catch (WindowsException x) {
+            if (x.lastError() == ERROR_DIRECTORY) {
+                throw new NotDirectoryException(dir.getPathForExceptionMessage());
+            }
+            x.rethrowAsIOException(dir);
+
+            // keep compiler happy
+            throw new AssertionError();
+        }
+    }
+
+    @Override
+    public void close()
+        throws IOException
+    {
+        synchronized (closeLock) {
+            if (!isOpen)
+                return;
+            isOpen = false;
+        }
+        findDataBuffer.release();
+        try {
+            FindClose(handle);
+        } catch (WindowsException x) {
+            x.rethrowAsIOException(dir);
+        }
+    }
+
+    @Override
+    public Iterator<Path> iterator() {
+        if (!isOpen) {
+            throw new IllegalStateException("Directory stream is closed");
+        }
+        synchronized (this) {
+            if (iterator != null)
+                throw new IllegalStateException("Iterator already obtained");
+            iterator = new WindowsDirectoryIterator(firstName);
+            return iterator;
+        }
+    }
+
+    private static void throwAsConcurrentModificationException(Throwable t) {
+        ConcurrentModificationException cme = new ConcurrentModificationException();
+        cme.initCause(t);
+        throw cme;
+    }
+
+    private class WindowsDirectoryIterator implements Iterator<Path> {
+        private boolean atEof;
+        private String first;
+        private Path nextEntry;
+        private Path prevEntry;
+
+        WindowsDirectoryIterator(String first) {
+            atEof = false;
+            this.first = first;
+        }
+
+        // applies filter and also ignores "." and ".."
+        private Path acceptEntry(String s, BasicFileAttributes attrs) {
+            if (s.equals(".") || s.equals(".."))
+                return null;
+            if (dir.needsSlashWhenResolving()) {
+                StringBuilder sb = new StringBuilder(dir.toString());
+                sb.append('\\');
+                sb.append(s);
+                s = sb.toString();
+            } else {
+                s = dir + s;
+            }
+            Path entry = WindowsPath
+                .createFromNormalizedPath(dir.getFileSystem(), s, attrs);
+            if (filter.accept(entry)) {
+                return entry;
+            } else {
+                return null;
+            }
+        }
+
+        // reads next directory entry
+        private Path readNextEntry() {
+            // handle first element returned by search
+            if (first != null) {
+                nextEntry = acceptEntry(first, null);
+                first = null;
+                if (nextEntry != null)
+                    return nextEntry;
+            }
+
+            for (;;) {
+                String name = null;
+                WindowsFileAttributes attrs;
+
+                // synchronize on closeLock to prevent close while reading
+                synchronized (closeLock) {
+                    if (!isOpen)
+                        throwAsConcurrentModificationException(new
+                            IllegalStateException("Directory stream is closed"));
+                    try {
+                        name = FindNextFile(handle, findDataBuffer.address());
+                        if (name == null) {
+                            // NO_MORE_FILES
+                            return null;
+                        }
+                    } catch (WindowsException x) {
+                        try {
+                            x.rethrowAsIOException(dir);
+                        } catch (IOException ioe) {
+                            throwAsConcurrentModificationException(ioe);
+                        }
+                    }
+
+                    // grab the attributes from the WIN32_FIND_DATA structure
+                    // (needs to be done while holding closeLock because close
+                    // will release the buffer)
+                    attrs = WindowsFileAttributes
+                        .fromFindData(findDataBuffer.address());
+                }
+
+                // return entry if accepted by filter
+                Path entry = acceptEntry(name, attrs);
+                if (entry != null)
+                    return entry;
+            }
+        }
+
+        @Override
+        public synchronized boolean hasNext() {
+            if (nextEntry == null && !atEof) {
+                nextEntry = readNextEntry();
+                atEof = (nextEntry == null);
+            }
+            return nextEntry != null;
+        }
+
+        @Override
+        public synchronized Path next() {
+            if (nextEntry == null) {
+                if (!atEof) {
+                    nextEntry = readNextEntry();
+                }
+                if (nextEntry == null) {
+                    atEof = true;
+                    throw new NoSuchElementException();
+                }
+            }
+            prevEntry = nextEntry;
+            nextEntry = null;
+            return prevEntry;
+        }
+
+        @Override
+        public void remove() {
+            if (!isOpen) {
+                throw new IllegalStateException("Directory stream is closed");
+            }
+            Path entry;
+            synchronized (this) {
+                if (prevEntry == null)
+                    throw new IllegalStateException("no last element");
+                entry = prevEntry;
+                prevEntry = null;
+            }
+            try {
+                entry.delete(true);
+            } catch (IOException ioe) {
+                throwAsConcurrentModificationException(ioe);
+            } catch (SecurityException se) {
+                throwAsConcurrentModificationException(se);
+            }
+        }
+    }
+}
diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsException.java b/jdk/src/windows/classes/sun/nio/fs/WindowsException.java
new file mode 100644
index 0000000..7da7220
--- /dev/null
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsException.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.*;
+import java.io.IOException;
+
+import static sun.nio.fs.WindowsConstants.*;
+
+/**
+ * Internal exception thrown when a Win32 calls fails.
+ */
+
+class WindowsException extends Exception {
+    static final long serialVersionUID = 2765039493083748820L;
+
+    private int lastError;
+    private String msg;
+
+    WindowsException(int lastError) {
+        this.lastError = lastError;
+        this.msg = null;
+    }
+
+    WindowsException(String msg) {
+        this.lastError = 0;
+        this.msg = msg;
+    }
+
+    int lastError() {
+        return lastError;
+    }
+
+    String errorString() {
+        if (msg == null) {
+            msg = WindowsNativeDispatcher.FormatMessage(lastError);
+            if (msg == null) {
+                msg = "Unknown error: 0x" + Integer.toHexString(lastError);
+            }
+        }
+        return msg;
+    }
+
+    @Override
+    public String getMessage() {
+        return errorString();
+    }
+
+    private IOException translateToIOException(String file, String other) {
+        // not created with last error
+        if (lastError() == 0)
+            return new IOException(errorString());
+
+        // handle specific cases
+        if (lastError() == ERROR_FILE_NOT_FOUND || lastError() == ERROR_PATH_NOT_FOUND)
+            return new NoSuchFileException(file, other, null);
+        if (lastError() == ERROR_FILE_EXISTS || lastError() == ERROR_ALREADY_EXISTS)
+            return new FileAlreadyExistsException(file, other, null);
+        if (lastError() == ERROR_ACCESS_DENIED)
+            return new AccessDeniedException(file, other, null);
+
+        // fallback to the more general exception
+        return new FileSystemException(file, other, errorString());
+    }
+
+    void rethrowAsIOException(String file) throws IOException {
+        IOException x = translateToIOException(file, null);
+        throw x;
+    }
+
+    void rethrowAsIOException(WindowsPath file, WindowsPath other) throws IOException {
+        String a = (file == null) ? null : file.getPathForExceptionMessage();
+        String b = (other == null) ? null : other.getPathForExceptionMessage();
+        IOException x = translateToIOException(a, b);
+        throw x;
+    }
+
+    void rethrowAsIOException(WindowsPath file) throws IOException {
+        rethrowAsIOException(file, null);
+    }
+
+    IOException asIOException(WindowsPath file) {
+        return translateToIOException(file.getPathForExceptionMessage(), null);
+    }
+
+}
diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsFileAttributeViews.java b/jdk/src/windows/classes/sun/nio/fs/WindowsFileAttributeViews.java
new file mode 100644
index 0000000..39c34a1
--- /dev/null
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsFileAttributeViews.java
@@ -0,0 +1,296 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+
+import java.nio.file.attribute.*;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import java.io.IOException;
+
+import static sun.nio.fs.WindowsNativeDispatcher.*;
+import static sun.nio.fs.WindowsConstants.*;
+
+class WindowsFileAttributeViews {
+
+    private static class Basic extends AbstractBasicFileAttributeView {
+        final WindowsPath file;
+        final boolean followLinks;
+
+        Basic(WindowsPath file, boolean followLinks) {
+            this.file = file;
+            this.followLinks = followLinks;
+        }
+
+        @Override
+        public WindowsFileAttributes readAttributes() throws IOException {
+            try {
+                return WindowsFileAttributes.get(file, followLinks);
+            } catch (WindowsException x) {
+                x.rethrowAsIOException(file);
+                return null;    // keep compiler happy
+            }
+        }
+
+        /**
+         * Parameter values in Windows times.
+         */
+        void setFileTimes(long createTime, long lastAccessTime, long lastWriteTime)
+            throws IOException
+        {
+            long handle = -1L;
+            try {
+                int flags = FILE_FLAG_BACKUP_SEMANTICS;
+                if (!followLinks && file.getFileSystem().supportsLinks())
+                    flags |= FILE_FLAG_OPEN_REPARSE_POINT;
+
+                handle = CreateFile(file.getPathForWin32Calls(),
+                                    FILE_WRITE_ATTRIBUTES,
+                                    (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE),
+                                    OPEN_EXISTING,
+                                    flags);
+            } catch (WindowsException x) {
+                x.rethrowAsIOException(file);
+            }
+
+            // update attributes
+            try {
+                SetFileTime(handle, createTime, lastAccessTime, lastWriteTime);
+            } catch (WindowsException x) {
+                x.rethrowAsIOException(file);
+            } finally {
+                CloseHandle(handle);
+            }
+        }
+
+        @Override
+        public void setTimes(Long lastModifiedTime,
+                             Long lastAccessTime,
+                             Long createTime,
+                             TimeUnit unit) throws IOException
+        {
+            file.checkWrite();
+
+            // if all null then do nothing
+            if (lastModifiedTime == null && lastAccessTime == null &&
+                createTime == null)
+            {
+                // no effect
+                return;
+            }
+
+            // null => no change
+            // -1 => change to current time
+            long now = System.currentTimeMillis();
+            long modTime = 0L, accTime = 0L, crTime = 0L;
+            if (lastModifiedTime != null) {
+                if (lastModifiedTime < 0L) {
+                    if (lastModifiedTime != -1L)
+                        throw new IllegalArgumentException();
+                    modTime = now;
+                } else {
+                    modTime = TimeUnit.MILLISECONDS.convert(lastModifiedTime, unit);
+                }
+                modTime = WindowsFileAttributes.toWindowsTime(modTime);
+            }
+            if (lastAccessTime != null) {
+                if (lastAccessTime < 0L) {
+                    if (lastAccessTime != -1L)
+                        throw new IllegalArgumentException();
+                    accTime = now;
+                } else {
+                    accTime = TimeUnit.MILLISECONDS.convert(lastAccessTime, unit);
+                }
+                accTime = WindowsFileAttributes.toWindowsTime(accTime);
+            }
+            if (createTime != null) {
+                if (createTime < 0L) {
+                    if (createTime != -1L)
+                        throw new IllegalArgumentException();
+                    crTime = now;
+                } else {
+                    crTime = TimeUnit.MILLISECONDS.convert(createTime, unit);
+                }
+                crTime = WindowsFileAttributes.toWindowsTime(crTime);
+            }
+
+            setFileTimes(crTime, accTime, modTime);
+        }
+    }
+
+    static class Dos extends Basic implements DosFileAttributeView {
+        private static final String READONLY_NAME = "readonly";
+        private static final String ARCHIVE_NAME = "archive";
+        private static final String SYSTEM_NAME = "system";
+        private static final String HIDDEN_NAME = "hidden";
+        private static final String ATTRIBUTES_NAME = "attributes";
+
+        Dos(WindowsPath file, boolean followLinks) {
+            super(file, followLinks);
+        }
+
+        @Override
+        public String name() {
+            return "dos";
+        }
+
+        @Override
+        public Object getAttribute(String attribute) throws IOException {
+            if (attribute.equals(READONLY_NAME))
+                return readAttributes().isReadOnly();
+            if (attribute.equals(ARCHIVE_NAME))
+                return readAttributes().isArchive();
+            if (attribute.equals(SYSTEM_NAME))
+                return readAttributes().isSystem();
+            if (attribute.equals(HIDDEN_NAME))
+                return readAttributes().isHidden();
+            // implementation specific
+            if (attribute.equals(ATTRIBUTES_NAME))
+                return readAttributes().attributes();
+            return super.getAttribute(attribute);
+        }
+
+        @Override
+        public void setAttribute(String attribute, Object value)
+            throws IOException
+        {
+            if (attribute.equals(READONLY_NAME)) {
+                setReadOnly((Boolean)value);
+                return;
+            }
+            if (attribute.equals(ARCHIVE_NAME)) {
+                setArchive((Boolean)value);
+                return;
+            }
+            if (attribute.equals(SYSTEM_NAME)) {
+                setSystem((Boolean)value);
+                return;
+            }
+            if (attribute.equals(HIDDEN_NAME)) {
+                setHidden((Boolean)value);
+                return;
+            }
+            super.setAttribute(attribute, value);
+        }
+
+        @Override
+        public Map<String,?> readAttributes(String first, String[] rest)
+            throws IOException
+        {
+            AttributesBuilder builder = AttributesBuilder.create(first, rest);
+            WindowsFileAttributes attrs = readAttributes();
+            addBasicAttributesToBuilder(attrs, builder);
+            if (builder.match(READONLY_NAME))
+                builder.add(READONLY_NAME, attrs.isReadOnly());
+            if (builder.match(ARCHIVE_NAME))
+                builder.add(ARCHIVE_NAME, attrs.isArchive());
+            if (builder.match(SYSTEM_NAME))
+                builder.add(SYSTEM_NAME, attrs.isSystem());
+            if (builder.match(HIDDEN_NAME))
+                builder.add(HIDDEN_NAME, attrs.isHidden());
+            if (builder.match(ATTRIBUTES_NAME))
+                builder.add(ATTRIBUTES_NAME, attrs.attributes());
+            return builder.unmodifiableMap();
+        }
+
+        /**
+         * Update DOS attributes
+         */
+        private void updateAttributes(int flag, boolean enable)
+            throws IOException
+        {
+            file.checkWrite();
+
+            // GetFileAttribtues & SetFileAttributes do not follow links so when
+            // following links we need the final target
+            String path = WindowsLinkSupport.getFinalPath(file, followLinks);
+            try {
+                int oldValue = GetFileAttributes(path);
+                int newValue = oldValue;
+                if (enable) {
+                    newValue |= flag;
+                } else {
+                    newValue &= ~flag;
+                }
+                if (newValue != oldValue) {
+                    SetFileAttributes(path, newValue);
+                }
+            } catch (WindowsException x) {
+                // don't reveal target in exception
+                x.rethrowAsIOException(file);
+            }
+        }
+
+        @Override
+        public void setReadOnly(boolean value) throws IOException {
+            updateAttributes(FILE_ATTRIBUTE_READONLY, value);
+        }
+
+        @Override
+        public void setHidden(boolean value) throws IOException {
+            updateAttributes(FILE_ATTRIBUTE_HIDDEN, value);
+        }
+
+        @Override
+        public void setArchive(boolean value) throws IOException {
+            updateAttributes(FILE_ATTRIBUTE_ARCHIVE, value);
+        }
+
+        @Override
+        public void setSystem(boolean value) throws IOException {
+            updateAttributes(FILE_ATTRIBUTE_SYSTEM, value);
+        }
+
+        // package-private
+        // Copy given attributes to the file.
+        void setAttributes(WindowsFileAttributes attrs)
+            throws IOException
+        {
+            // copy DOS attributes to target
+            int flags = 0;
+            if (attrs.isReadOnly()) flags |= FILE_ATTRIBUTE_READONLY;
+            if (attrs.isHidden()) flags |= FILE_ATTRIBUTE_HIDDEN;
+            if (attrs.isArchive()) flags |= FILE_ATTRIBUTE_ARCHIVE;
+            if (attrs.isSystem()) flags |= FILE_ATTRIBUTE_SYSTEM;
+            updateAttributes(flags, true);
+
+            // copy file times to target - must be done after updating FAT attributes
+            // as otherwise the last modified time may be wrong.
+            setFileTimes(
+                WindowsFileAttributes.toWindowsTime(attrs.creationTime()),
+                WindowsFileAttributes.toWindowsTime(attrs.lastModifiedTime()),
+                WindowsFileAttributes.toWindowsTime(attrs.lastAccessTime()));
+        }
+    }
+
+    static BasicFileAttributeView createBasicView(WindowsPath file, boolean followLinks) {
+        return new Basic(file, followLinks);
+    }
+
+    static WindowsFileAttributeViews.Dos createDosView(WindowsPath file, boolean followLinks) {
+        return new Dos(file, followLinks);
+    }
+}
diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsFileAttributes.java b/jdk/src/windows/classes/sun/nio/fs/WindowsFileAttributes.java
new file mode 100644
index 0000000..ce053cf
--- /dev/null
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsFileAttributes.java
@@ -0,0 +1,461 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.attribute.*;
+import java.util.concurrent.TimeUnit;
+import java.security.AccessController;
+import sun.misc.Unsafe;
+import sun.security.action.GetPropertyAction;
+
+import static sun.nio.fs.WindowsNativeDispatcher.*;
+import static sun.nio.fs.WindowsConstants.*;
+
+/**
+ * Windows implementation of DosFileAttributes/BasicFileAttributes
+ */
+
+class WindowsFileAttributes
+    implements DosFileAttributes
+{
+    private static final Unsafe unsafe = Unsafe.getUnsafe();
+
+    /*
+     * typedef struct _BY_HANDLE_FILE_INFORMATION {
+     *     DWORD    dwFileAttributes;
+     *     FILETIME ftCreationTime;
+     *     FILETIME ftLastAccessTime;
+     *     FILETIME ftLastWriteTime;
+     *     DWORD    dwVolumeSerialNumber;
+     *     DWORD    nFileSizeHigh;
+     *     DWORD    nFileSizeLow;
+     *     DWORD    nNumberOfLinks;
+     *     DWORD    nFileIndexHigh;
+     *     DWORD    nFileIndexLow;
+     * } BY_HANDLE_FILE_INFORMATION;
+     */
+    private static final short SIZEOF_FILE_INFORMATION  = 52;
+    private static final short OFFSETOF_FILE_INFORMATION_ATTRIBUTES      = 0;
+    private static final short OFFSETOF_FILE_INFORMATION_CREATETIME      = 4;
+    private static final short OFFSETOF_FILE_INFORMATION_LASTACCESSTIME  = 12;
+    private static final short OFFSETOF_FILE_INFORMATION_LASTWRITETIME   = 20;
+    private static final short OFFSETOF_FILE_INFORMATION_VOLSERIALNUM    = 28;
+    private static final short OFFSETOF_FILE_INFORMATION_SIZEHIGH        = 32;
+    private static final short OFFSETOF_FILE_INFORMATION_SIZELOW         = 36;
+    private static final short OFFSETOF_FILE_INFORMATION_NUMLINKS        = 40;
+    private static final short OFFSETOF_FILE_INFORMATION_INDEXHIGH       = 44;
+    private static final short OFFSETOF_FILE_INFORMATION_INDEXLOW        = 48;
+
+    /*
+     * typedef struct _WIN32_FILE_ATTRIBUTE_DATA {
+     *   DWORD dwFileAttributes;
+     *   FILETIME ftCreationTime;
+     *   FILETIME ftLastAccessTime;
+     *   FILETIME ftLastWriteTime;
+     *   DWORD nFileSizeHigh;
+     *   DWORD nFileSizeLow;
+     * } WIN32_FILE_ATTRIBUTE_DATA;
+     */
+    private static final short SIZEOF_FILE_ATTRIBUTE_DATA = 36;
+    private static final short OFFSETOF_FILE_ATTRIBUTE_DATA_ATTRIBUTES      = 0;
+    private static final short OFFSETOF_FILE_ATTRIBUTE_DATA_CREATETIME      = 4;
+    private static final short OFFSETOF_FILE_ATTRIBUTE_DATA_LASTACCESSTIME  = 12;
+    private static final short OFFSETOF_FILE_ATTRIBUTE_DATA_LASTWRITETIME   = 20;
+    private static final short OFFSETOF_FILE_ATTRIBUTE_DATA_SIZEHIGH        = 28;
+    private static final short OFFSETOF_FILE_ATTRIBUTE_DATA_SIZELOW         = 32;
+
+    /**
+     * typedef struct _WIN32_FIND_DATA {
+     *   DWORD dwFileAttributes;
+     *   FILETIME ftCreationTime;
+     *   FILETIME ftLastAccessTime;
+     *   FILETIME ftLastWriteTime;
+     *   DWORD nFileSizeHigh;
+     *   DWORD nFileSizeLow;
+     *   DWORD dwReserved0;
+     *   DWORD dwReserved1;
+     *   TCHAR cFileName[MAX_PATH];
+     *   TCHAR cAlternateFileName[14];
+     * } WIN32_FIND_DATA;
+     */
+    private static final short SIZEOF_FIND_DATA = 592;
+    private static final short OFFSETOF_FIND_DATA_ATTRIBUTES = 0;
+    private static final short OFFSETOF_FIND_DATA_CREATETIME = 4;
+    private static final short OFFSETOF_FIND_DATA_LASTACCESSTIME = 12;
+    private static final short OFFSETOF_FIND_DATA_LASTWRITETIME = 20;
+    private static final short OFFSETOF_FIND_DATA_SIZEHIGH = 28;
+    private static final short OFFSETOF_FIND_DATA_SIZELOW = 32;
+    private static final short OFFSETOF_FIND_DATA_RESERVED0 = 36;
+
+    // indicates if accurate metadata is required (interesting on NTFS only)
+    private static final boolean ensureAccurateMetadata;
+    static {
+        String propValue = AccessController.doPrivileged(
+            new GetPropertyAction("sun.nio.fs.ensureAccurateMetadata", "false"));
+        ensureAccurateMetadata = (propValue.length() == 0) ?
+            true : Boolean.valueOf(propValue);
+    }
+
+    // attributes
+    private final int fileAttrs;
+    private final long creationTime;
+    private final long lastAccessTime;
+    private final long lastWriteTime;
+    private final long size;
+    private final int reparseTag;
+
+    // additional attributes when using GetFileInformationByHandle
+    private final int linkCount;
+    private final int volSerialNumber;
+    private final int fileIndexHigh;
+    private final int fileIndexLow;
+
+    /**
+     * Convert 64-bit value representing the number of 100-nanosecond intervals
+     * since January 1, 1601 to java time.
+     */
+    private static long toJavaTime(long time) {
+        time /= 10000L;
+        time -= 11644473600000L;
+        return time;
+    }
+
+    /**
+     * Convert java time to 64-bit value representing the number of 100-nanosecond
+     * intervals since January 1, 1601.
+     */
+    static long toWindowsTime(long time) {
+        time += 11644473600000L;
+        time *= 10000L;
+        return time;
+    }
+
+    /**
+     * Initialize a new instance of this class
+     */
+    private WindowsFileAttributes(int fileAttrs,
+                                  long creationTime,
+                                  long lastAccessTime,
+                                  long lastWriteTime,
+                                  long size,
+                                  int reparseTag,
+                                  int linkCount,
+                                  int volSerialNumber,
+                                  int fileIndexHigh,
+                                  int fileIndexLow)
+    {
+        this.fileAttrs = fileAttrs;
+        this.creationTime = creationTime;
+        this.lastAccessTime = lastAccessTime;
+        this.lastWriteTime = lastWriteTime;
+        this.size = size;
+        this.reparseTag = reparseTag;
+        this.linkCount = linkCount;
+        this.volSerialNumber = volSerialNumber;
+        this.fileIndexHigh = fileIndexHigh;
+        this.fileIndexLow = fileIndexLow;
+    }
+
+    /**
+     * Create a WindowsFileAttributes from a BY_HANDLE_FILE_INFORMATION structure
+     */
+    private static WindowsFileAttributes fromFileInformation(long address, int reparseTag) {
+        int fileAttrs = unsafe.getInt(address + OFFSETOF_FILE_INFORMATION_ATTRIBUTES);
+        long creationTime =
+            toJavaTime(unsafe.getLong(address + OFFSETOF_FILE_INFORMATION_CREATETIME));
+        long lastAccessTime =
+            toJavaTime(unsafe.getLong(address + OFFSETOF_FILE_INFORMATION_LASTACCESSTIME));
+        long lastWriteTime =
+            toJavaTime(unsafe.getLong(address + OFFSETOF_FILE_INFORMATION_LASTWRITETIME));
+        long size = ((long)(unsafe.getInt(address + OFFSETOF_FILE_INFORMATION_SIZEHIGH)) << 32)
+            + (unsafe.getInt(address + OFFSETOF_FILE_INFORMATION_SIZELOW) & 0xFFFFFFFFL);
+        int linkCount = unsafe.getInt(address + OFFSETOF_FILE_INFORMATION_NUMLINKS);
+        int volSerialNumber = unsafe.getInt(address + OFFSETOF_FILE_INFORMATION_VOLSERIALNUM);
+        int fileIndexHigh = unsafe.getInt(address + OFFSETOF_FILE_INFORMATION_INDEXHIGH);
+        int fileIndexLow = unsafe.getInt(address + OFFSETOF_FILE_INFORMATION_INDEXLOW);
+        return new WindowsFileAttributes(fileAttrs,
+                                         creationTime,
+                                         lastAccessTime,
+                                         lastWriteTime,
+                                         size,
+                                         reparseTag,
+                                         linkCount,
+                                         volSerialNumber,
+                                         fileIndexHigh,
+                                         fileIndexLow);
+    }
+
+    /**
+     * Create a WindowsFileAttributes from a WIN32_FILE_ATTRIBUTE_DATA structure
+     */
+    private static WindowsFileAttributes fromFileAttributeData(long address, int reparseTag) {
+        int fileAttrs = unsafe.getInt(address + OFFSETOF_FILE_ATTRIBUTE_DATA_ATTRIBUTES);
+        long creationTime =
+            toJavaTime(unsafe.getLong(address + OFFSETOF_FILE_ATTRIBUTE_DATA_CREATETIME));
+        long lastAccessTime =
+            toJavaTime(unsafe.getLong(address + OFFSETOF_FILE_ATTRIBUTE_DATA_LASTACCESSTIME));
+        long lastWriteTime =
+            toJavaTime(unsafe.getLong(address + OFFSETOF_FILE_ATTRIBUTE_DATA_LASTWRITETIME));
+        long size = ((long)(unsafe.getInt(address + OFFSETOF_FILE_ATTRIBUTE_DATA_SIZEHIGH)) << 32)
+            + (unsafe.getInt(address + OFFSETOF_FILE_ATTRIBUTE_DATA_SIZELOW) & 0xFFFFFFFFL);
+        return new WindowsFileAttributes(fileAttrs,
+                                         creationTime,
+                                         lastAccessTime,
+                                         lastWriteTime,
+                                         size,
+                                         reparseTag,
+                                         1,  // linkCount
+                                         0,  // volSerialNumber
+                                         0,  // fileIndexHigh
+                                         0); // fileIndexLow
+    }
+
+
+    /**
+     * Allocates a native buffer for a WIN32_FIND_DATA structure
+     */
+    static NativeBuffer getBufferForFindData() {
+        return NativeBuffers.getNativeBuffer(SIZEOF_FIND_DATA);
+    }
+
+    /**
+     * Create a WindowsFileAttributes from a WIN32_FIND_DATA structure
+     */
+    static WindowsFileAttributes fromFindData(long address) {
+        int fileAttrs = unsafe.getInt(address + OFFSETOF_FIND_DATA_ATTRIBUTES);
+        long creationTime =
+            toJavaTime(unsafe.getLong(address + OFFSETOF_FIND_DATA_CREATETIME));
+        long lastAccessTime =
+            toJavaTime(unsafe.getLong(address + OFFSETOF_FIND_DATA_LASTACCESSTIME));
+        long lastWriteTime =
+            toJavaTime(unsafe.getLong(address + OFFSETOF_FIND_DATA_LASTWRITETIME));
+        long size = ((long)(unsafe.getInt(address + OFFSETOF_FIND_DATA_SIZEHIGH)) << 32)
+            + (unsafe.getInt(address + OFFSETOF_FIND_DATA_SIZELOW) & 0xFFFFFFFFL);
+        int reparseTag = ((fileAttrs & FILE_ATTRIBUTE_REPARSE_POINT) != 0) ?
+            + unsafe.getInt(address + OFFSETOF_FIND_DATA_RESERVED0) : 0;
+        return new WindowsFileAttributes(fileAttrs,
+                                         creationTime,
+                                         lastAccessTime,
+                                         lastWriteTime,
+                                         size,
+                                         reparseTag,
+                                         1,  // linkCount
+                                         0,  // volSerialNumber
+                                         0,  // fileIndexHigh
+                                         0); // fileIndexLow
+    }
+
+    /**
+     * Reads the attributes of an open file
+     */
+    static WindowsFileAttributes readAttributes(long handle)
+        throws WindowsException
+    {
+        NativeBuffer buffer = NativeBuffers
+            .getNativeBuffer(SIZEOF_FILE_INFORMATION);
+        try {
+            long address = buffer.address();
+            GetFileInformationByHandle(handle, address);
+
+            // if file is a reparse point then read the tag
+            int reparseTag = 0;
+            int fileAttrs = unsafe
+                .getInt(address + OFFSETOF_FILE_INFORMATION_ATTRIBUTES);
+            if ((fileAttrs & FILE_ATTRIBUTE_REPARSE_POINT) != 0) {
+                int size = MAXIMUM_REPARSE_DATA_BUFFER_SIZE;
+                NativeBuffer reparseBuffer = NativeBuffers.getNativeBuffer(size);
+                try {
+                    DeviceIoControlGetReparsePoint(handle, reparseBuffer.address(), size);
+                    reparseTag = (int)unsafe.getLong(reparseBuffer.address());
+                } finally {
+                    reparseBuffer.release();
+                }
+            }
+
+            return fromFileInformation(address, reparseTag);
+        } finally {
+            buffer.release();
+        }
+    }
+
+    /**
+     * Returns attributes of given file.
+     */
+    static WindowsFileAttributes get(WindowsPath path, boolean followLinks)
+        throws WindowsException
+    {
+        if (!ensureAccurateMetadata) {
+            NativeBuffer buffer =
+                NativeBuffers.getNativeBuffer(SIZEOF_FILE_ATTRIBUTE_DATA);
+            try {
+                long address = buffer.address();
+                GetFileAttributesEx(path.getPathForWin32Calls(), address);
+                // if reparse point then file may be a sym link; otherwise
+                // just return the attributes
+                int fileAttrs = unsafe
+                    .getInt(address + OFFSETOF_FILE_ATTRIBUTE_DATA_ATTRIBUTES);
+                if ((fileAttrs & FILE_ATTRIBUTE_REPARSE_POINT) == 0)
+                    return fromFileAttributeData(address, 0);
+            } finally {
+                buffer.release();
+            }
+        }
+
+        // file is reparse point so need to open file to get attributes
+        long handle = path.openForReadAttributeAccess(followLinks);
+        try {
+            return readAttributes(handle);
+        } finally {
+            CloseHandle(handle);
+        }
+    }
+
+    /**
+     * Returns true if the attribtues are of the same file - both files must
+     * be open.
+     */
+    static boolean isSameFile(WindowsFileAttributes attrs1,
+                              WindowsFileAttributes attrs2)
+    {
+        // volume serial number and file index must be the same
+        return (attrs1.volSerialNumber == attrs2.volSerialNumber) &&
+               (attrs1.fileIndexHigh == attrs2.fileIndexHigh) &&
+               (attrs1.fileIndexLow == attrs2.fileIndexLow);
+    }
+
+    // package-private
+    int attributes() {
+        return fileAttrs;
+    }
+
+    int volSerialNumber() {
+        if (volSerialNumber == 0)
+            throw new AssertionError("Should not get here");
+        return volSerialNumber;
+    }
+
+    int fileIndexHigh() {
+        if (volSerialNumber == 0)
+            throw new AssertionError("Should not get here");
+        return fileIndexHigh;
+    }
+
+    int fileIndexLow() {
+        if (volSerialNumber == 0)
+            throw new AssertionError("Should not get here");
+        return fileIndexLow;
+    }
+
+    @Override
+    public long size() {
+        return size;
+    }
+
+    @Override
+    public long lastModifiedTime() {
+        return (lastWriteTime >= 0L) ? lastWriteTime : 0L;
+    }
+
+    @Override
+    public long lastAccessTime() {
+        return (lastAccessTime >= 0L) ? lastAccessTime : 0L;
+    }
+
+    @Override
+    public long creationTime() {
+        return (creationTime >= 0L) ? creationTime : 0L;
+    }
+
+    @Override
+    public TimeUnit resolution() {
+        return TimeUnit.MILLISECONDS;
+    }
+
+    @Override
+    public int linkCount() {
+        return linkCount;
+    }
+
+    @Override
+    public Object fileKey() {
+        return null;
+    }
+
+    // package private
+    boolean isReparsePoint() {
+        return (fileAttrs & FILE_ATTRIBUTE_REPARSE_POINT) != 0;
+    }
+
+    boolean isDirectoryLink() {
+        return isSymbolicLink() && ((fileAttrs & FILE_ATTRIBUTE_DIRECTORY) != 0);
+    }
+
+    @Override
+    public boolean isSymbolicLink() {
+        return reparseTag == IO_REPARSE_TAG_SYMLINK;
+    }
+
+    @Override
+    public boolean isDirectory() {
+        // ignore FILE_ATTRIBUTE_DIRECTORY attribute if file is a sym link
+        if (isSymbolicLink())
+            return false;
+        return ((fileAttrs & FILE_ATTRIBUTE_DIRECTORY) != 0);
+    }
+
+    @Override
+    public boolean isOther() {
+        if (isSymbolicLink())
+            return false;
+        // return true if device or reparse point
+        return ((fileAttrs & (FILE_ATTRIBUTE_DEVICE | FILE_ATTRIBUTE_REPARSE_POINT)) != 0);
+    }
+
+    @Override
+    public boolean isRegularFile() {
+        return !isSymbolicLink() && !isDirectory() && !isOther();
+    }
+
+    @Override
+    public boolean isReadOnly() {
+        return (fileAttrs & FILE_ATTRIBUTE_READONLY) != 0;
+    }
+
+    @Override
+    public boolean isHidden() {
+        return (fileAttrs & FILE_ATTRIBUTE_HIDDEN) != 0;
+    }
+
+    @Override
+    public boolean isArchive() {
+        return (fileAttrs & FILE_ATTRIBUTE_ARCHIVE) != 0;
+    }
+
+    @Override
+    public boolean isSystem() {
+        return (fileAttrs & FILE_ATTRIBUTE_SYSTEM) != 0;
+    }
+}
diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsFileCopy.java b/jdk/src/windows/classes/sun/nio/fs/WindowsFileCopy.java
new file mode 100644
index 0000000..69a41262
--- /dev/null
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsFileCopy.java
@@ -0,0 +1,519 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.*;
+import java.io.IOException;
+import java.util.concurrent.ExecutionException;
+import com.sun.nio.file.ExtendedCopyOption;
+
+import static sun.nio.fs.WindowsNativeDispatcher.*;
+import static sun.nio.fs.WindowsConstants.*;
+
+/**
+ * Utility methods for copying and moving files.
+ */
+
+class WindowsFileCopy {
+    private WindowsFileCopy() {
+    }
+
+    /**
+     * Copy file from source to target
+     */
+    static void copy(final WindowsPath source,
+                     final WindowsPath target,
+                     CopyOption... options)
+        throws IOException
+    {
+        // map options
+        boolean replaceExisting = false;
+        boolean copyAttributes = false;
+        boolean followLinks = true;
+        boolean interruptible = false;
+        for (CopyOption option: options) {
+            if (option == StandardCopyOption.REPLACE_EXISTING) {
+                replaceExisting = true;
+                continue;
+            }
+            if (option == LinkOption.NOFOLLOW_LINKS) {
+                followLinks = false;
+                continue;
+            }
+            if (option == StandardCopyOption.COPY_ATTRIBUTES) {
+                copyAttributes = true;
+                continue;
+            }
+            if (option == ExtendedCopyOption.INTERRUPTIBLE) {
+                interruptible = true;
+                continue;
+            }
+            if (option == null)
+                throw new NullPointerException();
+            throw new UnsupportedOperationException("Unsupported copy option");
+        }
+
+        // check permissions. If the source file is a symbolic link then
+        // later we must also check LinkPermission
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            source.checkRead();
+            target.checkWrite();
+        }
+
+        // get attributes of source file
+        // attempt to get attributes of target file
+        // if both files are the same there is nothing to do
+        // if target exists and !replace then throw exception
+
+        WindowsFileAttributes sourceAttrs = null;
+        WindowsFileAttributes targetAttrs = null;
+
+        long sourceHandle = 0L;
+        try {
+            sourceHandle = source.openForReadAttributeAccess(followLinks);
+        } catch (WindowsException x) {
+            x.rethrowAsIOException(source);
+        }
+        try {
+            // source attributes
+            try {
+                sourceAttrs = WindowsFileAttributes.readAttributes(sourceHandle);
+            } catch (WindowsException x) {
+                x.rethrowAsIOException(source);
+            }
+
+            // open target (don't follow links)
+            long targetHandle = 0L;
+            try {
+                targetHandle = target.openForReadAttributeAccess(false);
+                try {
+                    targetAttrs = WindowsFileAttributes.readAttributes(targetHandle);
+
+                    // if both files are the same then nothing to do
+                    if (WindowsFileAttributes.isSameFile(sourceAttrs, targetAttrs)) {
+                        return;
+                    }
+
+                    // can't replace file
+                    if (!replaceExisting) {
+                        throw new FileAlreadyExistsException(
+                            target.getPathForExceptionMessage());
+                    }
+
+                } finally {
+                    CloseHandle(targetHandle);
+                }
+            } catch (WindowsException x) {
+                // ignore
+            }
+
+        } finally {
+            CloseHandle(sourceHandle);
+        }
+
+        // if source file is a symbolic link then we must check for LinkPermission
+        if (sm != null && sourceAttrs.isSymbolicLink()) {
+            sm.checkPermission(new LinkPermission("symbolic"));
+        }
+
+        final String sourcePath = asWin32Path(source);
+        final String targetPath = asWin32Path(target);
+
+        // if target exists then delete it.
+        if (targetAttrs != null) {
+            try {
+                if (targetAttrs.isDirectory() || targetAttrs.isDirectoryLink()) {
+                    RemoveDirectory(targetPath);
+                } else {
+                    DeleteFile(targetPath);
+                }
+            } catch (WindowsException x) {
+                if (targetAttrs.isDirectory()) {
+                    // ERROR_ALREADY_EXISTS is returned when attempting to delete
+                    // non-empty directory on SAMBA servers.
+                    if (x.lastError() == ERROR_DIR_NOT_EMPTY ||
+                        x.lastError() == ERROR_ALREADY_EXISTS)
+                    {
+                        throw new FileAlreadyExistsException(
+                            target.getPathForExceptionMessage());
+                    }
+                }
+                x.rethrowAsIOException(target);
+            }
+        }
+
+        // Use CopyFileEx if the file is not a directory or junction
+        if (!sourceAttrs.isDirectory() && !sourceAttrs.isDirectoryLink()) {
+            final int flags =
+                (source.getFileSystem().supportsLinks() && !followLinks) ?
+                COPY_FILE_COPY_SYMLINK : 0;
+
+            if (interruptible) {
+                // interruptible copy
+                Cancellable copyTask = new Cancellable() {
+                    @Override
+                    public int cancelValue() {
+                        return 1;  // TRUE
+                    }
+                    @Override
+                    public void implRun() throws IOException {
+                        try {
+                            CopyFileEx(sourcePath, targetPath, flags,
+                                       addressToPollForCancel());
+                        } catch (WindowsException x) {
+                            x.rethrowAsIOException(source, target);
+                        }
+                    }
+                };
+                try {
+                    Cancellable.runInterruptibly(copyTask);
+                } catch (ExecutionException e) {
+                    Throwable t = e.getCause();
+                    if (t instanceof IOException)
+                        throw (IOException)t;
+                    throw new IOException(t);
+                }
+            } else {
+                // non-interruptible copy
+                try {
+                    CopyFileEx(sourcePath, targetPath, flags, 0L);
+                } catch (WindowsException x) {
+                    x.rethrowAsIOException(source, target);
+                }
+            }
+            if (copyAttributes) {
+                // CopyFileEx does not copy security attributes
+                try {
+                    copySecurityAttributes(source, target, followLinks);
+                } catch (IOException x) {
+                    // ignore
+                }
+            }
+            return;
+        }
+
+        // copy directory or directory junction
+        try {
+            if (sourceAttrs.isDirectory()) {
+                CreateDirectory(targetPath, 0L);
+            } else {
+                String linkTarget = WindowsLinkSupport.readLink(source);
+                int flags = SYMBOLIC_LINK_FLAG_DIRECTORY;
+                CreateSymbolicLink(targetPath,
+                                   addPrefixIfNeeded(linkTarget),
+                                   flags);
+            }
+        } catch (WindowsException x) {
+            x.rethrowAsIOException(target);
+        }
+        if (copyAttributes) {
+            // copy DOS/timestamps attributes
+            WindowsFileAttributeViews.Dos view =
+                WindowsFileAttributeViews.createDosView(target, false);
+            try {
+                view.setAttributes(sourceAttrs);
+            } catch (IOException x) {
+                if (sourceAttrs.isDirectory()) {
+                    try {
+                        RemoveDirectory(targetPath);
+                    } catch (WindowsException ignore) { }
+                }
+            }
+
+            // copy security attributes. If this fail it doesn't cause the move
+            // to fail.
+            try {
+                copySecurityAttributes(source, target, followLinks);
+            } catch (IOException ignore) { }
+        }
+    }
+
+    /**
+     * Move file from source to target
+     */
+    static void move(WindowsPath source, WindowsPath target, CopyOption... options)
+        throws IOException
+    {
+        // map options
+        boolean atomicMove = false;
+        boolean replaceExisting = false;
+        for (CopyOption option: options) {
+            if (option == StandardCopyOption.ATOMIC_MOVE) {
+                atomicMove = true;
+                continue;
+            }
+            if (option == StandardCopyOption.REPLACE_EXISTING) {
+                replaceExisting = true;
+                continue;
+            }
+            if (option == LinkOption.NOFOLLOW_LINKS) {
+                // ignore
+                continue;
+            }
+            if (option == null) throw new NullPointerException();
+            throw new UnsupportedOperationException("Unsupported copy option");
+        }
+
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            source.checkWrite();
+            target.checkWrite();
+        }
+
+        final String sourcePath = asWin32Path(source);
+        final String targetPath = asWin32Path(target);
+
+        // atomic case
+        if (atomicMove) {
+            try {
+                MoveFileEx(sourcePath, targetPath, MOVEFILE_REPLACE_EXISTING);
+            } catch (WindowsException x) {
+                if (x.lastError() == ERROR_NOT_SAME_DEVICE) {
+                    throw new AtomicMoveNotSupportedException(
+                        source.getPathForExceptionMessage(),
+                        target.getPathForExceptionMessage(),
+                        x.errorString());
+                }
+                x.rethrowAsIOException(source, target);
+            }
+            return;
+        }
+
+        // get attributes of source file
+        // attempt to get attributes of target file
+        // if both files are the same there is nothing to do
+        // if target exists and !replace then throw exception
+
+        WindowsFileAttributes sourceAttrs = null;
+        WindowsFileAttributes targetAttrs = null;
+
+        long sourceHandle = 0L;
+        try {
+            sourceHandle = source.openForReadAttributeAccess(false);
+        } catch (WindowsException x) {
+            x.rethrowAsIOException(source);
+        }
+        try {
+            // source attributes
+            try {
+                sourceAttrs = WindowsFileAttributes.readAttributes(sourceHandle);
+            } catch (WindowsException x) {
+                x.rethrowAsIOException(source);
+            }
+
+            // open target (don't follow links)
+            long targetHandle = 0L;
+            try {
+                targetHandle = target.openForReadAttributeAccess(false);
+                try {
+                    targetAttrs = WindowsFileAttributes.readAttributes(targetHandle);
+
+                    // if both files are the same then nothing to do
+                    if (WindowsFileAttributes.isSameFile(sourceAttrs, targetAttrs)) {
+                        return;
+                    }
+
+                    // can't replace file
+                    if (!replaceExisting) {
+                        throw new FileAlreadyExistsException(
+                            target.getPathForExceptionMessage());
+                    }
+
+                } finally {
+                    CloseHandle(targetHandle);
+                }
+            } catch (WindowsException x) {
+                // ignore
+            }
+
+        } finally {
+            CloseHandle(sourceHandle);
+        }
+
+        // if target exists then delete it.
+        if (targetAttrs != null) {
+            try {
+                if (targetAttrs.isDirectory() || targetAttrs.isDirectoryLink()) {
+                    RemoveDirectory(targetPath);
+                } else {
+                    DeleteFile(targetPath);
+                }
+            } catch (WindowsException x) {
+                if (targetAttrs.isDirectory()) {
+                    // ERROR_ALREADY_EXISTS is returned when attempting to delete
+                    // non-empty directory on SAMBA servers.
+                    if (x.lastError() == ERROR_DIR_NOT_EMPTY ||
+                        x.lastError() == ERROR_ALREADY_EXISTS)
+                    {
+                        throw new FileAlreadyExistsException(
+                            target.getPathForExceptionMessage());
+                    }
+                }
+                x.rethrowAsIOException(target);
+            }
+        }
+
+        // first try MoveFileEx (no options). If target is on same volume then
+        // all attributes (including security attributes) are preserved.
+        try {
+            MoveFileEx(sourcePath, targetPath, 0);
+            return;
+        } catch (WindowsException x) {
+            if (x.lastError() != ERROR_NOT_SAME_DEVICE)
+                x.rethrowAsIOException(source, target);
+        }
+
+        // target is on different volume so use MoveFileEx with copy option
+        if (!sourceAttrs.isDirectory() && !sourceAttrs.isDirectoryLink()) {
+            try {
+                MoveFileEx(sourcePath, targetPath, MOVEFILE_COPY_ALLOWED);
+            } catch (WindowsException x) {
+                x.rethrowAsIOException(source, target);
+            }
+            // MoveFileEx does not copy security attributes when moving
+            // across volumes.
+            try {
+                copySecurityAttributes(source, target, false);
+            } catch (IOException x) {
+                // ignore
+            }
+            return;
+        }
+
+        // moving directory or directory-link to another file system
+        assert sourceAttrs.isDirectory() || sourceAttrs.isDirectoryLink();
+
+        // create new directory or directory junction
+        try {
+            if (sourceAttrs.isDirectory()) {
+                CreateDirectory(targetPath, 0L);
+            } else {
+                String linkTarget = WindowsLinkSupport.readLink(source);
+                CreateSymbolicLink(targetPath,
+                                   addPrefixIfNeeded(linkTarget),
+                                   SYMBOLIC_LINK_FLAG_DIRECTORY);
+            }
+        } catch (WindowsException x) {
+            x.rethrowAsIOException(target);
+        }
+
+        // copy timestamps/DOS attributes
+        WindowsFileAttributeViews.Dos view =
+                WindowsFileAttributeViews.createDosView(target, false);
+        try {
+            view.setAttributes(sourceAttrs);
+        } catch (IOException x) {
+            // rollback
+            try {
+                RemoveDirectory(targetPath);
+            } catch (WindowsException ignore) { }
+            throw x;
+        }
+
+        // copy security attributes. If this fails it doesn't cause the move
+        // to fail.
+        try {
+            copySecurityAttributes(source, target, false);
+        } catch (IOException ignore) { }
+
+        // delete source
+        try {
+            RemoveDirectory(sourcePath);
+        } catch (WindowsException x) {
+            // rollback
+            try {
+                RemoveDirectory(targetPath);
+            } catch (WindowsException ignore) { }
+            // ERROR_ALREADY_EXISTS is returned when attempting to delete
+            // non-empty directory on SAMBA servers.
+            if (x.lastError() == ERROR_DIR_NOT_EMPTY ||
+                x.lastError() == ERROR_ALREADY_EXISTS)
+            {
+                throw new DirectoryNotEmptyException(
+                    target.getPathForExceptionMessage());
+            }
+            x.rethrowAsIOException(source);
+        }
+    }
+
+
+    private static String asWin32Path(WindowsPath path) throws IOException {
+        try {
+            return path.getPathForWin32Calls();
+        } catch (WindowsException x) {
+            x.rethrowAsIOException(path);
+            return null;
+        }
+    }
+
+    /**
+     * Copy DACL/owner/group from source to target
+     */
+    private static void copySecurityAttributes(WindowsPath source,
+                                               WindowsPath target,
+                                               boolean followLinks)
+        throws IOException
+    {
+        String path = WindowsLinkSupport.getFinalPath(source, followLinks);
+
+        // may need SeRestorePrivilege to set file owner
+        WindowsSecurity.Privilege priv =
+            WindowsSecurity.enablePrivilege("SeRestorePrivilege");
+        try {
+            int request = (DACL_SECURITY_INFORMATION |
+                OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION);
+            NativeBuffer buffer =
+                WindowsAclFileAttributeView.getFileSecurity(path, request);
+            try {
+                try {
+                    SetFileSecurity(target.getPathForWin32Calls(), request,
+                        buffer.address());
+                } catch (WindowsException x) {
+                    x.rethrowAsIOException(target);
+                }
+            } finally {
+                buffer.release();
+            }
+        } finally {
+            priv.drop();
+        }
+    }
+
+    /**
+     * Add long path prefix to path if required
+     */
+    private static String addPrefixIfNeeded(String path) {
+        if (path.length() > 248) {
+            if (path.startsWith("\\\\")) {
+                path = "\\\\?\\UNC" + path.substring(1, path.length());
+            } else {
+                path = "\\\\?\\" + path;
+            }
+        }
+        return path;
+    }
+}
diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsFileStore.java b/jdk/src/windows/classes/sun/nio/fs/WindowsFileStore.java
new file mode 100644
index 0000000..5d3a0af
--- /dev/null
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsFileStore.java
@@ -0,0 +1,337 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.util.*;
+import java.io.IOException;
+
+import static sun.nio.fs.WindowsConstants.*;
+import static sun.nio.fs.WindowsNativeDispatcher.*;
+
+/**
+ * Windows implementation of FileStore.
+ */
+
+class WindowsFileStore
+    extends FileStore
+{
+    private final String root;
+    private final VolumeInformation volInfo;
+    private final int volType;
+    private final String displayName;   // returned by toString
+
+    private WindowsFileStore(String root) throws WindowsException {
+        assert root.charAt(root.length()-1) == '\\';
+        this.root = root;
+        this.volInfo = GetVolumeInformation(root);
+        this.volType = GetDriveType(root);
+
+        // file store "display name" is the volume name if available
+        String vol = volInfo.volumeName();
+        if (vol.length() > 0) {
+            this.displayName = vol;
+        } else {
+            // TBD - should we map all types? Does this need to be localized?
+            this.displayName = (volType == DRIVE_REMOVABLE) ? "Removable Disk" : "";
+        }
+    }
+
+    static WindowsFileStore create(String root, boolean ignoreNotReady)
+        throws IOException
+    {
+        try {
+            return new WindowsFileStore(root);
+        } catch (WindowsException x) {
+            if (ignoreNotReady && x.lastError() == ERROR_NOT_READY)
+                return null;
+            x.rethrowAsIOException(root);
+            return null; // keep compiler happy
+        }
+    }
+
+    static WindowsFileStore create(WindowsPath file) throws IOException {
+        try {
+            // if the file is a link then GetVolumePathName returns the
+            // volume that the link is on so we need to call it with the
+            // final target
+            String target;
+            if (file.getFileSystem().supportsLinks()) {
+                target = WindowsLinkSupport.getFinalPath(file, true);
+            } else {
+                // file must exist
+                WindowsFileAttributes.get(file, true);
+                target = file.getPathForWin32Calls();
+            }
+            String root = GetVolumePathName(target);
+            return new WindowsFileStore(root);
+        } catch (WindowsException x) {
+            x.rethrowAsIOException(file);
+            return null; // keep compiler happy
+        }
+    }
+
+    VolumeInformation volumeInformation() {
+        return volInfo;
+    }
+
+    int volumeType() {
+        return volType;
+    }
+
+    @Override
+    public String name() {
+        return volInfo.volumeName();   // "SYSTEM", "DVD-RW", ...
+    }
+
+    @Override
+    public String type() {
+        return volInfo.fileSystemName();  // "FAT", "NTFS", ...
+    }
+
+    @Override
+    public boolean isReadOnly() {
+        return ((volInfo.flags() & FILE_READ_ONLY_VOLUME) != 0);
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public <V extends FileStoreAttributeView> V getFileStoreAttributeView(Class<V> view) {
+        if (view == FileStoreSpaceAttributeView.class)
+            return (V) new WindowsFileStoreAttributeView(this);
+        return (V) null;
+    }
+
+    @Override
+    public FileStoreAttributeView getFileStoreAttributeView(String name) {
+        if (name.equals("space"))
+            return new WindowsFileStoreAttributeView(this);
+        if (name.equals("volume"))
+            return new VolumeFileStoreAttributeView(this);
+        return null;
+    }
+
+    @Override
+    public boolean supportsFileAttributeView(Class<? extends FileAttributeView> type) {
+        if (type == BasicFileAttributeView.class)
+            return true;
+        if (type == AclFileAttributeView.class || type == FileOwnerAttributeView.class)
+            return ((volInfo.flags() & FILE_PERSISTENT_ACLS) != 0);
+        if (type == UserDefinedFileAttributeView.class)
+            return ((volInfo.flags() & FILE_NAMED_STREAMS) != 0);
+        return false;
+    }
+
+    @Override
+    public boolean supportsFileAttributeView(String name) {
+        if (name.equals("basic") || name.equals("dos"))
+            return true;
+        if (name.equals("acl"))
+            return supportsFileAttributeView(AclFileAttributeView.class);
+        if (name.equals("owner"))
+            return supportsFileAttributeView(FileOwnerAttributeView.class);
+        if (name.equals("xattr"))
+            return supportsFileAttributeView(UserDefinedFileAttributeView.class);
+        return false;
+    }
+
+    @Override
+    public boolean equals(Object ob) {
+        if (ob == this)
+            return true;
+        if (!(ob instanceof WindowsFileStore))
+            return false;
+        WindowsFileStore other = (WindowsFileStore)ob;
+        return this.volInfo.volumeSerialNumber() == other.volInfo.volumeSerialNumber();
+    }
+
+    @Override
+    public int hashCode() {
+        // reveals VSN without permission check - okay?
+        return volInfo.volumeSerialNumber();
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder(displayName);
+        if (sb.length() > 0)
+            sb.append(" ");
+        sb.append("(");
+        // drop trailing slash
+        sb.append(root.subSequence(0, root.length()-1));
+        sb.append(")");
+        return sb.toString();
+    }
+
+    static class WindowsFileStoreAttributeView
+        extends AbstractFileStoreSpaceAttributeView
+    {
+        private final WindowsFileStore fs;
+
+        WindowsFileStoreAttributeView(WindowsFileStore fs) {
+            this.fs = fs;
+        }
+
+        @Override
+        public FileStoreSpaceAttributes readAttributes()
+            throws IOException
+        {
+            // read the free space info
+            DiskFreeSpace info = null;
+            try {
+                info = GetDiskFreeSpaceEx(fs.root);
+            } catch (WindowsException x) {
+                x.rethrowAsIOException(fs.root);
+            }
+
+            final DiskFreeSpace result = info;
+            return new FileStoreSpaceAttributes() {
+                @Override
+                public long totalSpace() {
+                    return result.totalNumberOfBytes();
+                }
+                @Override
+                public long usableSpace() {
+                    return result.freeBytesAvailable();
+                }
+                @Override
+                public long unallocatedSpace() {
+                    return result.totalNumberOfFreeBytes();
+                }
+            };
+        }
+    }
+
+    /**
+     * Windows-specific attribute view to allow access to volume information.
+     */
+    static class VolumeFileStoreAttributeView
+        implements FileStoreAttributeView
+    {
+        private static final String VSN_NAME = "vsn";
+        private static final String COMPRESSED_NAME = "compressed";
+        private static final String REMOVABLE_NAME = "removable";
+        private static final String CDROM_NAME = "cdrom";
+
+        private final WindowsFileStore fs;
+
+        VolumeFileStoreAttributeView(WindowsFileStore fs) {
+            this.fs = fs;
+        }
+
+        @Override
+        public String name() {
+            return "volume";
+        }
+
+        private int vsn() {
+            return fs.volumeInformation().volumeSerialNumber();
+        }
+
+        private boolean isCompressed() {
+            return (fs.volumeInformation().flags() &
+                    FILE_VOLUME_IS_COMPRESSED) > 0;
+        }
+
+        private boolean isRemovable() {
+            return fs.volumeType() == DRIVE_REMOVABLE;
+        }
+
+        private boolean isCdrom() {
+            return fs.volumeType() == DRIVE_CDROM;
+        }
+
+        @Override
+        public Object getAttribute(String attribute) throws IOException {
+            if (attribute.equals(VSN_NAME))
+                return vsn();
+            if (attribute.equals(COMPRESSED_NAME))
+                return isCompressed();
+            if (attribute.equals(REMOVABLE_NAME))
+                return isRemovable();
+            if (attribute.equals(CDROM_NAME))
+                return isCdrom();
+            return null;
+        }
+
+        @Override
+        public void setAttribute(String attribute, Object value)
+            throws IOException
+        {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public Map<String,?> readAttributes(String first, String... rest)
+            throws IOException
+        {
+            boolean all = false;
+            boolean vsn = false;
+            boolean compressed = false;
+            boolean removable = false;
+            boolean cdrom = false;
+
+            if (first.equals(VSN_NAME)) vsn = true;
+            else if (first.equals(COMPRESSED_NAME)) compressed = true;
+            else if (first.equals(REMOVABLE_NAME)) removable = true;
+            else if (first.equals(CDROM_NAME)) cdrom = true;
+            else if (first.equals("*")) all = true;
+
+            if (!all) {
+                for (String attribute: rest) {
+                    if (attribute.equals("*")) {
+                        all = true;
+                        break;
+                    }
+                    if (attribute.equals(VSN_NAME)) {
+                        vsn = true;
+                        continue;
+                    }
+                    if (attribute.equals(COMPRESSED_NAME)) {
+                        compressed = true;
+                        continue;
+                    }
+                    if (attribute.equals(REMOVABLE_NAME)) {
+                        removable = true;
+                        continue;
+                    }
+                }
+            }
+
+            Map<String,Object> result = new HashMap<String,Object>();
+            if (all || vsn)
+                result.put(VSN_NAME, vsn());
+            if (all || compressed)
+                result.put(COMPRESSED_NAME, isCompressed());
+            if (all || removable)
+                result.put(REMOVABLE_NAME, isRemovable());
+            if (all || cdrom)
+                result.put(CDROM_NAME, isCdrom());
+            return result;
+        }
+    }
+}
diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsFileSystem.java b/jdk/src/windows/classes/sun/nio/fs/WindowsFileSystem.java
new file mode 100644
index 0000000..e80c829
--- /dev/null
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsFileSystem.java
@@ -0,0 +1,317 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.nio.file.spi.*;
+import java.util.*;
+import java.util.regex.Pattern;
+import java.io.IOException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import sun.security.action.GetPropertyAction;
+
+class WindowsFileSystem
+    extends FileSystem
+{
+    private final WindowsFileSystemProvider provider;
+
+    // default directory (is absolute), and default root
+    private final String defaultDirectory;
+    private final String defaultRoot;
+
+    private final boolean supportsLinks;
+    private final boolean supportsStreamEnumeration;
+
+    // package-private
+    WindowsFileSystem(WindowsFileSystemProvider provider,
+                      String dir)
+    {
+        this.provider = provider;
+
+        // parse default directory and check it is absolute
+        WindowsPathParser.Result result = WindowsPathParser.parse(dir);
+
+        if (result.type() != WindowsPathType.ABSOLUTE)
+            throw new AssertionError("Default directory must be absolute/non-UNC");
+        this.defaultDirectory = result.path();
+        this.defaultRoot = result.root();
+
+        PrivilegedAction<String> pa = new GetPropertyAction("os.version");
+        String osversion = AccessController.doPrivileged(pa);
+        String[] vers = osversion.split("\\.", 0);
+        int major = Integer.parseInt(vers[0]);
+        int minor = Integer.parseInt(vers[1]);
+
+        // symbolic links available on Vista and newer
+        supportsLinks = (major >= 6);
+
+        // enumeration of data streams available on Windows Server 2003 and newer
+        supportsStreamEnumeration = (major >= 6) || (major == 5 && minor >= 2);
+    }
+
+    // package-private
+    String defaultDirectory() {
+        return defaultDirectory;
+    }
+
+    String defaultRoot() {
+        return defaultRoot;
+    }
+
+    boolean supportsLinks() {
+        return supportsLinks;
+    }
+
+    boolean supportsStreamEnumeration() {
+        return supportsStreamEnumeration;
+    }
+
+    @Override
+    public FileSystemProvider provider() {
+        return provider;
+    }
+
+    @Override
+    public String getSeparator() {
+        return "\\";
+    }
+
+    @Override
+    public boolean isOpen() {
+        return true;
+    }
+
+    @Override
+    public boolean isReadOnly() {
+        return false;
+    }
+
+    @Override
+    public void close() throws IOException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Iterable<Path> getRootDirectories() {
+        int drives = 0;
+        try {
+            drives = WindowsNativeDispatcher.GetLogicalDrives();
+        } catch (WindowsException x) {
+            // shouldn't happen
+            throw new AssertionError(x.getMessage());
+        }
+
+        // iterate over roots, ignoring those that the security manager denies
+        ArrayList<Path> result = new ArrayList<Path>();
+        SecurityManager sm = System.getSecurityManager();
+        for (int i = 0; i <= 25; i++) {  // 0->A, 1->B, 2->C...
+            if ((drives & (1 << i)) != 0) {
+                StringBuilder sb = new StringBuilder(3);
+                sb.append((char)('A' + i));
+                sb.append(":\\");
+                String root = sb.toString();
+                if (sm != null) {
+                    try {
+                        sm.checkRead(root);
+                    } catch (SecurityException x) {
+                        continue;
+                    }
+                }
+                result.add(WindowsPath.createFromNormalizedPath(this, root));
+            }
+        }
+        return Collections.unmodifiableList(result);
+    }
+
+    /**
+     * Iterator returned by getFileStores method.
+     */
+    private class FileStoreIterator implements Iterator<FileStore> {
+        private final Iterator<Path> roots;
+        private FileStore next;
+
+        FileStoreIterator() {
+            this.roots = getRootDirectories().iterator();
+        }
+
+        private FileStore readNext() {
+            assert Thread.holdsLock(this);
+            for (;;) {
+                if (!roots.hasNext())
+                    return null;
+                WindowsPath root = (WindowsPath)roots.next();
+                // ignore if security manager denies access
+                try {
+                    root.checkRead();
+                } catch (SecurityException x) {
+                    continue;
+                }
+                try {
+                    FileStore fs = WindowsFileStore.create(root.toString(), true);
+                    if (fs != null)
+                        return fs;
+                } catch (IOException ioe) {
+                    // skip it
+                }
+            }
+        }
+
+        @Override
+        public synchronized boolean hasNext() {
+            if (next != null)
+                return true;
+            next = readNext();
+            return next != null;
+        }
+
+        @Override
+        public synchronized FileStore next() {
+            if (next == null)
+                next = readNext();
+            if (next == null) {
+                throw new NoSuchElementException();
+            } else {
+                FileStore result = next;
+                next = null;
+                return result;
+            }
+        }
+
+        @Override
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    @Override
+    public Iterable<FileStore> getFileStores() {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            try {
+                sm.checkPermission(new RuntimePermission("getFileStoreAttributes"));
+            } catch (SecurityException se) {
+                return Collections.emptyList();
+            }
+        }
+        return new Iterable<FileStore>() {
+            public Iterator<FileStore> iterator() {
+                return new FileStoreIterator();
+            }
+        };
+    }
+
+    // supported views
+    private static final Set<String> supportedFileAttributeViews = Collections
+        .unmodifiableSet(new HashSet<String>(Arrays.asList("basic", "dos", "acl", "owner", "xattr")));
+
+    @Override
+    public Set<String> supportedFileAttributeViews() {
+        return supportedFileAttributeViews;
+    }
+
+    @Override
+    public Path getPath(String path) {
+        return WindowsPath.parse(this, path);
+    }
+
+    @Override
+    public UserPrincipalLookupService getUserPrincipalLookupService() {
+        return theLookupService;
+    }
+
+    private static final UserPrincipalLookupService theLookupService =
+        new UserPrincipalLookupService() {
+            @Override
+            public UserPrincipal lookupPrincipalByName(String name)
+                throws IOException
+            {
+                return WindowsUserPrincipals.lookup(name);
+            }
+            @Override
+            public GroupPrincipal lookupPrincipalByGroupName(String group)
+                throws IOException
+            {
+                UserPrincipal user = WindowsUserPrincipals.lookup(group);
+                if (!(user instanceof GroupPrincipal))
+                    throw new UserPrincipalNotFoundException(group);
+                return (GroupPrincipal)user;
+            }
+        };
+
+    @Override
+    public PathMatcher getPathMatcher(String syntaxAndInput) {
+        int pos = syntaxAndInput.indexOf(':');
+        if (pos <= 0 || pos == syntaxAndInput.length())
+            throw new IllegalArgumentException();
+        String syntax = syntaxAndInput.substring(0, pos);
+        String input = syntaxAndInput.substring(pos+1);
+
+        String expr;
+        if (syntax.equals(GLOB_SYNTAX)) {
+            expr = Globs.toWindowsRegexPattern(input);
+        } else {
+            if (syntax.equals(REGEX_SYNTAX)) {
+                expr = input;
+            } else {
+                throw new UnsupportedOperationException("Syntax '" + syntax +
+                    "' not recognized");
+            }
+        }
+
+        // match in uppercase
+        StringBuilder sb = new StringBuilder(expr.length());
+        for (int i=0; i<expr.length(); i++) {
+            sb.append(Character.toUpperCase(expr.charAt(i)));
+        }
+        expr = sb.toString();
+
+        // return matcher
+        final Pattern pattern = Pattern.compile(expr);
+        return new PathMatcher() {
+            @Override
+            public boolean matches(Path path) {
+                // match in uppercase
+                String s = path.toString();
+                StringBuilder sb = new StringBuilder(s.length());
+                for (int i=0; i<s.length(); i++) {
+                    sb.append( Character.toUpperCase(s.charAt(i)) );
+                }
+                return pattern.matcher(sb).matches();
+            }
+        };
+    }
+    private static final String GLOB_SYNTAX = "glob";
+    private static final String REGEX_SYNTAX = "regex";
+
+    @Override
+    public WatchService newWatchService()
+        throws IOException
+    {
+        return new WindowsWatchService(this);
+    }
+}
diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java b/jdk/src/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java
new file mode 100644
index 0000000..bc28e95
--- /dev/null
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.*;
+import java.nio.file.spi.*;
+import java.nio.file.attribute.*;
+import java.nio.channels.*;
+import java.net.URI;
+import java.util.concurrent.ExecutorService;
+import java.io.IOException;
+import java.util.*;
+
+import sun.nio.ch.ThreadPool;
+
+public class WindowsFileSystemProvider
+    extends FileSystemProvider
+{
+    private static final String USER_DIR = "user.dir";
+    private final WindowsFileSystem theFileSystem;
+
+    public WindowsFileSystemProvider() {
+        theFileSystem = new WindowsFileSystem(this, System.getProperty(USER_DIR));
+    }
+
+    @Override
+    public String getScheme() {
+        return "file";
+    }
+
+    private void checkUri(URI uri) {
+        if (!uri.getScheme().equalsIgnoreCase(getScheme()))
+            throw new IllegalArgumentException("URI does not match this provider");
+        if (uri.getAuthority() != null)
+            throw new IllegalArgumentException("Authority component present");
+        if (uri.getPath() == null)
+            throw new IllegalArgumentException("Path component is undefined");
+        if (!uri.getPath().equals("/"))
+            throw new IllegalArgumentException("Path component should be '/'");
+        if (uri.getQuery() != null)
+            throw new IllegalArgumentException("Query component present");
+        if (uri.getFragment() != null)
+            throw new IllegalArgumentException("Fragment component present");
+    }
+
+    @Override
+    public FileSystem newFileSystem(URI uri, Map<String,?> env)
+        throws IOException
+    {
+        checkUri(uri);
+        throw new FileSystemAlreadyExistsException();
+    }
+
+    @Override
+    public final FileSystem getFileSystem(URI uri) {
+        checkUri(uri);
+        return theFileSystem;
+    }
+
+    @Override
+    public Path getPath(URI uri) {
+        return WindowsUriSupport.fromUri(theFileSystem, uri);
+    }
+
+    @Override
+    public FileChannel newFileChannel(Path path,
+                                      Set<? extends OpenOption> options,
+                                      FileAttribute<?>... attrs)
+        throws IOException
+    {
+        if (path == null)
+            throw new NullPointerException();
+        if (!(path instanceof WindowsPath))
+            throw new ProviderMismatchException();
+        WindowsPath file = (WindowsPath)path;
+
+        WindowsSecurityDescriptor sd = WindowsSecurityDescriptor.fromAttribute(attrs);
+        try {
+            return WindowsChannelFactory
+                .newFileChannel(file.getPathForWin32Calls(),
+                                file.getPathForPermissionCheck(),
+                                options,
+                                sd.address());
+        } catch (WindowsException x) {
+            x.rethrowAsIOException(file);
+            return null;
+        } finally {
+            if (sd != null)
+                sd.release();
+        }
+    }
+
+    @Override
+    public AsynchronousFileChannel newAsynchronousFileChannel(Path path,
+                                                              Set<? extends OpenOption> options,
+                                                              ExecutorService executor,
+                                                              FileAttribute<?>... attrs)
+        throws IOException
+    {
+        if (path == null)
+            throw new NullPointerException();
+        if (!(path instanceof WindowsPath))
+            throw new ProviderMismatchException();
+        WindowsPath file = (WindowsPath)path;
+        ThreadPool pool = (executor == null) ? null : ThreadPool.wrap(executor, 0);
+        WindowsSecurityDescriptor sd =
+            WindowsSecurityDescriptor.fromAttribute(attrs);
+        try {
+            return WindowsChannelFactory
+                .newAsynchronousFileChannel(file.getPathForWin32Calls(),
+                                            file.getPathForPermissionCheck(),
+                                            options,
+                                            sd.address(),
+                                            pool);
+        } catch (WindowsException x) {
+            x.rethrowAsIOException(file);
+            return null;
+        } finally {
+            if (sd != null)
+                sd.release();
+        }
+    }
+}
diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsLinkSupport.java b/jdk/src/windows/classes/sun/nio/fs/WindowsLinkSupport.java
new file mode 100644
index 0000000..516275d
--- /dev/null
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsLinkSupport.java
@@ -0,0 +1,446 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.*;
+import java.io.IOException;
+import java.io.IOError;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import sun.misc.Unsafe;
+
+import static sun.nio.fs.WindowsNativeDispatcher.*;
+import static sun.nio.fs.WindowsConstants.*;
+
+/**
+ * Utility methods for symbolic link support on Windows Vista and newer.
+ */
+
+class WindowsLinkSupport {
+    private static final Unsafe unsafe = Unsafe.getUnsafe();
+
+    private WindowsLinkSupport() {
+    }
+
+    /**
+     * Returns the target of a symbolic link
+     */
+    static String readLink(WindowsPath path) throws IOException {
+        long handle = 0L;
+        try {
+            handle = path.openForReadAttributeAccess(false); // don't follow links
+        } catch (WindowsException x) {
+            x.rethrowAsIOException(path);
+        }
+        try {
+            return readLinkImpl(handle);
+        } finally {
+            CloseHandle(handle);
+        }
+    }
+
+    /**
+     * Returns the final path of a given path as a String. This should be used
+     * prior to calling Win32 system calls that do not follow links.
+     */
+    static String getFinalPath(WindowsPath input, boolean followLinks)
+        throws IOException
+    {
+        WindowsFileSystem fs = input.getFileSystem();
+
+        try {
+            // if not following links then don't need final path
+            if (!followLinks || !fs.supportsLinks())
+                return input.getPathForWin32Calls();
+
+            // if file is a sym link then don't need final path
+            if (!WindowsFileAttributes.get(input, false).isSymbolicLink()) {
+                return input.getPathForWin32Calls();
+            }
+        } catch (WindowsException x) {
+            x.rethrowAsIOException(input);
+        }
+
+        // The file is a symbolic link so we open it and try to get the
+        // normalized path. This should succeed on NTFS but may fail if there
+        // is a link to a non-NFTS file system.
+        long h = 0;
+        try {
+            h = input.openForReadAttributeAccess(true);
+        } catch (WindowsException x) {
+            x.rethrowAsIOException(input);
+        }
+        try {
+            return stripPrefix(GetFinalPathNameByHandle(h));
+        } catch (WindowsException x) {
+            // ERROR_INVALID_LEVEL is the error returned when not supported by
+            // the file system
+            if (x.lastError() != ERROR_INVALID_LEVEL)
+                x.rethrowAsIOException(input);
+        } finally {
+            CloseHandle(h);
+        }
+
+        // Fallback: read target of link, resolve against parent, and repeat
+        // until file is not a link.
+        WindowsPath target = input;
+        int linkCount = 0;
+        do {
+            try {
+                WindowsFileAttributes attrs =
+                    WindowsFileAttributes.get(target, false);
+                // non a link so we are done
+                if (!attrs.isSymbolicLink()) {
+                    return target.getPathForWin32Calls();
+                }
+            } catch (WindowsException x) {
+                x.rethrowAsIOException(target);
+            }
+            WindowsPath link = WindowsPath
+                .createFromNormalizedPath(fs, readLink(target));
+            WindowsPath parent = target.getParent();
+            if (parent == null) {
+                // no parent so use parent of absolute path
+                final WindowsPath t = target;
+                target = AccessController
+                    .doPrivileged(new PrivilegedAction<WindowsPath>() {
+                        @Override
+                        public WindowsPath run() {
+                            return t.toAbsolutePath();
+                        }});
+                parent = target.getParent();
+            }
+            target = parent.resolve(link);
+
+        } while (++linkCount < 32);
+
+        throw new FileSystemException(input.getPathForExceptionMessage(), null,
+            "Too many links");
+    }
+
+    /**
+     * Returns the actual path of a file, optionally resolving all symbolic
+     * links.
+     */
+    static String getRealPath(WindowsPath input, boolean resolveLinks)
+        throws IOException
+    {
+        WindowsFileSystem fs = input.getFileSystem();
+        if (!fs.supportsLinks())
+            resolveLinks = false;
+
+        // On Vista use GetFinalPathNameByHandle. This should succeed on NTFS
+        // but may fail if there is a link to a non-NFTS file system.
+        if (resolveLinks) {
+            long h = 0;
+            try {
+                h = input.openForReadAttributeAccess(true);
+            } catch (WindowsException x) {
+                x.rethrowAsIOException(input);
+            }
+            try {
+                return stripPrefix(GetFinalPathNameByHandle(h));
+            } catch (WindowsException x) {
+                if (x.lastError() != ERROR_INVALID_LEVEL)
+                    x.rethrowAsIOException(input);
+            } finally {
+                CloseHandle(h);
+            }
+        }
+
+        // Not resolving links or we are on Windows Vista (or newer) with a
+        // link to non-NFTS file system.
+
+        // Start with absolute path
+        String path = null;
+        try {
+            path = input.toAbsolutePath().toString();
+        } catch (IOError x) {
+            throw (IOException)(x.getCause());
+        }
+
+        // Collapse "." and ".."
+        try {
+            path = GetFullPathName(path);
+        } catch (WindowsException x) {
+            x.rethrowAsIOException(input);
+        }
+
+        // eliminate all symbolic links
+        if (resolveLinks) {
+            path = resolveAllLinks(WindowsPath.createFromNormalizedPath(fs, path));
+        }
+
+        // string builder to build up components of path
+        StringBuilder sb = new StringBuilder(path.length());
+
+        // Copy root component
+        int start;
+        char c0 = path.charAt(0);
+        char c1 = path.charAt(1);
+        if ((c0 <= 'z' && c0 >= 'a' || c0 <= 'Z' && c0 >= 'A') &&
+            c1 == ':' && path.charAt(2) == '\\') {
+            // Driver specifier
+            sb.append(Character.toUpperCase(c0));
+            sb.append(":\\");
+            start = 3;
+        } else if (c0 == '\\' && c1 == '\\') {
+            // UNC pathname, begins with "\\\\host\\share"
+            int last = path.length() - 1;
+            int pos = path.indexOf('\\', 2);
+            // skip both server and share names
+            if (pos == -1 || (pos == last)) {
+                // The UNC does not have a share name (collapsed by GetFullPathName)
+                throw new FileSystemException(input.getPathForExceptionMessage(),
+                    null, "UNC has invalid share");
+            }
+            pos = path.indexOf('\\', pos+1);
+            if (pos < 0) {
+                pos = last;
+                sb.append(path).append("\\");
+            } else {
+                sb.append(path, 0, pos+1);
+            }
+            start = pos + 1;
+        } else {
+            throw new AssertionError("path type not recognized");
+        }
+
+        // check root directory exists
+        try {
+            FirstFile fileData = FindFirstFile(sb.toString() + "*");
+            FindClose(fileData.handle());
+        } catch (WindowsException x) {
+            x.rethrowAsIOException(path);
+        }
+
+        // iterate through each component to get its actual name in the
+        // directory
+        int curr = start;
+        while (curr < path.length()) {
+            int next = path.indexOf('\\', curr);
+            int end = (next == -1) ? path.length() : next;
+            String search = sb.toString() + path.substring(curr, end);
+            try {
+                FirstFile fileData = FindFirstFile(addLongPathPrefixIfNeeded(search));
+                try {
+                    sb.append(fileData.name());
+                    if (next != -1) {
+                        sb.append('\\');
+                    }
+                } finally {
+                    FindClose(fileData.handle());
+                }
+            } catch (WindowsException e) {
+                e.rethrowAsIOException(path);
+            }
+            curr = end + 1;
+        }
+
+        return sb.toString();
+    }
+
+    /**
+     * Returns target of a symbolic link given the handle of an open file
+     * (that should be a link).
+     */
+    private static String readLinkImpl(long handle) throws IOException {
+        int size = MAXIMUM_REPARSE_DATA_BUFFER_SIZE;
+        NativeBuffer buffer = NativeBuffers.getNativeBuffer(size);
+        try {
+            try {
+                DeviceIoControlGetReparsePoint(handle, buffer.address(), size);
+            } catch (WindowsException x) {
+                // FIXME: exception doesn't have file name
+                if (x.lastError() == ERROR_NOT_A_REPARSE_POINT)
+                    throw new NotLinkException(null, null, x.errorString());
+                x.rethrowAsIOException((String)null);
+            }
+
+            /*
+             * typedef struct _REPARSE_DATA_BUFFER {
+             *     ULONG  ReparseTag;
+             *     USHORT  ReparseDataLength;
+             *     USHORT  Reserved;
+             *     union {
+             *         struct {
+             *             USHORT  SubstituteNameOffset;
+             *             USHORT  SubstituteNameLength;
+             *             USHORT  PrintNameOffset;
+             *             USHORT  PrintNameLength;
+             *             WCHAR  PathBuffer[1];
+             *         } SymbolicLinkReparseBuffer;
+             *         struct {
+             *             USHORT  SubstituteNameOffset;
+             *             USHORT  SubstituteNameLength;
+             *             USHORT  PrintNameOffset;
+             *             USHORT  PrintNameLength;
+             *             WCHAR  PathBuffer[1];
+             *         } MountPointReparseBuffer;
+             *         struct {
+             *             UCHAR  DataBuffer[1];
+             *         } GenericReparseBuffer;
+             *     };
+             * } REPARSE_DATA_BUFFER
+             */
+            final short OFFSETOF_REPARSETAG = 0;
+            final short OFFSETOF_PATHOFFSET = 8;
+            final short OFFSETOF_PATHLENGTH = 10;
+            final short OFFSETOF_PATHBUFFER = 16 + 4;   // check this
+
+            int tag = (int)unsafe.getLong(buffer.address() + OFFSETOF_REPARSETAG);
+            if (tag != IO_REPARSE_TAG_SYMLINK) {
+                // FIXME: exception doesn't have file name
+                throw new NotLinkException(null, null, "Reparse point is not a symbolic link");
+            }
+
+            // get offset and length of target
+            short nameOffset = unsafe.getShort(buffer.address() + OFFSETOF_PATHOFFSET);
+            short nameLengthInBytes = unsafe.getShort(buffer.address() + OFFSETOF_PATHLENGTH);
+            if ((nameLengthInBytes % 2) != 0)
+                throw new FileSystemException(null, null, "Symbolic link corrupted");
+
+            // copy into char array
+            char[] name = new char[nameLengthInBytes/2];
+            unsafe.copyMemory(null, buffer.address() + OFFSETOF_PATHBUFFER + nameOffset,
+                name, Unsafe.ARRAY_CHAR_BASE_OFFSET, nameLengthInBytes);
+
+            // remove special prefix
+            String target = stripPrefix(new String(name));
+            if (target.length() == 0) {
+                throw new IOException("Symbolic link target is invalid");
+            }
+            return target;
+        } finally {
+            buffer.release();
+        }
+    }
+
+    /**
+     * Resolve all symbolic-links in a given absolute and normalized path
+     */
+    private static String resolveAllLinks(WindowsPath path)
+        throws IOException
+    {
+        assert path.isAbsolute();
+        WindowsFileSystem fs = path.getFileSystem();
+
+        // iterate through each name element of the path, resolving links as
+        // we go.
+        int linkCount = 0;
+        int elem = 0;
+        while (elem < path.getNameCount()) {
+            WindowsPath current = path.getRoot().resolve(path.subpath(0, elem+1));
+
+            WindowsFileAttributes attrs = null;
+            try {
+                attrs = WindowsFileAttributes.get(current, false);
+            } catch (WindowsException x) {
+                x.rethrowAsIOException(current);
+            }
+
+            /**
+             * If a symbolic link then we resolve it against the parent
+             * of the current name element. We then resolve any remaining
+             * part of the path against the result. The target of the link
+             * may have "." and ".." components so re-normalize and restart
+             * the process from the first element.
+             */
+            if (attrs.isSymbolicLink()) {
+                linkCount++;
+                if (linkCount > 32)
+                    throw new IOException("Too many links");
+                WindowsPath target = WindowsPath
+                    .createFromNormalizedPath(fs, readLink(current));
+                WindowsPath remainder = null;
+                int count = path.getNameCount();
+                if ((elem+1) < count) {
+                    remainder = path.subpath(elem+1, count);
+                }
+                path = current.getParent().resolve(target);
+                try {
+                    String full = GetFullPathName(path.toString());
+                    if (!full.equals(path.toString())) {
+                        path = WindowsPath.createFromNormalizedPath(fs, full);
+                    }
+                } catch (WindowsException x) {
+                    x.rethrowAsIOException(path);
+                }
+                if (remainder != null) {
+                    path = path.resolve(remainder);
+                }
+
+                // reset
+                elem = 0;
+            } else {
+                // not a link
+                elem++;
+            }
+        }
+
+        return path.toString();
+    }
+
+    /**
+     * Add long path prefix to path if required.
+     */
+    private static String addLongPathPrefixIfNeeded(String path) {
+        if (path.length() > 248) {
+            if (path.startsWith("\\\\")) {
+                path = "\\\\?\\UNC" + path.substring(1, path.length());
+            } else {
+                path = "\\\\?\\" + path;
+            }
+        }
+        return path;
+    }
+
+    /**
+     * Strip long path or symbolic link prefix from path
+     */
+    private static String stripPrefix(String path) {
+        // prefix for resolved/long path
+        if (path.startsWith("\\\\?\\")) {
+            if (path.startsWith("\\\\?\\UNC\\")) {
+                path = "\\" + path.substring(7);
+            } else {
+                path = path.substring(4);
+            }
+            return path;
+        }
+
+        // prefix for target of symbolic link
+        if (path.startsWith("\\??\\")) {
+            if (path.startsWith("\\??\\UNC\\")) {
+                path = "\\" + path.substring(7);
+            } else {
+                path = path.substring(4);
+            }
+            return path;
+        }
+        return path;
+    }
+}
diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsNativeDispatcher.java b/jdk/src/windows/classes/sun/nio/fs/WindowsNativeDispatcher.java
new file mode 100644
index 0000000..fafee20
--- /dev/null
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsNativeDispatcher.java
@@ -0,0 +1,1134 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import sun.misc.Unsafe;
+
+/**
+ * Win32 and library calls.
+ */
+
+class WindowsNativeDispatcher {
+    private WindowsNativeDispatcher() { }
+
+    /**
+     * HANDLE CreateFile(
+     *   LPCTSTR lpFileName,
+     *   DWORD dwDesiredAccess,
+     *   DWORD dwShareMode,
+     *   LPSECURITY_ATTRIBUTES lpSecurityAttributes,
+     *   DWORD dwCreationDisposition,
+     *   DWORD dwFlagsAndAttributes,
+     *   HANDLE hTemplateFile
+     * )
+     */
+    static long CreateFile(String path,
+                           int dwDesiredAccess,
+                           int dwShareMode,
+                           long lpSecurityAttributes,
+                           int dwCreationDisposition,
+                           int dwFlagsAndAttributes)
+        throws WindowsException
+    {
+        NativeBuffer buffer = asNativeBuffer(path);
+        try {
+            return CreateFile0(buffer.address(),
+                               dwDesiredAccess,
+                               dwShareMode,
+                               lpSecurityAttributes,
+                               dwCreationDisposition,
+                               dwFlagsAndAttributes);
+        } finally {
+            buffer.release();
+        }
+    }
+    static long CreateFile(String path,
+                           int dwDesiredAccess,
+                           int dwShareMode,
+                           int dwCreationDisposition,
+                           int dwFlagsAndAttributes)
+        throws WindowsException
+    {
+        return CreateFile(path, dwDesiredAccess, dwShareMode, 0L,
+                          dwCreationDisposition, dwFlagsAndAttributes);
+    }
+    private static native long CreateFile0(long lpFileName,
+                                           int dwDesiredAccess,
+                                           int dwShareMode,
+                                           long lpSecurityAttributes,
+                                           int dwCreationDisposition,
+                                           int dwFlagsAndAttributes)
+        throws WindowsException;
+
+    /**
+     * CloseHandle(
+     *   HANDLE hObject
+     * )
+     */
+    static native void CloseHandle(long handle);
+
+    /**
+     * DeleteFile(
+     *   LPCTSTR lpFileName
+     * )
+     */
+    static void DeleteFile(String path) throws WindowsException {
+        NativeBuffer buffer = asNativeBuffer(path);
+        try {
+            DeleteFile0(buffer.address());
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native void DeleteFile0(long lpFileName)
+        throws WindowsException;
+
+    /**
+     * CreateDirectory(
+     *   LPCTSTR lpPathName,
+     *   LPSECURITY_ATTRIBUTES lpSecurityAttributes
+     * )
+     */
+    static void CreateDirectory(String path, long lpSecurityAttributes) throws WindowsException {
+        NativeBuffer buffer = asNativeBuffer(path);
+        try {
+            CreateDirectory0(buffer.address(), lpSecurityAttributes);
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native void CreateDirectory0(long lpFileName, long lpSecurityAttributes)
+        throws WindowsException;
+
+    /**
+     * RemoveDirectory(
+     *   LPCTSTR lpPathName
+     * )
+     */
+    static void RemoveDirectory(String path) throws WindowsException {
+        NativeBuffer buffer = asNativeBuffer(path);
+        try {
+            RemoveDirectory0(buffer.address());
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native void RemoveDirectory0(long lpFileName)
+        throws WindowsException;
+
+    /**
+     * Marks a file as a sparse file.
+     *
+     * DeviceIoControl(
+     *   FSCTL_SET_SPARSE
+     * )
+     */
+    static native void DeviceIoControlSetSparse(long handle)
+        throws WindowsException;
+
+    /**
+     * Retrieves the reparse point data associated with the file or directory.
+     *
+     * DeviceIoControl(
+     *   FSCTL_GET_REPARSE_POINT
+     * )
+     */
+    static native void DeviceIoControlGetReparsePoint(long handle,
+        long bufferAddress, int bufferSize) throws WindowsException;
+
+    /**
+     * HANDLE FindFirstFile(
+     *   LPCTSTR lpFileName,
+     *   LPWIN32_FIND_DATA lpFindFileData
+     * )
+     */
+    static FirstFile FindFirstFile(String path) throws WindowsException {
+        NativeBuffer buffer = asNativeBuffer(path);
+        try {
+            FirstFile data = new FirstFile();
+            FindFirstFile0(buffer.address(), data);
+            return data;
+        } finally {
+            buffer.release();
+        }
+    }
+    static class FirstFile {
+        private long handle;
+        private String name;
+
+        private FirstFile() { }
+        public long handle()    { return handle; }
+        public String name()    { return name; }
+    }
+    private static native void FindFirstFile0(long lpFileName, FirstFile obj)
+        throws WindowsException;
+
+    /**
+     * HANDLE FindFirstFile(
+     *   LPCTSTR lpFileName,
+     *   LPWIN32_FIND_DATA lpFindFileData
+     * )
+     */
+    static long FindFirstFile(String path, long address) throws WindowsException {
+        NativeBuffer buffer = asNativeBuffer(path);
+        try {
+            return FindFirstFile1(buffer.address(), address);
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native long FindFirstFile1(long lpFileName, long address)
+        throws WindowsException;
+
+    /**
+     * FindNextFile(
+     *   HANDLE hFindFile,
+     *   LPWIN32_FIND_DATA lpFindFileData
+     * )
+     *
+     * @return  lpFindFileData->cFileName or null
+     */
+    static native String FindNextFile(long handle, long address)
+        throws WindowsException;
+
+    /**
+     * HANDLE FindFirstStreamW(
+     *   LPCWSTR lpFileName,
+     *   STREAM_INFO_LEVELS InfoLevel,
+     *   LPVOID lpFindStreamData,
+     *   DWORD dwFlags
+     * )
+     */
+    static FirstStream FindFirstStream(String path) throws WindowsException {
+        NativeBuffer buffer = asNativeBuffer(path);
+        try {
+            FirstStream data = new FirstStream();
+            FindFirstStream0(buffer.address(), data);
+            if (data.handle() == WindowsConstants.INVALID_HANDLE_VALUE)
+                return null;
+            return data;
+        } finally {
+            buffer.release();
+        }
+    }
+    static class FirstStream {
+        private long handle;
+        private String name;
+
+        private FirstStream() { }
+        public long handle()    { return handle; }
+        public String name()    { return name; }
+    }
+    private static native void FindFirstStream0(long lpFileName, FirstStream obj)
+        throws WindowsException;
+
+    /*
+     * FindNextStreamW(
+     *   HANDLE hFindStream,
+     *   LPVOID lpFindStreamData
+     * )
+     */
+    static native String FindNextStream(long handle) throws WindowsException;
+
+    /**
+     * FindClose(
+     *   HANDLE hFindFile
+     * )
+     */
+    static native void FindClose(long handle) throws WindowsException;
+
+    /**
+     * GetFileInformationByHandle(
+     *   HANDLE hFile,
+     *   LPBY_HANDLE_FILE_INFORMATION lpFileInformation
+     * )
+     */
+    static native void GetFileInformationByHandle(long handle, long address)
+        throws WindowsException;
+
+    /**
+     * CopyFileEx(
+     *   LPCWSTR lpExistingFileName
+     *   LPCWSTR lpNewFileName,
+     *   LPPROGRESS_ROUTINE lpProgressRoutine
+     *   LPVOID lpData,
+     *   LPBOOL pbCancel,
+     *   DWORD dwCopyFlags
+     * )
+     */
+    static void CopyFileEx(String source, String target, int flags,
+                           long addressToPollForCancel)
+        throws WindowsException
+    {
+        NativeBuffer sourceBuffer = asNativeBuffer(source);
+        NativeBuffer targetBuffer = asNativeBuffer(target);
+        try {
+            CopyFileEx0(sourceBuffer.address(), targetBuffer.address(), flags,
+                        addressToPollForCancel);
+        } finally {
+            targetBuffer.release();
+            sourceBuffer.release();
+        }
+    }
+    private static native void CopyFileEx0(long existingAddress, long newAddress,
+        int flags, long addressToPollForCancel) throws WindowsException;
+
+    /**
+     * MoveFileEx(
+     *   LPCTSTR lpExistingFileName,
+     *   LPCTSTR lpNewFileName,
+     *   DWORD dwFlags
+     * )
+     */
+    static void MoveFileEx(String source, String target, int flags)
+        throws WindowsException
+    {
+        NativeBuffer sourceBuffer = asNativeBuffer(source);
+        NativeBuffer targetBuffer = asNativeBuffer(target);
+        try {
+            MoveFileEx0(sourceBuffer.address(), targetBuffer.address(), flags);
+        } finally {
+            targetBuffer.release();
+            sourceBuffer.release();
+        }
+    }
+    private static native void MoveFileEx0(long existingAddress, long newAddress,
+        int flags) throws WindowsException;
+
+    /**
+     * DWORD GetFileAttributes(
+     *   LPCTSTR lpFileName
+     * )
+     */
+    static int GetFileAttributes(String path) throws WindowsException {
+        NativeBuffer buffer = asNativeBuffer(path);
+        try {
+            return GetFileAttributes0(buffer.address());
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native int GetFileAttributes0(long lpFileName)
+        throws WindowsException;
+
+    /**
+     * SetFileAttributes(
+     *   LPCTSTR lpFileName,
+     *   DWORD dwFileAttributes
+     */
+    static void SetFileAttributes(String path, int dwFileAttributes)
+        throws WindowsException
+    {
+        NativeBuffer buffer = asNativeBuffer(path);
+        try {
+            SetFileAttributes0(buffer.address(), dwFileAttributes);
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native void SetFileAttributes0(long lpFileName,
+        int dwFileAttributes) throws WindowsException;
+
+    /**
+     * GetFileAttributesEx(
+     *   LPCTSTR lpFileName,
+     *   GET_FILEEX_INFO_LEVELS fInfoLevelId,
+     *   LPVOID lpFileInformation
+     * );
+     */
+    static void GetFileAttributesEx(String path, long address) throws WindowsException {
+        NativeBuffer buffer = asNativeBuffer(path);
+        try {
+            GetFileAttributesEx0(buffer.address(), address);
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native void GetFileAttributesEx0(long lpFileName, long address)
+        throws WindowsException;
+    /**
+     * SetFileTime(
+     *   HANDLE hFile,
+     *   CONST FILETIME *lpCreationTime,
+     *   CONST FILETIME *lpLastAccessTime,
+     *   CONST FILETIME *lpLastWriteTime
+     * )
+     */
+    static native void SetFileTime(long handle, long createTime,
+        long lastAccessTime, long lastWriteTime) throws WindowsException;
+
+    /**
+     * SetEndOfFile(
+     *   HANDLE hFile
+     * )
+     */
+    static native void SetEndOfFile(long handle) throws WindowsException;
+
+    /**
+     * DWORD GetLogicalDrives(VOID)
+     */
+    static native int GetLogicalDrives() throws WindowsException;
+
+    /**
+     * GetVolumeInformation(
+     *   LPCTSTR lpRootPathName,
+     *   LPTSTR lpVolumeNameBuffer,
+     *   DWORD nVolumeNameSize,
+     *   LPDWORD lpVolumeSerialNumber,
+     *   LPDWORD lpMaximumComponentLength,
+     *   LPDWORD lpFileSystemFlags,
+     *   LPTSTR lpFileSystemNameBuffer,
+     *   DWORD nFileSystemNameSize
+     * )
+     */
+    static VolumeInformation GetVolumeInformation(String root)
+        throws WindowsException
+    {
+        NativeBuffer buffer = asNativeBuffer(root);
+        try {
+            VolumeInformation info = new VolumeInformation();
+            GetVolumeInformation0(buffer.address(), info);
+            return info;
+        } finally {
+            buffer.release();
+        }
+    }
+    static class VolumeInformation {
+        private String fileSystemName;
+        private String volumeName;
+        private int volumeSerialNumber;
+        private int flags;
+        private VolumeInformation() { }
+
+        public String fileSystemName()      { return fileSystemName; }
+        public String volumeName()          { return volumeName; }
+        public int volumeSerialNumber()     { return volumeSerialNumber; }
+        public int flags()                  { return flags; }
+    }
+    private static native void GetVolumeInformation0(long lpRoot,
+                                                     VolumeInformation obj)
+        throws WindowsException;
+
+    /**
+     * UINT GetDriveType(
+     *   LPCTSTR lpRootPathName
+     * )
+     */
+    static int GetDriveType(String root) throws WindowsException {
+        NativeBuffer buffer = asNativeBuffer(root);
+        try {
+            return GetDriveType0(buffer.address());
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native int GetDriveType0(long lpRoot) throws WindowsException;
+
+    /**
+     * GetDiskFreeSpaceEx(
+     *   LPCTSTR lpDirectoryName,
+     *   PULARGE_INTEGER lpFreeBytesAvailableToCaller,
+     *   PULARGE_INTEGER lpTotalNumberOfBytes,
+     *   PULARGE_INTEGER lpTotalNumberOfFreeBytes
+     * )
+     */
+    static DiskFreeSpace GetDiskFreeSpaceEx(String path)
+        throws WindowsException
+    {
+        NativeBuffer buffer = asNativeBuffer(path);
+        try {
+            DiskFreeSpace space = new DiskFreeSpace();
+            GetDiskFreeSpaceEx0(buffer.address(), space);
+            return space;
+        } finally {
+            buffer.release();
+        }
+    }
+    static class DiskFreeSpace {
+        private long freeBytesAvailable;
+        private long totalNumberOfBytes;
+        private long totalNumberOfFreeBytes;
+        private DiskFreeSpace() { }
+
+        public long freeBytesAvailable()      { return freeBytesAvailable; }
+        public long totalNumberOfBytes()      { return totalNumberOfBytes; }
+        public long totalNumberOfFreeBytes()  { return totalNumberOfFreeBytes; }
+    }
+    private static native void GetDiskFreeSpaceEx0(long lpDirectoryName,
+                                                   DiskFreeSpace obj)
+        throws WindowsException;
+
+
+    /**
+     * GetVolumePathName(
+     *   LPCTSTR lpszFileName,
+     *   LPTSTR lpszVolumePathName,
+     *   DWORD cchBufferLength
+     * )
+     *
+     * @return  lpFileName
+     */
+    static String GetVolumePathName(String path) throws WindowsException {
+        NativeBuffer buffer = asNativeBuffer(path);
+        try {
+            return GetVolumePathName0(buffer.address());
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native String GetVolumePathName0(long lpFileName)
+        throws WindowsException;
+
+
+    /**
+     * InitializeSecurityDescriptor(
+     *   PSECURITY_DESCRIPTOR pSecurityDescriptor,
+     *   DWORD dwRevision
+     * )
+     */
+    static native void InitializeSecurityDescriptor(long sdAddress)
+        throws WindowsException;
+
+    /**
+     * InitializeAcl(
+     *   PACL pAcl,
+     *   DWORD nAclLength,
+     *   DWORD dwAclRevision
+     * )
+     */
+    static native void InitializeAcl(long aclAddress, int size)
+         throws WindowsException;
+
+    /**
+     * GetFileSecurity(
+     *   LPCTSTR lpFileName,
+     *   SECURITY_INFORMATION RequestedInformation,
+     *   PSECURITY_DESCRIPTOR pSecurityDescriptor,
+     *   DWORD nLength,
+     *   LPDWORD lpnLengthNeeded
+     * )
+     */
+    static int GetFileSecurity(String path,
+                               int requestedInformation,
+                               long pSecurityDescriptor,
+                               int nLength) throws WindowsException
+    {
+        NativeBuffer buffer = asNativeBuffer(path);
+        try {
+            return GetFileSecurity0(buffer.address(), requestedInformation,
+                pSecurityDescriptor, nLength);
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native int GetFileSecurity0(long lpFileName,
+                                               int requestedInformation,
+                                               long pSecurityDescriptor,
+                                               int nLength) throws WindowsException;
+
+    /**
+     * SetFileSecurity(
+     *   LPCTSTR lpFileName,
+     *   SECURITY_INFORMATION SecurityInformation,
+     *   PSECURITY_DESCRIPTOR pSecurityDescriptor
+     * )
+     */
+    static void SetFileSecurity(String path,
+                                int securityInformation,
+                                long pSecurityDescriptor)
+        throws WindowsException
+    {
+        NativeBuffer buffer = asNativeBuffer(path);
+        try {
+            SetFileSecurity0(buffer.address(), securityInformation,
+                pSecurityDescriptor);
+        } finally {
+            buffer.release();
+        }
+    }
+    static native void SetFileSecurity0(long lpFileName, int securityInformation,
+        long pSecurityDescriptor) throws WindowsException;
+
+    /**
+     * GetSecurityDescriptorOwner(
+     *   PSECURITY_DESCRIPTOR pSecurityDescriptor
+     *   PSID *pOwner,
+     *   LPBOOL lpbOwnerDefaulted
+     * )
+     *
+     * @return  pOwner
+     */
+    static native long GetSecurityDescriptorOwner(long pSecurityDescriptor)
+        throws WindowsException;
+
+    /**
+     * SetSecurityDescriptorOwner(
+     *   PSECURITY_DESCRIPTOR pSecurityDescriptor,
+     *   PSID pOwner,
+     *   BOOL bOwnerDefaulted
+     * )
+     */
+    static native void SetSecurityDescriptorOwner(long pSecurityDescriptor,
+                                                  long pOwner)
+        throws WindowsException;
+
+    /**
+     * GetSecurityDescriptorDacl(
+     *   PSECURITY_DESCRIPTOR pSecurityDescriptor,
+     *   LPBOOL lpbDaclPresent,
+     *   PACL *pDacl,
+     *   LPBOOL lpbDaclDefaulted
+     * )
+     */
+    static native long GetSecurityDescriptorDacl(long pSecurityDescriptor);
+
+    /**
+     * SetSecurityDescriptorDacl(
+     *   PSECURITY_DESCRIPTOR pSecurityDescriptor,
+     *   BOOL bDaclPresent,
+     *   PACL pDacl,
+     *   BOOL bDaclDefaulted
+     * )
+     */
+    static native void SetSecurityDescriptorDacl(long pSecurityDescriptor, long pAcl)
+        throws WindowsException;
+
+
+    /**
+     * GetAclInformation(
+     *   PACL pAcl,
+     *   LPVOID pAclInformation,
+     *   DWORD nAclInformationLength,
+     *   ACL_INFORMATION_CLASS dwAclInformationClass
+     * )
+     */
+    static AclInformation GetAclInformation(long aclAddress) {
+        AclInformation info = new AclInformation();
+        GetAclInformation0(aclAddress, info);
+        return info;
+    }
+    static class AclInformation {
+        private int aceCount;
+        private AclInformation() { }
+
+        public int aceCount()   { return aceCount; }
+    }
+    private static native void GetAclInformation0(long aclAddress,
+        AclInformation obj);
+
+    /**
+     * GetAce(
+     *   PACL pAcl,
+     *   DWORD dwAceIndex,
+     *   LPVOID *pAce
+     * )
+     */
+    static native long GetAce(long aclAddress, int aceIndex);
+
+    /**
+     * AddAccessAllowedAceEx(
+     *   PACL pAcl,
+     *   DWORD dwAceRevision,
+     *   DWORD AceFlags,
+     *   DWORD AccessMask,
+     *   PSID pSid
+     * )
+     */
+    static native void AddAccessAllowedAceEx(long aclAddress, int flags,
+        int mask, long sidAddress) throws WindowsException;
+
+    /**
+     * AddAccessDeniedAceEx(
+     *   PACL pAcl,
+     *   DWORD dwAceRevision,
+     *   DWORD AceFlags,
+     *   DWORD AccessMask,
+     *   PSID pSid
+     * )
+     */
+    static native void AddAccessDeniedAceEx(long aclAddress, int flags,
+        int mask, long sidAddress) throws WindowsException;
+
+    /**
+     * LookupAccountSid(
+     *   LPCTSTR lpSystemName,
+     *   PSID Sid,
+     *   LPTSTR Name,
+     *   LPDWORD cbName,
+     *   LPTSTR ReferencedDomainName,
+     *   LPDWORD cbReferencedDomainName,
+     *   PSID_NAME_USE peUse
+     * )
+     */
+    static Account LookupAccountSid(long sidAddress) throws WindowsException {
+        Account acc = new Account();
+        LookupAccountSid0(sidAddress, acc);
+        return acc;
+    }
+    static class Account {
+        private String domain;
+        private String name;
+        private int use;
+        private Account() { }
+
+        public String domain()  { return domain; }
+        public String name()    { return name; }
+        public int use()        { return use; }
+    }
+    private static native void LookupAccountSid0(long sidAddress, Account obj)
+        throws WindowsException;
+
+    /**
+     * LookupAccountName(
+     *   LPCTSTR lpSystemName,
+     *   LPCTSTR lpAccountName,
+     *   PSID Sid,
+     *   LPDWORD cbSid,
+     *   LPTSTR ReferencedDomainName,
+     *   LPDWORD cbReferencedDomainName,
+     *   PSID_NAME_USE peUse
+     * )
+     *
+     * @return  cbSid
+     */
+    static int LookupAccountName(String accountName,
+                                 long pSid,
+                                 int cbSid) throws WindowsException
+    {
+        NativeBuffer buffer = asNativeBuffer(accountName);
+        try {
+            return LookupAccountName0(buffer.address(), pSid, cbSid);
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native int LookupAccountName0(long lpAccountName, long pSid,
+        int cbSid) throws WindowsException;
+
+    /**
+     * DWORD GetLengthSid(
+     *   PSID pSid
+     * )
+     */
+    static native int GetLengthSid(long sidAddress);
+
+    /**
+     * ConvertSidToStringSid(
+     *   PSID Sid,
+     *   LPTSTR* StringSid
+     * )
+     *
+     * @return  StringSid
+     */
+    static native String ConvertSidToStringSid(long sidAddress)
+        throws WindowsException;
+
+    /**
+     * ConvertStringSidToSid(
+     *   LPCTSTR StringSid,
+     *   PSID* pSid
+     * )
+     *
+     * @return  pSid
+     */
+    static long ConvertStringSidToSid(String sidString)
+        throws WindowsException
+    {
+        NativeBuffer buffer = asNativeBuffer(sidString);
+        try {
+            return ConvertStringSidToSid0(buffer.address());
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native long ConvertStringSidToSid0(long lpStringSid)
+        throws WindowsException;
+
+    /**
+     * HANDLE GetCurrentProcess(VOID)
+     */
+    static native long GetCurrentProcess();
+
+    /**
+     * HANDLE GetCurrentThread(VOID)
+     */
+    static native long GetCurrentThread();
+
+    /**
+     * OpenProcessToken(
+     *   HANDLE ProcessHandle,
+     *   DWORD DesiredAccess,
+     *   PHANDLE TokenHandle
+     * )
+     */
+    static native long OpenProcessToken(long hProcess, int desiredAccess)
+        throws WindowsException;
+
+    /**
+     * OpenThreadToken(
+     *   HANDLE ThreadHandle,
+     *   DWORD DesiredAccess,
+     *   BOOL OpenAsSelf,
+     *   PHANDLE TokenHandle
+     * )
+     */
+    static native long OpenThreadToken(long hThread, int desiredAccess,
+        boolean openAsSelf) throws WindowsException;
+
+    /**
+     */
+    static native long DuplicateTokenEx(long hThread, int desiredAccess)
+        throws WindowsException;
+
+    /**
+     * SetThreadToken(
+     *   PHANDLE Thread,
+     *   HANDLE Token
+     * )
+     */
+    static native void SetThreadToken(long thread, long hToken)
+        throws WindowsException;
+
+    /**
+     * GetTokenInformation(
+     *   HANDLE TokenHandle,
+     *   TOKEN_INFORMATION_CLASS TokenInformationClass,
+     *   LPVOID TokenInformation,
+     *   DWORD TokenInformationLength,
+     *   PDWORD ReturnLength
+     * )
+     */
+    static native int GetTokenInformation(long token, int tokenInfoClass,
+        long pTokenInfo, int tokenInfoLength) throws WindowsException;
+
+    /**
+     * AdjustTokenPrivileges(
+     *   HANDLE TokenHandle,
+     *   BOOL DisableAllPrivileges
+     *   PTOKEN_PRIVILEGES NewState
+     *   DWORD BufferLength
+     *   PTOKEN_PRIVILEGES
+     *   PDWORD ReturnLength
+     * )
+     */
+    static native void AdjustTokenPrivileges(long token, long luid, int attributes)
+        throws WindowsException;
+
+    /**
+     */
+    static long LookupPrivilegeValue(String name) throws WindowsException {
+        NativeBuffer buffer = asNativeBuffer(name);
+        try {
+            return LookupPrivilegeValue0(buffer.address());
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native long LookupPrivilegeValue0(long lpName)
+        throws WindowsException;
+
+    /**
+     * BuildTrusteeWithSid(
+     *   PTRUSTEE pTrustee,
+     *   PSID pSid
+     * )
+     *
+     * @return  pTrustee
+     */
+    static native long BuildTrusteeWithSid(long pSid);
+
+    /**
+     * GetEffectiveRightsFromAcl(
+     *   PACL pacl,
+     *   PTRUSTEE pTrustee,
+     *   PACCESS_MASK pAccessRights
+     * )
+     *
+     * @return  AccessRights
+     */
+    static native int GetEffectiveRightsFromAcl(long pAcl, long pTrustee)
+        throws WindowsException;
+
+    /**
+     * CreateSymbolicLink(
+     *   LPCWSTR lpSymlinkFileName,
+     *   LPCWSTR lpTargetFileName,
+     *   DWORD dwFlags
+     * )
+     */
+    static void CreateSymbolicLink(String link, String target, int flags)
+        throws WindowsException
+    {
+        NativeBuffer linkBuffer = asNativeBuffer(link);
+        NativeBuffer targetBuffer = asNativeBuffer(target);
+        try {
+            CreateSymbolicLink0(linkBuffer.address(), targetBuffer.address(),
+                                flags);
+        } finally {
+            targetBuffer.release();
+            linkBuffer.release();
+        }
+    }
+    private static native void CreateSymbolicLink0(long linkAddress,
+        long targetAddress, int flags) throws WindowsException;
+
+    /**
+     * CreateHardLink(
+     *    LPCTSTR lpFileName,
+     *    LPCTSTR lpExistingFileName,
+     *    LPSECURITY_ATTRIBUTES lpSecurityAttributes
+     * )
+     */
+    static void CreateHardLink(String newFile, String existingFile)
+        throws WindowsException
+    {
+        NativeBuffer newFileBuffer = asNativeBuffer(newFile);
+        NativeBuffer existingFileBuffer = asNativeBuffer(existingFile);
+        try {
+            CreateHardLink0(newFileBuffer.address(), existingFileBuffer.address());
+        } finally {
+            existingFileBuffer.release();
+            newFileBuffer.release();
+        }
+    }
+    private static native void CreateHardLink0(long newFileBuffer,
+        long existingFiletBuffer) throws WindowsException;
+
+    /**
+     * GetFullPathName(
+     *   LPCTSTR lpFileName,
+     *   DWORD nBufferLength,
+     *   LPTSTR lpBuffer,
+     *   LPTSTR *lpFilePart
+     * )
+     */
+    static String GetFullPathName(String path) throws WindowsException {
+        NativeBuffer buffer = asNativeBuffer(path);
+        try {
+            return GetFullPathName0(buffer.address());
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native String GetFullPathName0(long pathAddress)
+        throws WindowsException;
+
+    /**
+     * GetFinalPathNameByHandle(
+     *   HANDLE hFile,
+     *   LPTSTR lpszFilePath,
+     *   DWORD cchFilePath,
+     *   DWORD dwFlags
+     * )
+     */
+    static native String GetFinalPathNameByHandle(long handle)
+        throws WindowsException;
+
+    /**
+     * FormatMessage(
+     *   DWORD dwFlags,
+     *   LPCVOID lpSource,
+     *   DWORD dwMessageId,
+     *   DWORD dwLanguageId,
+     *   LPTSTR lpBuffer,
+     *   DWORD nSize,
+     *   va_list *Arguments
+     * )
+     */
+    static native String FormatMessage(int errorCode);
+
+    /**
+     * LocalFree(
+     *   HLOCAL hMem
+     * )
+     */
+    static native void LocalFree(long address);
+
+    /**
+     * HANDLE CreateIoCompletionPort (
+     *   HANDLE FileHandle,
+     *   HANDLE ExistingCompletionPort,
+     *   DWORD CompletionKey,
+     *   DWORD NumberOfConcurrentThreads
+     * )
+     */
+    static native long CreateIoCompletionPort(long fileHandle, long existingPort,
+        int completionKey) throws WindowsException;
+
+
+    /**
+     * GetQueuedCompletionStatus(
+     *   HANDLE CompletionPort,
+     *   LPDWORD lpNumberOfBytesTransferred,
+     *   LPDWORD lpCompletionKey,
+     *   LPOVERLAPPED *lpOverlapped,
+     *   DWORD dwMilliseconds
+     */
+    static CompletionStatus GetQueuedCompletionStatus(long completionPort)
+        throws WindowsException
+    {
+        CompletionStatus status = new CompletionStatus();
+        GetQueuedCompletionStatus0(completionPort, status);
+        return status;
+    }
+    static class CompletionStatus {
+        private int error;
+        private int bytesTransferred;
+        private int completionKey;
+        private CompletionStatus() { }
+
+        int error() { return error; }
+        int bytesTransferred() { return bytesTransferred; }
+        int completionKey() { return completionKey; }
+    }
+    private static native void GetQueuedCompletionStatus0(long completionPort,
+        CompletionStatus status) throws WindowsException;
+
+    /**
+     * PostQueuedCompletionStatus(
+     *   HANDLE CompletionPort,
+     *   DWORD dwNumberOfBytesTransferred,
+     *   DWORD dwCompletionKey,
+     *   LPOVERLAPPED lpOverlapped
+     * )
+     */
+    static native void PostQueuedCompletionStatus(long completionPort,
+        int completionKey) throws WindowsException;
+
+    /**
+     * ReadDirectoryChangesW(
+     *   HANDLE hDirectory,
+     *   LPVOID lpBuffer,
+     *   DWORD nBufferLength,
+     *   BOOL bWatchSubtree,
+     *   DWORD dwNotifyFilter,
+     *   LPDWORD lpBytesReturned,
+     *   LPOVERLAPPED lpOverlapped,
+     *   LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
+     * )
+     */
+    static native void ReadDirectoryChangesW(long hDirectory,
+                                             long bufferAddress,
+                                             int bufferLength,
+                                             boolean watchSubTree,
+                                             int filter,
+                                             long bytesReturnedAddress,
+                                             long pOverlapped)
+        throws WindowsException;
+
+    /**
+     * BackupRead(
+     *   HANDLE hFile,
+     *   LPBYTE lpBuffer,
+     *   DWORD nNumberOfBytesToRead,
+     *   LPDWORD lpNumberOfBytesRead,
+     *   BOOL bAbort,
+     *   BOOL bProcessSecurity,
+     *   LPVOID* lpContext
+     * )
+     */
+    static BackupResult BackupRead(long hFile,
+                                   long bufferAddress,
+                                   int bufferSize,
+                                   boolean abort,
+                                   long context)
+        throws WindowsException
+    {
+        BackupResult result = new BackupResult();
+        BackupRead0(hFile, bufferAddress, bufferSize, abort, context, result);
+        return result;
+    }
+    static class BackupResult {
+        private int bytesTransferred;
+        private long context;
+        private BackupResult() { }
+
+        int bytesTransferred() { return bytesTransferred; }
+        long context() { return context; }
+    }
+    private static native void BackupRead0(long hFile, long bufferAddress,
+        int bufferSize, boolean abort, long context, BackupResult result)
+        throws WindowsException;
+
+    /**
+     * BackupSeek(
+     *   HANDLE hFile,
+     *   DWORD dwLowBytesToSeek,
+     *   DWORD dwHighBytesToSeek,
+     *   LPDWORD lpdwLowByteSeeked,
+     *   LPDWORD lpdwHighByteSeeked,
+     *   LPVOID* lpContext
+     * )
+     */
+    static native void BackupSeek(long hFile, long bytesToSeek, long context)
+        throws WindowsException;
+
+
+    // -- support for copying String with a NativeBuffer --
+
+    private static final Unsafe unsafe = Unsafe.getUnsafe();
+
+    static NativeBuffer asNativeBuffer(String s) {
+        int stringLengthInBytes = s.length() << 1;
+        int sizeInBytes = stringLengthInBytes + 2;  // char terminator
+
+        // get a native buffer of sufficient size
+        NativeBuffer buffer = NativeBuffers.getNativeBufferFromCache(sizeInBytes);
+        if (buffer == null) {
+            buffer = NativeBuffers.allocNativeBuffer(sizeInBytes);
+        } else {
+            // buffer already contains the string contents
+            if (buffer.owner() == s)
+                return buffer;
+        }
+
+        // copy into buffer and zero terminate
+        char[] chars = s.toCharArray();
+        unsafe.copyMemory(chars, Unsafe.ARRAY_CHAR_BASE_OFFSET, null,
+            buffer.address(), (long)stringLengthInBytes);
+        unsafe.putChar(buffer.address() + stringLengthInBytes, (char)0);
+        buffer.setOwner(s);
+        return buffer;
+    }
+
+    // -- native library initialization --
+
+    private static native void initIDs();
+
+    static {
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+            public Void run() {
+                // nio.dll has dependency on net.dll
+                System.loadLibrary("net");
+                System.loadLibrary("nio");
+                return null;
+        }});
+        initIDs();
+    }
+
+}
diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsPath.java b/jdk/src/windows/classes/sun/nio/fs/WindowsPath.java
new file mode 100644
index 0000000..2fda59d
--- /dev/null
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsPath.java
@@ -0,0 +1,1375 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.nio.file.spi.AbstractPath;
+import java.nio.channels.*;
+import java.io.*;
+import java.net.URI;
+import java.security.AccessController;
+import java.util.*;
+import java.lang.ref.WeakReference;
+
+import com.sun.nio.file.ExtendedWatchEventModifier;
+
+import sun.security.util.SecurityConstants;
+import sun.misc.Unsafe;
+
+import static sun.nio.fs.WindowsNativeDispatcher.*;
+import static sun.nio.fs.WindowsConstants.*;
+
+/**
+ * Windows implementation of Path
+ */
+
+class WindowsPath extends AbstractPath {
+    private static final Unsafe unsafe = Unsafe.getUnsafe();
+
+    // The maximum path that does not require long path prefix. On Windows
+    // the maximum path is 260 minus 1 (NUL) but for directories it is 260
+    // minus 12 minus 1 (to allow for the creation of a 8.3 file in the
+    // directory).
+    private static final int MAX_PATH = 247;
+
+    // Maximum extended-length path
+    private static final int MAX_LONG_PATH = 32000;
+
+    // FIXME - eliminate this reference to reduce space
+    private final WindowsFileSystem fs;
+
+    // path type
+    private final WindowsPathType type;
+    // root component (may be empty)
+    private final String root;
+    // normalized path
+    private final String path;
+
+    // the path to use in Win32 calls. This differs from path for relative
+    // paths and has a long path prefix for all paths longer than MAX_PATH.
+    private volatile WeakReference<String> pathForWin32Calls;
+
+    // offsets into name components (computed lazily)
+    private volatile Integer[] offsets;
+
+    // computed hash code (computed lazily, no need to be volatile)
+    private int hash;
+
+
+    /**
+     * Initializes a new instance of this class.
+     */
+    private WindowsPath(WindowsFileSystem fs,
+                        WindowsPathType type,
+                        String root,
+                        String path)
+    {
+        this.fs = fs;
+        this.type = type;
+        this.root = root;
+        this.path = path;
+    }
+
+    /**
+     * Creates a Path by parsing the given path.
+     */
+    static WindowsPath parse(WindowsFileSystem fs, String path) {
+        WindowsPathParser.Result result = WindowsPathParser.parse(path);
+        return new WindowsPath(fs, result.type(), result.root(), result.path());
+    }
+
+    /**
+     * Creates a Path from a given path that is known to be normalized.
+     */
+    static WindowsPath createFromNormalizedPath(WindowsFileSystem fs,
+                                                String path,
+                                                BasicFileAttributes attrs)
+    {
+        try {
+            WindowsPathParser.Result result =
+                WindowsPathParser.parseNormalizedPath(path);
+            if (attrs == null) {
+                return new WindowsPath(fs,
+                                       result.type(),
+                                       result.root(),
+                                       result.path());
+            } else {
+                return new WindowsPathWithAttributes(fs,
+                                                     result.type(),
+                                                     result.root(),
+                                                     result.path(),
+                                                     attrs);
+            }
+        } catch (InvalidPathException x) {
+            throw new AssertionError(x.getMessage());
+        }
+    }
+
+    /**
+     * Creates a WindowsPath from a given path that is known to be normalized.
+     */
+    static WindowsPath createFromNormalizedPath(WindowsFileSystem fs,
+                                                String path)
+    {
+        return createFromNormalizedPath(fs, path, null);
+    }
+
+    /**
+     * Special implementation with attached/cached attributes (used to quicken
+     * file tree traveral)
+     */
+    private static class WindowsPathWithAttributes
+        extends WindowsPath implements BasicFileAttributesHolder
+    {
+        final WeakReference<BasicFileAttributes> ref;
+
+        WindowsPathWithAttributes(WindowsFileSystem fs,
+                                  WindowsPathType type,
+                                  String root,
+                                  String path,
+                                  BasicFileAttributes attrs)
+        {
+            super(fs, type, root, path);
+            ref = new WeakReference<BasicFileAttributes>(attrs);
+        }
+
+        @Override
+        public BasicFileAttributes get() {
+            return ref.get();
+        }
+
+        @Override
+        public void invalidate() {
+            ref.clear();
+        }
+    }
+
+    // use this message when throwing exceptions
+    String getPathForExceptionMessage() {
+        return path;
+    }
+
+    // use this path for permission checks
+    String getPathForPermissionCheck() {
+        return path;
+    }
+
+    // use this path for Win32 calls
+    // This method will prefix long paths with \\?\ or \\?\UNC as required.
+    String getPathForWin32Calls() throws WindowsException {
+        // short absolute paths can be used directly
+        if (isAbsolute() && path.length() <= MAX_PATH)
+            return path;
+
+        // return cached values if available
+        WeakReference<String> ref = pathForWin32Calls;
+        String resolved = (ref != null) ? ref.get() : null;
+        if (resolved != null) {
+            // Win32 path already available
+            return resolved;
+        }
+
+        // resolve against default directory
+        resolved = getAbsolutePath();
+
+        // Long paths need to have "." and ".." removed and be prefixed with
+        // "\\?\". Note that it is okay to remove ".." even when it follows
+        // a link - for example, it is okay for foo/link/../bar to be changed
+        // to foo/bar. The reason is that Win32 APIs to access foo/link/../bar
+        // will access foo/bar anyway (which differs to Unix systems)
+        if (resolved.length() > MAX_PATH) {
+            if (resolved.length() > MAX_LONG_PATH) {
+                throw new WindowsException("Cannot access file with path exceeding "
+                    + MAX_LONG_PATH + " characters");
+            }
+            resolved = addPrefixIfNeeded(GetFullPathName(resolved));
+        }
+
+        // cache the resolved path (except drive relative paths as the working
+        // directory on removal media devices can change during the lifetime
+        // of the VM)
+        if (type != WindowsPathType.DRIVE_RELATIVE) {
+            synchronized (path) {
+                pathForWin32Calls = new WeakReference<String>(resolved);
+            }
+        }
+        return resolved;
+    }
+
+    // return this path resolved against the file system's default directory
+    private String getAbsolutePath() throws WindowsException {
+        if (isAbsolute())
+            return path;
+
+        // Relative path ("foo" for example)
+        if (type == WindowsPathType.RELATIVE) {
+            String defaultDirectory = getFileSystem().defaultDirectory();
+            if (defaultDirectory.endsWith("\\")) {
+                return defaultDirectory + path;
+            } else {
+                StringBuilder sb =
+                    new StringBuilder(defaultDirectory.length() + path.length() + 1);
+                return sb.append(defaultDirectory).append('\\').append(path).toString();
+            }
+        }
+
+        // Directory relative path ("\foo" for example)
+        if (type == WindowsPathType.DIRECTORY_RELATIVE) {
+            String defaultRoot = getFileSystem().defaultRoot();
+            return defaultRoot + path.substring(1);
+        }
+
+        // Drive relative path ("C:foo" for example).
+        if (isSameDrive(root, getFileSystem().defaultRoot())) {
+            // relative to default directory
+            String remaining = path.substring(root.length());
+            String defaultDirectory = getFileSystem().defaultDirectory();
+            String result;
+            if (defaultDirectory.endsWith("\\")) {
+                result = defaultDirectory + remaining;
+            } else {
+                result = defaultDirectory + "\\" + remaining;
+            }
+            return result;
+        } else {
+            // relative to some other drive
+            String wd;
+            try {
+                int dt = GetDriveType(root + "\\");
+                if (dt == DRIVE_UNKNOWN || dt == DRIVE_NO_ROOT_DIR)
+                    throw new WindowsException("");
+                wd = GetFullPathName(root + ".");
+            } catch (WindowsException x) {
+                throw new WindowsException("Unable to get working directory of drive '" +
+                    Character.toUpperCase(root.charAt(0)) + "'");
+            }
+            String result = wd;
+            if (wd.endsWith("\\")) {
+                result += path.substring(root.length());
+            } else {
+                if (path.length() > root.length())
+                    result += "\\" + path.substring(root.length());
+            }
+            return result;
+        }
+    }
+
+    // returns true if same drive letter
+    private static boolean isSameDrive(String root1, String root2) {
+        return Character.toUpperCase(root1.charAt(0)) ==
+               Character.toUpperCase(root2.charAt(0));
+    }
+
+    // Add long path prefix to path if required
+    private static String addPrefixIfNeeded(String path) {
+        if (path.length() > 248) {
+            if (path.startsWith("\\\\")) {
+                path = "\\\\?\\UNC" + path.substring(1, path.length());
+            } else {
+                path = "\\\\?\\" + path;
+            }
+        }
+        return path;
+    }
+
+    @Override
+    public WindowsFileSystem getFileSystem() {
+        return fs;
+    }
+
+    // -- Path operations --
+
+    @Override
+    public Path getName() {
+        // represents root component only
+        if (root.length() == path.length())
+            return null;
+        int off = path.lastIndexOf('\\');
+        if (off < root.length())
+            off = root.length();
+        else
+            off++;
+        return new WindowsPath(getFileSystem(), WindowsPathType.RELATIVE, "", path.substring(off));
+    }
+
+    @Override
+    public WindowsPath getParent() {
+        // represents root component only
+        if (root.length() == path.length())
+            return null;
+        int off = path.lastIndexOf('\\');
+        if (off < root.length())
+            return getRoot();
+        else
+            return new WindowsPath(getFileSystem(),
+                                   type,
+                                   root,
+                                   path.substring(0, off));
+    }
+
+    @Override
+    public WindowsPath getRoot() {
+        if (root.length() == 0)
+            return null;
+        return new WindowsPath(getFileSystem(), type, root, root);
+    }
+
+    // package-private
+    boolean isUnc() {
+        return type == WindowsPathType.UNC;
+    }
+
+    boolean needsSlashWhenResolving() {
+        if (path.endsWith("\\"))
+            return false;
+        return path.length() > root.length();
+    }
+
+    @Override
+    public boolean isAbsolute() {
+        return type == WindowsPathType.ABSOLUTE || type == WindowsPathType.UNC;
+    }
+
+    private WindowsPath checkPath(FileRef path) {
+        if (path == null)
+            throw new NullPointerException();
+        if (!(path instanceof WindowsPath)) {
+            throw new ProviderMismatchException();
+        }
+        return (WindowsPath)path;
+    }
+
+    @Override
+    public WindowsPath relativize(Path obj) {
+        WindowsPath other = checkPath(obj);
+        if (this.equals(other))
+            return null;
+
+        // can only relativize paths of the same type
+        if (this.type != other.type)
+            throw new IllegalArgumentException("'other' is different type of Path");
+
+        // can only relativize paths if root component matches
+        if (!this.root.equalsIgnoreCase(other.root))
+            throw new IllegalArgumentException("'other' has different root");
+
+        int bn = this.getNameCount();
+        int cn = other.getNameCount();
+
+        // skip matching names
+        int n = (bn > cn) ? cn : bn;
+        int i = 0;
+        while (i < n) {
+            if (!this.getName(i).equals(other.getName(i)))
+                break;
+            i++;
+        }
+
+        // append ..\ for remaining names in the base
+        StringBuilder result = new StringBuilder();
+        for (int j=i; j<bn; j++) {
+            result.append("..\\");
+        }
+
+        // append remaining names in child
+        for (int j=i; j<cn; j++) {
+            result.append(other.getName(j).toString());
+            result.append("\\");
+        }
+
+        // drop trailing slash in result
+        result.setLength(result.length()-1);
+        return createFromNormalizedPath(getFileSystem(), result.toString());
+    }
+
+    @Override
+    public Path normalize() {
+        final int count = getNameCount();
+        if (count == 0)
+            return this;
+
+        boolean[] ignore = new boolean[count];      // true => ignore name
+        int remaining = count;                      // number of names remaining
+
+        // multiple passes to eliminate all occurences of "." and "name/.."
+        int prevRemaining;
+        do {
+            prevRemaining = remaining;
+            int prevName = -1;
+            for (int i=0; i<count; i++) {
+                if (ignore[i])
+                    continue;
+
+                String name = elementAsString(i);
+
+                // not "." or ".."
+                if (name.length() > 2) {
+                    prevName = i;
+                    continue;
+                }
+
+                // "." or something else
+                if (name.length() == 1) {
+                    // ignore "."
+                    if (name.charAt(0) == '.') {
+                        ignore[i] = true;
+                        remaining--;
+                    } else {
+                        prevName = i;
+                    }
+                    continue;
+                }
+
+                // not ".."
+                if (name.charAt(0) != '.' || name.charAt(1) != '.') {
+                    prevName = i;
+                    continue;
+                }
+
+                // ".." found
+                if (prevName >= 0) {
+                    // name/<ignored>/.. found so mark name and ".." to be
+                    // ignored
+                    ignore[prevName] = true;
+                    ignore[i] = true;
+                    remaining = remaining - 2;
+                    prevName = -1;
+                } else {
+                    // Cases:
+                    //    C:\<ignored>\..
+                    //    \\server\\share\<ignored>\..
+                    //    \<ignored>..
+                    if (isAbsolute() || type == WindowsPathType.DIRECTORY_RELATIVE) {
+                        boolean hasPrevious = false;
+                        for (int j=0; j<i; j++) {
+                            if (!ignore[j]) {
+                                hasPrevious = true;
+                                break;
+                            }
+                        }
+                        if (!hasPrevious) {
+                            // all proceeding names are ignored
+                            ignore[i] = true;
+                            remaining--;
+                        }
+                    }
+                }
+            }
+        } while (prevRemaining > remaining);
+
+        // no redundant names
+        if (remaining == count)
+            return this;
+
+        // corner case - all names removed
+        if (remaining == 0) {
+            return getRoot();
+        }
+
+        // re-constitute the path from the remaining names.
+        StringBuilder result = new StringBuilder();
+        if (root != null)
+            result.append(root);
+        for (int i=0; i<count; i++) {
+            if (!ignore[i]) {
+                result.append(getName(i).toString());
+                result.append("\\");
+            }
+        }
+
+        // drop trailing slash in result
+        result.setLength(result.length()-1);
+        return createFromNormalizedPath(getFileSystem(), result.toString());
+    }
+
+    @Override
+    public WindowsPath resolve(Path obj) {
+        if (obj == null)
+            return this;
+        WindowsPath other = checkPath(obj);
+        if (other.isAbsolute())
+            return other;
+
+        switch (other.type) {
+            case RELATIVE: {
+                String result;
+                if (path.endsWith("\\") || (root.length() == path.length())) {
+                    result = path + other.path;
+                } else {
+                    result = path + "\\" + other.path;
+                }
+                return new WindowsPath(getFileSystem(), type, root, result);
+            }
+
+            case DIRECTORY_RELATIVE: {
+                String result;
+                if (root.endsWith("\\")) {
+                    result = root + other.path.substring(1);
+                } else {
+                    result = root + other.path;
+                }
+                return createFromNormalizedPath(getFileSystem(), result);
+            }
+
+            case DRIVE_RELATIVE: {
+                if (!root.endsWith("\\"))
+                    return other;
+                // if different roots then return other
+                String thisRoot = root.substring(0, root.length()-1);
+                if (!thisRoot.equalsIgnoreCase(other.root))
+                    return other;
+                // same roots
+                String remaining = other.path.substring(other.root.length());
+                String result;
+                if (path.endsWith("\\")) {
+                    result = path + remaining;
+                } else {
+                    result = path + "\\" + remaining;
+                }
+                return createFromNormalizedPath(getFileSystem(), result);
+            }
+
+            default:
+                throw new AssertionError();
+        }
+    }
+
+    @Override
+    public WindowsPath resolve(String other) {
+        return resolve(getFileSystem().getPath(other));
+    }
+
+    // generate offset array
+    private void initOffsets() {
+        if (offsets == null) {
+            ArrayList<Integer> list = new ArrayList<Integer>();
+            int start = root.length();
+            int off = root.length();
+            while (off < path.length()) {
+                if (path.charAt(off) != '\\') {
+                    off++;
+                } else {
+                    list.add(start);
+                    start = ++off;
+                }
+            }
+            if (start != off)
+                list.add(start);
+            synchronized (this) {
+                if (offsets == null)
+                    offsets = list.toArray(new Integer[list.size()]);
+            }
+        }
+    }
+
+    @Override
+    public int getNameCount() {
+        initOffsets();
+        return offsets.length;
+    }
+
+    private String elementAsString(int i) {
+        initOffsets();
+        if (i == (offsets.length-1))
+            return path.substring(offsets[i]);
+        return path.substring(offsets[i], offsets[i+1]-1);
+    }
+
+    @Override
+    public WindowsPath getName(int index) {
+        initOffsets();
+        if (index < 0 || index >= offsets.length)
+            throw new IllegalArgumentException();
+        return new WindowsPath(getFileSystem(), WindowsPathType.RELATIVE, "", elementAsString(index));
+    }
+
+    @Override
+    public WindowsPath subpath(int beginIndex, int endIndex) {
+        initOffsets();
+        if (beginIndex < 0)
+            throw new IllegalArgumentException();
+        if (beginIndex >= offsets.length)
+            throw new IllegalArgumentException();
+        if (endIndex > offsets.length)
+            throw new IllegalArgumentException();
+        if (beginIndex >= endIndex)
+            throw new IllegalArgumentException();
+
+        StringBuilder sb = new StringBuilder();
+        Integer[] nelems = new Integer[endIndex - beginIndex];
+        for (int i = beginIndex; i < endIndex; i++) {
+            nelems[i-beginIndex] = sb.length();
+            sb.append(elementAsString(i));
+            if (i != (endIndex-1))
+                sb.append("\\");
+        }
+        return new WindowsPath(getFileSystem(), WindowsPathType.RELATIVE, "", sb.toString());
+    }
+
+    @Override
+    public boolean startsWith(Path obj) {
+        WindowsPath other = checkPath(obj);
+
+        // if this path has a root component the given path's root must match
+        if (!this.root.equalsIgnoreCase(other.root))
+            return false;
+
+        // roots match so compare elements
+        int thisCount = getNameCount();
+        int otherCount = other.getNameCount();
+        if (otherCount <= thisCount) {
+            while (--otherCount >= 0) {
+                String thisElement = this.elementAsString(otherCount);
+                String otherElement = other.elementAsString(otherCount);
+                // FIXME: should compare in uppercase
+                if (!thisElement.equalsIgnoreCase(otherElement))
+                    return false;
+            }
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean endsWith(Path obj) {
+        WindowsPath other = checkPath(obj);
+
+        // other path is longer
+        if (other.path.length() > path.length()) {
+            return false;
+        }
+
+        int thisCount = this.getNameCount();
+        int otherCount = other.getNameCount();
+
+        // given path has more elements that this path
+        if (otherCount > thisCount) {
+            return false;
+        }
+
+        // compare roots
+        if (other.root.length() > 0) {
+            if (otherCount < thisCount)
+                return false;
+            // FIXME: should compare in uppercase
+            if (!this.root.equalsIgnoreCase(other.root))
+                return false;
+        }
+
+        // match last 'otherCount' elements
+        int off = thisCount - otherCount;
+        while (--otherCount >= 0) {
+            String thisElement = this.elementAsString(off + otherCount);
+            String otherElement = other.elementAsString(otherCount);
+            // FIXME: should compare in uppercase
+            if (!thisElement.equalsIgnoreCase(otherElement))
+                return false;
+        }
+        return true;
+    }
+
+    @Override
+    public int compareTo(Path obj) {
+        if (obj == null)
+            throw new NullPointerException();
+        String s1 = path;
+        String s2 = ((WindowsPath)obj).path;
+        int n1 = s1.length();
+        int n2 = s2.length();
+        int min = Math.min(n1, n2);
+        for (int i = 0; i < min; i++) {
+            char c1 = s1.charAt(i);
+            char c2 = s2.charAt(i);
+             if (c1 != c2) {
+                 c1 = Character.toUpperCase(c1);
+                 c2 = Character.toUpperCase(c2);
+                 if (c1 != c2) {
+                     return c1 - c2;
+                 }
+             }
+        }
+        return n1 - n2;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if ((obj != null) && (obj instanceof WindowsPath)) {
+            return compareTo((Path)obj) == 0;
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        // OK if two or more threads compute hash
+        int h = hash;
+        if (h == 0) {
+            for (int i = 0; i< path.length(); i++) {
+                h = 31*h + Character.toUpperCase(path.charAt(i));
+            }
+            hash = h;
+        }
+        return h;
+    }
+
+    @Override
+    public String toString() {
+        return path;
+    }
+
+    @Override
+    public Iterator<Path> iterator() {
+        return new Iterator<Path>() {
+            private int i = 0;
+            @Override
+            public boolean hasNext() {
+                return (i < getNameCount());
+            }
+            @Override
+            public Path next() {
+                if (i < getNameCount()) {
+                    Path result = getName(i);
+                    i++;
+                    return result;
+                } else {
+                    throw new NoSuchElementException();
+                }
+            }
+            @Override
+            public void remove() {
+                throw new UnsupportedOperationException();
+            }
+        };
+    }
+
+    // -- file operations --
+
+    // package-private
+    long openForReadAttributeAccess(boolean followLinks)
+        throws WindowsException
+    {
+        int flags = FILE_FLAG_BACKUP_SEMANTICS;
+        if (!followLinks && getFileSystem().supportsLinks())
+            flags |= FILE_FLAG_OPEN_REPARSE_POINT;
+        return CreateFile(getPathForWin32Calls(),
+                          FILE_READ_ATTRIBUTES,
+                          (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE),
+                          0L,
+                          OPEN_EXISTING,
+                          flags);
+    }
+
+    void checkRead() {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkRead(getPathForPermissionCheck());
+        }
+    }
+
+    void checkWrite() {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkWrite(getPathForPermissionCheck());
+        }
+    }
+
+    void checkDelete() {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkDelete(getPathForPermissionCheck());
+        }
+    }
+
+    @Override
+    public FileStore getFileStore()
+        throws IOException
+    {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(new RuntimePermission("getFileStoreAttributes"));
+            checkRead();
+        }
+        return WindowsFileStore.create(this);
+    }
+
+    /**
+     * Returns buffer with SID_AND_ATTRIBUTES structure representing the user
+     * associated with the current thread access token.
+     * FIXME - this should be cached.
+     */
+    private NativeBuffer getUserInfo() throws IOException {
+        try {
+            long hToken = WindowsSecurity.processTokenWithQueryAccess;
+            int size = GetTokenInformation(hToken, TokenUser, 0L, 0);
+            assert size > 0;
+
+            NativeBuffer buffer = NativeBuffers.getNativeBuffer(size);
+            try {
+                int newsize = GetTokenInformation(hToken, TokenUser,
+                                                  buffer.address(), size);
+                if (newsize != size)
+                    throw new AssertionError();
+                return buffer;
+            } catch (WindowsException x) {
+                buffer.release();
+                throw x;
+            }
+        } catch (WindowsException x) {
+            throw new IOException(x.getMessage());
+        }
+    }
+
+    /**
+     * Reads the file ACL and return the effective access as ACCESS_MASK
+     */
+    private int getEffectiveAccess() throws IOException {
+        // read security descriptor continaing ACL (symlinks are followed)
+        String target = WindowsLinkSupport.getFinalPath(this, true);
+        NativeBuffer aclBuffer = WindowsAclFileAttributeView
+            .getFileSecurity(target, DACL_SECURITY_INFORMATION);
+
+        // retrieves DACL from security descriptor
+        long pAcl = GetSecurityDescriptorDacl(aclBuffer.address());
+
+        // Use GetEffectiveRightsFromAcl to get effective access to file
+        try {
+            NativeBuffer userBuffer = getUserInfo();
+            try {
+                try {
+                    // SID_AND_ATTRIBUTES->pSid
+                    long pSid = unsafe.getAddress(userBuffer.address());
+                    long pTrustee = BuildTrusteeWithSid(pSid);
+                    try {
+                        return GetEffectiveRightsFromAcl(pAcl, pTrustee);
+                    } finally {
+                        LocalFree(pTrustee);
+                    }
+                } catch (WindowsException x) {
+                    throw new IOException("Unable to get effective rights from ACL: " +
+                        x.getMessage());
+                }
+            } finally {
+                userBuffer.release();
+            }
+        } finally {
+            aclBuffer.release();
+        }
+    }
+
+    @Override
+    public void checkAccess(AccessMode... modes) throws IOException {
+        // if no access modes then simply file attributes
+        if (modes.length == 0) {
+            checkRead();
+            try {
+                WindowsFileAttributes.get(this, true);
+            } catch (WindowsException exc) {
+                exc.rethrowAsIOException(this);
+            }
+            return;
+        }
+
+        boolean r = false;
+        boolean w = false;
+        boolean x = false;
+        for (AccessMode mode: modes) {
+            switch (mode) {
+                case READ : r = true; break;
+                case WRITE : w = true; break;
+                case EXECUTE : x = true; break;
+                default: throw new AssertionError("Should not get here");
+            }
+        }
+
+        int mask = 0;
+        if (r) {
+            checkRead();
+            mask |= FILE_READ_DATA;
+        }
+        if (w) {
+            checkWrite();
+            mask |= FILE_WRITE_DATA;
+        }
+        if (x) {
+            SecurityManager sm = System.getSecurityManager();
+            if (sm != null)
+                sm.checkExec(getPathForPermissionCheck());
+            mask |= FILE_EXECUTE;
+        }
+
+        if ((getEffectiveAccess() & mask) == 0)
+            throw new AccessDeniedException(
+                this.getPathForExceptionMessage(), null,
+                "Effective permissions does not allow requested access");
+
+        // for write access we neeed to check if the DOS readonly attribute
+        // and if the volume is read-only
+        if (w) {
+            try {
+                WindowsFileAttributes attrs = WindowsFileAttributes.get(this, true);
+                if (!attrs.isDirectory() && attrs.isReadOnly())
+                    throw new AccessDeniedException(
+                        this.getPathForExceptionMessage(), null,
+                        "DOS readonly attribute is set");
+            } catch (WindowsException exc) {
+                exc.rethrowAsIOException(this);
+            }
+
+            if (WindowsFileStore.create(this).isReadOnly()) {
+                throw new AccessDeniedException(
+                    this.getPathForExceptionMessage(), null, "Read-only file system");
+            }
+            return;
+        }
+    }
+
+    @Override
+    public void delete(boolean failIfNotExists) throws IOException {
+        checkDelete();
+
+        WindowsFileAttributes attrs = null;
+        try {
+             // need to know if file is a directory or junction
+             attrs = WindowsFileAttributes.get(this, false);
+             if (attrs.isDirectory() || attrs.isDirectoryLink()) {
+                RemoveDirectory(getPathForWin32Calls());
+             } else {
+                DeleteFile(getPathForWin32Calls());
+             }
+        } catch (WindowsException x) {
+
+            // no-op if file does not exist
+            if (!failIfNotExists &&
+                (x.lastError() == ERROR_FILE_NOT_FOUND ||
+                 x.lastError() == ERROR_PATH_NOT_FOUND)) return;
+
+            if (attrs != null && attrs.isDirectory()) {
+                // ERROR_ALREADY_EXISTS is returned when attempting to delete
+                // non-empty directory on SAMBA servers.
+                if (x.lastError() == ERROR_DIR_NOT_EMPTY ||
+                    x.lastError() == ERROR_ALREADY_EXISTS)
+                {
+                    throw new DirectoryNotEmptyException(
+                        getPathForExceptionMessage());
+                }
+            }
+            x.rethrowAsIOException(this);
+        }
+    }
+
+    @Override
+    public DirectoryStream<Path> newDirectoryStream(DirectoryStream.Filter<? super Path> filter)
+        throws IOException
+    {
+        checkRead();
+        if (filter == null)
+            throw new NullPointerException();
+        return new WindowsDirectoryStream(this, filter);
+    }
+
+    @Override
+    public void implCopyTo(Path obj, CopyOption... options) throws IOException {
+        WindowsPath target = (WindowsPath)obj;
+        WindowsFileCopy.copy(this, target, options);
+    }
+
+    @Override
+    public void implMoveTo(Path obj, CopyOption... options) throws IOException {
+        WindowsPath target = (WindowsPath)obj;
+        WindowsFileCopy.move(this, target, options);
+    }
+
+    private boolean followLinks(LinkOption... options) {
+        boolean followLinks = true;
+        for (LinkOption option: options) {
+            if (option == LinkOption.NOFOLLOW_LINKS) {
+                followLinks = false;
+                continue;
+            }
+            if (option == null)
+                throw new NullPointerException();
+            throw new AssertionError("Should not get here");
+        }
+        return followLinks;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public <V extends FileAttributeView> V
+        getFileAttributeView(Class<V> view, LinkOption... options)
+    {
+        if (view == null)
+            throw new NullPointerException();
+        boolean followLinks = followLinks(options);
+        if (view == BasicFileAttributeView.class)
+            return (V) WindowsFileAttributeViews.createBasicView(this, followLinks);
+        if (view == DosFileAttributeView.class)
+            return (V) WindowsFileAttributeViews.createDosView(this, followLinks);
+        if (view == AclFileAttributeView.class)
+            return (V) new WindowsAclFileAttributeView(this, followLinks);
+        if (view == FileOwnerAttributeView.class)
+            return (V) new FileOwnerAttributeViewImpl(
+                new WindowsAclFileAttributeView(this, followLinks));
+        if (view == UserDefinedFileAttributeView.class)
+            return (V) new WindowsUserDefinedFileAttributeView(this, followLinks);
+        return (V) null;
+    }
+
+    @Override
+    public FileAttributeView getFileAttributeView(String name, LinkOption... options) {
+        boolean followLinks = followLinks(options);
+        if (name.equals("basic"))
+            return WindowsFileAttributeViews.createBasicView(this, followLinks);
+        if (name.equals("dos"))
+            return WindowsFileAttributeViews.createDosView(this, followLinks);
+        if (name.equals("acl"))
+            return new WindowsAclFileAttributeView(this, followLinks);
+        if (name.equals("owner"))
+            return new FileOwnerAttributeViewImpl(
+                new WindowsAclFileAttributeView(this, followLinks));
+        if (name.equals("xattr"))
+            return new WindowsUserDefinedFileAttributeView(this, followLinks);
+        return null;
+    }
+
+    @Override
+    public WindowsPath createDirectory(FileAttribute<?>... attrs)
+        throws IOException
+    {
+        checkWrite();
+        WindowsSecurityDescriptor sd = WindowsSecurityDescriptor.fromAttribute(attrs);
+        try {
+            CreateDirectory(getPathForWin32Calls(), sd.address());
+        } catch (WindowsException x) {
+            x.rethrowAsIOException(this);
+        } finally {
+            sd.release();
+        }
+        return this;
+    }
+
+    @Override
+    public InputStream newInputStream()throws IOException {
+        try {
+            Set<OpenOption> options = Collections.emptySet();
+            FileChannel fc = WindowsChannelFactory
+                .newFileChannel(getPathForWin32Calls(),
+                                getPathForPermissionCheck(),
+                                options,
+                                0L);
+            return Channels.newInputStream(fc);
+        } catch (WindowsException x) {
+            x.rethrowAsIOException(this);
+            return null;  // keep compiler happy
+        }
+    }
+
+    @Override
+    public SeekableByteChannel newByteChannel(Set<? extends OpenOption> options,
+                                              FileAttribute<?>... attrs)
+         throws IOException
+    {
+        WindowsSecurityDescriptor sd =
+            WindowsSecurityDescriptor.fromAttribute(attrs);
+        try {
+            return WindowsChannelFactory
+                .newFileChannel(getPathForWin32Calls(),
+                                getPathForPermissionCheck(),
+                                options,
+                                sd.address());
+        } catch (WindowsException x) {
+            x.rethrowAsIOException(this);
+            return null;  // keep compiler happy
+        } finally {
+            sd.release();
+        }
+    }
+
+    @Override
+    public OutputStream newOutputStream(Set<? extends OpenOption> options,
+                                        FileAttribute<?>... attrs)
+        throws IOException
+    {
+        // need to copy options to add WRITE
+        Set<OpenOption> opts = new HashSet<OpenOption>(options);
+        if (opts.contains(StandardOpenOption.READ))
+            throw new IllegalArgumentException("READ not allowed");
+        opts.add(StandardOpenOption.WRITE);
+
+        WindowsSecurityDescriptor sd =
+            WindowsSecurityDescriptor.fromAttribute(attrs);
+        FileChannel fc;
+        try {
+            fc = WindowsChannelFactory
+                .newFileChannel(getPathForWin32Calls(),
+                                getPathForPermissionCheck(),
+                                opts,
+                                sd.address());
+            return Channels.newOutputStream(fc);
+        } catch (WindowsException x) {
+            x.rethrowAsIOException(this);
+            return null;  // keep compiler happy
+        } finally {
+            sd.release();
+        }
+    }
+
+    @Override
+    public boolean isSameFile(FileRef obj) throws IOException {
+        if (this.equals(obj))
+            return true;
+        if (!(obj instanceof WindowsPath))  // includes null check
+            return false;
+        WindowsPath other = (WindowsPath)obj;
+
+        // check security manager access to both files
+        this.checkRead();
+        other.checkRead();
+
+        // open both files and see if they are the same
+        long h1 = 0L;
+        try {
+            h1 = this.openForReadAttributeAccess(true);
+        } catch (WindowsException x) {
+            x.rethrowAsIOException(this);
+        }
+        try {
+            WindowsFileAttributes attrs1 = null;
+            try {
+                attrs1 = WindowsFileAttributes.readAttributes(h1);
+            } catch (WindowsException x) {
+                x.rethrowAsIOException(this);
+            }
+            long h2 = 0L;
+            try {
+                h2 = other.openForReadAttributeAccess(true);
+            } catch (WindowsException x) {
+                x.rethrowAsIOException(other);
+            }
+            try {
+                WindowsFileAttributes attrs2 = null;
+                try {
+                    attrs2 = WindowsFileAttributes.readAttributes(h2);
+                } catch (WindowsException x) {
+                    x.rethrowAsIOException(other);
+                }
+                return WindowsFileAttributes.isSameFile(attrs1, attrs2);
+            } finally {
+                CloseHandle(h2);
+            }
+        } finally {
+            CloseHandle(h1);
+        }
+    }
+
+    @Override
+    public WindowsPath createSymbolicLink(Path obj, FileAttribute<?>... attrs)
+        throws IOException
+    {
+        if (!getFileSystem().supportsLinks()) {
+            throw new UnsupportedOperationException("Symbolic links not supported "
+                + "on this operating system");
+        }
+
+        WindowsPath target = checkPath(obj);
+
+        // no attributes allowed
+        if (attrs.length > 0) {
+            WindowsSecurityDescriptor.fromAttribute(attrs);  // may throw NPE or UOE
+            throw new UnsupportedOperationException("Initial file attributes" +
+                "not supported when creating symbolic link");
+        }
+
+        // permission check
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(new LinkPermission("symbolic"));
+            this.checkWrite();
+        }
+
+        /**
+         * Throw I/O exception for the drive-relative case because Windows
+         * creates a link with the resolved target for this case.
+         */
+        if (target.type == WindowsPathType.DRIVE_RELATIVE) {
+            throw new IOException("Cannot create symbolic link to drive-relative target");
+        }
+
+        /*
+         * Windows treates symbolic links to directories differently than it
+         * does to other file types. For that reason we check if the exists and
+         * is a directory.
+         */
+        int flags = 0;
+        WindowsPath resolvedTarget =
+            WindowsPath.createFromNormalizedPath(getFileSystem(), resolve(target).path);
+        try {
+            if (WindowsFileAttributes.get(resolvedTarget, true).isDirectory())
+                flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
+        } catch (WindowsException x) {
+            // unable to access target so assume target is not a directory
+        }
+
+        // create the link
+        try {
+            CreateSymbolicLink(getPathForWin32Calls(),
+                               addPrefixIfNeeded(target.toString()),
+                               flags);
+        } catch (WindowsException x) {
+            if (x.lastError() == ERROR_INVALID_REPARSE_DATA) {
+                x.rethrowAsIOException(this, target);
+            } else {
+                x.rethrowAsIOException(this);
+            }
+        }
+        return this;
+    }
+
+    @Override
+    public Path createLink(Path obj) throws IOException {
+        WindowsPath existing = checkPath(obj);
+
+        // permission check
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(new LinkPermission("hard"));
+            this.checkWrite();
+            existing.checkWrite();
+        }
+
+        // create hard link
+        try {
+            CreateHardLink(this.getPathForWin32Calls(),
+                           existing.getPathForWin32Calls());
+        } catch (WindowsException x) {
+            x.rethrowAsIOException(this, existing);
+        }
+
+        return this;
+    }
+
+    @Override
+    public WindowsPath readSymbolicLink() throws IOException {
+        if (!getFileSystem().supportsLinks()) {
+            throw new UnsupportedOperationException("symbolic links not supported");
+        }
+
+        // permission check
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            FilePermission perm = new FilePermission(getPathForPermissionCheck(),
+                SecurityConstants.FILE_READLINK_ACTION);
+            AccessController.checkPermission(perm);
+        }
+
+        String target = WindowsLinkSupport.readLink(this);
+        return createFromNormalizedPath(getFileSystem(), target);
+    }
+
+    @Override
+    public URI toUri() {
+        return WindowsUriSupport.toUri(this);
+    }
+
+    @Override
+    public WindowsPath toAbsolutePath() {
+        if (isAbsolute())
+            return this;
+
+        // permission check as per spec
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPropertyAccess("user.dir");
+        }
+
+        try {
+            return createFromNormalizedPath(getFileSystem(), getAbsolutePath());
+        } catch (WindowsException x) {
+            throw new IOError(new IOException(x.getMessage()));
+        }
+    }
+
+    @Override
+    public WindowsPath toRealPath(boolean resolveLinks) throws IOException {
+        checkRead();
+        String rp = WindowsLinkSupport.getRealPath(this, resolveLinks);
+        return createFromNormalizedPath(getFileSystem(), rp);
+    }
+
+    @Override
+    public boolean isHidden() throws IOException {
+        checkRead();
+        WindowsFileAttributes attrs = null;
+        try {
+            attrs = WindowsFileAttributes.get(this, true);
+        } catch (WindowsException x) {
+            x.rethrowAsIOException(this);
+        }
+        // DOS hidden attribute not meaningful when set on directories
+        if (attrs.isDirectory())
+            return false;
+        return attrs.isHidden();
+    }
+
+    @Override
+    public WatchKey register(WatchService watcher,
+                             WatchEvent.Kind<?>[] events,
+                             WatchEvent.Modifier... modifiers)
+        throws IOException
+    {
+        if (watcher == null)
+            throw new NullPointerException();
+        if (!(watcher instanceof WindowsWatchService))
+            throw new ProviderMismatchException();
+
+        // When a security manager is set then we need to make a defensive
+        // copy of the modifiers and check for the Windows specific FILE_TREE
+        // modifier. When the modifier is present then check that permission
+        // has been granted recursively.
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            boolean watchSubtree = false;
+            final int ml = modifiers.length;
+            if (ml > 0) {
+                modifiers = Arrays.copyOf(modifiers, ml);
+                int i=0;
+                while (i < ml) {
+                    if (modifiers[i++] == ExtendedWatchEventModifier.FILE_TREE) {
+                        watchSubtree = true;
+                        break;
+                    }
+                }
+            }
+            String s = getPathForPermissionCheck();
+            sm.checkRead(s);
+            if (watchSubtree)
+                sm.checkRead(s + "\\-");
+        }
+
+        return ((WindowsWatchService)watcher).register(this, events, modifiers);
+    }
+}
diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsPathParser.java b/jdk/src/windows/classes/sun/nio/fs/WindowsPathParser.java
new file mode 100644
index 0000000..411b91b
--- /dev/null
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsPathParser.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.InvalidPathException;
+
+/**
+ * A parser of Windows path strings
+ */
+
+class WindowsPathParser {
+    private WindowsPathParser() { }
+
+    /**
+     * The result of a parse operation
+     */
+    static class Result {
+        private final WindowsPathType type;
+        private final String root;
+        private final String path;
+
+        Result(WindowsPathType type, String root, String path) {
+            this.type = type;
+            this.root = root;
+            this.path = path;
+        }
+
+        /**
+         * The path type
+         */
+        WindowsPathType type() {
+            return type;
+        }
+
+        /**
+         * The root component
+         */
+        String root() {
+            return root;
+        }
+
+        /**
+         * The normalized path (includes root)
+         */
+        String path() {
+            return path;
+        }
+    }
+
+    /**
+     * Parses the given input as a Windows path
+     */
+    static Result parse(String input) {
+        if (input == null || input.length() == 0)
+            throw new InvalidPathException(input, "Empty or null path");
+        return parse(input, true);
+    }
+
+    /**
+     * Parses the given input as a Windows path where it is known that the
+     * path is already normalized.
+     */
+    static Result parseNormalizedPath(String input) {
+        return parse(input, false);
+    }
+
+    /**
+     * Parses the given input as a Windows path.
+     *
+     * @param   requireToNormalize
+     *          Indicates if the path requires to be normalized
+     */
+    private static Result parse(String input, boolean requireToNormalize) {
+        String root = "";
+        WindowsPathType type = null;
+
+        int len = input.length();
+        int off = 0;
+        if (len > 1) {
+            char c0 = input.charAt(0);
+            char c1 = input.charAt(1);
+            char c = 0;
+            int next = 2;
+            if (isSlash(c0) && isSlash(c1)) {
+                // UNC: We keep the first two slash, collapse all the
+                // following, then take the hostname and share name out,
+                // meanwhile collapsing all the redundant slashes.
+                type = WindowsPathType.UNC;
+                off = nextNonSlash(input, next, len);
+                next = nextSlash(input, off, len);
+                if (off == next)
+                    throw new InvalidPathException(input, "UNC path is missing hostname");
+                String host = input.substring(off, next);  //host
+                off = nextNonSlash(input, next, len);
+                next = nextSlash(input, off, len);
+                if (off == next)
+                    throw new InvalidPathException(input, "UNC path is missing sharename");
+                root = "\\\\" + host + "\\" + input.substring(off, next) + "\\";
+                off = next;
+            } else {
+                if (isLetter(c0) && c1 == ':') {
+                    root = input.substring(0, 2);
+                    if (len > 2 && isSlash(input.charAt(2))) {
+                        off = 3;
+                        root += "\\";
+                        type = WindowsPathType.ABSOLUTE;
+                    } else {
+                        off = 2;
+                        type = WindowsPathType.DRIVE_RELATIVE;
+                    }
+                }
+            }
+        }
+        if (off == 0) {
+            if (isSlash(input.charAt(0))) {
+                type = WindowsPathType.DIRECTORY_RELATIVE;
+                root = "\\";
+            } else {
+                type = WindowsPathType.RELATIVE;
+            }
+        }
+
+        if (requireToNormalize) {
+            StringBuilder sb = new StringBuilder(input.length());
+            sb.append(root);
+            return new Result(type, root, normalize(sb, input, off));
+        } else {
+            return new Result(type, root, input);
+        }
+    }
+
+    /**
+     * Remove redundant slashes from the rest of the path, forcing all slashes
+     * into the preferred slash.
+    */
+    private static String normalize(StringBuilder sb, String path, int off) {
+        int len = path.length();
+        off = nextNonSlash(path, off, len);
+        int start = off;
+        char lastC = 0;
+        while (off < len) {
+            char c = path.charAt(off);
+            if (isSlash(c)) {
+                if (lastC == ' ')
+                    throw new InvalidPathException(path,
+                                                   "Trailing char <" + lastC + ">",
+                                                   off - 1);
+                sb.append(path, start, off);
+                off = nextNonSlash(path, off, len);
+                if (off != len)   //no slash at the end of normalized path
+                    sb.append('\\');
+                start = off;
+            } else {
+                if (isInvalidPathChar(c))
+                    throw new InvalidPathException(path,
+                                                   "Illegal char <" + c + ">",
+                                                   off);
+                lastC = c;
+                off++;
+            }
+        }
+        if (start != off) {
+            if (lastC == ' ')
+                throw new InvalidPathException(path,
+                                               "Trailing char <" + lastC + ">",
+                                               off - 1);
+            sb.append(path, start, off);
+        }
+        return sb.toString();
+    }
+
+    private static final boolean isSlash(char c) {
+        return (c == '\\') || (c == '/');
+    }
+
+    private static final int nextNonSlash(String path, int off, int end) {
+        while (off < end && isSlash(path.charAt(off))) { off++; }
+        return off;
+    }
+
+    private static final int nextSlash(String path, int off, int end) {
+        char c;
+        while (off < end && !isSlash(c=path.charAt(off))) {
+            if (isInvalidPathChar(c))
+                throw new InvalidPathException(path,
+                                               "Illegal character [" + c + "] in path",
+                                               off);
+            off++;
+        }
+        return off;
+    }
+
+    private static final boolean isLetter(char c) {
+        return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'));
+    }
+
+    // Reserved characters for window path name
+    private static final String reservedChars = "<>:\"|?*";
+    private static final boolean isInvalidPathChar(char ch) {
+        return ch < '\u0020' || reservedChars.indexOf(ch) != -1;
+    }
+}
diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsPathType.java b/jdk/src/windows/classes/sun/nio/fs/WindowsPathType.java
new file mode 100644
index 0000000..ae3651f
--- /dev/null
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsPathType.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+/**
+ * A type safe enum of Windows path types.
+ */
+
+enum WindowsPathType {
+    ABSOLUTE,                   //  C:\foo
+    UNC,                        //  \\server\share\foo
+    RELATIVE,                   //  foo
+    DIRECTORY_RELATIVE,         //  \foo
+    DRIVE_RELATIVE              //  C:foo
+}
diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsSecurity.java b/jdk/src/windows/classes/sun/nio/fs/WindowsSecurity.java
new file mode 100644
index 0000000..9d44257
--- /dev/null
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsSecurity.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import static sun.nio.fs.WindowsNativeDispatcher.*;
+import static sun.nio.fs.WindowsConstants.*;
+
+/**
+ * Security related utility methods.
+ */
+
+class WindowsSecurity {
+    private WindowsSecurity() { }
+
+    // opens process token for given access
+    private static long openProcessToken(int access) {
+        try {
+            return OpenProcessToken(GetCurrentProcess(), access);
+        } catch (WindowsException x) {
+            return 0L;
+        }
+    }
+
+    /**
+     * Returns the access token for this process with TOKEN_DUPLICATE access
+     */
+    static final long processTokenWithDuplicateAccess =
+        openProcessToken(TOKEN_DUPLICATE);
+
+    /**
+     * Returns the access token for this process with TOKEN_QUERY access
+     */
+    static final long processTokenWithQueryAccess =
+        openProcessToken(TOKEN_QUERY);
+
+    /**
+     * Returned by enablePrivilege when code may require a given privilege.
+     * The drop method should be invoked after the operation completes so as
+     * to revert the privilege.
+     */
+    static interface Privilege {
+        void drop();
+    }
+
+    /**
+     * Attempts to enable the given privilege for this method.
+     */
+    static Privilege enablePrivilege(String priv) {
+        final long pLuid;
+        try {
+            pLuid = LookupPrivilegeValue(priv);
+        } catch (WindowsException x) {
+            // indicates bug in caller
+            throw new AssertionError(x);
+        }
+
+        long hToken = 0L;
+        boolean impersontating = false;
+        boolean elevated = false;
+        try {
+            hToken = OpenThreadToken(GetCurrentThread(),
+                                     TOKEN_ADJUST_PRIVILEGES, false);
+            if (hToken == 0L && processTokenWithDuplicateAccess != 0L) {
+                hToken = DuplicateTokenEx(processTokenWithDuplicateAccess,
+                    (TOKEN_ADJUST_PRIVILEGES|TOKEN_IMPERSONATE));
+                SetThreadToken(0L, hToken);
+                impersontating = true;
+            }
+
+            if (hToken != 0L) {
+                AdjustTokenPrivileges(hToken, pLuid, SE_PRIVILEGE_ENABLED);
+                elevated = true;
+            }
+        } catch (WindowsException x) {
+            // nothing to do, privilege not enabled
+        }
+
+        final long token = hToken;
+        final boolean stopImpersontating = impersontating;
+        final boolean needToRevert = elevated;
+
+        return new Privilege() {
+            @Override
+            public void drop() {
+                try {
+                    if (stopImpersontating) {
+                        SetThreadToken(0L, 0L);
+                    } else {
+                        if (needToRevert) {
+                            AdjustTokenPrivileges(token, pLuid, 0);
+                        }
+                    }
+                } catch (WindowsException x) {
+                    // should not happen
+                    throw new AssertionError(x);
+                }
+            }
+        };
+    }
+}
diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsSecurityDescriptor.java b/jdk/src/windows/classes/sun/nio/fs/WindowsSecurityDescriptor.java
new file mode 100644
index 0000000..0fa0725
--- /dev/null
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsSecurityDescriptor.java
@@ -0,0 +1,392 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.ProviderMismatchException;
+import java.nio.file.attribute.*;
+import java.util.*;
+import java.io.IOException;
+import sun.misc.Unsafe;
+
+import static sun.nio.fs.WindowsNativeDispatcher.*;
+import static sun.nio.fs.WindowsConstants.*;
+
+/**
+ * A SecurityDescriptor for use when setting a file's ACL or creating a file
+ * with an initial ACL.
+ */
+
+class WindowsSecurityDescriptor {
+    private static final Unsafe unsafe = Unsafe.getUnsafe();
+
+    /**
+     * typedef struct _ACL {
+     *     BYTE  AclRevision;
+     *     BYTE  Sbz1;
+     *     WORD  AclSize;
+     *     WORD  AceCount;
+     *     WORD  Sbz2;
+     * } ACL;
+     *
+     * typedef struct _ACE_HEADER {
+     *     BYTE AceType;
+     *     BYTE AceFlags;
+     *     WORD AceSize;
+     * } ACE_HEADER;
+     *
+     * typedef struct _ACCESS_ALLOWED_ACE {
+     *     ACE_HEADER Header;
+     *     ACCESS_MASK Mask;
+     *     DWORD SidStart;
+     * } ACCESS_ALLOWED_ACE;
+     *
+     * typedef struct _ACCESS_DENIED_ACE {
+     *     ACE_HEADER Header;
+     *     ACCESS_MASK Mask;
+     *     DWORD SidStart;
+     * } ACCESS_DENIED_ACE;
+     *
+     * typedef struct _SECURITY_DESCRIPTOR {
+     *     BYTE  Revision;
+     *     BYTE  Sbz1;
+     *     SECURITY_DESCRIPTOR_CONTROL Control;
+     *     PSID Owner;
+     *     PSID Group;
+     *     PACL Sacl;
+     *     PACL Dacl;
+     * } SECURITY_DESCRIPTOR;
+     */
+    private static final short SIZEOF_ACL                   = 8;
+    private static final short SIZEOF_ACCESS_ALLOWED_ACE    = 12;
+    private static final short SIZEOF_ACCESS_DENIED_ACE     = 12;
+    private static final short SIZEOF_SECURITY_DESCRIPTOR   = 20;
+
+    private static final short OFFSETOF_TYPE                = 0;
+    private static final short OFFSETOF_FLAGS               = 1;
+    private static final short OFFSETOF_ACCESS_MASK         = 4;
+    private static final short OFFSETOF_SID                 = 8;
+
+    // null security descriptor
+    private static final WindowsSecurityDescriptor NULL_DESCRIPTOR =
+        new WindowsSecurityDescriptor();
+
+    // native resources
+    private final List<Long> sidList;
+    private final NativeBuffer aclBuffer, sdBuffer;
+
+    /**
+     * Creates the "null" SecurityDescriptor
+     */
+    private WindowsSecurityDescriptor() {
+        this.sidList = null;
+        this.aclBuffer = null;
+        this.sdBuffer = null;
+    }
+
+    /**
+     * Creates a SecurityDescriptor from the given ACL
+     */
+    private WindowsSecurityDescriptor(List<AclEntry> acl) throws IOException {
+        boolean initialized = false;
+
+        // SECURITY: need to copy list in case size changes during processing
+        acl = new ArrayList<AclEntry>(acl);
+
+        // list of SIDs
+        sidList = new ArrayList<Long>(acl.size());
+        try {
+            // initial size of ACL
+            int size = SIZEOF_ACL;
+
+            // get the SID for each entry
+            for (AclEntry entry: acl) {
+                UserPrincipal user = entry.principal();
+                if (!(user instanceof WindowsUserPrincipals.User))
+                    throw new ProviderMismatchException();
+                String sidString = ((WindowsUserPrincipals.User)user).sidString();
+                try {
+                    long pSid = ConvertStringSidToSid(sidString);
+                    sidList.add(pSid);
+
+                    // increase size to allow for entry
+                    size += GetLengthSid(pSid) +
+                        Math.max(SIZEOF_ACCESS_ALLOWED_ACE, SIZEOF_ACCESS_DENIED_ACE);
+
+                } catch (WindowsException x) {
+                    throw new IOException("Failed to get SID for " + user.getName()
+                        + ": " + x.errorString());
+                }
+            }
+
+            // allocate memory for the ACL
+            aclBuffer = NativeBuffers.getNativeBuffer(size);
+            sdBuffer = NativeBuffers.getNativeBuffer(SIZEOF_SECURITY_DESCRIPTOR);
+
+            InitializeAcl(aclBuffer.address(), size);
+
+            // Add entry ACE to the ACL
+            int i = 0;
+            while (i < acl.size()) {
+                AclEntry entry = acl.get(i);
+                long pSid = sidList.get(i);
+                try {
+                    encode(entry, pSid, aclBuffer.address());
+                } catch (WindowsException x) {
+                    throw new IOException("Failed to encode ACE: " +
+                        x.errorString());
+                }
+                i++;
+            }
+
+            // initialize security descriptor and set DACL
+            InitializeSecurityDescriptor(sdBuffer.address());
+            SetSecurityDescriptorDacl(sdBuffer.address(), aclBuffer.address());
+            initialized = true;
+        } catch (WindowsException x) {
+            throw new IOException(x.getMessage());
+        } finally {
+            // release resources if not completely initialized
+            if (!initialized)
+                release();
+        }
+    }
+
+    /**
+     * Releases memory associated with SecurityDescriptor
+     */
+    void release() {
+        if (sdBuffer != null)
+            sdBuffer.release();
+        if (aclBuffer != null)
+            aclBuffer.release();
+        if (sidList != null) {
+            // release memory for SIDs
+            for (Long sid: sidList) {
+                LocalFree(sid);
+            }
+        }
+    }
+
+    /**
+     * Returns address of SecurityDescriptor
+     */
+    long address() {
+        return (sdBuffer == null) ? 0L : sdBuffer.address();
+    }
+
+    // decode Windows ACE to NFSv4 AclEntry
+    private static AclEntry decode(long aceAddress)
+        throws IOException
+    {
+        // map type
+        byte aceType = unsafe.getByte(aceAddress + OFFSETOF_TYPE);
+        if (aceType != ACCESS_ALLOWED_ACE_TYPE && aceType != ACCESS_DENIED_ACE_TYPE)
+            return null;
+        AclEntryType type;
+        if (aceType == ACCESS_ALLOWED_ACE_TYPE) {
+            type = AclEntryType.ALLOW;
+        } else {
+            type = AclEntryType.DENY;
+        }
+
+        // map flags
+        byte aceFlags = unsafe.getByte(aceAddress + OFFSETOF_FLAGS);
+        Set<AclEntryFlag> flags = new HashSet<AclEntryFlag>();
+        if ((aceFlags & OBJECT_INHERIT_ACE) != 0)
+            flags.add(AclEntryFlag.FILE_INHERIT);
+        if ((aceFlags & CONTAINER_INHERIT_ACE) != 0)
+            flags.add(AclEntryFlag.DIRECTORY_INHERIT);
+        if ((aceFlags & NO_PROPAGATE_INHERIT_ACE) != 0)
+            flags.add(AclEntryFlag.NO_PROPAGATE_INHERIT);
+        if ((aceFlags & INHERIT_ONLY_ACE) != 0)
+            flags.add(AclEntryFlag.INHERIT_ONLY);
+
+        // map access mask
+        int mask = unsafe.getInt(aceAddress + OFFSETOF_ACCESS_MASK);
+        Set<AclEntryPermission> perms = new HashSet<AclEntryPermission>();
+        if ((mask & FILE_READ_DATA) > 0)
+            perms.add(AclEntryPermission.READ_DATA);
+        if ((mask & FILE_WRITE_DATA) > 0)
+            perms.add(AclEntryPermission.WRITE_DATA);
+        if ((mask & FILE_APPEND_DATA ) > 0)
+            perms.add(AclEntryPermission.APPEND_DATA);
+        if ((mask & FILE_READ_EA) > 0)
+            perms.add(AclEntryPermission.READ_NAMED_ATTRS);
+        if ((mask & FILE_WRITE_EA) > 0)
+            perms.add(AclEntryPermission.WRITE_NAMED_ATTRS);
+        if ((mask & FILE_EXECUTE) > 0)
+            perms.add(AclEntryPermission.EXECUTE);
+        if ((mask & FILE_DELETE_CHILD ) > 0)
+            perms.add(AclEntryPermission.DELETE_CHILD);
+        if ((mask & FILE_READ_ATTRIBUTES) > 0)
+            perms.add(AclEntryPermission.READ_ATTRIBUTES);
+        if ((mask & FILE_WRITE_ATTRIBUTES) > 0)
+            perms.add(AclEntryPermission.WRITE_ATTRIBUTES);
+        if ((mask & DELETE) > 0)
+            perms.add(AclEntryPermission.DELETE);
+        if ((mask & READ_CONTROL) > 0)
+            perms.add(AclEntryPermission.READ_ACL);
+        if ((mask & WRITE_DAC) > 0)
+            perms.add(AclEntryPermission.WRITE_ACL);
+        if ((mask & WRITE_OWNER) > 0)
+            perms.add(AclEntryPermission.WRITE_OWNER);
+        if ((mask & SYNCHRONIZE) > 0)
+            perms.add(AclEntryPermission.SYNCHRONIZE);
+
+        // lookup SID to create UserPrincipal
+        long sidAddress = aceAddress + OFFSETOF_SID;
+        UserPrincipal user = WindowsUserPrincipals.fromSid(sidAddress);
+
+        return AclEntry.newBuilder()
+            .setType(type)
+            .setPrincipal(user)
+            .setFlags(flags).setPermissions(perms).build();
+    }
+
+    // encode NFSv4 AclEntry as Windows ACE to given ACL
+    private static void encode(AclEntry ace, long sidAddress, long aclAddress)
+        throws WindowsException
+    {
+        // ignore non-allow/deny entries for now
+        if (ace.type() != AclEntryType.ALLOW && ace.type() != AclEntryType.DENY)
+            return;
+        boolean allow = (ace.type() == AclEntryType.ALLOW);
+
+        // map access mask
+        Set<AclEntryPermission> aceMask = ace.permissions();
+        int mask = 0;
+        if (aceMask.contains(AclEntryPermission.READ_DATA))
+            mask |= FILE_READ_DATA;
+        if (aceMask.contains(AclEntryPermission.WRITE_DATA))
+            mask |= FILE_WRITE_DATA;
+        if (aceMask.contains(AclEntryPermission.APPEND_DATA))
+            mask |= FILE_APPEND_DATA;
+        if (aceMask.contains(AclEntryPermission.READ_NAMED_ATTRS))
+            mask |= FILE_READ_EA;
+        if (aceMask.contains(AclEntryPermission.WRITE_NAMED_ATTRS))
+            mask |= FILE_WRITE_EA;
+        if (aceMask.contains(AclEntryPermission.EXECUTE))
+            mask |= FILE_EXECUTE;
+        if (aceMask.contains(AclEntryPermission.DELETE_CHILD))
+            mask |= FILE_DELETE_CHILD;
+        if (aceMask.contains(AclEntryPermission.READ_ATTRIBUTES))
+            mask |= FILE_READ_ATTRIBUTES;
+        if (aceMask.contains(AclEntryPermission.WRITE_ATTRIBUTES))
+            mask |= FILE_WRITE_ATTRIBUTES;
+        if (aceMask.contains(AclEntryPermission.DELETE))
+            mask |= DELETE;
+        if (aceMask.contains(AclEntryPermission.READ_ACL))
+            mask |= READ_CONTROL;
+        if (aceMask.contains(AclEntryPermission.WRITE_ACL))
+            mask |= WRITE_DAC;
+        if (aceMask.contains(AclEntryPermission.WRITE_OWNER))
+            mask |= WRITE_OWNER;
+        if (aceMask.contains(AclEntryPermission.SYNCHRONIZE))
+            mask |= SYNCHRONIZE;
+
+        // map flags
+        Set<AclEntryFlag> aceFlags = ace.flags();
+        byte flags = 0;
+        if (aceFlags.contains(AclEntryFlag.FILE_INHERIT))
+            flags |= OBJECT_INHERIT_ACE;
+        if (aceFlags.contains(AclEntryFlag.DIRECTORY_INHERIT))
+            flags |= CONTAINER_INHERIT_ACE;
+        if (aceFlags.contains(AclEntryFlag.NO_PROPAGATE_INHERIT))
+            flags |= NO_PROPAGATE_INHERIT_ACE;
+        if (aceFlags.contains(AclEntryFlag.INHERIT_ONLY))
+            flags |= INHERIT_ONLY_ACE;
+
+        if (allow) {
+            AddAccessAllowedAceEx(aclAddress, flags, mask, sidAddress);
+        } else {
+            AddAccessDeniedAceEx(aclAddress, flags, mask, sidAddress);
+        }
+    }
+
+    /**
+     * Creates a security descriptor with a DACL representing the given ACL.
+     */
+    static WindowsSecurityDescriptor create(List<AclEntry> acl)
+        throws IOException
+    {
+        return new WindowsSecurityDescriptor(acl);
+    }
+
+    /**
+     * Processes the array of attributes looking for the attribute "acl:acl".
+     * Returns security descriptor representing the ACL or the "null" security
+     * descriptor if the attribute is not in the array.
+     */
+    @SuppressWarnings("unchecked")
+    static WindowsSecurityDescriptor fromAttribute(FileAttribute<?>... attrs)
+        throws IOException
+    {
+        WindowsSecurityDescriptor sd = NULL_DESCRIPTOR;
+        for (FileAttribute<?> attr: attrs) {
+            // if more than one ACL specified then last one wins
+            if (sd != NULL_DESCRIPTOR)
+                sd.release();
+            if (attr == null)
+                throw new NullPointerException();
+            if (attr.name().equals("acl:acl")) {
+                List<AclEntry> acl = (List<AclEntry>)attr.value();
+                sd = new WindowsSecurityDescriptor(acl);
+            } else {
+                throw new UnsupportedOperationException("'" + attr.name() +
+                   "' not supported as initial attribute");
+            }
+        }
+        return sd;
+    }
+
+    /**
+     * Extracts DACL from security descriptor.
+     */
+    static List<AclEntry> getAcl(long pSecurityDescriptor) throws IOException {
+        // get address of DACL
+        long aclAddress = GetSecurityDescriptorDacl(pSecurityDescriptor);
+
+        // get ACE count
+        int aceCount = 0;
+        if (aclAddress == 0L) {
+            // no ACEs
+            aceCount = 0;
+        } else {
+            AclInformation aclInfo = GetAclInformation(aclAddress);
+            aceCount = aclInfo.aceCount();
+        }
+        ArrayList<AclEntry> result = new ArrayList<AclEntry>(aceCount);
+
+        // decode each of the ACEs to AclEntry objects
+        for (int i=0; i<aceCount; i++) {
+            long aceAddress = GetAce(aclAddress, i);
+            AclEntry entry = decode(aceAddress);
+            if (entry != null)
+                result.add(entry);
+        }
+        return result;
+    }
+}
diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsUriSupport.java b/jdk/src/windows/classes/sun/nio/fs/WindowsUriSupport.java
new file mode 100644
index 0000000..d87ba82
--- /dev/null
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsUriSupport.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+/**
+ * Utility methods to convert between Path and URIs.
+ */
+
+class WindowsUriSupport {
+    private WindowsUriSupport() {
+    }
+
+    // suffix for IPv6 literal address
+    private static final String IPV6_LITERAL_SUFFIX = ".ipv6-literal.net";
+
+    /**
+     * Returns URI to represent the given (absolute) path
+     */
+    private static URI toUri(String path, boolean isUnc, boolean addSlash) {
+        String uriHost;
+        String uriPath;
+
+        if (isUnc) {
+            int slash = path.indexOf('\\', 2);
+            uriHost = path.substring(2, slash);
+            uriPath = path.substring(slash).replace('\\', '/');
+
+            // handle IPv6 literal addresses
+            // 1. drop .ivp6-literal.net
+            // 2. replace "-" with ":"
+            // 3. replace "s" with "%" (zone/scopeID delimiter)
+            if (uriHost.endsWith(IPV6_LITERAL_SUFFIX)) {
+                uriHost = uriHost
+                    .substring(0, uriHost.length() - IPV6_LITERAL_SUFFIX.length())
+                    .replace('-', ':')
+                    .replace('s', '%');
+            }
+        } else {
+            uriHost = "";
+            uriPath = "/" + path.replace('\\', '/');
+        }
+
+        // append slash if known to be directory
+        if (addSlash)
+            uriPath += "/";
+
+        // return file:///C:/My%20Documents or file://server/share/foo
+        try {
+            return new URI("file", uriHost, uriPath, null);
+        } catch (URISyntaxException x) {
+            if (!isUnc)
+                throw new AssertionError(x);
+        }
+
+        // if we get here it means we've got a UNC with reserved characters
+        // in the server name. The authority component cannot contain escaped
+        // octets so fallback to encoding the server name into the URI path
+        // component.
+        uriPath = "//" + path.replace('\\', '/');
+        if (addSlash)
+            uriPath += "/";
+        try {
+            return new URI("file", null, uriPath, null);
+        } catch (URISyntaxException x) {
+            throw new AssertionError(x);
+        }
+    }
+
+    /**
+     * Converts given Path to a URI
+     */
+    static URI toUri(WindowsPath path) {
+        path = path.toAbsolutePath();
+        String s = path.toString();
+
+        // trailing slash will be added if file is a directory. Skip check if
+        // already have trailing space
+        boolean addSlash = false;
+        if (!s.endsWith("\\")) {
+            try {
+                 addSlash = WindowsFileAttributes.get(path, true).isDirectory();
+            } catch (WindowsException x) {
+            }
+        }
+
+        return toUri(s, path.isUnc(), addSlash);
+    }
+
+    /**
+     * Converts given URI to a Path
+     */
+    static WindowsPath fromUri(WindowsFileSystem fs, URI uri) {
+        if (!uri.isAbsolute())
+            throw new IllegalArgumentException("URI is not absolute");
+        if (uri.isOpaque())
+            throw new IllegalArgumentException("URI is not hierarchical");
+        String scheme = uri.getScheme();
+        if ((scheme == null) || !scheme.equalsIgnoreCase("file"))
+            throw new IllegalArgumentException("URI scheme is not \"file\"");
+        if (uri.getFragment() != null)
+            throw new IllegalArgumentException("URI has a fragment component");
+        if (uri.getQuery() != null)
+            throw new IllegalArgumentException("URI has a query component");
+        String path = uri.getPath();
+        if (path.equals(""))
+            throw new IllegalArgumentException("URI path component is empty");
+
+        // UNC
+        String auth = uri.getAuthority();
+        if (auth != null && !auth.equals("")) {
+            String host = uri.getHost();
+            if (host == null)
+                throw new IllegalArgumentException("URI authority component has undefined host");
+            if (uri.getUserInfo() != null)
+                throw new IllegalArgumentException("URI authority component has user-info");
+            if (uri.getPort() != -1)
+                throw new IllegalArgumentException("URI authority component has port number");
+
+            // IPv6 literal
+            // 1. drop enclosing brackets
+            // 2. replace ":" with "-"
+            // 3. replace "%" with "s" (zone/scopeID delimiter)
+            // 4. Append .ivp6-literal.net
+            if (host.startsWith("[")) {
+                host = host.substring(1, host.length()-1)
+                           .replace(':', '-')
+                           .replace('%', 's');
+                host += IPV6_LITERAL_SUFFIX;
+            }
+
+            // reconstitute the UNC
+            path = "\\\\" + host + path;
+        } else {
+            if ((path.length() > 2) && (path.charAt(2) == ':')) {
+                // "/c:/foo" --> "c:/foo"
+                path = path.substring(1);
+            }
+        }
+        return WindowsPath.parse(fs, path);
+    }
+}
diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsUserDefinedFileAttributeView.java b/jdk/src/windows/classes/sun/nio/fs/WindowsUserDefinedFileAttributeView.java
new file mode 100644
index 0000000..db361c9
--- /dev/null
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsUserDefinedFileAttributeView.java
@@ -0,0 +1,342 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.*;
+import static java.nio.file.StandardOpenOption.*;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.io.IOException;
+import java.util.*;
+import sun.misc.Unsafe;
+
+import static sun.nio.fs.WindowsNativeDispatcher.*;
+import static sun.nio.fs.WindowsConstants.*;
+
+/**
+ * Windows emulation of NamedAttributeView using Alternative Data Streams
+ */
+
+class WindowsUserDefinedFileAttributeView
+    extends AbstractUserDefinedFileAttributeView
+{
+    private static final Unsafe unsafe = Unsafe.getUnsafe();
+
+    // syntax to address named streams
+    private String join(String file, String name) {
+        if (name == null)
+            throw new NullPointerException("'name' is null");
+        return file + ":" + name;
+    }
+    private String join(WindowsPath file, String name) throws WindowsException {
+        return join(file.getPathForWin32Calls(), name);
+    }
+
+    private final WindowsPath file;
+    private final boolean followLinks;
+
+    WindowsUserDefinedFileAttributeView(WindowsPath file, boolean followLinks) {
+        this.file = file;
+        this.followLinks = followLinks;
+    }
+
+    // enumerates the file streams using FindFirstStream/FindNextStream APIs.
+    private List<String> listUsingStreamEnumeration() throws IOException {
+        List<String> list = new ArrayList<String>();
+        try {
+            FirstStream first = FindFirstStream(file.getPathForWin32Calls());
+            if (first != null) {
+                long handle = first.handle();
+                try {
+                    // first stream is always ::$DATA for files
+                    String name = first.name();
+                    if (!name.equals("::$DATA")) {
+                        String[] segs = name.split(":");
+                        list.add(segs[1]);
+                    }
+                    while ((name = FindNextStream(handle)) != null) {
+                        String[] segs = name.split(":");
+                        list.add(segs[1]);
+                    }
+                } finally {
+                    FindClose(handle);
+                }
+            }
+        } catch (WindowsException x) {
+            x.rethrowAsIOException(file);
+        }
+        return Collections.unmodifiableList(list);
+    }
+
+    // enumerates the file streams by reading the stream headers using
+    // BackupRead
+    private List<String> listUsingBackupRead() throws IOException {
+        long handle = -1L;
+        try {
+            int flags = FILE_FLAG_BACKUP_SEMANTICS;
+            if (!followLinks && file.getFileSystem().supportsLinks())
+                flags |= FILE_FLAG_OPEN_REPARSE_POINT;
+
+            handle = CreateFile(file.getPathForWin32Calls(),
+                                GENERIC_READ,
+                                FILE_SHARE_READ, // no write as we depend on file size
+                                OPEN_EXISTING,
+                                flags);
+        } catch (WindowsException x) {
+            x.rethrowAsIOException(file);
+        }
+
+        // buffer to read stream header and stream name.
+        final int BUFFER_SIZE = 4096;
+        NativeBuffer buffer = null;
+
+        // result with names of alternative data streams
+        final List<String> list = new ArrayList<String>();
+
+        try {
+            buffer = NativeBuffers.getNativeBuffer(BUFFER_SIZE);
+            long address = buffer.address();
+
+            /**
+             * typedef struct _WIN32_STREAM_ID {
+             *     DWORD dwStreamId;
+             *     DWORD dwStreamAttributes;
+             *     LARGE_INTEGER Size;
+             *     DWORD dwStreamNameSize;
+             *     WCHAR cStreamName[ANYSIZE_ARRAY];
+             * } WIN32_STREAM_ID;
+             */
+            final int SIZEOF_STREAM_HEADER      = 20;
+            final int OFFSETOF_STREAM_ID        = 0;
+            final int OFFSETOF_STREAM_SIZE      = 8;
+            final int OFFSETOF_STREAM_NAME_SIZE = 16;
+
+            long context = 0L;
+            try {
+                for (;;) {
+                    // read stream header
+                    BackupResult result = BackupRead(handle, address,
+                       SIZEOF_STREAM_HEADER, false, context);
+                    context = result.context();
+                    if (result.bytesTransferred() == 0)
+                        break;
+
+                    int streamId = unsafe.getInt(address + OFFSETOF_STREAM_ID);
+                    long streamSize = unsafe.getLong(address + OFFSETOF_STREAM_SIZE);
+                    int nameSize = unsafe.getInt(address + OFFSETOF_STREAM_NAME_SIZE);
+
+                    // read stream name
+                    if (nameSize > 0) {
+                        result = BackupRead(handle, address, nameSize, false, context);
+                        if (result.bytesTransferred() != nameSize)
+                            break;
+                    }
+
+                    // check for alternative data stream
+                    if (streamId == BACKUP_ALTERNATE_DATA) {
+                        char[] nameAsArray = new char[nameSize/2];
+                        unsafe.copyMemory(null, address, nameAsArray,
+                            Unsafe.ARRAY_CHAR_BASE_OFFSET, nameSize);
+
+                        String[] segs = new String(nameAsArray).split(":");
+                        if (segs.length == 3)
+                            list.add(segs[1]);
+                    }
+
+                    // sparse blocks not currently handled as documentation
+                    // is not sufficient on how the spase block can be skipped.
+                    if (streamId == BACKUP_SPARSE_BLOCK) {
+                        throw new IOException("Spare blocks not handled");
+                    }
+
+                    // seek to end of stream
+                    if (streamSize > 0L) {
+                        BackupSeek(handle, streamSize, context);
+                    }
+                }
+            } catch (WindowsException x) {
+                // failed to read or seek
+                throw new IOException(x.errorString());
+            } finally {
+                // release context
+                if (context != 0L) {
+                   try {
+                       BackupRead(handle, 0L, 0, true, context);
+                   } catch (WindowsException ignore) { }
+                }
+            }
+        } finally {
+            if (buffer != null)
+                buffer.release();
+            CloseHandle(handle);
+        }
+        return Collections.unmodifiableList(list);
+    }
+
+    @Override
+    public List<String> list() throws IOException  {
+        if (System.getSecurityManager() != null)
+            checkAccess(file.getPathForPermissionCheck(), true, false);
+        // use stream APIs on Windwos Server 2003 and newer
+        if (file.getFileSystem().supportsStreamEnumeration()) {
+            return listUsingStreamEnumeration();
+        } else {
+            return listUsingBackupRead();
+        }
+    }
+
+    @Override
+    public int size(String name) throws IOException  {
+        if (System.getSecurityManager() != null)
+            checkAccess(file.getPathForPermissionCheck(), true, false);
+
+        // wrap with channel
+        FileChannel fc = null;
+        try {
+            Set<OpenOption> opts = new HashSet<OpenOption>();
+            opts.add(READ);
+            if (!followLinks)
+                opts.add(WindowsChannelFactory.OPEN_REPARSE_POINT);
+            fc = WindowsChannelFactory
+                .newFileChannel(join(file, name), null, opts, 0L);
+        } catch (WindowsException x) {
+            x.rethrowAsIOException(join(file.getPathForPermissionCheck(), name));
+        }
+        try {
+            long size = fc.size();
+            if (size > Integer.MAX_VALUE)
+                throw new ArithmeticException("Stream too large");
+            return (int)size;
+        } finally {
+            fc.close();
+        }
+    }
+
+    @Override
+    public int read(String name, ByteBuffer dst) throws IOException {
+        if (System.getSecurityManager() != null)
+            checkAccess(file.getPathForPermissionCheck(), true, false);
+
+        // wrap with channel
+        FileChannel fc = null;
+        try {
+            Set<OpenOption> opts = new HashSet<OpenOption>();
+            opts.add(READ);
+            if (!followLinks)
+                opts.add(WindowsChannelFactory.OPEN_REPARSE_POINT);
+            fc = WindowsChannelFactory
+                .newFileChannel(join(file, name), null, opts, 0L);
+        } catch (WindowsException x) {
+            x.rethrowAsIOException(join(file.getPathForPermissionCheck(), name));
+        }
+
+        // read to EOF (nothing we can do if I/O error occurs)
+        try {
+            if (fc.size() > dst.remaining())
+                throw new IOException("Stream too large");
+            int total = 0;
+            while (dst.hasRemaining()) {
+                int n = fc.read(dst);
+                if (n < 0)
+                    break;
+                total += n;
+            }
+            return total;
+        } finally {
+            fc.close();
+        }
+    }
+
+    @Override
+    public int write(String name, ByteBuffer src) throws IOException {
+        if (System.getSecurityManager() != null)
+            checkAccess(file.getPathForPermissionCheck(), false, true);
+
+        /**
+         * Creating a named stream will cause the unnamed stream to be created
+         * if it doesn't already exist. To avoid this we open the unnamed stream
+         * for reading and hope it isn't deleted/moved while we create or
+         * replace the named stream. Opening the file without sharing options
+         * may cause sharing violations with other programs that are accessing
+         * the unnamed stream.
+         */
+        long handle = -1L;
+        try {
+            int flags = FILE_FLAG_BACKUP_SEMANTICS;
+            if (!followLinks)
+                flags |= FILE_FLAG_OPEN_REPARSE_POINT;
+
+            handle = CreateFile(file.getPathForWin32Calls(),
+                                GENERIC_READ,
+                                (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE),
+                                OPEN_EXISTING,
+                                flags);
+        } catch (WindowsException x) {
+            x.rethrowAsIOException(file);
+        }
+        try {
+            Set<OpenOption> opts = new HashSet<OpenOption>();
+            if (!followLinks)
+                opts.add(WindowsChannelFactory.OPEN_REPARSE_POINT);
+            opts.add(CREATE);
+            opts.add(WRITE);
+            opts.add(StandardOpenOption.TRUNCATE_EXISTING);
+            FileChannel named = null;
+            try {
+                named = WindowsChannelFactory
+                    .newFileChannel(join(file, name), null, opts, 0L);
+            } catch (WindowsException x) {
+                x.rethrowAsIOException(join(file.getPathForPermissionCheck(), name));
+            }
+            // write value (nothing we can do if I/O error occurs)
+            try {
+                int rem = src.remaining();
+                while (src.hasRemaining()) {
+                    named.write(src);
+                }
+                return rem;
+            } finally {
+                named.close();
+            }
+        } finally {
+            CloseHandle(handle);
+        }
+    }
+
+    @Override
+    public void delete(String name) throws IOException {
+        if (System.getSecurityManager() != null)
+            checkAccess(file.getPathForPermissionCheck(), false, true);
+
+        String path = WindowsLinkSupport.getFinalPath(file, followLinks);
+        String toDelete = join(path, name);
+        try {
+            DeleteFile(toDelete);
+        } catch (WindowsException x) {
+            x.rethrowAsIOException(toDelete);
+        }
+    }
+}
diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsUserPrincipals.java b/jdk/src/windows/classes/sun/nio/fs/WindowsUserPrincipals.java
new file mode 100644
index 0000000..caf36f1
--- /dev/null
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsUserPrincipals.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package sun.nio.fs;
+
+import java.nio.file.attribute.*;
+import java.io.IOException;
+
+import static sun.nio.fs.WindowsConstants.*;
+import static sun.nio.fs.WindowsNativeDispatcher.*;
+
+class WindowsUserPrincipals {
+    private WindowsUserPrincipals() { }
+
+    static class User implements UserPrincipal {
+        // String representation of SID
+        private final String sidString;
+
+        // SID type
+        private final int sidType;
+
+        // Account name (if available) or SID
+        private final String accountName;
+
+        User(String sidString, int sidType, String accountName) {
+            this.sidString = sidString;
+            this.sidType = sidType;
+            this.accountName = accountName;
+        }
+
+        // package-private
+        String sidString() {
+            return sidString;
+        }
+
+        @Override
+        public String getName() {
+            return accountName;
+        }
+
+        @Override
+        public String toString() {
+            String type;
+            switch (sidType) {
+                case SidTypeUser : type = "User"; break;
+                case SidTypeGroup : type = "Group"; break;
+                case SidTypeDomain : type = "Domain"; break;
+                case SidTypeAlias : type = "Alias"; break;
+                case SidTypeWellKnownGroup : type = "Well-known group"; break;
+                case SidTypeDeletedAccount : type = "Deleted"; break;
+                case SidTypeInvalid : type = "Invalid"; break;
+                case SidTypeComputer : type = "Computer"; break;
+                default: type = "Unknown";
+            }
+            return accountName + " (" + type + ")";
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj == this)
+                return true;
+            if (!(obj instanceof WindowsUserPrincipals.User))
+                return false;
+            WindowsUserPrincipals.User other = (WindowsUserPrincipals.User)obj;
+            return this.sidString.equals(other.sidString);
+        }
+
+        @Override
+        public int hashCode() {
+            return sidString.hashCode();
+        }
+    }
+
+    static class Group extends User implements GroupPrincipal {
+        Group(String sidString, int sidType, String accountName) {
+            super(sidString, sidType, accountName);
+        }
+    }
+
+    static UserPrincipal fromSid(long sidAddress) throws IOException {
+        String sidString;
+        try {
+            sidString = ConvertSidToStringSid(sidAddress);
+            if (sidString == null) {
+                // pre-Windows XP system?
+                throw new AssertionError();
+            }
+        } catch (WindowsException x) {
+            throw new IOException("Unable to convert SID to String: " +
+                x.errorString());
+        }
+
+        // lookup account; if not available then use the SID as the name
+        Account account = null;
+        String name;
+        try {
+            account = LookupAccountSid(sidAddress);
+            name = account.domain() + "\\" + account.name();
+        } catch (WindowsException x) {
+            name = sidString;
+        }
+
+        int sidType = (account == null) ? SidTypeUnknown : account.use();
+        if ((sidType == SidTypeGroup) ||
+            (sidType == SidTypeWellKnownGroup) ||
+            (sidType == SidTypeAlias)) // alias for local group
+        {
+            return new Group(sidString, sidType, name);
+        } else {
+            return new User(sidString, sidType, name);
+        }
+    }
+
+    static UserPrincipal lookup(String name) throws IOException {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(new RuntimePermission("lookupUserInformation"));
+        }
+
+        // invoke LookupAccountName to get buffer size needed for SID
+        int size = 0;
+        try {
+            size = LookupAccountName(name, 0L, 0);
+        } catch (WindowsException x) {
+            if (x.lastError() == ERROR_NONE_MAPPED)
+                throw new UserPrincipalNotFoundException(name);
+            throw new IOException(name + ": " + x.errorString());
+        }
+        assert size > 0;
+
+        // allocate buffer and re-invoke LookupAccountName get SID
+        NativeBuffer sidBuffer = NativeBuffers.getNativeBuffer(size);
+        try {
+            int newSize = LookupAccountName(name, sidBuffer.address(), size);
+            if (newSize != size) {
+                // can this happen?
+                throw new AssertionError("SID change during lookup");
+            }
+
+            // return user principal
+            return fromSid(sidBuffer.address());
+        } catch (WindowsException x) {
+            throw new IOException(name + ": " + x.errorString());
+        } finally {
+            sidBuffer.release();
+        }
+    }
+}
diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsWatchService.java b/jdk/src/windows/classes/sun/nio/fs/WindowsWatchService.java
new file mode 100644
index 0000000..6a51907
--- /dev/null
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsWatchService.java
@@ -0,0 +1,582 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.*;
+import java.io.IOException;
+import java.util.*;
+import com.sun.nio.file.ExtendedWatchEventModifier;
+import sun.misc.Unsafe;
+
+import static sun.nio.fs.WindowsNativeDispatcher.*;
+import static sun.nio.fs.WindowsConstants.*;
+
+/*
+ * Win32 implementation of WatchService based on ReadDirectoryChangesW.
+ */
+
+class WindowsWatchService
+    extends AbstractWatchService
+{
+    private final Unsafe unsafe = Unsafe.getUnsafe();
+
+    // background thread to service I/O completion port
+    private final Poller poller;
+
+    /**
+     * Creates an I/O completion port and a daemon thread to service it
+     */
+    WindowsWatchService(WindowsFileSystem fs) throws IOException {
+        // create I/O completion port
+        long port = 0L;
+        try {
+            port = CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0);
+        } catch (WindowsException x) {
+            throw new IOException(x.getMessage());
+        }
+
+        this.poller = new Poller(fs, this, port);
+        this.poller.start();
+    }
+
+    @Override
+    WatchKey register(Path path,
+                      WatchEvent.Kind<?>[] events,
+                      WatchEvent.Modifier... modifiers)
+         throws IOException
+    {
+        // delegate to poller
+        return poller.register(path, events, modifiers);
+    }
+
+    @Override
+    void implClose() throws IOException {
+        // delegate to poller
+        poller.close();
+    }
+
+    /**
+     * Windows implementation of WatchKey.
+     */
+    private class WindowsWatchKey extends AbstractWatchKey {
+        // file key (used to detect existing registrations)
+        private FileKey fileKey;
+
+        // handle to directory
+        private volatile long handle = INVALID_HANDLE_VALUE;
+
+        // interest events
+        private Set<? extends WatchEvent.Kind<?>> events;
+
+        // subtree
+        private boolean watchSubtree;
+
+        // buffer for change events
+        private NativeBuffer buffer;
+
+        // pointer to bytes returned (in buffer)
+        private long countAddress;
+
+        // pointer to overlapped structure (in buffer)
+        private long overlappedAddress;
+
+        // completion key (used to map I/O completion to WatchKey)
+        private int completionKey;
+
+        WindowsWatchKey(AbstractWatchService watcher, FileKey fileKey) {
+            super(watcher);
+            this.fileKey = fileKey;
+        }
+
+        WindowsWatchKey init(long handle,
+                             Set<? extends WatchEvent.Kind<?>> events,
+                             boolean watchSubtree,
+                             NativeBuffer buffer,
+                             long countAddress,
+                             long overlappedAddress,
+                             int completionKey)
+        {
+            this.handle = handle;
+            this.events = events;
+            this.watchSubtree = watchSubtree;
+            this.buffer = buffer;
+            this.countAddress = countAddress;
+            this.overlappedAddress = overlappedAddress;
+            this.completionKey = completionKey;
+            return this;
+        }
+
+        long handle() {
+            return handle;
+        }
+
+        Set<? extends WatchEvent.Kind<?>> events() {
+            return events;
+        }
+
+        void setEvents(Set<? extends WatchEvent.Kind<?>> events) {
+            this.events = events;
+        }
+
+        boolean watchSubtree() {
+            return watchSubtree;
+        }
+
+        NativeBuffer buffer() {
+            return buffer;
+        }
+
+        long countAddress() {
+            return countAddress;
+        }
+
+        long overlappedAddress() {
+            return overlappedAddress;
+        }
+
+        FileKey fileKey() {
+            return fileKey;
+        }
+
+        int completionKey() {
+            return completionKey;
+        }
+
+        // close directory and release buffer
+        void releaseResources() {
+            CloseHandle(handle);
+            buffer.cleaner().clean();
+        }
+
+        // Invalidate key by closing directory and releasing buffer
+        void invalidate() {
+            releaseResources();
+            handle = INVALID_HANDLE_VALUE;
+            buffer = null;
+            countAddress = 0;
+            overlappedAddress = 0;
+        }
+
+        @Override
+        public boolean isValid() {
+            return handle != INVALID_HANDLE_VALUE;
+        }
+
+        @Override
+        public void cancel() {
+            if (isValid()) {
+                // delegate to poller
+                poller.cancel(this);
+            }
+        }
+    }
+
+    // file key to unique identify (open) directory
+    private static class FileKey {
+        private final int volSerialNumber;
+        private final int fileIndexHigh;
+        private final int fileIndexLow;
+
+        FileKey(int volSerialNumber, int fileIndexHigh, int fileIndexLow) {
+            this.volSerialNumber = volSerialNumber;
+            this.fileIndexHigh = fileIndexHigh;
+            this.fileIndexLow = fileIndexLow;
+        }
+
+        @Override
+        public int hashCode() {
+            return volSerialNumber ^ fileIndexHigh ^ fileIndexLow;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj == this)
+                return true;
+            if (!(obj instanceof FileKey))
+                return false;
+            FileKey other = (FileKey)obj;
+            if (this.volSerialNumber != other.volSerialNumber) return false;
+            if (this.fileIndexHigh != other.fileIndexHigh) return false;
+            if (this.fileIndexLow != other.fileIndexLow) return false;
+            return true;
+        }
+    }
+
+    // all change events
+    private static final int ALL_FILE_NOTIFY_EVENTS =
+        FILE_NOTIFY_CHANGE_FILE_NAME |
+        FILE_NOTIFY_CHANGE_DIR_NAME |
+        FILE_NOTIFY_CHANGE_ATTRIBUTES  |
+        FILE_NOTIFY_CHANGE_SIZE |
+        FILE_NOTIFY_CHANGE_LAST_WRITE |
+        FILE_NOTIFY_CHANGE_CREATION |
+        FILE_NOTIFY_CHANGE_SECURITY;
+
+    /**
+     * Background thread to service I/O completion port.
+     */
+    private class Poller extends AbstractPoller {
+        /*
+         * typedef struct _OVERLAPPED {
+         *     DWORD  Internal;
+         *     DWORD  InternalHigh;
+         *     DWORD  Offset;
+         *     DWORD  OffsetHigh;
+         *     HANDLE hEvent;
+         * } OVERLAPPED;
+         */
+        private static final short SIZEOF_DWORD         = 4;
+        private static final short SIZEOF_OVERLAPPED    = 32; // 20 on 32-bit
+
+        /*
+         * typedef struct _FILE_NOTIFY_INFORMATION {
+         *     DWORD NextEntryOffset;
+         *     DWORD Action;
+         *     DWORD FileNameLength;
+         *     WCHAR FileName[1];
+         * } FileNameLength;
+         */
+        private static final short OFFSETOF_NEXTENTRYOFFSET = 0;
+        private static final short OFFSETOF_ACTION          = 4;
+        private static final short OFFSETOF_FILENAMELENGTH  = 8;
+        private static final short OFFSETOF_FILENAME        = 12;
+
+        // size of per-directory buffer for events (FIXME - make this configurable)
+        private static final int CHANGES_BUFFER_SIZE    = 16 * 1024;
+
+        private final WindowsFileSystem fs;
+        private final WindowsWatchService watcher;
+        private final long port;
+
+        // maps completion key to WatchKey
+        private final Map<Integer,WindowsWatchKey> int2key;
+
+        // maps file key to WatchKey
+        private final Map<FileKey,WindowsWatchKey> fk2key;
+
+        // unique completion key for each directory
+        private int lastCompletionKey;
+
+        Poller(WindowsFileSystem fs, WindowsWatchService watcher, long port) {
+            this.fs = fs;
+            this.watcher = watcher;
+            this.port = port;
+            this.int2key = new HashMap<Integer,WindowsWatchKey>();
+            this.fk2key = new HashMap<FileKey,WindowsWatchKey>();
+            this.lastCompletionKey = 0;
+        }
+
+        @Override
+        void wakeup() throws IOException {
+            try {
+                PostQueuedCompletionStatus(port, 0);
+            } catch (WindowsException x) {
+                throw new IOException(x.getMessage());
+            }
+        }
+
+        /**
+         * Register a directory for changes as follows:
+         *
+         * 1. Open directory
+         * 2. Read its attributes (and check it really is a directory)
+         * 3. Assign completion key and associated handle with completion port
+         * 4. Call ReadDirectoryChangesW to start (async) read of changes
+         * 5. Create or return existing key representing registration
+         */
+        @Override
+        Object implRegister(Path obj,
+                            Set<? extends WatchEvent.Kind<?>> events,
+                            WatchEvent.Modifier... modifiers)
+        {
+            WindowsPath dir = (WindowsPath)obj;
+            boolean watchSubtree = false;
+
+            // FILE_TREE modifier allowed
+            for (WatchEvent.Modifier modifier: modifiers) {
+                if (modifier == ExtendedWatchEventModifier.FILE_TREE) {
+                    watchSubtree = true;
+                    continue;
+                } else {
+                    if (modifier == null)
+                        return new NullPointerException();
+                    if (modifier instanceof com.sun.nio.file.SensitivityWatchEventModifier)
+                        continue; // ignore
+                    return new UnsupportedOperationException("Modifier not supported");
+                }
+            }
+
+            // open directory
+            long handle = -1L;
+            try {
+                handle = CreateFile(dir.getPathForWin32Calls(),
+                                    FILE_LIST_DIRECTORY,
+                                    (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE),
+                                    OPEN_EXISTING,
+                                    FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED);
+            } catch (WindowsException x) {
+                return x.asIOException(dir);
+            }
+
+            boolean registered = false;
+            try {
+                // read attributes and check file is a directory
+                WindowsFileAttributes attrs = null;
+                try {
+                    attrs = WindowsFileAttributes.readAttributes(handle);
+                } catch (WindowsException x) {
+                    return x.asIOException(dir);
+                }
+                if (!attrs.isDirectory()) {
+                    return new NotDirectoryException(dir.getPathForExceptionMessage());
+                }
+
+                // check if this directory is already registered
+                FileKey fk = new FileKey(attrs.volSerialNumber(),
+                                         attrs.fileIndexHigh(),
+                                         attrs.fileIndexLow());
+                WindowsWatchKey existing = fk2key.get(fk);
+
+                // if already registered and we're not changing the subtree
+                // modifier then simply update the event and return the key.
+                if (existing != null && watchSubtree == existing.watchSubtree()) {
+                    existing.setEvents(events);
+                    return existing;
+                }
+
+                // unique completion key (skip 0)
+                int completionKey = ++lastCompletionKey;
+                if (completionKey == 0)
+                    completionKey = ++lastCompletionKey;
+
+                // associate handle with completion port
+                try {
+                    CreateIoCompletionPort(handle, port, completionKey);
+                } catch (WindowsException x) {
+                    return new IOException(x.getMessage());
+                }
+
+                // allocate memory for events, including space for other structures
+                // needed to do overlapped I/O
+                int size = CHANGES_BUFFER_SIZE + SIZEOF_DWORD + SIZEOF_OVERLAPPED;
+                NativeBuffer buffer = NativeBuffers.getNativeBuffer(size);
+
+                long bufferAddress = buffer.address();
+                long overlappedAddress = bufferAddress + size - SIZEOF_OVERLAPPED;
+                long countAddress = overlappedAddress - SIZEOF_DWORD;
+
+                // start async read of changes to directory
+                try {
+                    ReadDirectoryChangesW(handle,
+                                          bufferAddress,
+                                          CHANGES_BUFFER_SIZE,
+                                          watchSubtree,
+                                          ALL_FILE_NOTIFY_EVENTS,
+                                          countAddress,
+                                          overlappedAddress);
+                } catch (WindowsException x) {
+                    buffer.release();
+                    return new IOException(x.getMessage());
+                }
+
+                WindowsWatchKey watchKey;
+                if (existing == null) {
+                    // not registered so create new watch key
+                    watchKey = new WindowsWatchKey(watcher, fk)
+                        .init(handle, events, watchSubtree, buffer, countAddress,
+                              overlappedAddress, completionKey);
+                    // map file key to watch key
+                    fk2key.put(fk, watchKey);
+                } else {
+                    // directory already registered so need to:
+                    // 1. remove mapping from old completion key to existing watch key
+                    // 2. release existing key's resources (handle/buffer)
+                    // 3. re-initialize key with new handle/buffer
+                    int2key.remove(existing.completionKey());
+                    existing.releaseResources();
+                    watchKey = existing.init(handle, events, watchSubtree, buffer,
+                        countAddress, overlappedAddress, completionKey);
+                }
+                // map completion map to watch key
+                int2key.put(completionKey, watchKey);
+
+                registered = true;
+                return watchKey;
+
+            } finally {
+                if (!registered) CloseHandle(handle);
+            }
+        }
+
+        // cancel single key
+        @Override
+        void implCancelKey(WatchKey obj) {
+            WindowsWatchKey key = (WindowsWatchKey)obj;
+            if (key.isValid()) {
+                fk2key.remove(key.fileKey());
+                int2key.remove(key.completionKey());
+                key.invalidate();
+            }
+        }
+
+        // close watch service
+        @Override
+        void implCloseAll() {
+            // cancel all keys
+            for (Map.Entry<Integer,WindowsWatchKey> entry: int2key.entrySet()) {
+                entry.getValue().invalidate();
+            }
+            fk2key.clear();
+            int2key.clear();
+
+            // close I/O completion port
+            CloseHandle(port);
+        }
+
+        // Translate file change action into watch event
+        private WatchEvent.Kind<?> translateActionToEvent(int action)
+        {
+            switch (action) {
+                case FILE_ACTION_MODIFIED :
+                    return StandardWatchEventKind.ENTRY_MODIFY;
+
+                case FILE_ACTION_ADDED :
+                case FILE_ACTION_RENAMED_NEW_NAME :
+                    return StandardWatchEventKind.ENTRY_CREATE;
+
+                case FILE_ACTION_REMOVED :
+                case FILE_ACTION_RENAMED_OLD_NAME :
+                    return StandardWatchEventKind.ENTRY_DELETE;
+
+                default :
+                    return null;  // action not recognized
+            }
+        }
+
+        // process events (list of FILE_NOTIFY_INFORMATION structures)
+        private void processEvents(WindowsWatchKey key, int size) {
+            long address = key.buffer().address();
+
+            int nextOffset;
+            do {
+                int action = unsafe.getInt(address + OFFSETOF_ACTION);
+
+                // map action to event
+                WatchEvent.Kind<?> kind = translateActionToEvent(action);
+                if (key.events().contains(kind)) {
+                    // copy the name
+                    int nameLengthInBytes = unsafe.getInt(address + OFFSETOF_FILENAMELENGTH);
+                    if ((nameLengthInBytes % 2) != 0) {
+                        throw new AssertionError("FileNameLength.FileNameLength is not a multiple of 2");
+                    }
+                    char[] nameAsArray = new char[nameLengthInBytes/2];
+                    unsafe.copyMemory(null, address + OFFSETOF_FILENAME, nameAsArray,
+                        Unsafe.ARRAY_CHAR_BASE_OFFSET, nameLengthInBytes);
+
+                    // create FileName and queue event
+                    WindowsPath name = WindowsPath
+                        .createFromNormalizedPath(fs, new String(nameAsArray));
+                    key.signalEvent(kind, name);
+                }
+
+                // next event
+                nextOffset = unsafe.getInt(address + OFFSETOF_NEXTENTRYOFFSET);
+                address += (long)nextOffset;
+            } while (nextOffset != 0);
+        }
+
+        /**
+         * Poller main loop
+         */
+        @Override
+        public void run() {
+            for (;;) {
+                CompletionStatus info = null;
+                try {
+                    info = GetQueuedCompletionStatus(port);
+                } catch (WindowsException x) {
+                    // this should not happen
+                    x.printStackTrace();
+                    return;
+                }
+
+                // wakeup
+                if (info.completionKey() == 0) {
+                    boolean shutdown = processRequests();
+                    if (shutdown) {
+                        return;
+                    }
+                    continue;
+                }
+
+                // map completionKey to get WatchKey
+                WindowsWatchKey key = int2key.get(info.completionKey());
+                if (key == null) {
+                    // We get here when a registration is changed. In that case
+                    // the directory is closed which causes an event with the
+                    // old completion key.
+                    continue;
+                }
+
+                // ReadDirectoryChangesW failed
+                if (info.error() != 0) {
+                    // buffer overflow
+                    if (info.error() == ERROR_NOTIFY_ENUM_DIR) {
+                        key.signalEvent(StandardWatchEventKind.OVERFLOW, null);
+                    } else {
+                        // other error so cancel key
+                        implCancelKey(key);
+                        key.signal();
+                    }
+                    continue;
+                }
+
+                // process the events
+                if (info.bytesTransferred() > 0) {
+                    processEvents(key, info.bytesTransferred());
+                } else {
+                    // insufficient buffer size
+                    key.signalEvent(StandardWatchEventKind.OVERFLOW, null);
+                }
+
+                // start read for next batch of changes
+                try {
+                    ReadDirectoryChangesW(key.handle(),
+                                          key.buffer().address(),
+                                          CHANGES_BUFFER_SIZE,
+                                          key.watchSubtree(),
+                                          ALL_FILE_NOTIFY_EVENTS,
+                                          key.countAddress(),
+                                          key.overlappedAddress());
+                } catch (WindowsException x) {
+                    // no choice but to cancel key
+                    implCancelKey(key);
+                    key.signal();
+                }
+            }
+        }
+    }
+}
diff --git a/jdk/src/windows/native/sun/nio/ch/FileChannelImpl.c b/jdk/src/windows/native/sun/nio/ch/FileChannelImpl.c
index da96a10..d1056b8 100644
--- a/jdk/src/windows/native/sun/nio/ch/FileChannelImpl.c
+++ b/jdk/src/windows/native/sun/nio/ch/FileChannelImpl.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2009 Sun Microsystems, Inc.  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
@@ -34,10 +34,6 @@
 
 static jfieldID chan_fd; /* id for jobject 'fd' in java.io.FileChannel */
 
-
-/* false for 95/98/ME, true for NT/W2K */
-static jboolean onNT = JNI_FALSE;
-
 /**************************************************************
  * static method to store field ID's in initializers
  * and retrieve the allocation granularity
@@ -47,15 +43,9 @@
 {
     SYSTEM_INFO si;
     jint align;
-    OSVERSIONINFO ver;
     GetSystemInfo(&si);
     align = si.dwAllocationGranularity;
     chan_fd = (*env)->GetFieldID(env, clazz, "fd", "Ljava/io/FileDescriptor;");
-    ver.dwOSVersionInfoSize = sizeof(ver);
-    GetVersionEx(&ver);
-    if (ver.dwPlatformId == VER_PLATFORM_WIN32_NT) {
-        onNT = JNI_TRUE;
-    }
     return align;
 }
 
@@ -146,56 +136,6 @@
     return 0;
 }
 
-JNIEXPORT jint JNICALL
-Java_sun_nio_ch_FileChannelImpl_truncate0(JNIEnv *env, jobject this,
-                                    jobject fdo, jlong size)
-{
-    DWORD lowPos = 0;
-    long highPos = 0;
-    BOOL result = 0;
-    HANDLE h = (HANDLE)(handleval(env, fdo));
-
-    lowPos = (DWORD)size;
-    highPos = (long)(size >> 32);
-    lowPos = SetFilePointer(h, lowPos, &highPos, FILE_BEGIN);
-    if (lowPos == ((DWORD)-1)) {
-        if (GetLastError() != ERROR_SUCCESS) {
-            JNU_ThrowIOExceptionWithLastError(env, "Truncation failed");
-            return IOS_THROWN;
-        }
-    }
-    result = SetEndOfFile(h);
-    if (result == 0) {
-        JNU_ThrowIOExceptionWithLastError(env, "Truncation failed");
-        return IOS_THROWN;
-    }
-    return 0;
-}
-
-
-JNIEXPORT jint JNICALL
-Java_sun_nio_ch_FileChannelImpl_force0(JNIEnv *env, jobject this,
-                                    jobject fdo, jboolean md)
-{
-    int result = 0;
-    HANDLE h = (HANDLE)(handleval(env, fdo));
-
-    if (h != INVALID_HANDLE_VALUE) {
-        result = FlushFileBuffers(h);
-        if (result == 0) {
-            int error = GetLastError();
-            if (error != ERROR_ACCESS_DENIED) {
-                JNU_ThrowIOExceptionWithLastError(env, "Force failed");
-                return IOS_THROWN;
-            }
-        }
-    } else {
-        JNU_ThrowIOExceptionWithLastError(env, "Force failed");
-        return IOS_THROWN;
-    }
-    return 0;
-}
-
 JNIEXPORT jlong JNICALL
 Java_sun_nio_ch_FileChannelImpl_position0(JNIEnv *env, jobject this,
                                           jobject fdo, jlong offset)
@@ -220,23 +160,6 @@
     return (((jlong)highPos) << 32) | lowPos;
 }
 
-JNIEXPORT jlong JNICALL
-Java_sun_nio_ch_FileChannelImpl_size0(JNIEnv *env, jobject this, jobject fdo)
-{
-    DWORD sizeLow = 0;
-    DWORD sizeHigh = 0;
-    HANDLE h = (HANDLE)(handleval(env, fdo));
-
-    sizeLow = GetFileSize(h, &sizeHigh);
-    if (sizeLow == ((DWORD)-1)) {
-        if (GetLastError() != ERROR_SUCCESS) {
-            JNU_ThrowIOExceptionWithLastError(env, "Size failed");
-            return IOS_THROWN;
-        }
-    }
-    return (((jlong)sizeHigh) << 32) | sizeLow;
-}
-
 JNIEXPORT void JNICALL
 Java_sun_nio_ch_FileChannelImpl_close0(JNIEnv *env, jobject this, jobject fdo)
 {
@@ -257,99 +180,3 @@
 {
     return IOS_UNSUPPORTED;
 }
-
-JNIEXPORT jint JNICALL
-Java_sun_nio_ch_FileChannelImpl_lock0(JNIEnv *env, jobject this, jobject fdo,
-                                      jboolean block, jlong pos, jlong size,
-                                      jboolean shared)
-{
-    HANDLE h = (HANDLE)(handleval(env, fdo));
-    DWORD lowPos = (DWORD)pos;
-    long highPos = (long)(pos >> 32);
-    DWORD lowNumBytes = (DWORD)size;
-    DWORD highNumBytes = (DWORD)(size >> 32);
-    jint result = 0;
-    if (onNT) {
-        DWORD flags = 0;
-        OVERLAPPED o;
-        o.hEvent = 0;
-        o.Offset = lowPos;
-        o.OffsetHigh = highPos;
-        if (block == JNI_FALSE) {
-            flags |= LOCKFILE_FAIL_IMMEDIATELY;
-        }
-        if (shared == JNI_FALSE) {
-            flags |= LOCKFILE_EXCLUSIVE_LOCK;
-        }
-        result = LockFileEx(h, flags, 0, lowNumBytes, highNumBytes, &o);
-        if (result == 0) {
-            int error = GetLastError();
-            if (error != ERROR_LOCK_VIOLATION) {
-                JNU_ThrowIOExceptionWithLastError(env, "Lock failed");
-                return sun_nio_ch_FileChannelImpl_NO_LOCK;
-            }
-            if (flags & LOCKFILE_FAIL_IMMEDIATELY) {
-                return sun_nio_ch_FileChannelImpl_NO_LOCK;
-            }
-            JNU_ThrowIOExceptionWithLastError(env, "Lock failed");
-            return sun_nio_ch_FileChannelImpl_NO_LOCK;
-        }
-        return sun_nio_ch_FileChannelImpl_LOCKED;
-    } else {
-        for(;;) {
-            if (size > 0x7fffffff) {
-                size = 0x7fffffff;
-            }
-            lowNumBytes = (DWORD)size;
-            highNumBytes = 0;
-            result = LockFile(h, lowPos, highPos, lowNumBytes, highNumBytes);
-            if (result != 0) {
-                if (shared == JNI_TRUE) {
-                    return sun_nio_ch_FileChannelImpl_RET_EX_LOCK;
-                } else {
-                    return sun_nio_ch_FileChannelImpl_LOCKED;
-                }
-            } else {
-                int error = GetLastError();
-                if (error != ERROR_LOCK_VIOLATION) {
-                    JNU_ThrowIOExceptionWithLastError(env, "Lock failed");
-                    return sun_nio_ch_FileChannelImpl_NO_LOCK;
-                }
-                if (block == JNI_FALSE) {
-                    return sun_nio_ch_FileChannelImpl_NO_LOCK;
-                }
-            }
-            Sleep(100);
-        }
-    }
-    return sun_nio_ch_FileChannelImpl_NO_LOCK;
-}
-
-JNIEXPORT void JNICALL
-Java_sun_nio_ch_FileChannelImpl_release0(JNIEnv *env, jobject this,
-                                        jobject fdo, jlong pos, jlong size)
-{
-    HANDLE h = (HANDLE)(handleval(env, fdo));
-    DWORD lowPos = (DWORD)pos;
-    long highPos = (long)(pos >> 32);
-    DWORD lowNumBytes = (DWORD)size;
-    DWORD highNumBytes = (DWORD)(size >> 32);
-    jint result = 0;
-    if (onNT) {
-        OVERLAPPED o;
-        o.hEvent = 0;
-        o.Offset = lowPos;
-        o.OffsetHigh = highPos;
-        result = UnlockFileEx(h, 0, lowNumBytes, highNumBytes, &o);
-    } else {
-        if (size > 0x7fffffff) {
-            size = 0x7fffffff;
-        }
-        lowNumBytes = (DWORD)size;
-        highNumBytes = 0;
-        result = UnlockFile(h, lowPos, highPos, lowNumBytes, highNumBytes);
-    }
-    if (result == 0) {
-        JNU_ThrowIOExceptionWithLastError(env, "Release failed");
-    }
-}
diff --git a/jdk/src/windows/native/sun/nio/ch/FileDispatcher.c b/jdk/src/windows/native/sun/nio/ch/FileDispatcherImpl.c
similarity index 67%
rename from jdk/src/windows/native/sun/nio/ch/FileDispatcher.c
rename to jdk/src/windows/native/sun/nio/ch/FileDispatcherImpl.c
index a3c3985..a65ad90 100644
--- a/jdk/src/windows/native/sun/nio/ch/FileDispatcher.c
+++ b/jdk/src/windows/native/sun/nio/ch/FileDispatcherImpl.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2003 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2009 Sun Microsystems, Inc.  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
@@ -28,18 +28,18 @@
 #include "jni_util.h"
 #include "jvm.h"
 #include "jlong.h"
-#include "sun_nio_ch_FileDispatcher.h"
+#include "sun_nio_ch_FileDispatcherImpl.h"
 #include <io.h>
 #include "nio.h"
 #include "nio_util.h"
 
 
 /**************************************************************
- * FileDispatcher.c
+ * FileDispatcherImpl.c
  */
 
 JNIEXPORT jint JNICALL
-Java_sun_nio_ch_FileDispatcher_read0(JNIEnv *env, jclass clazz, jobject fdo,
+Java_sun_nio_ch_FileDispatcherImpl_read0(JNIEnv *env, jclass clazz, jobject fdo,
                                       jlong address, jint len)
 {
     DWORD read = 0;
@@ -70,7 +70,7 @@
 }
 
 JNIEXPORT jlong JNICALL
-Java_sun_nio_ch_FileDispatcher_readv0(JNIEnv *env, jclass clazz, jobject fdo,
+Java_sun_nio_ch_FileDispatcherImpl_readv0(JNIEnv *env, jclass clazz, jobject fdo,
                                        jlong address, jint len)
 {
     DWORD read = 0;
@@ -119,7 +119,7 @@
 }
 
 JNIEXPORT jint JNICALL
-Java_sun_nio_ch_FileDispatcher_pread0(JNIEnv *env, jclass clazz, jobject fdo,
+Java_sun_nio_ch_FileDispatcherImpl_pread0(JNIEnv *env, jclass clazz, jobject fdo,
                             jlong address, jint len, jlong offset)
 {
     DWORD read = 0;
@@ -182,7 +182,7 @@
 }
 
 JNIEXPORT jint JNICALL
-Java_sun_nio_ch_FileDispatcher_write0(JNIEnv *env, jclass clazz, jobject fdo,
+Java_sun_nio_ch_FileDispatcherImpl_write0(JNIEnv *env, jclass clazz, jobject fdo,
                                        jlong address, jint len)
 {
     BOOL result = 0;
@@ -205,7 +205,7 @@
 }
 
 JNIEXPORT jlong JNICALL
-Java_sun_nio_ch_FileDispatcher_writev0(JNIEnv *env, jclass clazz, jobject fdo,
+Java_sun_nio_ch_FileDispatcherImpl_writev0(JNIEnv *env, jclass clazz, jobject fdo,
                                        jlong address, jint len)
 {
     BOOL result = 0;
@@ -244,7 +244,7 @@
 }
 
 JNIEXPORT jint JNICALL
-Java_sun_nio_ch_FileDispatcher_pwrite0(JNIEnv *env, jclass clazz, jobject fdo,
+Java_sun_nio_ch_FileDispatcherImpl_pwrite0(JNIEnv *env, jclass clazz, jobject fdo,
                             jlong address, jint len, jlong offset)
 {
     BOOL result = 0;
@@ -295,6 +295,130 @@
     return convertReturnVal(env, (jint)written, JNI_FALSE);
 }
 
+JNIEXPORT jint JNICALL
+Java_sun_nio_ch_FileDispatcherImpl_force0(JNIEnv *env, jobject this,
+                                          jobject fdo, jboolean md)
+{
+    int result = 0;
+    HANDLE h = (HANDLE)(handleval(env, fdo));
+
+    if (h != INVALID_HANDLE_VALUE) {
+        result = FlushFileBuffers(h);
+        if (result == 0) {
+            int error = GetLastError();
+            if (error != ERROR_ACCESS_DENIED) {
+                JNU_ThrowIOExceptionWithLastError(env, "Force failed");
+                return IOS_THROWN;
+            }
+        }
+    } else {
+        JNU_ThrowIOExceptionWithLastError(env, "Force failed");
+        return IOS_THROWN;
+    }
+    return 0;
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_ch_FileDispatcherImpl_truncate0(JNIEnv *env, jobject this,
+                                             jobject fdo, jlong size)
+{
+    DWORD lowPos = 0;
+    long highPos = 0;
+    BOOL result = 0;
+    HANDLE h = (HANDLE)(handleval(env, fdo));
+
+    lowPos = (DWORD)size;
+    highPos = (long)(size >> 32);
+    lowPos = SetFilePointer(h, lowPos, &highPos, FILE_BEGIN);
+    if (lowPos == ((DWORD)-1)) {
+        if (GetLastError() != ERROR_SUCCESS) {
+            JNU_ThrowIOExceptionWithLastError(env, "Truncation failed");
+            return IOS_THROWN;
+        }
+    }
+    result = SetEndOfFile(h);
+    if (result == 0) {
+        JNU_ThrowIOExceptionWithLastError(env, "Truncation failed");
+        return IOS_THROWN;
+    }
+    return 0;
+}
+
+JNIEXPORT jlong JNICALL
+Java_sun_nio_ch_FileDispatcherImpl_size0(JNIEnv *env, jobject this, jobject fdo)
+{
+    DWORD sizeLow = 0;
+    DWORD sizeHigh = 0;
+    HANDLE h = (HANDLE)(handleval(env, fdo));
+
+    sizeLow = GetFileSize(h, &sizeHigh);
+    if (sizeLow == ((DWORD)-1)) {
+        if (GetLastError() != ERROR_SUCCESS) {
+            JNU_ThrowIOExceptionWithLastError(env, "Size failed");
+            return IOS_THROWN;
+        }
+    }
+    return (((jlong)sizeHigh) << 32) | sizeLow;
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_ch_FileDispatcherImpl_lock0(JNIEnv *env, jobject this, jobject fdo,
+                                      jboolean block, jlong pos, jlong size,
+                                      jboolean shared)
+{
+    HANDLE h = (HANDLE)(handleval(env, fdo));
+    DWORD lowPos = (DWORD)pos;
+    long highPos = (long)(pos >> 32);
+    DWORD lowNumBytes = (DWORD)size;
+    DWORD highNumBytes = (DWORD)(size >> 32);
+    BOOL result;
+    DWORD flags = 0;
+    OVERLAPPED o;
+    o.hEvent = 0;
+    o.Offset = lowPos;
+    o.OffsetHigh = highPos;
+    if (block == JNI_FALSE) {
+        flags |= LOCKFILE_FAIL_IMMEDIATELY;
+    }
+    if (shared == JNI_FALSE) {
+        flags |= LOCKFILE_EXCLUSIVE_LOCK;
+    }
+    result = LockFileEx(h, flags, 0, lowNumBytes, highNumBytes, &o);
+    if (result == 0) {
+        int error = GetLastError();
+        if (error != ERROR_LOCK_VIOLATION) {
+            JNU_ThrowIOExceptionWithLastError(env, "Lock failed");
+            return sun_nio_ch_FileDispatcherImpl_NO_LOCK;
+        }
+        if (flags & LOCKFILE_FAIL_IMMEDIATELY) {
+            return sun_nio_ch_FileDispatcherImpl_NO_LOCK;
+        }
+        JNU_ThrowIOExceptionWithLastError(env, "Lock failed");
+        return sun_nio_ch_FileDispatcherImpl_NO_LOCK;
+    }
+    return sun_nio_ch_FileDispatcherImpl_LOCKED;
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_FileDispatcherImpl_release0(JNIEnv *env, jobject this,
+                                        jobject fdo, jlong pos, jlong size)
+{
+    HANDLE h = (HANDLE)(handleval(env, fdo));
+    DWORD lowPos = (DWORD)pos;
+    long highPos = (long)(pos >> 32);
+    DWORD lowNumBytes = (DWORD)size;
+    DWORD highNumBytes = (DWORD)(size >> 32);
+    jint result = 0;
+    OVERLAPPED o;
+    o.hEvent = 0;
+    o.Offset = lowPos;
+    o.OffsetHigh = highPos;
+    result = UnlockFileEx(h, 0, lowNumBytes, highNumBytes, &o);
+    if (result == 0) {
+        JNU_ThrowIOExceptionWithLastError(env, "Release failed");
+    }
+}
+
 static void closeFile(JNIEnv *env, jlong fd) {
     HANDLE h = (HANDLE)fd;
     if (h != INVALID_HANDLE_VALUE) {
@@ -305,14 +429,14 @@
 }
 
 JNIEXPORT void JNICALL
-Java_sun_nio_ch_FileDispatcher_close0(JNIEnv *env, jclass clazz, jobject fdo)
+Java_sun_nio_ch_FileDispatcherImpl_close0(JNIEnv *env, jclass clazz, jobject fdo)
 {
     jlong fd = handleval(env, fdo);
     closeFile(env, fd);
 }
 
 JNIEXPORT void JNICALL
-Java_sun_nio_ch_FileDispatcher_closeByHandle(JNIEnv *env, jclass clazz,
+Java_sun_nio_ch_FileDispatcherImpl_closeByHandle(JNIEnv *env, jclass clazz,
                                              jlong fd)
 {
     closeFile(env, fd);
diff --git a/jdk/src/windows/native/sun/nio/ch/Iocp.c b/jdk/src/windows/native/sun/nio/ch/Iocp.c
new file mode 100644
index 0000000..9568189
--- /dev/null
+++ b/jdk/src/windows/native/sun/nio/ch/Iocp.c
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+#include <windows.h>
+
+#include "jni.h"
+#include "jni_util.h"
+#include "jlong.h"
+#include "nio.h"
+#include "nio_util.h"
+
+#include "sun_nio_ch_Iocp.h"
+
+
+static jfieldID completionStatus_error;
+static jfieldID completionStatus_bytesTransferred;
+static jfieldID completionStatus_completionKey;
+static jfieldID completionStatus_overlapped;
+
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_Iocp_initIDs(JNIEnv* env, jclass this)
+{
+    jclass clazz;
+
+    clazz = (*env)->FindClass(env, "sun/nio/ch/Iocp$CompletionStatus");
+    if (clazz == NULL) {
+        return;
+    }
+    completionStatus_error = (*env)->GetFieldID(env, clazz, "error", "I");
+    if (completionStatus_error == NULL) return;
+    completionStatus_bytesTransferred = (*env)->GetFieldID(env, clazz, "bytesTransferred", "I");
+    if (completionStatus_bytesTransferred == NULL) return;
+    completionStatus_completionKey = (*env)->GetFieldID(env, clazz, "completionKey", "I");
+    if (completionStatus_completionKey == NULL) return;
+    completionStatus_overlapped = (*env)->GetFieldID(env, clazz, "overlapped", "J");
+}
+
+JNIEXPORT jlong JNICALL
+Java_sun_nio_ch_Iocp_createIoCompletionPort(JNIEnv* env, jclass this,
+    jlong handle, jlong existingPort, jint completionKey, jint concurrency)
+{
+    HANDLE port = CreateIoCompletionPort((HANDLE)jlong_to_ptr(handle),
+                                         (HANDLE)jlong_to_ptr(existingPort),
+                                         (DWORD)completionKey,
+                                         (DWORD)concurrency);
+    if (port == NULL) {
+        JNU_ThrowIOExceptionWithLastError(env, "CreateIoCompletionPort failed");
+    }
+    return ptr_to_jlong(port);
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_Iocp_close0(JNIEnv* env, jclass this,
+    jlong handle)
+{
+    HANDLE h = (HANDLE)jlong_to_ptr(handle);
+    CloseHandle(h);
+}
+
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_Iocp_getQueuedCompletionStatus(JNIEnv* env, jclass this,
+    jlong completionPort, jobject obj)
+{
+    DWORD bytesTransferred;
+    DWORD completionKey;
+    OVERLAPPED *lpOverlapped;
+    BOOL res;
+
+    res = GetQueuedCompletionStatus((HANDLE)jlong_to_ptr(completionPort),
+                                  &bytesTransferred,
+                                  &completionKey,
+                                  &lpOverlapped,
+                                  INFINITE);
+    if (res == 0 && lpOverlapped == NULL) {
+        JNU_ThrowIOExceptionWithLastError(env, "GetQueuedCompletionStatus failed");
+    } else {
+        DWORD ioResult = (res == 0) ? GetLastError() : 0;
+        (*env)->SetIntField(env, obj, completionStatus_error, ioResult);
+        (*env)->SetIntField(env, obj, completionStatus_bytesTransferred,
+            (jint)bytesTransferred);
+        (*env)->SetIntField(env, obj, completionStatus_completionKey,
+            (jint)completionKey);
+        (*env)->SetLongField(env, obj, completionStatus_overlapped,
+            ptr_to_jlong(lpOverlapped));
+
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_Iocp_postQueuedCompletionStatus(JNIEnv* env, jclass this,
+    jlong completionPort, jint completionKey)
+{
+    BOOL res;
+
+    res = PostQueuedCompletionStatus((HANDLE)jlong_to_ptr(completionPort),
+                                     (DWORD)0,
+                                     (DWORD)completionKey,
+                                     NULL);
+    if (res == 0) {
+        JNU_ThrowIOExceptionWithLastError(env, "PostQueuedCompletionStatus");
+    }
+}
+
+JNIEXPORT jstring JNICALL
+Java_sun_nio_ch_Iocp_getErrorMessage(JNIEnv* env, jclass this, jint errorCode)
+{
+    WCHAR message[255];
+
+    DWORD len = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM,
+                               NULL,
+                               (DWORD)errorCode,
+                               0,
+                               &message[0],
+                               255,
+                               NULL);
+
+
+    if (len == 0) {
+        return NULL;
+    } else {
+        return (*env)->NewString(env, (const jchar *)message, (jsize)wcslen(message));
+    }
+}
diff --git a/jdk/src/windows/native/sun/nio/ch/WindowsAsynchronousFileChannelImpl.c b/jdk/src/windows/native/sun/nio/ch/WindowsAsynchronousFileChannelImpl.c
new file mode 100644
index 0000000..d8346ba
--- /dev/null
+++ b/jdk/src/windows/native/sun/nio/ch/WindowsAsynchronousFileChannelImpl.c
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+#include <windows.h>
+
+#include "jni.h"
+#include "jni_util.h"
+#include "jlong.h"
+#include "nio.h"
+#include "nio_util.h"
+
+#include "sun_nio_ch_WindowsAsynchronousFileChannelImpl.h"
+
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_ch_WindowsAsynchronousFileChannelImpl_readFile(JNIEnv* env, jclass this,
+    jlong handle, jlong address, jint len, jlong offset, jlong ov)
+{
+    BOOL res;
+    DWORD nread = 0;
+
+    OVERLAPPED* lpOverlapped = (OVERLAPPED*)jlong_to_ptr(ov);
+    lpOverlapped->Offset = (DWORD)offset;
+    lpOverlapped->OffsetHigh = (DWORD)((long)(offset >> 32));
+    lpOverlapped->hEvent = NULL;
+
+    res = ReadFile((HANDLE) jlong_to_ptr(handle),
+                   (LPVOID) jlong_to_ptr(address),
+                   (DWORD)len,
+                   &nread,
+                   lpOverlapped);
+
+    if (res == 0) {
+        int error = GetLastError();
+        if (error == ERROR_IO_PENDING)
+            return IOS_UNAVAILABLE;
+        if (error == ERROR_HANDLE_EOF)
+            return IOS_EOF;
+        JNU_ThrowIOExceptionWithLastError(env, "ReadFile failed");
+        return IOS_THROWN;
+    }
+
+    return (jint)nread;
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_ch_WindowsAsynchronousFileChannelImpl_writeFile(JNIEnv* env, jclass this,
+    jlong handle, jlong address, jint len, jlong offset, jlong ov)
+{
+    BOOL res;
+    DWORD nwritten = 0;
+
+    OVERLAPPED* lpOverlapped = (OVERLAPPED*)jlong_to_ptr(ov);
+    lpOverlapped->Offset = (DWORD)offset;
+    lpOverlapped->OffsetHigh = (DWORD)((long)(offset >> 32));
+    lpOverlapped->hEvent = NULL;
+
+    res = WriteFile((HANDLE)jlong_to_ptr(handle),
+                   (LPVOID) jlong_to_ptr(address),
+                   (DWORD)len,
+                   &nwritten,
+                   lpOverlapped);
+
+    if (res == 0) {
+        int error = GetLastError();
+        if (error == ERROR_IO_PENDING) {
+            return IOS_UNAVAILABLE;
+        }
+        JNU_ThrowIOExceptionWithLastError(env, "WriteFile failed");
+        return IOS_THROWN;
+    }
+    return (jint)nwritten;
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_ch_WindowsAsynchronousFileChannelImpl_lockFile(JNIEnv *env, jobject this, jlong handle,
+                                                            jlong pos, jlong size, jboolean shared, jlong ov)
+{
+    BOOL res;
+    HANDLE h = jlong_to_ptr(handle);
+    DWORD lowPos = (DWORD)pos;
+    long highPos = (long)(pos >> 32);
+    DWORD lowNumBytes = (DWORD)size;
+    DWORD highNumBytes = (DWORD)(size >> 32);
+    DWORD flags = (shared == JNI_TRUE) ? 0 : LOCKFILE_EXCLUSIVE_LOCK;
+    OVERLAPPED* lpOverlapped = (OVERLAPPED*)jlong_to_ptr(ov);
+
+    lpOverlapped->Offset = lowPos;
+    lpOverlapped->OffsetHigh = highPos;
+    lpOverlapped->hEvent = NULL;
+
+    res = LockFileEx(h, flags, 0, lowNumBytes, highNumBytes, lpOverlapped);
+    if (res == 0) {
+        int error = GetLastError();
+        if (error == ERROR_IO_PENDING) {
+            return IOS_UNAVAILABLE;
+        }
+        JNU_ThrowIOExceptionWithLastError(env, "WriteFile failed");
+        return IOS_THROWN;
+    }
+    return 0;
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_WindowsAsynchronousFileChannelImpl_close0(JNIEnv* env, jclass this,
+    jlong handle)
+{
+    HANDLE h = (HANDLE)jlong_to_ptr(handle);
+    CloseHandle(h);
+}
diff --git a/jdk/src/windows/native/sun/nio/ch/WindowsAsynchronousServerSocketChannelImpl.c b/jdk/src/windows/native/sun/nio/ch/WindowsAsynchronousServerSocketChannelImpl.c
new file mode 100644
index 0000000..ba706a4
--- /dev/null
+++ b/jdk/src/windows/native/sun/nio/ch/WindowsAsynchronousServerSocketChannelImpl.c
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+#include <windows.h>
+#include <winsock2.h>
+
+#include "jni.h"
+#include "jni_util.h"
+#include "jlong.h"
+#include "nio.h"
+#include "nio_util.h"
+#include "net_util.h"
+
+#include "sun_nio_ch_WindowsAsynchronousServerSocketChannelImpl.h"
+
+
+#ifndef WSAID_ACCEPTEX
+#define WSAID_ACCEPTEX {0xb5367df1,0xcbac,0x11cf,{0x95,0xca,0x00,0x80,0x5f,0x48,0xa1,0x92}}
+#endif
+
+#ifndef SO_UPDATE_ACCEPT_CONTEXT
+#define SO_UPDATE_ACCEPT_CONTEXT 0x700B
+#endif
+
+
+typedef BOOL (*AcceptEx_t)
+(
+    SOCKET sListenSocket,
+    SOCKET sAcceptSocket,
+    PVOID lpOutputBuffer,
+    DWORD dwReceiveDataLength,
+    DWORD dwLocalAddressLength,
+    DWORD dwRemoteAddressLength,
+    LPDWORD lpdwBytesReceived,
+    LPOVERLAPPED lpOverlapped
+);
+
+
+static AcceptEx_t AcceptEx_func;
+
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_WindowsAsynchronousServerSocketChannelImpl_initIDs(JNIEnv* env, jclass this) {
+    GUID GuidAcceptEx = WSAID_ACCEPTEX;
+    SOCKET s;
+    int rv;
+    DWORD dwBytes;
+
+    s = socket(AF_INET, SOCK_STREAM, 0);
+    if (s == INVALID_SOCKET) {
+        JNU_ThrowIOExceptionWithLastError(env, "socket failed");
+        return;
+    }
+    rv = WSAIoctl(s,
+                  SIO_GET_EXTENSION_FUNCTION_POINTER,
+                  (LPVOID)&GuidAcceptEx,
+                  sizeof(GuidAcceptEx),
+                  &AcceptEx_func,
+                  sizeof(AcceptEx_func),
+                  &dwBytes,
+                  NULL,
+                  NULL);
+    if (rv != 0)
+        JNU_ThrowIOExceptionWithLastError(env, "WSAIoctl failed");
+    closesocket(s);
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_ch_WindowsAsynchronousServerSocketChannelImpl_accept0(JNIEnv* env, jclass this,
+    jlong listenSocket, jlong acceptSocket, jlong ov, jlong buf)
+{
+    BOOL res;
+    SOCKET s1 = (SOCKET)jlong_to_ptr(listenSocket);
+    SOCKET s2 = (SOCKET)jlong_to_ptr(acceptSocket);
+    PVOID outputBuffer = (PVOID)jlong_to_ptr(buf);
+
+    DWORD nread = 0;
+    OVERLAPPED* lpOverlapped = (OVERLAPPED*)jlong_to_ptr(ov);
+    ZeroMemory((PVOID)lpOverlapped, sizeof(OVERLAPPED));
+
+    res = (*AcceptEx_func)(s1,
+                           s2,
+                           outputBuffer,
+                           0,
+                           sizeof(SOCKETADDRESS)+16,
+                           sizeof(SOCKETADDRESS)+16,
+                           &nread,
+                           lpOverlapped);
+    if (res == 0) {
+        int error = WSAGetLastError();
+        if (error == ERROR_IO_PENDING) {
+            return IOS_UNAVAILABLE;
+        }
+        JNU_ThrowIOExceptionWithLastError(env, "AcceptEx failed");
+        return IOS_THROWN;
+    }
+
+    return 0;
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_WindowsAsynchronousServerSocketChannelImpl_updateAcceptContext(JNIEnv* env, jclass this,
+    jlong listenSocket, jlong acceptSocket)
+{
+    SOCKET s1 = (SOCKET)jlong_to_ptr(listenSocket);
+    SOCKET s2 = (SOCKET)jlong_to_ptr(acceptSocket);
+
+    setsockopt(s2, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, (char *)&s1, sizeof(s1));
+}
+
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_WindowsAsynchronousServerSocketChannelImpl_closesocket0(JNIEnv* env, jclass this,
+    jlong socket)
+{
+    SOCKET s = (SOCKET)jlong_to_ptr(socket);
+
+    if (closesocket(s) == SOCKET_ERROR)
+        JNU_ThrowIOExceptionWithLastError(env, "closesocket failed");
+}
diff --git a/jdk/src/windows/native/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.c b/jdk/src/windows/native/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.c
new file mode 100644
index 0000000..97c49f6
--- /dev/null
+++ b/jdk/src/windows/native/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.c
@@ -0,0 +1,222 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+#include <windows.h>
+#include <winsock2.h>
+#include <stddef.h>
+
+#include "jni.h"
+#include "jni_util.h"
+#include "jlong.h"
+#include "nio.h"
+#include "nio_util.h"
+#include "net_util.h"
+
+#include "sun_nio_ch_WindowsAsynchronousSocketChannelImpl.h"
+
+#ifndef WSAID_CONNECTEX
+#define WSAID_CONNECTEX {0x25a207b9,0xddf3,0x4660,{0x8e,0xe9,0x76,0xe5,0x8c,0x74,0x06,0x3e}}
+#endif
+
+#ifndef SO_UPDATE_CONNECT_CONTEXT
+#define SO_UPDATE_CONNECT_CONTEXT 0x7010
+#endif
+
+typedef BOOL (*ConnectEx_t)
+(
+    SOCKET s,
+    const struct sockaddr* name,
+    int namelen,
+    PVOID lpSendBuffer,
+    DWORD dwSendDataLength,
+    LPDWORD lpdwBytesSent,
+    LPOVERLAPPED lpOverlapped
+);
+
+static ConnectEx_t ConnectEx_func;
+
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_WindowsAsynchronousSocketChannelImpl_initIDs(JNIEnv* env, jclass this) {
+    GUID GuidConnectEx = WSAID_CONNECTEX;
+    SOCKET s;
+    int rv;
+    DWORD dwBytes;
+
+    s = socket(AF_INET, SOCK_STREAM, 0);
+    if (s == INVALID_SOCKET) {
+        JNU_ThrowIOExceptionWithLastError(env, "socket failed");
+        return;
+    }
+    rv = WSAIoctl(s,
+                  SIO_GET_EXTENSION_FUNCTION_POINTER,
+                  (LPVOID)&GuidConnectEx,
+                  sizeof(GuidConnectEx),
+                  &ConnectEx_func,
+                  sizeof(ConnectEx_func),
+                  &dwBytes,
+                  NULL,
+                  NULL);
+    if (rv != 0)
+        JNU_ThrowIOExceptionWithLastError(env, "WSAIoctl failed");
+    closesocket(s);
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_ch_WindowsAsynchronousSocketChannelImpl_connect0(JNIEnv* env, jclass this,
+    jlong socket, jboolean preferIPv6, jobject iao, jint port, jlong ov)
+{
+    SOCKET s = (SOCKET) jlong_to_ptr(socket);
+    OVERLAPPED* lpOverlapped = (OVERLAPPED*) jlong_to_ptr(ov);
+
+    SOCKETADDRESS sa;
+    int sa_len;
+    BOOL res;
+
+    if (NET_InetAddressToSockaddr(env, iao, port, (struct sockaddr *)&sa, &sa_len, preferIPv6) != 0) {
+        return IOS_THROWN;
+    }
+
+    ZeroMemory((PVOID)lpOverlapped, sizeof(OVERLAPPED));
+
+    res = (*ConnectEx_func)(s,
+                            (struct sockaddr *)&sa,
+                            sa_len,
+                            NULL,
+                            0,
+                            NULL,
+                            lpOverlapped);
+    if (res == 0) {
+        int error = GetLastError();
+        if (error == ERROR_IO_PENDING) {
+            return IOS_UNAVAILABLE;
+        }
+        JNU_ThrowIOExceptionWithLastError(env, "ConnectEx failed");
+        return IOS_THROWN;
+    }
+    return 0;
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_WindowsAsynchronousSocketChannelImpl_updateConnectContext(JNIEnv* env, jclass this,
+    jlong socket)
+{
+    SOCKET s = (SOCKET)jlong_to_ptr(socket);
+    setsockopt(s, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0);
+}
+
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_WindowsAsynchronousSocketChannelImpl_shutdown0(JNIEnv *env, jclass cl,
+    jlong socket, jint how)
+{
+    SOCKET s =(SOCKET) jlong_to_ptr(socket);
+    if (shutdown(s, how) == SOCKET_ERROR) {
+        JNU_ThrowIOExceptionWithLastError(env, "shutdown failed");
+    }
+}
+
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_WindowsAsynchronousSocketChannelImpl_closesocket0(JNIEnv* env, jclass this,
+    jlong socket)
+{
+    SOCKET s = (SOCKET)jlong_to_ptr(socket);
+    if (closesocket(s) == SOCKET_ERROR)
+        JNU_ThrowIOExceptionWithLastError(env, "closesocket failed");
+}
+
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_ch_WindowsAsynchronousSocketChannelImpl_read0(JNIEnv* env, jclass this,
+    jlong socket, jint count, jlong address, jlong ov)
+{
+    SOCKET s = (SOCKET) jlong_to_ptr(socket);
+    WSABUF* lpWsaBuf = (WSABUF*) jlong_to_ptr(address);
+    OVERLAPPED* lpOverlapped = (OVERLAPPED*) jlong_to_ptr(ov);
+    BOOL res;
+    DWORD nread = 0;
+    DWORD flags = 0;
+
+    ZeroMemory((PVOID)lpOverlapped, sizeof(OVERLAPPED));
+    res = WSARecv(s,
+                  lpWsaBuf,
+                  (DWORD)count,
+                  &nread,
+                  &flags,
+                  lpOverlapped,
+                  NULL);
+
+    if (res == SOCKET_ERROR) {
+        int error = WSAGetLastError();
+        if (error == WSA_IO_PENDING) {
+            return IOS_UNAVAILABLE;
+        }
+        if (error == WSAESHUTDOWN) {
+            return 0;       // input shutdown
+        }
+        JNU_ThrowIOExceptionWithLastError(env, "WSARecv failed");
+        return IOS_THROWN;
+    }
+    if (nread == 0) {
+        // Handle graceful close or bytes not yet available cases
+        // via completion port notification.
+        return IOS_UNAVAILABLE;
+    }
+    return (jint)nread;
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_ch_WindowsAsynchronousSocketChannelImpl_write0(JNIEnv* env, jclass this,
+    jlong socket, jint count, jlong address, jlong ov)
+{
+    SOCKET s = (SOCKET) jlong_to_ptr(socket);
+    WSABUF* lpWsaBuf = (WSABUF*) jlong_to_ptr(address);
+    OVERLAPPED* lpOverlapped = (OVERLAPPED*) jlong_to_ptr(ov);
+    BOOL res;
+    DWORD nwritten;
+
+    ZeroMemory((PVOID)lpOverlapped, sizeof(OVERLAPPED));
+    res = WSASend(s,
+                  lpWsaBuf,
+                  (DWORD)count,
+                  &nwritten,
+                  0,
+                  lpOverlapped,
+                  NULL);
+
+    if (res == SOCKET_ERROR) {
+        int error = WSAGetLastError();
+        if (error == WSA_IO_PENDING) {
+            return IOS_UNAVAILABLE;
+        }
+        if (error == WSAESHUTDOWN) {
+            return IOS_EOF;     // output shutdown
+        }
+        JNU_ThrowIOExceptionWithLastError(env, "WSASend failed");
+        return IOS_THROWN;
+    }
+    return (jint)nwritten;
+}
diff --git a/jdk/src/windows/native/sun/nio/fs/RegistryFileTypeDetector.c b/jdk/src/windows/native/sun/nio/fs/RegistryFileTypeDetector.c
new file mode 100644
index 0000000..14c7f6a
--- /dev/null
+++ b/jdk/src/windows/native/sun/nio/fs/RegistryFileTypeDetector.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+#include <windows.h>
+
+#include "jni.h"
+#include "jni_util.h"
+#include "jlong.h"
+
+#include "sun_nio_fs_RegistryFileTypeDetector.h"
+
+
+JNIEXPORT jstring JNICALL
+Java_sun_nio_fs_RegistryFileTypeDetector_queryStringValue(JNIEnv* env, jclass this,
+    jlong keyAddress, jlong nameAddress)
+{
+    LPCWSTR lpSubKey= (LPCWSTR)jlong_to_ptr(keyAddress);
+    LPWSTR lpValueName = (LPWSTR)jlong_to_ptr(nameAddress);
+    LONG res;
+    HKEY hKey;
+    jstring result = NULL;
+
+    res = RegOpenKeyExW(HKEY_CLASSES_ROOT, lpSubKey, 0, KEY_READ, &hKey);
+    if (res == ERROR_SUCCESS) {
+        DWORD type;
+        BYTE data[255];
+        DWORD size = sizeof(data);
+
+        res = RegQueryValueExW(hKey, lpValueName, NULL, &type, (LPBYTE)&data, &size);
+        if (res == ERROR_SUCCESS) {
+            if (type == REG_SZ) {
+                jsize len = wcslen((WCHAR*)data);
+                result = (*env)->NewString(env, (const jchar*)&data, len);
+            }
+        }
+
+        RegCloseKey(hKey);
+    }
+    return result;
+}
diff --git a/jdk/src/windows/native/sun/nio/fs/WindowsNativeDispatcher.c b/jdk/src/windows/native/sun/nio/fs/WindowsNativeDispatcher.c
new file mode 100644
index 0000000..45a3646
--- /dev/null
+++ b/jdk/src/windows/native/sun/nio/fs/WindowsNativeDispatcher.c
@@ -0,0 +1,1345 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+#ifndef _WIN32_WINNT
+#define _WIN32_WINNT 0x0500
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <direct.h>
+#include <malloc.h>
+#include <io.h>
+#include <windows.h>
+#include <aclapi.h>
+#include <winioctl.h>
+
+#include "jni.h"
+#include "jni_util.h"
+#include "jlong.h"
+
+#include "sun_nio_fs_WindowsNativeDispatcher.h"
+
+/**
+ * jfieldIDs
+ */
+static jfieldID findFirst_handle;
+static jfieldID findFirst_name;
+
+static jfieldID findStream_handle;
+static jfieldID findStream_name;
+
+static jfieldID volumeInfo_fsName;
+static jfieldID volumeInfo_volName;
+static jfieldID volumeInfo_volSN;
+static jfieldID volumeInfo_flags;
+
+static jfieldID diskSpace_bytesAvailable;
+static jfieldID diskSpace_totalBytes;
+static jfieldID diskSpace_totalFree;
+
+static jfieldID account_domain;
+static jfieldID account_name;
+static jfieldID account_use;
+
+static jfieldID aclInfo_aceCount;
+
+static jfieldID completionStatus_error;
+static jfieldID completionStatus_bytesTransferred;
+static jfieldID completionStatus_completionKey;
+
+static jfieldID backupResult_bytesTransferred;
+static jfieldID backupResult_context;
+
+
+/**
+ * Win32 APIs not defined in Visual Studio 2003 header files
+ */
+
+typedef enum {
+  FindStreamInfoStandard
+} MY_STREAM_INFO_LEVELS;
+
+typedef struct _MY_WIN32_FIND_STREAM_DATA {
+  LARGE_INTEGER StreamSize;
+  WCHAR cStreamName[MAX_PATH + 36];
+} MY_WIN32_FIND_STREAM_DATA;
+
+typedef HANDLE (WINAPI* FindFirstStream_Proc)(LPCWSTR, MY_STREAM_INFO_LEVELS, LPVOID, DWORD);
+typedef BOOL (WINAPI* FindNextStream_Proc)(HANDLE, LPVOID);
+
+typedef BOOLEAN (WINAPI* CreateSymbolicLinkProc) (LPCWSTR, LPCWSTR, DWORD);
+typedef BOOL (WINAPI* CreateHardLinkProc) (LPCWSTR, LPCWSTR, LPSECURITY_ATTRIBUTES);
+typedef BOOL (WINAPI* GetFinalPathNameByHandleProc) (HANDLE, LPWSTR, DWORD, DWORD);
+
+typedef BOOL (WINAPI* ConvertSidToStringSidProc) (PSID, LPWSTR*);
+typedef BOOL (WINAPI* ConvertStringSidToSidProc) (LPWSTR, PSID*);
+typedef DWORD (WINAPI* GetLengthSidProc) (PSID);
+
+static FindFirstStream_Proc FindFirstStream_func;
+static FindNextStream_Proc FindNextStream_func;
+
+static CreateSymbolicLinkProc CreateSymbolicLink_func;
+static CreateHardLinkProc CreateHardLink_func;
+static GetFinalPathNameByHandleProc GetFinalPathNameByHandle_func;
+
+static ConvertSidToStringSidProc ConvertSidToStringSid_func;
+static ConvertStringSidToSidProc ConvertStringSidToSid_func;
+static GetLengthSidProc GetLengthSid_func;
+
+static void throwWindowsException(JNIEnv* env, DWORD lastError) {
+    jobject x = JNU_NewObjectByName(env, "sun/nio/fs/WindowsException",
+        "(I)V", lastError);
+    if (x != NULL) {
+        (*env)->Throw(env, x);
+    }
+}
+
+/**
+ * Initializes jfieldIDs and get address of Win32 calls that are located
+ * at runtime.
+ */
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_initIDs(JNIEnv* env, jclass this)
+{
+    jclass clazz;
+    HMODULE h;
+
+    clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$FirstFile");
+    if (clazz == NULL) {
+        return;
+    }
+    findFirst_handle = (*env)->GetFieldID(env, clazz, "handle", "J");
+    findFirst_name = (*env)->GetFieldID(env, clazz, "name", "Ljava/lang/String;");
+
+    clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$FirstStream");
+    if (clazz == NULL) {
+        return;
+    }
+    findStream_handle = (*env)->GetFieldID(env, clazz, "handle", "J");
+    findStream_name = (*env)->GetFieldID(env, clazz, "name", "Ljava/lang/String;");
+
+    clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$VolumeInformation");
+    if (clazz == NULL) {
+        return;
+    }
+    volumeInfo_fsName = (*env)->GetFieldID(env, clazz, "fileSystemName", "Ljava/lang/String;");
+    volumeInfo_volName = (*env)->GetFieldID(env, clazz, "volumeName", "Ljava/lang/String;");
+    volumeInfo_volSN = (*env)->GetFieldID(env, clazz, "volumeSerialNumber", "I");
+    volumeInfo_flags = (*env)->GetFieldID(env, clazz, "flags", "I");
+
+    clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$DiskFreeSpace");
+    if (clazz == NULL) {
+        return;
+    }
+    diskSpace_bytesAvailable = (*env)->GetFieldID(env, clazz, "freeBytesAvailable", "J");
+    diskSpace_totalBytes = (*env)->GetFieldID(env, clazz, "totalNumberOfBytes", "J");
+    diskSpace_totalFree = (*env)->GetFieldID(env, clazz, "totalNumberOfFreeBytes", "J");
+
+    clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$Account");
+    if (clazz == NULL) {
+        return;
+    }
+    account_domain = (*env)->GetFieldID(env, clazz, "domain", "Ljava/lang/String;");
+    account_name = (*env)->GetFieldID(env, clazz, "name", "Ljava/lang/String;");
+    account_use = (*env)->GetFieldID(env, clazz, "use", "I");
+
+    clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$AclInformation");
+    if (clazz == NULL) {
+        return;
+    }
+    aclInfo_aceCount = (*env)->GetFieldID(env, clazz, "aceCount", "I");
+
+    clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$CompletionStatus");
+    if (clazz == NULL) {
+        return;
+    }
+    completionStatus_error = (*env)->GetFieldID(env, clazz, "error", "I");
+    completionStatus_bytesTransferred = (*env)->GetFieldID(env, clazz, "bytesTransferred", "I");
+    completionStatus_completionKey = (*env)->GetFieldID(env, clazz, "completionKey", "I");
+
+    clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$BackupResult");
+    if (clazz == NULL) {
+        return;
+    }
+    backupResult_bytesTransferred = (*env)->GetFieldID(env, clazz, "bytesTransferred", "I");
+    backupResult_context = (*env)->GetFieldID(env, clazz, "context", "J");
+
+
+    h = LoadLibrary("kernel32");
+    if (h != INVALID_HANDLE_VALUE) {
+        FindFirstStream_func =
+            (FindFirstStream_Proc)GetProcAddress(h, "FindFirstStreamW");
+        FindNextStream_func =
+            (FindNextStream_Proc)GetProcAddress(h, "FindNextStreamW");
+        CreateSymbolicLink_func =
+            (CreateSymbolicLinkProc)GetProcAddress(h, "CreateSymbolicLinkW");
+        CreateHardLink_func =
+            (CreateHardLinkProc)GetProcAddress(h, "CreateHardLinkW");
+        GetFinalPathNameByHandle_func =
+            (GetFinalPathNameByHandleProc)GetProcAddress(h, "GetFinalPathNameByHandleW");
+        FreeLibrary(h);
+    }
+
+    h = LoadLibrary("advapi32");
+    if (h != INVALID_HANDLE_VALUE) {
+        ConvertSidToStringSid_func =
+            (ConvertSidToStringSidProc)GetProcAddress(h, "ConvertSidToStringSidW");
+        ConvertStringSidToSid_func =
+            (ConvertStringSidToSidProc)GetProcAddress(h, "ConvertStringSidToSidW");
+        GetLengthSid_func =
+            (GetLengthSidProc)GetProcAddress(h, "GetLengthSid");
+        FreeLibrary(h);
+    }
+
+}
+
+JNIEXPORT jstring JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_FormatMessage(JNIEnv* env, jclass this, jint errorCode) {
+    WCHAR message[255];
+
+    DWORD len = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM,
+                               NULL,
+                               (DWORD)errorCode,
+                               0,
+                               &message[0],
+                               255,
+                               NULL);
+
+
+    if (len == 0) {
+        return NULL;
+    } else {
+        return (*env)->NewString(env, (const jchar *)message, (jsize)wcslen(message));
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_LocalFree(JNIEnv* env, jclass this, jlong address)
+{
+    HLOCAL hMem = (HLOCAL)jlong_to_ptr(address);
+    LocalFree(hMem);
+}
+
+JNIEXPORT jlong JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_CreateFile0(JNIEnv* env, jclass this,
+    jlong address, jint dwDesiredAccess, jint dwShareMode, jlong sdAddress,
+    jint dwCreationDisposition, jint dwFlagsAndAttributes)
+{
+    HANDLE handle;
+    LPCWSTR lpFileName = jlong_to_ptr(address);
+
+    SECURITY_ATTRIBUTES securityAttributes;
+    LPSECURITY_ATTRIBUTES lpSecurityAttributes;
+    PSECURITY_DESCRIPTOR lpSecurityDescriptor = jlong_to_ptr(sdAddress);
+
+
+    if (lpSecurityDescriptor == NULL) {
+        lpSecurityAttributes = NULL;
+    } else {
+        securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
+        securityAttributes.lpSecurityDescriptor = lpSecurityDescriptor;
+        securityAttributes.bInheritHandle = FALSE;
+        lpSecurityAttributes = &securityAttributes;
+    }
+
+    handle = CreateFileW(lpFileName,
+                        (DWORD)dwDesiredAccess,
+                        (DWORD)dwShareMode,
+                        lpSecurityAttributes,
+                        (DWORD)dwCreationDisposition,
+                        (DWORD)dwFlagsAndAttributes,
+                        NULL);
+    if (handle == INVALID_HANDLE_VALUE) {
+        throwWindowsException(env, GetLastError());
+    }
+    return ptr_to_jlong(handle);
+}
+
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_DeviceIoControlSetSparse(JNIEnv* env, jclass this,
+    jlong handle)
+{
+    DWORD bytesReturned;
+    HANDLE h = (HANDLE)jlong_to_ptr(handle);
+    if (DeviceIoControl(h, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, &bytesReturned, NULL) == 0) {
+        throwWindowsException(env, GetLastError());
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_DeviceIoControlGetReparsePoint(JNIEnv* env, jclass this,
+    jlong handle, jlong bufferAddress, jint bufferSize)
+{
+    DWORD bytesReturned;
+    HANDLE h = (HANDLE)jlong_to_ptr(handle);
+    LPVOID outBuffer = (LPVOID)jlong_to_ptr(bufferAddress);
+
+    if (DeviceIoControl(h, FSCTL_GET_REPARSE_POINT, NULL, 0, outBuffer, (DWORD)bufferSize,
+                        &bytesReturned, NULL) == 0)
+    {
+        throwWindowsException(env, GetLastError());
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_DeleteFile0(JNIEnv* env, jclass this, jlong address)
+{
+    LPCWSTR lpFileName = jlong_to_ptr(address);
+    if (DeleteFileW(lpFileName) == 0) {
+        throwWindowsException(env, GetLastError());
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_CreateDirectory0(JNIEnv* env, jclass this,
+    jlong address, jlong sdAddress)
+{
+    LPCWSTR lpFileName = jlong_to_ptr(address);
+
+    SECURITY_ATTRIBUTES securityAttributes;
+    LPSECURITY_ATTRIBUTES lpSecurityAttributes;
+    PSECURITY_DESCRIPTOR lpSecurityDescriptor = jlong_to_ptr(sdAddress);
+
+
+    if (lpSecurityDescriptor == NULL) {
+        lpSecurityAttributes = NULL;
+    } else {
+        securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
+        securityAttributes.lpSecurityDescriptor = lpSecurityDescriptor;
+        securityAttributes.bInheritHandle = FALSE;
+        lpSecurityAttributes = &securityAttributes;
+    }
+
+    if (CreateDirectoryW(lpFileName, lpSecurityAttributes) == 0) {
+        throwWindowsException(env, GetLastError());
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_RemoveDirectory0(JNIEnv* env, jclass this, jlong address)
+{
+    LPCWSTR lpFileName = jlong_to_ptr(address);
+    if (RemoveDirectoryW(lpFileName) == 0) {
+        throwWindowsException(env, GetLastError());
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_CloseHandle(JNIEnv* env, jclass this,
+    jlong handle)
+{
+    HANDLE h = (HANDLE)jlong_to_ptr(handle);
+    CloseHandle(h);
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_FindFirstFile0(JNIEnv* env, jclass this,
+    jlong address, jobject obj)
+{
+    WIN32_FIND_DATAW data;
+    LPCWSTR lpFileName = jlong_to_ptr(address);
+
+    HANDLE handle = FindFirstFileW(lpFileName, &data);
+    if (handle != INVALID_HANDLE_VALUE) {
+        jstring name = (*env)->NewString(env, data.cFileName, wcslen(data.cFileName));
+        if (name == NULL)
+            return;
+        (*env)->SetLongField(env, obj, findFirst_handle, ptr_to_jlong(handle));
+        (*env)->SetObjectField(env, obj, findFirst_name, name);
+    } else {
+        throwWindowsException(env, GetLastError());
+    }
+}
+
+JNIEXPORT jlong JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_FindFirstFile1(JNIEnv* env, jclass this,
+    jlong pathAddress, jlong dataAddress)
+{
+    LPCWSTR lpFileName = jlong_to_ptr(pathAddress);
+    WIN32_FIND_DATAW* data = (WIN32_FIND_DATAW*)jlong_to_ptr(dataAddress);
+
+    HANDLE handle = FindFirstFileW(lpFileName, data);
+    if (handle == INVALID_HANDLE_VALUE) {
+        throwWindowsException(env, GetLastError());
+    }
+        return ptr_to_jlong(handle);
+}
+
+JNIEXPORT jstring JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_FindNextFile(JNIEnv* env, jclass this,
+    jlong handle, jlong dataAddress)
+{
+    HANDLE h = (HANDLE)jlong_to_ptr(handle);
+    WIN32_FIND_DATAW* data = (WIN32_FIND_DATAW*)jlong_to_ptr(dataAddress);
+
+    if (FindNextFileW(h, data) != 0) {
+        return (*env)->NewString(env, data->cFileName, wcslen(data->cFileName));
+    } else {
+    if (GetLastError() != ERROR_NO_MORE_FILES)
+        throwWindowsException(env, GetLastError());
+        return NULL;
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_FindFirstStream0(JNIEnv* env, jclass this,
+    jlong address, jobject obj)
+{
+    MY_WIN32_FIND_STREAM_DATA data;
+    LPCWSTR lpFileName = jlong_to_ptr(address);
+    HANDLE handle;
+
+    if (FindFirstStream_func == NULL) {
+        JNU_ThrowInternalError(env, "Should not get here");
+        return;
+    }
+
+    handle = (*FindFirstStream_func)(lpFileName, FindStreamInfoStandard, &data, 0);
+    if (handle != INVALID_HANDLE_VALUE) {
+        jstring name = (*env)->NewString(env, data.cStreamName, wcslen(data.cStreamName));
+        if (name == NULL)
+            return;
+        (*env)->SetLongField(env, obj, findStream_handle, ptr_to_jlong(handle));
+        (*env)->SetObjectField(env, obj, findStream_name, name);
+    } else {
+        if (GetLastError() == ERROR_HANDLE_EOF) {
+             (*env)->SetLongField(env, obj, findStream_handle, ptr_to_jlong(handle));
+        } else {
+            throwWindowsException(env, GetLastError());
+        }
+    }
+
+}
+
+JNIEXPORT jstring JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_FindNextStream(JNIEnv* env, jclass this,
+    jlong handle)
+{
+    MY_WIN32_FIND_STREAM_DATA data;
+    HANDLE h = (HANDLE)jlong_to_ptr(handle);
+
+    if (FindNextStream_func == NULL) {
+        JNU_ThrowInternalError(env, "Should not get here");
+        return NULL;
+    }
+
+    if ((*FindNextStream_func)(h, &data) != 0) {
+        return (*env)->NewString(env, data.cStreamName, wcslen(data.cStreamName));
+    } else {
+        if (GetLastError() != ERROR_HANDLE_EOF)
+            throwWindowsException(env, GetLastError());
+        return NULL;
+    }
+}
+
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_FindClose(JNIEnv* env, jclass this,
+    jlong handle)
+{
+    HANDLE h = (HANDLE)jlong_to_ptr(handle);
+    if (FindClose(h) == 0) {
+        throwWindowsException(env, GetLastError());
+    }
+}
+
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_GetFileInformationByHandle(JNIEnv* env, jclass this,
+    jlong handle, jlong address)
+{
+    HANDLE h = (HANDLE)jlong_to_ptr(handle);
+    BY_HANDLE_FILE_INFORMATION* info =
+        (BY_HANDLE_FILE_INFORMATION*)jlong_to_ptr(address);
+    if (GetFileInformationByHandle(h, info) == 0) {
+        throwWindowsException(env, GetLastError());
+    }
+}
+
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_CopyFileEx0(JNIEnv* env, jclass this,
+    jlong existingAddress, jlong newAddress, jint flags, jlong cancelAddress)
+{
+    LPCWSTR lpExistingFileName = jlong_to_ptr(existingAddress);
+    LPCWSTR lpNewFileName = jlong_to_ptr(newAddress);
+    LPBOOL cancel = (LPBOOL)jlong_to_ptr(cancelAddress);
+    if (CopyFileExW(lpExistingFileName, lpNewFileName, NULL, NULL, cancel,
+                    (DWORD)flags) == 0)
+    {
+        throwWindowsException(env, GetLastError());
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_MoveFileEx0(JNIEnv* env, jclass this,
+    jlong existingAddress, jlong newAddress, jint flags)
+{
+    LPCWSTR lpExistingFileName = jlong_to_ptr(existingAddress);
+    LPCWSTR lpNewFileName = jlong_to_ptr(newAddress);
+    if (MoveFileExW(lpExistingFileName, lpNewFileName, (DWORD)flags) == 0) {
+        throwWindowsException(env, GetLastError());
+    }
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_GetLogicalDrives(JNIEnv* env, jclass this)
+{
+    DWORD res = GetLogicalDrives();
+    if (res == 0) {
+        throwWindowsException(env, GetLastError());
+    }
+    return (jint)res;
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_GetFileAttributes0(JNIEnv* env, jclass this,
+    jlong address)
+{
+    LPCWSTR lpFileName = jlong_to_ptr(address);
+    DWORD value = GetFileAttributesW(lpFileName);
+
+    if (value == INVALID_FILE_ATTRIBUTES) {
+        throwWindowsException(env, GetLastError());
+    }
+    return (jint)value;
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_SetFileAttributes0(JNIEnv* env, jclass this,
+    jlong address, jint value)
+{
+    LPCWSTR lpFileName = jlong_to_ptr(address);
+    if (SetFileAttributesW(lpFileName, (DWORD)value) == 0) {
+        throwWindowsException(env, GetLastError());
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_GetFileAttributesEx0(JNIEnv* env, jclass this,
+    jlong pathAddress, jlong dataAddress)
+{
+    LPCWSTR lpFileName = jlong_to_ptr(pathAddress);
+    WIN32_FILE_ATTRIBUTE_DATA* data = (WIN32_FILE_ATTRIBUTE_DATA*)jlong_to_ptr(dataAddress);
+
+    BOOL res = GetFileAttributesExW(lpFileName, GetFileExInfoStandard, (LPVOID)data);
+    if (res == 0)
+        throwWindowsException(env, GetLastError());
+}
+
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_SetFileTime(JNIEnv* env, jclass this,
+    jlong handle, jlong createTime, jlong lastAccessTime, jlong lastWriteTime)
+{
+    HANDLE h = (HANDLE)jlong_to_ptr(handle);
+
+    if (SetFileTime(h,
+        (createTime == (jlong)0) ? NULL : (CONST FILETIME *)&createTime,
+        (lastAccessTime == (jlong)0) ? NULL : (CONST FILETIME *)&lastAccessTime,
+        (lastWriteTime == (jlong)0) ? NULL : (CONST FILETIME *)&lastWriteTime) == 0)
+    {
+        throwWindowsException(env, GetLastError());
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_SetEndOfFile(JNIEnv* env, jclass this,
+    jlong handle)
+{
+    HANDLE h = (HANDLE)jlong_to_ptr(handle);
+
+    if (SetEndOfFile(h) == 0)
+        throwWindowsException(env, GetLastError());
+}
+
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_GetVolumeInformation0(JNIEnv* env, jclass this,
+    jlong address, jobject obj)
+{
+    WCHAR volumeName[MAX_PATH+1];
+    DWORD volumeSerialNumber;
+    DWORD maxComponentLength;
+    DWORD flags;
+    WCHAR fileSystemName[MAX_PATH+1];
+    LPCWSTR lpFileName = jlong_to_ptr(address);
+    jstring str;
+
+    BOOL res = GetVolumeInformationW(lpFileName,
+                                     &volumeName[0],
+                                     MAX_PATH+1,
+                                     &volumeSerialNumber,
+                                     &maxComponentLength,
+                                     &flags,
+                                     &fileSystemName[0],
+                                     MAX_PATH+1);
+    if (res == 0) {
+        throwWindowsException(env, GetLastError());
+        return;
+    }
+
+    str = (*env)->NewString(env, (const jchar *)fileSystemName, (jsize)wcslen(fileSystemName));
+    if (str == NULL) return;
+    (*env)->SetObjectField(env, obj, volumeInfo_fsName, str);
+
+    str = (*env)->NewString(env, (const jchar *)volumeName, (jsize)wcslen(volumeName));
+    if (str == NULL) return;
+    (*env)->SetObjectField(env, obj, volumeInfo_volName, str);
+
+    (*env)->SetIntField(env, obj, volumeInfo_volSN, (jint)volumeSerialNumber);
+    (*env)->SetIntField(env, obj, volumeInfo_flags, (jint)flags);
+}
+
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_GetDriveType0(JNIEnv* env, jclass this, jlong address) {
+    LPCWSTR lpRootPathName = jlong_to_ptr(address);
+    return (jint)GetDriveTypeW(lpRootPathName);
+}
+
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_GetDiskFreeSpaceEx0(JNIEnv* env, jclass this,
+    jlong address, jobject obj)
+{
+    ULARGE_INTEGER freeBytesAvailable;
+    ULARGE_INTEGER totalNumberOfBytes;
+    ULARGE_INTEGER totalNumberOfFreeBytes;
+    LPCWSTR lpDirName = jlong_to_ptr(address);
+
+
+    BOOL res = GetDiskFreeSpaceExW(lpDirName,
+                                   &freeBytesAvailable,
+                                   &totalNumberOfBytes,
+                                   &totalNumberOfFreeBytes);
+    if (res == 0) {
+        throwWindowsException(env, GetLastError());
+        return;
+    }
+
+    (*env)->SetLongField(env, obj, diskSpace_bytesAvailable,
+        long_to_jlong(freeBytesAvailable.QuadPart));
+    (*env)->SetLongField(env, obj, diskSpace_totalBytes,
+        long_to_jlong(totalNumberOfBytes.QuadPart));
+    (*env)->SetLongField(env, obj, diskSpace_totalFree,
+        long_to_jlong(totalNumberOfFreeBytes.QuadPart));
+}
+
+
+JNIEXPORT jstring JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_GetVolumePathName0(JNIEnv* env, jclass this,
+    jlong address)
+{
+    WCHAR volumeName[MAX_PATH+1];
+    LPCWSTR lpFileName = jlong_to_ptr(address);
+
+
+    BOOL res = GetVolumePathNameW(lpFileName,
+                                  &volumeName[0],
+                                  MAX_PATH+1);
+    if (res == 0) {
+        throwWindowsException(env, GetLastError());
+        return NULL;
+    } else {
+        return (*env)->NewString(env, (const jchar *)volumeName, (jsize)wcslen(volumeName));
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_InitializeSecurityDescriptor(JNIEnv* env, jclass this,
+    jlong address)
+{
+    PSECURITY_DESCRIPTOR pSecurityDescriptor =
+        (PSECURITY_DESCRIPTOR)jlong_to_ptr(address);
+
+    if (InitializeSecurityDescriptor(pSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION) == 0) {
+        throwWindowsException(env, GetLastError());
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_InitializeAcl(JNIEnv* env, jclass this,
+    jlong address, jint size)
+{
+    PACL pAcl = (PACL)jlong_to_ptr(address);
+
+    if (InitializeAcl(pAcl, (DWORD)size, ACL_REVISION) == 0) {
+        throwWindowsException(env, GetLastError());
+    }
+}
+
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_SetFileSecurity0(JNIEnv* env, jclass this,
+    jlong pathAddress, jint requestedInformation, jlong descAddress)
+{
+    LPCWSTR lpFileName = jlong_to_ptr(pathAddress);
+    PSECURITY_DESCRIPTOR pSecurityDescriptor = jlong_to_ptr(descAddress);
+    DWORD lengthNeeded = 0;
+
+    BOOL res = SetFileSecurityW(lpFileName,
+                                (SECURITY_INFORMATION)requestedInformation,
+                                pSecurityDescriptor);
+
+    if (res == 0) {
+        throwWindowsException(env, GetLastError());
+    }
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_GetFileSecurity0(JNIEnv* env, jclass this,
+    jlong pathAddress, jint requestedInformation, jlong descAddress, jint nLength)
+{
+    LPCWSTR lpFileName = jlong_to_ptr(pathAddress);
+    PSECURITY_DESCRIPTOR pSecurityDescriptor = jlong_to_ptr(descAddress);
+    DWORD lengthNeeded = 0;
+
+    BOOL res = GetFileSecurityW(lpFileName,
+                                (SECURITY_INFORMATION)requestedInformation,
+                                pSecurityDescriptor,
+                                (DWORD)nLength,
+                                &lengthNeeded);
+
+    if (res == 0) {
+        if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+            return (jint)lengthNeeded;
+        } else {
+            throwWindowsException(env, GetLastError());
+            return 0;
+        }
+    } else {
+        return (jint)nLength;
+    }
+}
+
+JNIEXPORT jlong JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_GetSecurityDescriptorOwner(JNIEnv* env,
+    jclass this, jlong address)
+{
+    PSECURITY_DESCRIPTOR pSecurityDescriptor = jlong_to_ptr(address);
+    PSID pOwner;
+    BOOL bOwnerDefaulted;
+
+
+    if (GetSecurityDescriptorOwner(pSecurityDescriptor, &pOwner, &bOwnerDefaulted) == 0) {
+        throwWindowsException(env, GetLastError());
+    }
+    return ptr_to_jlong(pOwner);
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_SetSecurityDescriptorOwner(JNIEnv* env,
+    jclass this, jlong descAddress, jlong ownerAddress)
+{
+    PSECURITY_DESCRIPTOR pSecurityDescriptor = jlong_to_ptr(descAddress);
+    PSID pOwner = jlong_to_ptr(ownerAddress);
+
+    if (SetSecurityDescriptorOwner(pSecurityDescriptor, pOwner, FALSE) == 0) {
+        throwWindowsException(env, GetLastError());
+    }
+}
+
+
+JNIEXPORT jlong JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_GetSecurityDescriptorDacl(JNIEnv* env,
+    jclass this, jlong address)
+{
+    PSECURITY_DESCRIPTOR pSecurityDescriptor = jlong_to_ptr(address);
+    BOOL bDaclPresent;
+    PACL pDacl;
+    BOOL bDaclDefaulted;
+
+    if (GetSecurityDescriptorDacl(pSecurityDescriptor, &bDaclPresent, &pDacl, &bDaclDefaulted) == 0) {
+        throwWindowsException(env, GetLastError());
+        return (jlong)0;
+    } else {
+        return (bDaclPresent) ? ptr_to_jlong(pDacl) : (jlong)0;
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_SetSecurityDescriptorDacl(JNIEnv* env,
+    jclass this, jlong descAddress, jlong aclAddress)
+{
+    PSECURITY_DESCRIPTOR pSecurityDescriptor = (PSECURITY_DESCRIPTOR)jlong_to_ptr(descAddress);
+    PACL pAcl = (PACL)jlong_to_ptr(aclAddress);
+
+    if (SetSecurityDescriptorDacl(pSecurityDescriptor, TRUE, pAcl, FALSE) == 0) {
+        throwWindowsException(env, GetLastError());
+    }
+}
+
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_GetAclInformation0(JNIEnv* env,
+    jclass this, jlong address, jobject obj)
+{
+    PACL pAcl = (PACL)jlong_to_ptr(address);
+    ACL_SIZE_INFORMATION acl_size_info;
+
+    if (GetAclInformation(pAcl, (void *) &acl_size_info, sizeof(acl_size_info), AclSizeInformation) == 0) {
+        throwWindowsException(env, GetLastError());
+    } else {
+        (*env)->SetIntField(env, obj, aclInfo_aceCount, (jint)acl_size_info.AceCount);
+    }
+}
+
+JNIEXPORT jlong JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_GetAce(JNIEnv* env, jclass this, jlong address,
+    jint aceIndex)
+{
+    PACL pAcl = (PACL)jlong_to_ptr(address);
+    LPVOID pAce;
+
+    if (GetAce(pAcl, (DWORD)aceIndex, &pAce) == 0) {
+        throwWindowsException(env, GetLastError());
+        return (jlong)0;
+    } else {
+        return ptr_to_jlong(pAce);
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_AddAccessAllowedAceEx(JNIEnv* env,
+    jclass this, jlong aclAddress, jint flags, jint mask, jlong sidAddress)
+{
+    PACL pAcl = (PACL)jlong_to_ptr(aclAddress);
+    PSID pSid = (PSID)jlong_to_ptr(sidAddress);
+
+    if (AddAccessAllowedAceEx(pAcl, ACL_REVISION, (DWORD)flags, (DWORD)mask, pSid) == 0) {
+        throwWindowsException(env, GetLastError());
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_AddAccessDeniedAceEx(JNIEnv* env,
+    jclass this, jlong aclAddress, jint flags, jint mask, jlong sidAddress)
+{
+    PACL pAcl = (PACL)jlong_to_ptr(aclAddress);
+    PSID pSid = (PSID)jlong_to_ptr(sidAddress);
+
+    if (AddAccessDeniedAceEx(pAcl, ACL_REVISION, (DWORD)flags, (DWORD)mask, pSid) == 0) {
+        throwWindowsException(env, GetLastError());
+    }
+}
+
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_LookupAccountSid0(JNIEnv* env,
+    jclass this, jlong address, jobject obj)
+{
+    WCHAR domain[255];
+    WCHAR name[255];
+    DWORD domainLen = sizeof(domain);
+    DWORD nameLen = sizeof(name);
+    SID_NAME_USE use;
+    PSID sid = jlong_to_ptr(address);
+    jstring s;
+
+    if (LookupAccountSidW(NULL, sid, &name[0], &nameLen, &domain[0], &domainLen, &use) == 0) {
+        throwWindowsException(env, GetLastError());
+        return;
+    }
+
+    s = (*env)->NewString(env, (const jchar *)domain, (jsize)wcslen(domain));
+    if (s == NULL)
+        return;
+    (*env)->SetObjectField(env, obj, account_domain, s);
+
+    s = (*env)->NewString(env, (const jchar *)name, (jsize)wcslen(name));
+    if (s == NULL)
+        return;
+    (*env)->SetObjectField(env, obj, account_name, s);
+    (*env)->SetIntField(env, obj, account_use, (jint)use);
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_LookupAccountName0(JNIEnv* env,
+    jclass this, jlong nameAddress, jlong sidAddress, jint cbSid)
+{
+
+    LPCWSTR accountName = jlong_to_ptr(nameAddress);
+    PSID sid = jlong_to_ptr(sidAddress);
+    WCHAR domain[255];
+    DWORD domainLen = sizeof(domain);
+    SID_NAME_USE use;
+
+    if (LookupAccountNameW(NULL, accountName, sid, (LPDWORD)&cbSid,
+                           &domain[0], &domainLen, &use) == 0)
+    {
+        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
+            throwWindowsException(env, GetLastError());
+        }
+    }
+
+    return cbSid;
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_GetLengthSid(JNIEnv* env,
+    jclass this, jlong address)
+{
+    PSID sid = jlong_to_ptr(address);
+
+    if (GetLengthSid_func == NULL) {
+        JNU_ThrowInternalError(env, "Should not get here");
+        return 0;
+    }
+    return (jint)(*GetLengthSid_func)(sid);
+}
+
+
+JNIEXPORT jstring JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_ConvertSidToStringSid(JNIEnv* env,
+    jclass this, jlong address)
+{
+    PSID sid = jlong_to_ptr(address);
+    LPWSTR string;
+
+    if (ConvertSidToStringSid_func == NULL) {
+        JNU_ThrowInternalError(env, "Should not get here");
+        return NULL;
+    }
+
+    if ((*ConvertSidToStringSid_func)(sid, &string) == 0) {
+        throwWindowsException(env, GetLastError());
+        return NULL;
+    } else {
+        jstring s = (*env)->NewString(env, (const jchar *)string,
+            (jsize)wcslen(string));
+        LocalFree(string);
+        return s;
+    }
+}
+
+JNIEXPORT jlong JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_ConvertStringSidToSid0(JNIEnv* env,
+    jclass this, jlong address)
+{
+    LPWSTR lpStringSid = jlong_to_ptr(address);
+    PSID pSid;
+
+    if (ConvertStringSidToSid_func == NULL) {
+        JNU_ThrowInternalError(env, "Should not get here");
+        return (jlong)0;
+    }
+
+    if ((*ConvertStringSidToSid_func)(lpStringSid, &pSid) == 0)
+        throwWindowsException(env, GetLastError());
+
+    return ptr_to_jlong(pSid);
+}
+
+JNIEXPORT jlong JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_GetCurrentProcess(JNIEnv* env, jclass this) {
+    HANDLE hProcess = GetCurrentProcess();
+    return ptr_to_jlong(hProcess);
+}
+
+JNIEXPORT jlong JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_GetCurrentThread(JNIEnv* env, jclass this) {
+    HANDLE hThread = GetCurrentThread();
+    return ptr_to_jlong(hThread);
+}
+
+JNIEXPORT jlong JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_OpenProcessToken(JNIEnv* env,
+    jclass this, jlong process, jint desiredAccess)
+{
+    HANDLE hProcess = (HANDLE)jlong_to_ptr(process);
+    HANDLE hToken;
+
+    if (OpenProcessToken(hProcess, (DWORD)desiredAccess, &hToken) == 0)
+        throwWindowsException(env, GetLastError());
+    return ptr_to_jlong(hToken);
+}
+
+JNIEXPORT jlong JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_OpenThreadToken(JNIEnv* env,
+    jclass this, jlong thread, jint desiredAccess, jboolean openAsSelf)
+{
+    HANDLE hThread = (HANDLE)jlong_to_ptr(thread);
+    HANDLE hToken;
+    BOOL bOpenAsSelf = (openAsSelf == JNI_TRUE) ? TRUE : FALSE;
+
+    if (OpenThreadToken(hThread, (DWORD)desiredAccess, bOpenAsSelf, &hToken) == 0) {
+        if (GetLastError() == ERROR_NO_TOKEN)
+            return (jlong)0;
+        throwWindowsException(env, GetLastError());
+    }
+    return ptr_to_jlong(hToken);
+}
+
+JNIEXPORT jlong JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_DuplicateTokenEx(JNIEnv* env,
+    jclass this, jlong token, jint desiredAccess)
+{
+    HANDLE hToken = (HANDLE)jlong_to_ptr(token);
+    HANDLE resultToken;
+    BOOL res;
+
+    res = DuplicateTokenEx(hToken,
+                           (DWORD)desiredAccess,
+                           NULL,
+                           SecurityImpersonation,
+                           TokenImpersonation,
+                           &resultToken);
+    if (res == 0)
+        throwWindowsException(env, GetLastError());
+    return ptr_to_jlong(resultToken);
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_SetThreadToken(JNIEnv* env,
+    jclass this, jlong thread, jlong token)
+{
+    HANDLE hThread = (HANDLE)jlong_to_ptr(thread);
+    HANDLE hToken = (HANDLE)jlong_to_ptr(token);
+
+    if (SetThreadToken(hThread, hToken) == 0)
+        throwWindowsException(env, GetLastError());
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_GetTokenInformation(JNIEnv* env,
+    jclass this, jlong token, jint tokenInfoClass, jlong tokenInfo, jint tokenInfoLength)
+{
+    BOOL res;
+    DWORD lengthNeeded;
+    HANDLE hToken = (HANDLE)jlong_to_ptr(token);
+    LPVOID result = (LPVOID)jlong_to_ptr(tokenInfo);
+
+    res = GetTokenInformation(hToken, (TOKEN_INFORMATION_CLASS)tokenInfoClass, (LPVOID)result,
+                              tokenInfoLength, &lengthNeeded);
+    if (res == 0) {
+        if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+            return (jint)lengthNeeded;
+        } else {
+            throwWindowsException(env, GetLastError());
+            return 0;
+        }
+    } else {
+        return tokenInfoLength;
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_AdjustTokenPrivileges(JNIEnv* env,
+    jclass this, jlong token, jlong luid, jint attributes)
+{
+    TOKEN_PRIVILEGES privs[1];
+    HANDLE hToken = (HANDLE)jlong_to_ptr(token);
+    PLUID pLuid = (PLUID)jlong_to_ptr(luid);
+
+    privs[0].PrivilegeCount = 1;
+    privs[0].Privileges[0].Luid = *pLuid;
+    privs[0].Privileges[0].Attributes = (DWORD)attributes;
+
+    if (AdjustTokenPrivileges(hToken, FALSE, &privs[0], 1, NULL, NULL) == 0)
+        throwWindowsException(env, GetLastError());
+}
+
+JNIEXPORT jlong JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_LookupPrivilegeValue0(JNIEnv* env,
+    jclass this, jlong name)
+{
+    LPCWSTR lpName = (LPCWSTR)jlong_to_ptr(name);
+    PLUID pLuid = LocalAlloc(0, sizeof(LUID));
+
+    if (pLuid == NULL) {
+        JNU_ThrowInternalError(env, "Unable to allocate LUID structure");
+    } else {
+        if (LookupPrivilegeValueW(NULL, lpName, pLuid) == 0)
+            throwWindowsException(env, GetLastError());
+    }
+    return ptr_to_jlong(pLuid);
+}
+
+JNIEXPORT jlong JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_BuildTrusteeWithSid(JNIEnv* env,
+    jclass this, jlong sid)
+{
+    PSID pSid = (HANDLE)jlong_to_ptr(sid);
+    PTRUSTEE_W pTrustee = LocalAlloc(0, sizeof(TRUSTEE_W));
+
+    if (pTrustee == NULL) {
+        JNU_ThrowInternalError(env, "Unable to allocate TRUSTEE_W structure");
+    } else {
+        BuildTrusteeWithSidW(pTrustee, pSid);
+    }
+    return ptr_to_jlong(pTrustee);
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_GetEffectiveRightsFromAcl(JNIEnv* env,
+    jclass this, jlong acl, jlong trustee)
+{
+    ACCESS_MASK access;
+    PACL pAcl = (PACL)jlong_to_ptr(acl);
+    PTRUSTEE pTrustee = (PTRUSTEE)jlong_to_ptr(trustee);
+
+    if (GetEffectiveRightsFromAcl(pAcl, pTrustee, &access) != ERROR_SUCCESS) {
+        throwWindowsException(env, GetLastError());
+    }
+    return (jint)access;
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_CreateSymbolicLink0(JNIEnv* env,
+    jclass this, jlong linkAddress, jlong targetAddress, jint flags)
+{
+    LPCWSTR link = jlong_to_ptr(linkAddress);
+    LPCWSTR target = jlong_to_ptr(targetAddress);
+
+    if (CreateSymbolicLink_func == NULL) {
+        JNU_ThrowInternalError(env, "Should not get here");
+        return;
+    }
+
+    /* On Windows 64-bit this appears to succeed even when there is insufficient privileges */
+    if ((*CreateSymbolicLink_func)(link, target, (DWORD)flags) == 0)
+        throwWindowsException(env, GetLastError());
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_CreateHardLink0(JNIEnv* env,
+    jclass this, jlong newFileAddress, jlong existingFileAddress)
+{
+    LPCWSTR newFile = jlong_to_ptr(newFileAddress);
+    LPCWSTR existingFile = jlong_to_ptr(existingFileAddress);
+
+    if (CreateHardLink_func == NULL) {
+        JNU_ThrowInternalError(env, "Should not get here");
+        return;
+    }
+    if ((*CreateHardLink_func)(newFile, existingFile, NULL) == 0)
+        throwWindowsException(env, GetLastError());
+}
+
+JNIEXPORT jstring JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_GetFullPathName0(JNIEnv *env,
+                                                         jclass clz,
+                                                         jlong pathAddress)
+{
+    jstring rv = NULL;
+    WCHAR *lpBuf = NULL;
+    WCHAR buf[MAX_PATH];
+    DWORD len;
+    LPCWSTR lpFileName = jlong_to_ptr(pathAddress);
+
+    len = GetFullPathNameW(lpFileName, MAX_PATH, buf, NULL);
+    if (len > 0) {
+        if (len < MAX_PATH) {
+            rv = (*env)->NewString(env, buf, len);
+        } else {
+            len += 1;  /* return length does not include terminator */
+            lpBuf = (WCHAR*)malloc(len * sizeof(WCHAR));
+            if (lpBuf != NULL) {
+                len = GetFullPathNameW(lpFileName, len, lpBuf, NULL);
+                if (len > 0) {
+                    rv = (*env)->NewString(env, lpBuf, len);
+                } else {
+                    JNU_ThrowInternalError(env, "GetFullPathNameW failed");
+                }
+                free(lpBuf);
+            }
+        }
+    }
+    if (len == 0)
+        throwWindowsException(env, GetLastError());
+
+    return rv;
+}
+
+JNIEXPORT jstring JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_GetFinalPathNameByHandle(JNIEnv* env,
+    jclass this, jlong handle)
+{
+    jstring rv = NULL;
+    WCHAR *lpBuf = NULL;
+    WCHAR path[MAX_PATH];
+    HANDLE h = (HANDLE)jlong_to_ptr(handle);
+    DWORD len;
+
+    if (GetFinalPathNameByHandle_func == NULL) {
+        JNU_ThrowInternalError(env, "Should not get here");
+        return NULL;
+    }
+
+    len = (*GetFinalPathNameByHandle_func)(h, path, MAX_PATH, 0);
+    if (len > 0) {
+        if (len < MAX_PATH) {
+            rv = (*env)->NewString(env, (const jchar *)path, (jsize)len);
+        } else {
+            len += 1;  /* return length does not include terminator */
+            lpBuf = (WCHAR*)malloc(len * sizeof(WCHAR));
+            if (lpBuf != NULL) {
+                len = (*GetFinalPathNameByHandle_func)(h, lpBuf, len, 0);
+                if (len > 0)  {
+                    rv = (*env)->NewString(env, (const jchar *)lpBuf, (jsize)len);
+                } else {
+                    JNU_ThrowInternalError(env, "GetFinalPathNameByHandleW failed");
+                }
+                free(lpBuf);
+            }
+        }
+    }
+
+    if (len == 0)
+        throwWindowsException(env, GetLastError());
+
+    return rv;
+}
+
+JNIEXPORT jlong JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_CreateIoCompletionPort(JNIEnv* env, jclass this,
+    jlong fileHandle, jlong existingPort, jint completionKey)
+{
+    HANDLE port = CreateIoCompletionPort((HANDLE)jlong_to_ptr(fileHandle),
+                                         (HANDLE)jlong_to_ptr(existingPort),
+                                         (DWORD)completionKey,
+                                         0);
+    if (port == NULL) {
+        throwWindowsException(env, GetLastError());
+    }
+    return ptr_to_jlong(port);
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_GetQueuedCompletionStatus0(JNIEnv* env, jclass this,
+    jlong completionPort, jobject obj)
+{
+    DWORD bytesTransferred;
+    DWORD completionKey;
+    OVERLAPPED *lpOverlapped;
+    BOOL res;
+
+    res = GetQueuedCompletionStatus((HANDLE)jlong_to_ptr(completionPort),
+                                  &bytesTransferred,
+                                  &completionKey,
+                                  &lpOverlapped,
+                                  INFINITE);
+    if (res == 0 && lpOverlapped == NULL) {
+        throwWindowsException(env, GetLastError());
+    } else {
+        DWORD ioResult = (res == 0) ? GetLastError() : 0;
+        (*env)->SetIntField(env, obj, completionStatus_error, ioResult);
+        (*env)->SetIntField(env, obj, completionStatus_bytesTransferred,
+            (jint)bytesTransferred);
+        (*env)->SetIntField(env, obj, completionStatus_completionKey,
+            (jint)completionKey);
+
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_PostQueuedCompletionStatus(JNIEnv* env, jclass this,
+    jlong completionPort, jint completionKey)
+{
+    BOOL res;
+
+    res = PostQueuedCompletionStatus((HANDLE)jlong_to_ptr(completionPort),
+                                     (DWORD)0,  /* dwNumberOfBytesTransferred */
+                                     (DWORD)completionKey,
+                                     NULL);  /* lpOverlapped */
+    if (res == 0) {
+        throwWindowsException(env, GetLastError());
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_ReadDirectoryChangesW(JNIEnv* env, jclass this,
+    jlong hDirectory, jlong bufferAddress, jint bufferLength, jboolean watchSubTree, jint filter,
+    jlong bytesReturnedAddress, jlong pOverlapped)
+{
+    BOOL res;
+    BOOL subtree = (watchSubTree == JNI_TRUE) ? TRUE : FALSE;
+
+    ((LPOVERLAPPED)jlong_to_ptr(pOverlapped))->hEvent = NULL;
+    res = ReadDirectoryChangesW((HANDLE)jlong_to_ptr(hDirectory),
+                                (LPVOID)jlong_to_ptr(bufferAddress),
+                                (DWORD)bufferLength,
+                                subtree,
+                                (DWORD)filter,
+                                (LPDWORD)jlong_to_ptr(bytesReturnedAddress),
+                                (LPOVERLAPPED)jlong_to_ptr(pOverlapped),
+                                NULL);
+    if (res == 0) {
+        throwWindowsException(env, GetLastError());
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_BackupRead0(JNIEnv* env, jclass this,
+    jlong hFile, jlong bufferAddress, jint bufferSize, jboolean abort,
+    jlong context, jobject obj)
+{
+    BOOL res;
+    DWORD bytesTransferred;
+    BOOL a = (abort == JNI_TRUE) ? TRUE : FALSE;
+    VOID* pContext = (VOID*)jlong_to_ptr(context);
+
+    res = BackupRead((HANDLE)jlong_to_ptr(hFile),
+                     (LPBYTE)jlong_to_ptr(bufferAddress),
+                     (DWORD)bufferSize,
+                     &bytesTransferred,
+                     a,
+                     FALSE,
+                     &pContext);
+    if (res == 0) {
+        throwWindowsException(env, GetLastError());
+    } else {
+        (*env)->SetIntField(env, obj, backupResult_bytesTransferred,
+            bytesTransferred);
+        (*env)->SetLongField(env, obj, backupResult_context,
+            ptr_to_jlong(pContext));
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_WindowsNativeDispatcher_BackupSeek(JNIEnv* env, jclass this,
+    jlong hFile, jlong bytesToSeek, jlong context)
+{
+    BOOL res;
+    jint lowBytesToSeek = (jint)bytesToSeek;
+    jint highBytesToSeek = (jint)(bytesToSeek >> 32);
+    DWORD lowBytesSeeked;
+    DWORD highBytesSeeked;
+    VOID* pContext = jlong_to_ptr(context);
+
+    res = BackupSeek((HANDLE)jlong_to_ptr(hFile),
+                     (DWORD)lowBytesToSeek,
+                     (DWORD)highBytesToSeek,
+                     &lowBytesSeeked,
+                     &highBytesSeeked,
+                     &pContext);
+    if (res == 0) {
+        throwWindowsException(env, GetLastError());
+    }
+}
diff --git a/jdk/test/java/nio/channels/AsynchronousChannelGroup/AsExecutor.java b/jdk/test/java/nio/channels/AsynchronousChannelGroup/AsExecutor.java
new file mode 100644
index 0000000..995c00f
--- /dev/null
+++ b/jdk/test/java/nio/channels/AsynchronousChannelGroup/AsExecutor.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.nio.channels.AsynchronousChannelGroup;
+import java.util.concurrent.*;
+
+/**
+ * Test that arbitrary tasks can be submitted to a channel group's thread pool.
+ */
+
+public class AsExecutor {
+
+    public static void main(String[] args) throws Exception {
+        // create channel groups
+        ThreadFactory factory = new PrivilegedThreadFactory();
+        AsynchronousChannelGroup group1 = AsynchronousChannelGroup
+            .withFixedThreadPool(5, factory);
+        AsynchronousChannelGroup group2 = AsynchronousChannelGroup
+            .withCachedThreadPool(Executors.newCachedThreadPool(factory), 0);
+
+        try {
+            // execute simple tasks
+            testSimpleTask(group1);
+            testSimpleTask(group2);
+
+            // install security manager and test again
+            System.setSecurityManager( new SecurityManager() );
+            testSimpleTask(group1);
+            testSimpleTask(group2);
+
+            // attempt to execute tasks that run with only frames from boot
+            // class loader on the stack.
+            testAttackingTask(group1);
+            testAttackingTask(group2);
+        } finally {
+            group1.shutdown();
+            group2.shutdown();
+        }
+    }
+
+    static void testSimpleTask(AsynchronousChannelGroup group) throws Exception {
+        Executor executor = (Executor)group;
+        final CountDownLatch latch = new CountDownLatch(1);
+        executor.execute(new Runnable() {
+            public void run() {
+                latch.countDown();
+            }
+        });
+        latch.await();
+    }
+
+    static void testAttackingTask(AsynchronousChannelGroup group) throws Exception {
+        Executor executor = (Executor)group;
+        Attack task = new Attack();
+        executor.execute(task);
+        task.waitUntilDone();
+        if (!task.failedDueToSecurityException())
+            throw new RuntimeException("SecurityException expected");
+    }
+
+}
diff --git a/jdk/test/java/nio/channels/AsynchronousChannelGroup/Attack.java b/jdk/test/java/nio/channels/AsynchronousChannelGroup/Attack.java
new file mode 100644
index 0000000..491926c
--- /dev/null
+++ b/jdk/test/java/nio/channels/AsynchronousChannelGroup/Attack.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.net.*;
+import java.io.IOException;
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * A task that attempts to attack the current host.
+ */
+
+public class Attack implements Runnable {
+    private final CountDownLatch latch = new CountDownLatch(1);
+    private volatile boolean failedDueToSecurityException;
+
+    public void Attack() {
+        // check class is on boot class path
+        if (Attack.class.getClassLoader() != null)
+            throw new RuntimeException("Attack class not on boot class path");
+    }
+
+    @Override
+    public void run() {
+        try {
+            new Socket("127.0.0.1", 9999).close();
+            throw new RuntimeException("Connected (not expected)");
+        } catch (IOException e) {
+            throw new RuntimeException("IOException (not expected)");
+        } catch (SecurityException e) {
+            failedDueToSecurityException = true;
+        } finally {
+            latch.countDown();
+        }
+    }
+
+    public void waitUntilDone() throws InterruptedException {
+        latch.await();
+    }
+
+    public boolean failedDueToSecurityException() {
+        return failedDueToSecurityException;
+    }
+}
diff --git a/jdk/test/java/nio/channels/AsynchronousChannelGroup/BadProperties.java b/jdk/test/java/nio/channels/AsynchronousChannelGroup/BadProperties.java
new file mode 100644
index 0000000..7c109b1
--- /dev/null
+++ b/jdk/test/java/nio/channels/AsynchronousChannelGroup/BadProperties.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 4607272
+ * @summary Unit test for AsynchronousChannelGroup
+ * @build BadProperties
+ * @run main/othervm/fail -Djava.nio.channels.DefaultThreadPool.threadFactory BadProperties
+ * @run main/othervm/fail -Djava.nio.channels.DefaultThreadPool.threadFactory=Missing BadProperties
+ * @run main/othervm/fail -Djava.nio.channels.DefaultThreadPool.initialSize BadProperties
+ * @run main/othervm/fail -Djava.nio.channels.DefaultThreadPool.initialSize=NaN BadProperties
+ */
+
+import java.nio.channels.AsynchronousSocketChannel;
+import java.io.IOException;
+
+public class BadProperties {
+    public static void main(String[] args) throws IOException {
+        AsynchronousSocketChannel.open();
+    }
+}
diff --git a/jdk/test/java/nio/channels/AsynchronousChannelGroup/Basic.java b/jdk/test/java/nio/channels/AsynchronousChannelGroup/Basic.java
new file mode 100644
index 0000000..f26ed17
--- /dev/null
+++ b/jdk/test/java/nio/channels/AsynchronousChannelGroup/Basic.java
@@ -0,0 +1,259 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 4607272
+ * @summary Unit test for AsynchronousChannelGroup
+ * @build Basic
+ * @run main/othervm -XX:-UseVMInterruptibleIO Basic
+ */
+
+import java.nio.ByteBuffer;
+import java.nio.channels.*;
+import java.net.*;
+import java.util.*;
+import java.util.concurrent.*;
+import java.io.IOException;
+
+public class Basic {
+    static final Random rand = new Random();
+    static final ThreadFactory threadFactory = new ThreadFactory() {
+        @Override
+        public Thread newThread(final Runnable r) {
+            return new Thread(r);
+        }};
+
+
+    public static void main(String[] args) throws Exception {
+        shutdownTests();
+        shutdownNowTests();
+        afterShutdownTests();
+        miscTests();
+    }
+
+    static void shutdownTests() throws Exception {
+        System.out.println("-- test shutdown --");
+
+        // test shutdown with no channels in groups
+        for (int i=0; i<500; i++) {
+            ExecutorService pool = null;
+            AsynchronousChannelGroup group;
+            if (rand.nextBoolean()) {
+                pool = Executors.newCachedThreadPool();
+                group = AsynchronousChannelGroup.withCachedThreadPool(pool, rand.nextInt(5));
+            } else {
+                int nThreads = 1 + rand.nextInt(8);
+                group = AsynchronousChannelGroup.withFixedThreadPool(nThreads, threadFactory);
+            }
+            group.shutdown();
+            if (!group.isShutdown())
+                throw new RuntimeException("Group should be shutdown");
+            // group should terminate quickly
+            boolean terminated = group.awaitTermination(3, TimeUnit.SECONDS);
+            if (!terminated)
+                throw new RuntimeException("Group should have terminated");
+            if (pool != null && !pool.isTerminated())
+                throw new RuntimeException("Executor should have terminated");
+        }
+
+        // shutdown with channel in group
+        for (int i=0; i<500; i++) {
+            ExecutorService pool = null;
+            AsynchronousChannelGroup group;
+            if (rand.nextBoolean()) {
+                pool = Executors.newCachedThreadPool();
+                group = AsynchronousChannelGroup.withCachedThreadPool(pool, rand.nextInt(10));
+            } else {
+                int nThreads = 1 + rand.nextInt(8);
+                group = AsynchronousChannelGroup.withFixedThreadPool(nThreads, threadFactory);
+            }
+            // create channel that is bound to group
+            AsynchronousChannel ch;
+            switch (rand.nextInt(3)) {
+                case 0 : ch = AsynchronousSocketChannel.open(group); break;
+                case 1 : ch = AsynchronousServerSocketChannel.open(group); break;
+                case 2 : ch = AsynchronousDatagramChannel.open(null, group); break;
+                default : throw new AssertionError();
+            }
+            group.shutdown();
+            if (!group.isShutdown())
+                throw new RuntimeException("Group should be shutdown");
+
+            // last channel so should terminate after this channel is closed
+            ch.close();
+
+            // group should terminate quickly
+            boolean terminated = group.awaitTermination(3, TimeUnit.SECONDS);
+            if (!terminated)
+                throw new RuntimeException("Group should have terminated");
+            if (pool != null && !pool.isTerminated())
+                throw new RuntimeException("Executor should have terminated");
+        }
+    }
+
+    static void shutdownNowTests() throws Exception {
+        System.out.println("-- test shutdownNow --");
+
+        for (int i=0; i< 10; i++) {
+            ExecutorService pool = null;
+            AsynchronousChannelGroup group;
+            if (rand.nextBoolean()) {
+                pool = Executors.newCachedThreadPool();
+                group = AsynchronousChannelGroup
+                    .withCachedThreadPool(pool, rand.nextInt(5));
+            } else {
+                int nThreads = 1 + rand.nextInt(8);
+                group = AsynchronousChannelGroup
+                    .withFixedThreadPool(nThreads, threadFactory);
+            }
+
+            // I/O in progress
+            AsynchronousChannel ch;
+            if (rand.nextBoolean()) {
+                AsynchronousServerSocketChannel listener = AsynchronousServerSocketChannel
+                    .open(group).bind(new InetSocketAddress(0));
+                listener.accept();
+                ch = listener;
+            } else {
+                AsynchronousDatagramChannel adc =
+                    AsynchronousDatagramChannel.open(null, group);
+                adc.receive(ByteBuffer.allocate(100));
+                ch = adc;
+            }
+
+            // forceful shutdown
+            group.shutdownNow();
+
+            // shutdownNow is required to close all channels
+            if (ch.isOpen())
+                throw new RuntimeException("Channel should be closed");
+
+            boolean terminated = group.awaitTermination(3, TimeUnit.SECONDS);
+            if (!terminated)
+                throw new RuntimeException("Group should have terminated");
+            if (pool != null && !pool.isTerminated())
+                throw new RuntimeException("Executor should have terminated");
+        }
+    }
+
+    // test creating channels in group after group is shutdown
+    static void afterShutdownTests() throws Exception {
+        System.out.println("-- test operations after group is shutdown  --");
+        AsynchronousChannelGroup group =
+            AsynchronousChannelGroup.withFixedThreadPool(1, threadFactory);
+
+        AsynchronousSocketChannel ch = AsynchronousSocketChannel.open(group);
+        AsynchronousServerSocketChannel listener = AsynchronousServerSocketChannel.open(group);
+
+        // initiate accept
+        listener.bind(new InetSocketAddress(0));
+        Future<AsynchronousSocketChannel> result = listener.accept();
+
+        // shutdown group
+        group.shutdown();
+        if (!group.isShutdown())
+            throw new RuntimeException("Group should be shutdown");
+
+        // attempt to create another channel
+        try {
+            AsynchronousSocketChannel.open(group);
+            throw new RuntimeException("ShutdownChannelGroupException expected");
+        } catch (ShutdownChannelGroupException x) {
+        }
+        try {
+            AsynchronousServerSocketChannel.open(group);
+            throw new RuntimeException("ShutdownChannelGroupException expected");
+        } catch (ShutdownChannelGroupException x) {
+        }
+
+        // attempt to create another channel by connecting. This should cause
+        // the accept operation to fail.
+        InetAddress lh = InetAddress.getLocalHost();
+        int port = ((InetSocketAddress)listener.getLocalAddress()).getPort();
+        InetSocketAddress isa = new InetSocketAddress(lh, port);
+        ch.connect(isa).get();
+        try {
+            result.get();
+            throw new RuntimeException("Connection was accepted");
+        } catch (ExecutionException x) {
+            Throwable cause = x.getCause();
+            if (!(cause instanceof IOException))
+                throw new RuntimeException("Cause should be IOException");
+            cause = cause.getCause();
+            if (!(cause instanceof ShutdownChannelGroupException))
+                throw new RuntimeException("IOException cause should be ShutdownChannelGroupException");
+        }
+
+        // initiate another accept even though channel group is shutdown.
+        Future<AsynchronousSocketChannel> res = listener.accept();
+        try {
+            res.get(3, TimeUnit.SECONDS);
+            throw new RuntimeException("TimeoutException expected");
+        } catch (TimeoutException x) {
+        }
+        // connect to the listener which should cause the accept to complete
+        AsynchronousSocketChannel.open().connect(isa);
+        try {
+            res.get();
+            throw new RuntimeException("Connection was accepted");
+        } catch (ExecutionException x) {
+            Throwable cause = x.getCause();
+            if (!(cause instanceof IOException))
+                throw new RuntimeException("Cause should be IOException");
+            cause = cause.getCause();
+            if (!(cause instanceof ShutdownChannelGroupException))
+                throw new RuntimeException("IOException cause should be ShutdownChannelGroupException");
+        }
+
+        // group should *not* terminate as channels are open
+        boolean terminated = group.awaitTermination(3, TimeUnit.SECONDS);
+        if (terminated)
+            throw new RuntimeException("Group should not have terminated");
+
+        // close channel; group should terminate quickly
+        ch.close();
+        listener.close();
+        terminated = group.awaitTermination(3, TimeUnit.SECONDS);
+        if (!terminated)
+            throw new RuntimeException("Group should have terminated");
+    }
+
+    static void miscTests() throws Exception {
+        System.out.println("-- miscellenous tests --");
+        try {
+            AsynchronousChannelGroup.withFixedThreadPool(1, null);
+            throw new RuntimeException("NPE expected");
+        } catch (NullPointerException x) {
+        }
+        try {
+            AsynchronousChannelGroup.withFixedThreadPool(0, threadFactory);
+            throw new RuntimeException("IAE expected");
+        } catch (IllegalArgumentException e) {
+        }
+        try {
+            AsynchronousChannelGroup.withCachedThreadPool(null, 0);
+            throw new RuntimeException("NPE expected");
+        } catch (NullPointerException x) {
+        }
+    }
+}
diff --git a/jdk/test/java/nio/channels/AsynchronousChannelGroup/GroupOfOne.java b/jdk/test/java/nio/channels/AsynchronousChannelGroup/GroupOfOne.java
new file mode 100644
index 0000000..b116245
--- /dev/null
+++ b/jdk/test/java/nio/channels/AsynchronousChannelGroup/GroupOfOne.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 4607272
+ * @summary Unit test for AsynchronousChannelGroup
+ */
+
+import java.nio.ByteBuffer;
+import java.nio.channels.*;
+import java.net.*;
+import java.util.concurrent.*;
+import java.io.IOException;
+
+/**
+ * This test verifies that a channel or channel group can be closed from a
+ * completion handler when there are no threads available to handle I/O events.
+ */
+
+public class GroupOfOne {
+
+    public static void main(String[] args) throws Exception {
+        // create listener to accept connections
+        final AsynchronousServerSocketChannel listener =
+            AsynchronousServerSocketChannel.open()
+                .bind(new InetSocketAddress(0));
+        listener.accept(null, new CompletionHandler<AsynchronousSocketChannel,Void>() {
+            public void completed(AsynchronousSocketChannel ch, Void att) {
+                listener.accept(null, this);
+            }
+            public void failed(Throwable exc, Void att) {
+            }
+            public void cancelled(Void att) {
+            }
+        });
+
+        int port = ((InetSocketAddress)(listener.getLocalAddress())).getPort();
+        SocketAddress sa = new InetSocketAddress(InetAddress.getLocalHost(), port);
+
+        test(sa, true, false);
+        test(sa, false, true);
+        test(sa, true, true);
+    }
+
+    static void test(SocketAddress sa,
+                     final boolean closeChannel,
+                     final boolean shutdownGroup)
+        throws Exception
+    {
+        // group with 1 thread
+        final AsynchronousChannelGroup group = AsynchronousChannelGroup
+            .withFixedThreadPool(1, new ThreadFactory() {
+                @Override
+                public Thread newThread(final Runnable r) {
+                    return new Thread(r);
+                }});
+        final AsynchronousSocketChannel ch = AsynchronousSocketChannel.open(group);
+
+        // the latch counts down when:
+        // 1. The read operation fails (expected)
+        // 2. the close/shutdown completes
+        final CountDownLatch latch = new CountDownLatch(2);
+
+        ch.connect(sa, null, new CompletionHandler<Void,Void>() {
+            public void completed(Void result, Void att)  {
+                System.out.println("Connected");
+
+                // initiate I/O operation that does not complete (successfully)
+                ByteBuffer buf = ByteBuffer.allocate(100);
+                ch.read(buf, null, new CompletionHandler<Integer,Void>() {
+                    public void completed(Integer bytesRead, Void att)  {
+                        throw new RuntimeException();
+                    }
+                    public void failed(Throwable exc, Void att) {
+                        if (!(exc instanceof AsynchronousCloseException))
+                            throw new RuntimeException(exc);
+                        System.out.println("Read failed (expected)");
+                        latch.countDown();
+                    }
+                    public void cancelled(Void att) {
+                        throw new RuntimeException();
+                    }
+                });
+
+                // close channel or shutdown group
+                try {
+                    if (closeChannel) {
+                        System.out.print("Close channel ...");
+                        ch.close();
+                        System.out.println(" done.");
+                    }
+                    if (shutdownGroup) {
+                        System.out.print("Shutdown group ...");
+                        group.shutdownNow();
+                        System.out.println(" done.");
+                    }
+                    latch.countDown();
+                } catch (IOException e) {
+                    throw new RuntimeException();
+                }
+            }
+            public void failed(Throwable exc, Void att) {
+                throw new RuntimeException(exc);
+            }
+            public void cancelled(Void att) {
+                throw new RuntimeException();
+            }
+        });
+
+        latch.await();
+
+        // clean-up
+        group.shutdown();
+        boolean terminated = group.awaitTermination(5, TimeUnit.SECONDS);
+        if (!terminated)
+            throw new RuntimeException("Group did not terminate");
+
+        System.out.println("TEST OKAY");
+    }
+}
diff --git a/jdk/test/java/nio/channels/AsynchronousChannelGroup/Identity.java b/jdk/test/java/nio/channels/AsynchronousChannelGroup/Identity.java
new file mode 100644
index 0000000..f41c12c
--- /dev/null
+++ b/jdk/test/java/nio/channels/AsynchronousChannelGroup/Identity.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 4607272
+ * @summary Unit test for AsynchronousChannelGroup
+ */
+
+import java.nio.ByteBuffer;
+import java.nio.channels.*;
+import java.net.*;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.*;
+
+/**
+ * Tests that the completion handler is invoked by a thread with
+ * the expected identity.
+ */
+
+public class Identity {
+    static final Random rand = new Random();
+    static final CountDownLatch done = new CountDownLatch(1);
+    static final AtomicBoolean failed = new AtomicBoolean(false);
+
+    static void fail(String msg) {
+        failed.set(true);
+        done.countDown();
+        throw new RuntimeException(msg);
+    }
+
+    // thread-local identifies the thread
+    private static final ThreadLocal<Integer> myGroup =
+        new ThreadLocal<Integer>() {
+            @Override protected Integer initialValue() {
+                return Integer.valueOf(-1);
+            }
+        };
+
+    // creates a ThreadFactory that constructs groups with the given identity
+    static final ThreadFactory createThreadFactory(final int groupId) {
+        return new ThreadFactory() {
+            @Override
+            public Thread newThread(final Runnable r) {
+                Thread t = new Thread(new Runnable() {
+                    public void run() {
+                        myGroup.set(groupId);
+                        r.run();
+                    }});
+                t.setDaemon(true);
+                return t;
+            }
+        };
+    }
+
+    public static void main(String[] args) throws Exception {
+        // create listener to accept connections
+        final AsynchronousServerSocketChannel listener =
+            AsynchronousServerSocketChannel.open()
+                .bind(new InetSocketAddress(0));
+        listener.accept(null, new CompletionHandler<AsynchronousSocketChannel,Void>() {
+            public void completed(final AsynchronousSocketChannel ch, Void att) {
+                listener.accept(null, this);
+
+                final ByteBuffer buf = ByteBuffer.allocate(100);
+                ch.read(buf, null, new CompletionHandler<Integer,Void>() {
+                    public void completed(Integer bytesRead, Void att) {
+                        buf.clear();
+                        ch.read(buf, null, this);
+                    }
+                    public void failed(Throwable exc, Void att) {
+                    }
+                    public void cancelled(Void att) {
+                    }
+                });
+            }
+            public void failed(Throwable exc, Void att) {
+            }
+            public void cancelled(Void att) {
+            }
+        });
+        int port = ((InetSocketAddress)(listener.getLocalAddress())).getPort();
+        SocketAddress sa = new InetSocketAddress(InetAddress.getLocalHost(), port);
+
+        // create 3-10 channels, each in its own group
+        final int groupCount = 3 + rand.nextInt(8);
+        final AsynchronousSocketChannel[] channel = new AsynchronousSocketChannel[groupCount];
+        for (int i=0; i<groupCount; i++) {
+            ThreadFactory factory = createThreadFactory(i);
+            AsynchronousChannelGroup group;
+            if (rand.nextBoolean()) {
+                int nThreads = 1 + rand.nextInt(10);
+                group = AsynchronousChannelGroup.withFixedThreadPool(nThreads, factory);
+            } else {
+                ExecutorService pool = Executors.newCachedThreadPool(factory);
+                group = AsynchronousChannelGroup.withCachedThreadPool(pool, rand.nextInt(5));
+            }
+
+            // create channel in group and connect it to the server
+            AsynchronousSocketChannel ch = AsynchronousSocketChannel.open(group);
+            ch.connect(sa).get();
+            channel[i] = ch;
+        }
+
+        // randomly write to each channel, ensuring that the completion handler
+        // is always invoked by a thread with the right identity.
+        final AtomicInteger writeCount = new AtomicInteger(100);
+        channel[0].write(getBuffer(), 0, new CompletionHandler<Integer,Integer>() {
+            public void completed(Integer bytesWritten, Integer groupId) {
+                if (bytesWritten != 1)
+                    fail("Expected 1 byte to be written");
+                if (!myGroup.get().equals(groupId))
+                    fail("Handler invoked by thread with the wrong identity");
+                if (writeCount.decrementAndGet() > 0) {
+                    int id = rand.nextInt(groupCount);
+                    channel[id].write(getBuffer(), id, this);
+                } else {
+                    done.countDown();
+                }
+            }
+            public void failed(Throwable exc, Integer groupId) {
+                fail(exc.getMessage());
+            }
+            public void cancelled(Integer groupId) {
+                fail("I/O operation was cancelled");
+            }
+        });
+
+        // wait until
+        done.await();
+        if (failed.get())
+            throw new RuntimeException("Test failed - see log for details");
+    }
+
+    static ByteBuffer getBuffer() {
+        ByteBuffer buf;
+        if (rand.nextBoolean()) {
+            buf = ByteBuffer.allocateDirect(1);
+        } else {
+            buf = ByteBuffer.allocate(1);
+        }
+        buf.put((byte)0);
+        buf.flip();
+        return buf;
+    }
+}
diff --git a/jdk/test/java/nio/channels/AsynchronousChannelGroup/PrivilegedThreadFactory.java b/jdk/test/java/nio/channels/AsynchronousChannelGroup/PrivilegedThreadFactory.java
new file mode 100644
index 0000000..e2c4575
--- /dev/null
+++ b/jdk/test/java/nio/channels/AsynchronousChannelGroup/PrivilegedThreadFactory.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.util.concurrent.ThreadFactory;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * The "privileged" ThreadFactory used by the AsExecutor test.
+ */
+
+public class PrivilegedThreadFactory implements ThreadFactory {
+    public void PrivilegedThreadPoolFactory() {
+        // check class is on boot class path
+        if (PrivilegedThreadFactory.class.getClassLoader() != null)
+            throw new RuntimeException("PrivilegedThreadFactory class not on boot class path");
+    }
+
+    @Override
+    public Thread newThread(final Runnable r) {
+        return AccessController.doPrivileged(new PrivilegedAction<Thread>() {
+            @Override
+            public Thread run() {
+                Thread t = new Thread(r);
+                t.setDaemon(true);
+                return t;
+            }
+        });
+    }
+}
diff --git a/jdk/test/java/nio/channels/AsynchronousChannelGroup/Restart.java b/jdk/test/java/nio/channels/AsynchronousChannelGroup/Restart.java
new file mode 100644
index 0000000..567321e
--- /dev/null
+++ b/jdk/test/java/nio/channels/AsynchronousChannelGroup/Restart.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 4607272
+ * @summary Unit test for AsynchronousChannelGroup
+ * @build Restart
+ * @run main/othervm -XX:-UseVMInterruptibleIO Restart
+ */
+
+import java.nio.channels.*;
+import java.net.*;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.*;
+import java.io.IOException;
+
+/**
+ * Exercise replacement of threads in the thread pool when completion handlers
+ * terminate due to errors or runtime exceptions.
+ */
+
+public class Restart {
+    static final Random rand = new Random();
+
+    public static void main(String[] args) throws Exception {
+        // thread group for thread pools
+        final ThreadGroup tg = new ThreadGroup("test");
+
+        // keep track of the number of threads that terminate
+        final AtomicInteger exceptionCount = new AtomicInteger(0);
+        final Thread.UncaughtExceptionHandler ueh =
+            new Thread.UncaughtExceptionHandler() {
+                public void uncaughtException(Thread t, Throwable e) {
+                    exceptionCount.incrementAndGet();
+                }
+            };
+        ThreadFactory factory = new ThreadFactory() {
+            @Override
+            public Thread newThread(Runnable r) {
+                Thread t = new Thread(tg, r);
+                t.setUncaughtExceptionHandler(ueh);
+                return t;
+            }
+        };
+
+        // group with fixed thread pool
+        int nThreads = 1 + rand.nextInt(4);
+        AsynchronousChannelGroup group =
+            AsynchronousChannelGroup.withFixedThreadPool(nThreads, factory);
+        testRestart(group, 100);
+        group.shutdown();
+
+        // group with custom thread pool
+        ExecutorService pool = Executors.newCachedThreadPool(factory);
+        group = AsynchronousChannelGroup.withCachedThreadPool(pool, rand.nextInt(5));
+        testRestart(group, 100);
+        group.shutdown();
+
+        // give time for threads to terminate
+        Thread.sleep(3000);
+        int actual = exceptionCount.get();
+        if (actual != 200)
+            throw new RuntimeException(actual + " exceptions, expected: " + 200);
+    }
+
+    static void testRestart(AsynchronousChannelGroup group, int count)
+        throws Exception
+    {
+        AsynchronousServerSocketChannel listener =
+            AsynchronousServerSocketChannel.open(group)
+                .bind(new InetSocketAddress(0));
+
+        for (int i=0; i<count; i++) {
+            final CountDownLatch latch = new CountDownLatch(1);
+
+            listener.accept(null, new CompletionHandler<AsynchronousSocketChannel,Void>() {
+                public void completed(AsynchronousSocketChannel ch, Void att) {
+                    try {
+                        ch.close();
+                    } catch (IOException ignore) { }
+
+                    latch.countDown();
+
+                    // throw error or runtime exception
+                    if (rand.nextBoolean()) {
+                        throw new Error();
+                    } else {
+                        throw new RuntimeException();
+                    }
+                }
+                public void failed(Throwable exc, Void att) {
+                }
+                public void cancelled(Void att) {
+                }
+            });
+
+            // establish loopback connection which should cause completion
+            // handler to be invoked.
+            int port = ((InetSocketAddress)(listener.getLocalAddress())).getPort();
+            AsynchronousSocketChannel ch = AsynchronousSocketChannel.open();
+            InetAddress lh = InetAddress.getLocalHost();
+            ch.connect(new InetSocketAddress(lh, port)).get();
+            ch.close();
+
+            // wait for handler to be invoked
+            latch.await();
+        }
+
+        // clean-up
+        listener.close();
+    }
+}
diff --git a/jdk/test/java/nio/channels/AsynchronousChannelGroup/Unbounded.java b/jdk/test/java/nio/channels/AsynchronousChannelGroup/Unbounded.java
new file mode 100644
index 0000000..f615c3c
--- /dev/null
+++ b/jdk/test/java/nio/channels/AsynchronousChannelGroup/Unbounded.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 4607272
+ * @summary Unit test for AsynchronousChannelGroup
+ */
+
+import java.nio.ByteBuffer;
+import java.nio.channels.*;
+import java.net.*;
+import java.util.concurrent.*;
+import java.io.IOException;
+
+public class Unbounded {
+    // number of concurrent completion handlers
+    static final int CONCURRENCY_COUNT = 512;
+
+    public static void main(String[] args) throws Exception {
+        // all accepted connections are added to a queue
+        final ArrayBlockingQueue<AsynchronousSocketChannel> queue =
+            new ArrayBlockingQueue<AsynchronousSocketChannel>(CONCURRENCY_COUNT);
+
+        // create listener to accept connections
+        final AsynchronousServerSocketChannel listener =
+            AsynchronousServerSocketChannel.open()
+                .bind(new InetSocketAddress(0));
+        listener.accept(null, new CompletionHandler<AsynchronousSocketChannel,Void>() {
+            public void completed(AsynchronousSocketChannel ch, Void att) {
+                queue.add(ch);
+                listener.accept(null, this);
+            }
+            public void failed(Throwable exc, Void att) {
+            }
+            public void cancelled(Void att) {
+            }
+        });
+        System.out.println("Listener created.");
+
+        // establish lots of connections
+        int port = ((InetSocketAddress)(listener.getLocalAddress())).getPort();
+        SocketAddress sa = new InetSocketAddress(InetAddress.getLocalHost(), port);
+        AsynchronousSocketChannel[] channels =
+            new AsynchronousSocketChannel[CONCURRENCY_COUNT];
+        for (int i=0; i<CONCURRENCY_COUNT; i++) {
+            int attempts = 0;
+            for (;;) {
+                try {
+                    channels[i] = AsynchronousSocketChannel.open();
+                    channels[i].connect(sa).get();
+                    break;
+                } catch (IOException x) {
+                    // probably resource issue so back off and retry
+                    if (++attempts >= 3)
+                        throw x;
+                    Thread.sleep(50);
+                }
+            }
+        }
+        System.out.println("All connection established.");
+
+        // the barrier where all threads (plus the main thread) wait
+        final CyclicBarrier barrier = new CyclicBarrier(CONCURRENCY_COUNT+1);
+
+        // initiate a read operation on each channel.
+        for (int i=0; i<CONCURRENCY_COUNT; i++) {
+            ByteBuffer buf = ByteBuffer.allocateDirect(100);
+            channels[i].read( buf, channels[i],
+                new CompletionHandler<Integer,AsynchronousSocketChannel>() {
+                    public void completed(Integer bytesRead, AsynchronousSocketChannel ch) {
+                        try {
+                            ch.close();
+                            barrier.await();
+                        } catch (Exception x) {
+                            throw new AssertionError(x);
+                        }
+                    }
+                    public void failed(Throwable exc, AsynchronousSocketChannel ch) {
+                    }
+                    public void cancelled(AsynchronousSocketChannel ch) {
+                    }
+                });
+        }
+        System.out.println("All read operations outstanding.");
+
+        // write data to each of the accepted connections
+        int remaining = CONCURRENCY_COUNT;
+        while (remaining > 0) {
+            AsynchronousSocketChannel ch = queue.take();
+            ch.write(ByteBuffer.wrap("welcome".getBytes())).get();
+            ch.close();
+            remaining--;
+        }
+
+        // wait for all threads to reach the barrier
+        System.out.println("Waiting for all threads to reach barrier");
+        barrier.await();
+        listener.close();
+    }
+}
diff --git a/jdk/test/java/nio/channels/AsynchronousChannelGroup/run_any_task.sh b/jdk/test/java/nio/channels/AsynchronousChannelGroup/run_any_task.sh
new file mode 100644
index 0000000..97f4f96
--- /dev/null
+++ b/jdk/test/java/nio/channels/AsynchronousChannelGroup/run_any_task.sh
@@ -0,0 +1,52 @@
+#
+# Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
+# @test
+# @bug 4607272
+# @summary Unit test for AsynchronousChannelGrou#execute
+# @build AsExecutor PrivilegedThreadFactory Attack
+# @run shell run_any_task.sh
+
+# if TESTJAVA isn't set then we assume an interactive run.
+
+if [ -z "$TESTJAVA" ]; then
+    TESTSRC=.
+    TESTCLASSES=.
+    JAVA=java
+    JAR=jar
+else
+    JAVA="${TESTJAVA}/bin/java"
+    JAR="${TESTJAVA}/bin/jar"
+fi
+
+echo "Creating JAR file ..."
+$JAR -cf "${TESTCLASSES}/Privileged.jar" \
+    -C "${TESTCLASSES}" PrivilegedThreadFactory.class \
+    -C "${TESTCLASSES}" PrivilegedThreadFactory\$1.class \
+    -C "${TESTCLASSES}" Attack.class
+
+echo "Running test ..."
+$JAVA -XX:-UseVMInterruptibleIO \
+    -Xbootclasspath/a:"${TESTCLASSES}/Privileged.jar" \
+    -classpath "${TESTCLASSES}" \
+    AsExecutor
diff --git a/jdk/test/java/nio/channels/AsynchronousDatagramChannel/Basic.java b/jdk/test/java/nio/channels/AsynchronousDatagramChannel/Basic.java
new file mode 100644
index 0000000..5ed3d83
--- /dev/null
+++ b/jdk/test/java/nio/channels/AsynchronousDatagramChannel/Basic.java
@@ -0,0 +1,448 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 4527345
+ * @summary Unit test for AsynchronousDatagramChannel
+ */
+
+import java.nio.ByteBuffer;
+import java.nio.channels.*;
+import java.net.*;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.*;
+
+public class Basic {
+
+    public static void main(String[] args) throws Exception {
+        doReceiveTests();
+        doReadTests();
+        doSendTests();
+        doWriteTests();
+        doCancelTests();
+        doMulticastTests();
+    }
+
+    // basic receive tests
+    static void doReceiveTests() throws Exception {
+        final byte[] msg = "hello".getBytes();
+
+        AsynchronousDatagramChannel ch = AsynchronousDatagramChannel.open()
+            .bind(new InetSocketAddress(0));
+        int port = ((InetSocketAddress)(ch.getLocalAddress())).getPort();
+        InetAddress rh = InetAddress.getLocalHost();
+        final SocketAddress sa = new InetSocketAddress(rh, port);
+
+        DatagramChannel sender = DatagramChannel.open();
+        ByteBuffer dst = ByteBuffer.allocateDirect(100);
+
+        // Test: datagram packet received immediately
+        sender.send(ByteBuffer.wrap(msg), sa);
+        dst.clear();
+        ch.receive(dst).get(1, TimeUnit.SECONDS);
+        if (dst.flip().remaining() != msg.length)
+            throw new RuntimeException("Unexpected number of bytes read");
+
+        // Test: datagram packet not received immediately
+        dst.clear();
+        final CountDownLatch latch = new CountDownLatch(1);
+        ch.receive(dst, null, new CompletionHandler<SocketAddress,Void>() {
+            public void completed(SocketAddress source, Void att) {
+                latch.countDown();
+            }
+            public void failed (Throwable exc, Void att) {
+            }
+            public void cancelled(Void att) {
+            }
+        });
+        Thread.sleep(2000);
+        sender.send(ByteBuffer.wrap(msg), sa);
+        latch.await(2, TimeUnit.SECONDS);  // wait for completion handler
+
+        // Test: timeout
+        dst.clear();
+        final AtomicReference<Throwable> exception = new AtomicReference<Throwable>();
+        ch.receive(dst, 2, TimeUnit.SECONDS, null, new CompletionHandler<SocketAddress,Void>() {
+            public void completed(SocketAddress source, Void att) {
+            }
+            public void failed (Throwable exc, Void att) {
+                exception.set(exc);
+            }
+            public void cancelled(Void att) {
+            }
+        });
+        Throwable result;
+        while ((result = exception.get()) == null) {
+            Thread.sleep(100);
+        }
+        if (!(result instanceof InterruptedByTimeoutException))
+            throw new RuntimeException("InterruptedByTimeoutException expected");
+
+        // AsynchronousCloseException
+        dst = ByteBuffer.allocateDirect(100);
+        exception.set(null);
+        ch.receive(dst, null, new CompletionHandler<SocketAddress,Void>() {
+            public void completed(SocketAddress source, Void att) {
+            }
+            public void failed (Throwable exc, Void att) {
+                exception.set(exc);
+            }
+            public void cancelled(Void att) {
+            }
+        });
+        ch.close();
+        while ((result = exception.get()) == null) {
+            Thread.sleep(100);
+        }
+        if (!(result instanceof AsynchronousCloseException))
+            throw new RuntimeException("AsynchronousCloseException expected");
+
+        // done
+        sender.close();
+    }
+
+    // basic read tests
+    static void doReadTests() throws Exception {
+        final byte[] msg = "hello".getBytes();
+
+        AsynchronousDatagramChannel ch = AsynchronousDatagramChannel.open()
+            .bind(new InetSocketAddress(0));
+        int port = ((InetSocketAddress)(ch.getLocalAddress())).getPort();
+        InetAddress lh = InetAddress.getLocalHost();
+        final SocketAddress sa = new InetSocketAddress(lh, port);
+
+        DatagramChannel sender = DatagramChannel.open();
+        ByteBuffer dst = ByteBuffer.allocateDirect(100);
+
+        // Test: not connected
+        try {
+            ch.read(dst);
+            throw new RuntimeException("NotYetConnectedException expected");
+        } catch (NotYetConnectedException e) {
+        }
+
+        // connect the channel
+        sender.bind(new InetSocketAddress(0));
+        ch.connect(new InetSocketAddress(lh,
+                ((InetSocketAddress)(sender.getLocalAddress())).getPort()));
+
+        // Test: datagram packet received immediately
+        sender.send(ByteBuffer.wrap(msg), sa);
+        dst.clear();
+        ch.read(dst).get(1, TimeUnit.SECONDS);
+        if (dst.flip().remaining() != msg.length)
+            throw new RuntimeException("Unexpected number of bytes read");
+
+        // Test: datagram packet not received immediately
+        dst.clear();
+        final CountDownLatch l1 = new CountDownLatch(1);
+        ch.read(dst, null, new CompletionHandler<Integer,Void>() {
+            public void completed(Integer bytesRead, Void att) {
+                l1.countDown();
+            }
+            public void failed (Throwable exc, Void att) {
+            }
+            public void cancelled(Void att) {
+            }
+        });
+        Thread.sleep(2000);
+        sender.send(ByteBuffer.wrap(msg), sa);
+        l1.await(2, TimeUnit.SECONDS);
+
+        // Test: timeout
+        dst.clear();
+        final AtomicReference<Throwable> exception = new AtomicReference<Throwable>();
+        ch.read(dst, 2, TimeUnit.SECONDS, null, new CompletionHandler<Integer,Void>() {
+            public void completed(Integer bytesRead, Void att) {
+            }
+            public void failed (Throwable exc, Void att) {
+                exception.set(exc);
+            }
+            public void cancelled(Void att) {
+            }
+        });
+        Throwable result;
+        while ((result = exception.get()) == null) {
+            Thread.sleep(100);
+        }
+        if (!(result instanceof InterruptedByTimeoutException))
+            throw new RuntimeException("InterruptedByTimeoutException expected");
+
+        // AsynchronousCloseException
+        dst.clear();
+        exception.set(null);
+        ch.read(dst, null, new CompletionHandler<Integer,Void>() {
+            public void completed(Integer bytesRead, Void att) {
+            }
+            public void failed (Throwable exc, Void att) {
+                exception.set(exc);
+            }
+            public void cancelled(Void att) {
+            }
+        });
+        ch.close();
+        while ((result = exception.get()) == null) {
+            Thread.sleep(100);
+        }
+        if (!(result instanceof AsynchronousCloseException))
+            throw new RuntimeException("AsynchronousCloseException expected");
+
+        // done
+        sender.close();
+    }
+
+    // basic send tests
+    static void doSendTests() throws Exception {
+        final byte[] msg = "hello".getBytes();
+
+        DatagramChannel reader = DatagramChannel.open()
+            .bind(new InetSocketAddress(0));
+        int port = ((InetSocketAddress)(reader.getLocalAddress())).getPort();
+        InetAddress rh = InetAddress.getLocalHost();
+        SocketAddress sa = new InetSocketAddress(rh, port);
+
+        AsynchronousDatagramChannel ch = AsynchronousDatagramChannel.open();
+
+        // Test: send datagram packet to reader
+        int bytesSent = ch.send(ByteBuffer.wrap(msg), sa).get();
+        if (bytesSent != msg.length)
+            throw new RuntimeException("Unexpected number of bytes sent");
+
+        // check received
+        ByteBuffer dst = ByteBuffer.allocateDirect(100);
+        reader.receive(dst);
+        dst.flip();
+        if (dst.remaining() != msg.length)
+            throw new RuntimeException("Unexpected number of bytes received");
+
+        // Test: send datagram packet to reader and check completion handler
+        // is invoked
+        final CountDownLatch l2 = new CountDownLatch(1);
+        ch.send(ByteBuffer.wrap(msg), sa, null, new CompletionHandler<Integer,Void>() {
+            public void completed(Integer bytesSent, Void att) {
+                if (bytesSent != msg.length)
+                    throw new RuntimeException("Unexpected number of bytes received");
+                l2.countDown();
+            }
+            public void failed (Throwable exc, Void att) {
+            }
+            public void cancelled(Void att) {
+            }
+        });
+        l2.await(5, TimeUnit.SECONDS);
+
+        // check received
+        dst.clear();
+        reader.receive(dst);
+        dst.flip();
+        if (dst.remaining() != msg.length)
+            throw new RuntimeException("Unexpected number of bytes received");
+
+        // Test: check that failed method is invoked
+        ch.close();
+        final CountDownLatch l3 = new CountDownLatch(1);
+        ch.send(ByteBuffer.wrap(msg), sa, null, new CompletionHandler<Integer,Void>() {
+            public void completed(Integer bytesSent, Void att) {
+                throw new RuntimeException("completed method invoked");
+            }
+            public void failed (Throwable exc, Void att) {
+                if (exc instanceof ClosedChannelException) {
+                    l3.countDown();
+                } else {
+                    throw new RuntimeException(exc);
+                }
+            }
+            public void cancelled(Void att) {
+            }
+        });
+        l3.await(5, TimeUnit.SECONDS);
+
+        // done
+        reader.close();
+    }
+
+    // basic write tests
+    static void doWriteTests() throws Exception {
+        final byte[] msg = "hello".getBytes();
+
+        DatagramChannel reader = DatagramChannel.open()
+            .bind(new InetSocketAddress(0));
+        int port = ((InetSocketAddress)(reader.getLocalAddress())).getPort();
+        InetAddress rh = InetAddress.getLocalHost();
+        SocketAddress sa = new InetSocketAddress(rh, port);
+
+        AsynchronousDatagramChannel ch = AsynchronousDatagramChannel.open();
+
+        // Test: unconnected
+        try {
+            ch.write(ByteBuffer.wrap(msg)).get();
+            throw new RuntimeException("NotYetConnectedException expected");
+        } catch (NotYetConnectedException e) {
+        }
+
+        // Test: connect, and write datagram
+        ch.connect(sa);
+        int bytesSent = ch.write(ByteBuffer.wrap(msg)).get();
+        if (bytesSent != msg.length)
+            throw new RuntimeException("Unexpected number of bytes sent");
+
+        // check received
+        ByteBuffer dst = ByteBuffer.allocateDirect(100);
+        reader.receive(dst);
+        dst.flip();
+        if (dst.remaining() != msg.length)
+            throw new RuntimeException("Unexpected number of bytes received");
+
+        // Test: write datagram and check completion handler is invoked
+        final CountDownLatch l2 = new CountDownLatch(1);
+        ch.write(ByteBuffer.wrap(msg), null, new CompletionHandler<Integer,Void>() {
+            public void completed(Integer bytesSent, Void att) {
+                if (bytesSent != msg.length)
+                    throw new RuntimeException("Unexpected number of bytes received");
+                l2.countDown();
+            }
+            public void failed (Throwable exc, Void att) {
+            }
+            public void cancelled(Void att) {
+            }
+        });
+        l2.await(5, TimeUnit.SECONDS);
+
+        // check received
+        dst.clear();
+        reader.receive(dst);
+        dst.flip();
+        if (dst.remaining() != msg.length)
+            throw new RuntimeException("Unexpected number of bytes received");
+
+        // done
+        ch.close();
+        reader.close();
+    }
+
+    static void cancelAndCheck(Future<?> result, CountDownLatch latch)
+        throws InterruptedException
+    {
+        boolean cancelled = result.cancel(false);
+        if (!cancelled)
+            throw new RuntimeException("Not cancelled");
+        if (!result.isDone())
+            throw new RuntimeException("Should be done");
+        try {
+            result.get();
+            throw new RuntimeException("Result not expected");
+        } catch (CancellationException e) {
+            // expected
+        } catch (ExecutionException e) {
+            throw new RuntimeException("Should not fail");
+        }
+
+        // make sure that completion handler is invoked
+        latch.await();
+    }
+
+    // basic cancel tests
+    static void doCancelTests() throws Exception {
+        InetAddress lh = InetAddress.getLocalHost();
+
+        // timed and non-timed receive
+        for (int i=0; i<2; i++) {
+            AsynchronousDatagramChannel ch =
+                AsynchronousDatagramChannel.open().bind(new InetSocketAddress(0));
+            final CountDownLatch latch = new CountDownLatch(1);
+            long timeout = (i == 0) ? 0L : 60L;
+            Future<SocketAddress> remote = ch
+                .receive(ByteBuffer.allocate(100), timeout, TimeUnit.SECONDS, null,
+                    new CompletionHandler<SocketAddress,Void>() {
+                        public void completed(SocketAddress source, Void att) {
+                        }
+                        public void failed (Throwable exc, Void att) {
+                        }
+                        public void cancelled(Void att) {
+                            latch.countDown();
+                        }
+                    });
+            cancelAndCheck(remote, latch);
+            ch.close();
+        }
+
+        // timed and non-timed read
+        for (int i=0; i<2; i++) {
+            AsynchronousDatagramChannel ch =
+                AsynchronousDatagramChannel.open().bind(new InetSocketAddress(0));
+             ch.connect(new InetSocketAddress(lh,
+                ((InetSocketAddress)(ch.getLocalAddress())).getPort()));
+            final CountDownLatch latch = new CountDownLatch(1);
+            long timeout = (i == 0) ? 0L : 60L;
+            Future<Integer> result = ch
+                .read(ByteBuffer.allocate(100), timeout, TimeUnit.SECONDS, null,
+                    new CompletionHandler<Integer,Void>() {
+                        public void completed(Integer bytesRead, Void att) {
+                        }
+                        public void failed (Throwable exc, Void att) {
+                        }
+                        public void cancelled(Void att) {
+                            latch.countDown();
+                        }
+                    });
+            cancelAndCheck(result, latch);
+            ch.close();
+        }
+    }
+
+    // basic multicast test
+    static void doMulticastTests() throws Exception {
+        final byte[] msg = "hello".getBytes();
+
+        AsynchronousDatagramChannel ch = AsynchronousDatagramChannel
+            .open(StandardProtocolFamily.INET, null)
+            .setOption(StandardSocketOption.SO_REUSEADDR, true)
+            .bind(new InetSocketAddress(0));
+
+        InetAddress lh = InetAddress.getLocalHost();
+        int port = ((InetSocketAddress)(ch.getLocalAddress())).getPort();
+
+        // join group
+        InetAddress group = InetAddress.getByName("225.4.5.6");
+        NetworkInterface interf = NetworkInterface.getByInetAddress(lh);
+        MembershipKey key = ch.join(group, interf);
+
+        // check key
+        if (key.channel() != ch)
+            throw new RuntimeException("Not the expected channel");
+
+        // send message to group
+        DatagramChannel sender = DatagramChannel.open();
+        sender.send(ByteBuffer.wrap(msg), new InetSocketAddress(group, port));
+        sender.close();
+
+        // check message received
+        ByteBuffer dst = ByteBuffer.allocate(200);
+        SocketAddress source = ch.receive(dst).get(2, TimeUnit.SECONDS);
+        if (!((InetSocketAddress)source).getAddress().equals(lh))
+            throw new RuntimeException("Unexpected source");
+
+        // done
+        ch.close();
+    }
+}
diff --git a/jdk/test/java/nio/channels/AsynchronousFileChannel/Basic.java b/jdk/test/java/nio/channels/AsynchronousFileChannel/Basic.java
new file mode 100644
index 0000000..5ffb42c
--- /dev/null
+++ b/jdk/test/java/nio/channels/AsynchronousFileChannel/Basic.java
@@ -0,0 +1,585 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 4607272
+ * @summary Unit test for AsynchronousFileChannel
+ */
+
+import java.nio.file.*;
+import java.nio.channels.*;
+import java.nio.ByteBuffer;
+import java.io.File;
+import java.io.IOException;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.AtomicReference;
+import static java.nio.file.StandardOpenOption.*;
+
+public class Basic {
+
+    private static final Random rand = new Random();
+
+    public static void main(String[] args) throws IOException {
+        // create temporary file
+        File blah = File.createTempFile("blah", null);
+        blah.deleteOnExit();
+
+        final AsynchronousFileChannel ch = AsynchronousFileChannel
+            .open(blah.toPath(), READ, WRITE);
+
+        // run tests
+        testUsingCompletionHandlers(ch);
+        testUsingWaitOnResult(ch);
+        testLocking(ch);
+        testInterruptHandlerThread(ch);
+
+        // close channel and invoke test that expects channel to be closed
+        ch.close();
+        testClosedChannel(ch);
+
+        // these tests open the file themselves
+        testCustomThreadPool(blah.toPath());
+        testAsynchronousClose(blah.toPath());
+        testCancel(blah.toPath());
+        testTruncate(blah.toPath());
+    }
+
+    /*
+     * Generate buffer with random contents
+     * Writes buffer to file using a CompletionHandler to consume the result
+     *    of each write operation
+     * Reads file to EOF to a new buffer using a CompletionHandler to consume
+     *    the result of each read operation
+     * Compares buffer contents
+     */
+    static void testUsingCompletionHandlers(AsynchronousFileChannel ch)
+        throws IOException
+    {
+        System.out.println("testUsingCompletionHandlers");
+
+        ch.truncate(0L);
+
+        // generate buffer with random elements and write it to file
+        ByteBuffer src = genBuffer();
+        writeFully(ch, src, 0L);
+
+        // read to EOF or buffer is full
+        ByteBuffer dst = (rand.nextBoolean()) ?
+            ByteBuffer.allocateDirect(src.capacity()) :
+            ByteBuffer.allocate(src.capacity());
+        readAll(ch, dst, 0L);
+
+        // check buffers are the same
+        src.flip();
+        dst.flip();
+        if (!src.equals(dst)) {
+            throw new RuntimeException("Contents differ");
+        }
+    }
+
+    /*
+     * Generate buffer with random contents
+     * Writes buffer to file, invoking the Future's get method to wait for
+     *    each write operation to complete
+     * Reads file to EOF to a new buffer, invoking the Future's get method to
+     *    wait for each write operation to complete
+     * Compares buffer contents
+     */
+    static void testUsingWaitOnResult(AsynchronousFileChannel ch)
+        throws IOException
+    {
+        System.out.println("testUsingWaitOnResult");
+
+        ch.truncate(0L);
+
+        // generate buffer
+        ByteBuffer src = genBuffer();
+
+        // write buffer completely to file
+        long position = 0L;
+        while (src.hasRemaining()) {
+            Future<Integer> result = ch.write(src, position);
+            try {
+                int n = result.get();
+                // update position
+                position += n;
+            } catch (ExecutionException x) {
+                throw new RuntimeException(x.getCause());
+            } catch (InterruptedException x) {
+                throw new RuntimeException(x);
+            }
+        }
+
+        // read file into new buffer
+        ByteBuffer dst = (rand.nextBoolean()) ?
+            ByteBuffer.allocateDirect(src.capacity()) :
+            ByteBuffer.allocate(src.capacity());
+        position = 0L;
+        int n;
+        do {
+            Future<Integer> result = ch.read(dst, position);
+            try {
+                n = result.get();
+
+                // update position
+                if (n > 0) position += n;
+            } catch (ExecutionException x) {
+                throw new RuntimeException(x.getCause());
+            } catch (InterruptedException x) {
+                throw new RuntimeException(x);
+            }
+        } while (n > 0);
+
+        // check buffers are the same
+        src.flip();
+        dst.flip();
+        if (!src.equals(dst)) {
+            throw new RuntimeException("Contents differ");
+        }
+    }
+
+    // exercise lock methods
+    static void testLocking(AsynchronousFileChannel ch)
+        throws IOException
+    {
+        System.out.println("testLocking");
+
+        // test 1 - acquire lock and check that tryLock throws
+        // OverlappingFileLockException
+        FileLock fl;
+        try {
+            fl = ch.lock().get();
+        } catch (ExecutionException x) {
+            throw new RuntimeException(x);
+        } catch (InterruptedException x) {
+            throw new RuntimeException("Should not be interrupted");
+        }
+        if (!fl.acquiredBy().equals(ch))
+            throw new RuntimeException("FileLock#acquiredBy returned incorrect channel");
+        try {
+            ch.tryLock();
+            throw new RuntimeException("OverlappingFileLockException expected");
+        } catch (OverlappingFileLockException x) {
+        }
+        fl.release();
+
+        // test 2 - acquire try and check that lock throws OverlappingFileLockException
+        fl = ch.tryLock();
+        if (fl == null)
+            throw new RuntimeException("Unable to acquire lock");
+        try {
+            ch.lock(null, new CompletionHandler<FileLock,Void> () {
+                public void completed(FileLock result, Void att) {
+                }
+                public void failed(Throwable exc, Void att) {
+                }
+                public void cancelled(Void att) {
+                }
+            });
+            throw new RuntimeException("OverlappingFileLockException expected");
+        } catch (OverlappingFileLockException x) {
+        }
+        fl.release();
+    }
+
+    // interrupt should not close channel
+    static void testInterruptHandlerThread(final AsynchronousFileChannel ch) {
+        System.out.println("testInterruptHandlerThread");
+
+        ByteBuffer buf = ByteBuffer.allocateDirect(100);
+        final CountDownLatch latch = new CountDownLatch(1);
+
+        ch.read(buf, 0L, null, new CompletionHandler<Integer,Void>() {
+            public void completed(Integer result, Void att) {
+                try {
+                    Thread.currentThread().interrupt();
+                    long size = ch.size();
+                    latch.countDown();
+                } catch (IOException x) {
+                    x.printStackTrace();
+                }
+            }
+            public void failed(Throwable exc, Void att) {
+            }
+            public void cancelled(Void att) {
+            }
+        });
+
+        // wait for handler to complete
+        await(latch);
+    }
+
+    // invoke method on closed channel
+    static void testClosedChannel(AsynchronousFileChannel ch) {
+        System.out.println("testClosedChannel");
+
+        if (ch.isOpen())
+            throw new RuntimeException("Channel should be closed");
+
+        ByteBuffer buf = ByteBuffer.allocateDirect(100);
+
+        // check read fails with ClosedChannelException
+        try {
+            ch.read(buf, 0L).get();
+            throw new RuntimeException("ExecutionException expected");
+        } catch (ExecutionException x) {
+            if (!(x.getCause() instanceof ClosedChannelException))
+                throw new RuntimeException("Cause of ClosedChannelException expected");
+        } catch (InterruptedException x) {
+        }
+
+        // check write fails with ClosedChannelException
+        try {
+            ch.write(buf, 0L).get();
+            throw new RuntimeException("ExecutionException expected");
+        } catch (ExecutionException x) {
+            if (!(x.getCause() instanceof ClosedChannelException))
+                throw new RuntimeException("Cause of ClosedChannelException expected");
+        } catch (InterruptedException x) {
+        }
+
+        // check lock fails with ClosedChannelException
+        try {
+            ch.lock().get();
+            throw new RuntimeException("ExecutionException expected");
+        } catch (ExecutionException x) {
+            if (!(x.getCause() instanceof ClosedChannelException))
+                throw new RuntimeException("Cause of ClosedChannelException expected");
+        } catch (InterruptedException x) {
+        }
+    }
+
+
+    // exercise custom thread pool
+    static void testCustomThreadPool(Path file) throws IOException {
+        System.out.println("testCustomThreadPool");
+
+        // records threads that are created
+        final List<Thread> threads = new ArrayList<Thread>();
+
+        ThreadFactory threadFactory = new ThreadFactory() {
+             @Override
+             public Thread newThread(Runnable r) {
+                 Thread t = new Thread(r);
+                 t.setDaemon(true);
+                 synchronized (threads) {
+                     threads.add(t);
+                 }
+                 return t;
+             }
+        };
+
+        // exercise tests with varied number of threads
+        for (int nThreads=1; nThreads<=5; nThreads++) {
+            synchronized (threads) {
+                threads.clear();
+            }
+            ExecutorService executor = Executors.newFixedThreadPool(nThreads, threadFactory);
+            Set<StandardOpenOption> opts = EnumSet.of(WRITE);
+            AsynchronousFileChannel ch = AsynchronousFileChannel.open(file, opts, executor);
+            try {
+                for (int i=0; i<10; i++) {
+                    // do I/O operation to see which thread invokes the completion handler
+                    final AtomicReference<Thread> invoker = new AtomicReference<Thread>();
+                    final CountDownLatch latch = new CountDownLatch(1);
+
+                    ch.write(genBuffer(), 0L, null, new CompletionHandler<Integer,Void>() {
+                        public void completed(Integer result, Void att) {
+                            invoker.set(Thread.currentThread());
+                            latch.countDown();
+                        }
+                        public void failed(Throwable exc, Void att) {
+                        }
+                        public void cancelled(Void att) {
+                        }
+                    });
+                    await(latch);
+
+                    // check invoker
+                    boolean found = false;
+                    synchronized (threads) {
+                        for (Thread t: threads) {
+                            if (t == invoker.get()) {
+                                found = true;
+                                break;
+                            }
+                        }
+                    }
+                    if (!found)
+                        throw new RuntimeException("Invoker thread not found");
+                }
+            } finally {
+                ch.close();
+            }
+        }
+    }
+
+    // exercise asynchronous close
+    static void testAsynchronousClose(Path file) throws IOException {
+        System.out.println("testAsynchronousClose");
+
+        // create file
+        AsynchronousFileChannel ch = AsynchronousFileChannel
+            .open(file, WRITE, TRUNCATE_EXISTING);
+        long size = 0L;
+        do {
+            ByteBuffer buf = genBuffer();
+            int n = buf.remaining();
+            writeFully(ch, buf, size);
+            size += n;
+        } while (size < (50L * 1024L * 1024L));
+
+        ch.close();
+
+        ch = AsynchronousFileChannel.open(file, WRITE, SYNC);
+
+        // randomize number of writers, buffer size, and positions
+
+        int nwriters = 1 + rand.nextInt(8);
+        ByteBuffer[] buf = new ByteBuffer[nwriters];
+        long[] position = new long[nwriters];
+        for (int i=0; i<nwriters; i++) {
+            buf[i] = genBuffer();
+            position[i] = rand.nextInt((int)size);
+        }
+
+        // initiate I/O
+        Future[] result = new Future[nwriters];
+        for (int i=0; i<nwriters; i++) {
+            result[i] = ch.write(buf[i], position[i]);
+        }
+
+        // close file
+        ch.close();
+
+        // write operations should complete or fail with AsynchronousCloseException
+        for (int i=0; i<nwriters; i++) {
+            try {
+                result[i].get();
+            } catch (ExecutionException x) {
+                Throwable cause = x.getCause();
+                if (!(cause instanceof AsynchronousCloseException))
+                    throw new RuntimeException(cause);
+            } catch (CancellationException  x) {
+                throw new RuntimeException(x);   // should not happen
+            } catch (InterruptedException x) {
+                throw new RuntimeException(x);   // should not happen
+            }
+        }
+    }
+
+    // exercise cancel method
+    static void testCancel(Path file) throws IOException {
+        System.out.println("testCancel");
+
+        for (int i=0; i<2; i++) {
+            boolean mayInterruptIfRunning = (i == 0) ? false : true;
+
+            // open with SYNC option to improve chances that write will not
+            // complete immediately
+            AsynchronousFileChannel ch = AsynchronousFileChannel
+                .open(file, WRITE, SYNC);
+
+            // start write operation
+            final CountDownLatch latch = new CountDownLatch(1);
+            Future<Integer> res = ch.write(genBuffer(), 0L, null,
+                new CompletionHandler<Integer,Void>() {
+                    public void completed(Integer result, Void att) {
+                    }
+                    public void failed(Throwable exc, Void att) {
+                    }
+                    public void cancelled(Void att) {
+                        latch.countDown();
+                    }
+            });
+
+            // cancel operation
+            boolean cancelled = res.cancel(mayInterruptIfRunning);
+
+            // check post-conditions
+            if (!res.isDone())
+                throw new RuntimeException("isDone should return true");
+            if (res.isCancelled() != cancelled)
+                throw new RuntimeException("isCancelled not consistent");
+            try {
+                res.get();
+                if (!cancelled)
+                    throw new RuntimeException("CancellationException expected");
+            } catch (CancellationException x) {
+                // expected
+            } catch (ExecutionException x) {
+                throw new RuntimeException(x);
+            } catch (InterruptedException x) {
+                throw new RuntimeException(x);
+            }
+            try {
+                res.get(1, TimeUnit.SECONDS);
+                throw new RuntimeException("CancellationException expected");
+            } catch (CancellationException x) {
+                // expected
+            } catch (ExecutionException x) {
+                throw new RuntimeException(x);
+            } catch (TimeoutException x) {
+                throw new RuntimeException(x);
+            } catch (InterruptedException x) {
+                throw new RuntimeException(x);
+            }
+
+            // check that cancelled method is invoked
+            if (cancelled)
+                await(latch);
+
+            ch.close();
+        }
+    }
+
+    // exercise truncate method
+    static void testTruncate(Path file) throws IOException {
+        System.out.println("testTruncate");
+
+        // basic tests
+        AsynchronousFileChannel ch = AsynchronousFileChannel
+            .open(file, CREATE, WRITE, TRUNCATE_EXISTING);
+        try {
+            writeFully(ch, genBuffer(), 0L);
+            long size = ch.size();
+
+            // attempt to truncate to a size greater than the current size
+            if (ch.truncate(size + 1L).size() != size)
+                throw new RuntimeException("Unexpected size after truncation");
+
+            // truncate file
+            if (ch.truncate(size - 1L).size() != (size - 1L))
+                throw new RuntimeException("Unexpected size after truncation");
+
+            // invalid size
+            try {
+                ch.truncate(-1L);
+                throw new RuntimeException("IllegalArgumentException expected");
+            } catch (IllegalArgumentException e) { }
+
+        } finally {
+            ch.close();
+        }
+
+        // channel is closed
+        try {
+            ch.truncate(0L);
+            throw new RuntimeException("ClosedChannelException expected");
+        } catch (ClosedChannelException  e) { }
+
+        // channel is read-only
+        ch = AsynchronousFileChannel.open(file, READ);
+        try {
+            try {
+            ch.truncate(0L);
+                throw new RuntimeException("NonWritableChannelException expected");
+            } catch (NonWritableChannelException  e) { }
+        } finally {
+            ch.close();
+        }
+    }
+
+    // returns ByteBuffer with random bytes
+    static ByteBuffer genBuffer() {
+        int size = 1024 + rand.nextInt(16000);
+        byte[] buf = new byte[size];
+        boolean useDirect = rand.nextBoolean();
+        if (useDirect) {
+            ByteBuffer bb = ByteBuffer.allocateDirect(buf.length);
+            bb.put(buf);
+            bb.flip();
+            return bb;
+        } else {
+            return ByteBuffer.wrap(buf);
+        }
+    }
+
+    // writes all remaining bytes in the buffer to the given channel at the
+    // given position
+    static void writeFully(final AsynchronousFileChannel ch,
+                           final ByteBuffer src,
+                           long position)
+    {
+        final CountDownLatch latch = new CountDownLatch(1);
+
+        // use position as attachment
+        ch.write(src, position, position, new CompletionHandler<Integer,Long>() {
+            public void completed(Integer result, Long position) {
+                int n = result;
+                if (src.hasRemaining()) {
+                    long p = position + n;
+                    ch.write(src, p, p, this);
+                } else {
+                    latch.countDown();
+                }
+            }
+            public void failed(Throwable exc, Long position) {
+            }
+            public void cancelled(Long position) {
+            }
+        });
+
+        // wait for writes to complete
+        await(latch);
+    }
+
+    static void readAll(final AsynchronousFileChannel ch,
+                        final ByteBuffer dst,
+                       long position)
+    {
+        final CountDownLatch latch = new CountDownLatch(1);
+
+        // use position as attachment
+        ch.read(dst, position, position, new CompletionHandler<Integer,Long>() {
+            public void completed(Integer result, Long position) {
+                int n = result;
+                if (n > 0) {
+                    long p = position + n;
+                    ch.read(dst, p, p, this);
+                } else {
+                    latch.countDown();
+                }
+            }
+            public void failed(Throwable exc, Long position) {
+            }
+            public void cancelled(Long position) {
+            }
+        });
+
+        // wait for reads to complete
+        await(latch);
+    }
+
+    static void await(CountDownLatch latch) {
+        // wait until done
+        boolean done = false;
+        while (!done) {
+            try {
+                latch.await();
+                done = true;
+            } catch (InterruptedException x) { }
+        }
+    }
+}
diff --git a/jdk/test/java/nio/channels/AsynchronousFileChannel/CustomThreadPool.java b/jdk/test/java/nio/channels/AsynchronousFileChannel/CustomThreadPool.java
new file mode 100644
index 0000000..9f9025d
--- /dev/null
+++ b/jdk/test/java/nio/channels/AsynchronousFileChannel/CustomThreadPool.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 4607272
+ * @summary Unit test for java.nio.channels.AsynchronousFileChannel
+ * @build CustomThreadPool MyThreadFactory
+ * @run main/othervm -Djava.nio.channels.DefaultThreadPool.threadFactory=MyThreadFactory CustomThreadPool
+ */
+
+import java.io.File;
+import static java.nio.file.StandardOpenOption.*;
+import java.nio.ByteBuffer;
+import java.nio.channels.*;
+import java.util.concurrent.atomic.AtomicReference;
+
+public class CustomThreadPool {
+
+    public static void main(String[] args) throws Exception {
+        File blah = File.createTempFile("blah", null);
+        blah.deleteOnExit();
+        AsynchronousFileChannel ch =
+            AsynchronousFileChannel.open(blah.toPath(), READ, WRITE);
+        ByteBuffer src = ByteBuffer.wrap("Scooby Snacks".getBytes());
+
+        final AtomicReference<Thread> invoker = new AtomicReference<Thread>();
+        ch.write(src, 0, invoker,
+            new CompletionHandler<Integer,AtomicReference<Thread>>() {
+                public void completed(Integer result, AtomicReference<Thread> invoker) {
+                    invoker.set(Thread.currentThread());
+                }
+                public void failed(Throwable exc, AtomicReference<Thread> invoker) {
+                }
+                public void cancelled(AtomicReference<Thread> invoker) {
+                }
+            });
+        Thread t;
+        while ((t = invoker.get()) == null) {
+            Thread.sleep(100);
+        }
+        ch.close();
+
+        // check handler was run by known thread
+        if (!MyThreadFactory.created(t))
+            throw new RuntimeException("Handler invoked by unknown thread");
+    }
+}
diff --git a/jdk/test/java/nio/channels/AsynchronousFileChannel/Lock.java b/jdk/test/java/nio/channels/AsynchronousFileChannel/Lock.java
new file mode 100644
index 0000000..38c0f7d
--- /dev/null
+++ b/jdk/test/java/nio/channels/AsynchronousFileChannel/Lock.java
@@ -0,0 +1,340 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+
+/* @test
+ * @bug 4607272
+ * @summary Unit test for AsynchronousFileChannel#lock method
+ */
+
+import java.net.*;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+import java.nio.file.*;
+import static java.nio.file.StandardOpenOption.*;
+import java.nio.channels.*;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Random;
+import java.util.concurrent.*;
+
+public class Lock {
+
+    static final Random rand = new Random();
+
+    public static void main(String[] args) throws Exception {
+        if (args.length > 0 && args[0].equals("-lockslave")) {
+            int port = Integer.parseInt(args[1]);
+            runLockSlave(port);
+            System.exit(0);
+        }
+
+        LockSlaveMirror slave = startLockSlave();
+        try {
+
+             // create temporary file
+            File blah = File.createTempFile("blah", null);
+            blah.deleteOnExit();
+
+            testLockProtocol(blah, slave);
+            testAsyncClose(blah, slave);
+
+        } finally {
+            slave.shutdown();
+        }
+    }
+
+    // test locking protocol
+    static void testLockProtocol(File file, LockSlaveMirror slave)
+        throws Exception
+    {
+        FileLock fl;
+
+        // slave VM opens file and acquires exclusive lock
+        slave.open(file.getPath()).lock();
+
+        AsynchronousFileChannel ch = AsynchronousFileChannel
+            .open(file.toPath(), READ, WRITE);
+
+        // this VM tries to acquire lock
+        // (lock should not be acquire until released by slave VM)
+        Future<FileLock> result = ch.lock();
+        try {
+            result.get(2, TimeUnit.SECONDS);
+            throw new RuntimeException("Timeout expected");
+        } catch (TimeoutException x) {
+        }
+
+        // slave VM releases lock
+        slave.unlock();
+
+        // this VM should now acquire lock
+        fl = result.get();
+        fl.release();
+
+        // slave VM acquires lock on range
+        slave.lock(0, 10, false);
+
+        // this VM acquires lock on non-overlapping range
+        fl = ch.lock(10, 10, false, null, null).get();
+        fl.release();
+
+        // done
+        ch.close();
+        slave.close();
+    }
+
+    // test close of channel with outstanding lock operation
+    static void testAsyncClose(File file, LockSlaveMirror slave) throws Exception {
+        // slave VM opens file and acquires exclusive lock
+        slave.open(file.getPath()).lock();
+
+        for (int i=0; i<100; i++) {
+            AsynchronousFileChannel ch = AsynchronousFileChannel
+                .open(file.toPath(), READ, WRITE);
+
+            // try to lock file (should not complete because file is locked by slave)
+            Future<FileLock> result = ch.lock();
+            try {
+                result.get(rand.nextInt(100), TimeUnit.MILLISECONDS);
+                throw new RuntimeException("Timeout expected");
+            } catch (TimeoutException x) {
+            }
+
+            // close channel with lock operation outstanding
+            ch.close();
+
+            // operation should complete with AsynchronousCloseException
+            try {
+                result.get();
+                throw new RuntimeException("ExecutionException expected");
+            } catch (ExecutionException x) {
+                if (!(x.getCause() instanceof AsynchronousCloseException)) {
+                    x.getCause().printStackTrace();
+                    throw new RuntimeException("AsynchronousCloseException expected");
+                }
+            }
+        }
+
+        slave.close();
+    }
+
+    // starts a "lock slave" in another process, returning a mirror object to
+    // control the slave
+    static LockSlaveMirror startLockSlave() throws Exception {
+        ServerSocketChannel ssc = ServerSocketChannel.open()
+            .bind(new InetSocketAddress(0));
+        int port = ((InetSocketAddress)(ssc.getLocalAddress())).getPort();
+
+        String sep = FileSystems.getDefault().getSeparator();
+
+        String command = System.getProperty("java.home") +
+            sep + "bin" + sep + "java Lock -lockslave " + port;
+        Process p = Runtime.getRuntime().exec(command);
+        IOHandler.handle(p.getInputStream());
+        IOHandler.handle(p.getErrorStream());
+
+        // wait for slave to connect
+        SocketChannel sc = ssc.accept();
+        return new LockSlaveMirror(sc);
+    }
+
+    // commands that the slave understands
+    static final String OPEN_CMD    = "open";
+    static final String CLOSE_CMD   = "close";
+    static final String LOCK_CMD    = "lock";
+    static final String UNLOCK_CMD  = "unlock";
+    static final char TERMINATOR    = ';';
+
+    // provides a proxy to a "lock slave"
+    static class LockSlaveMirror {
+        private final SocketChannel sc;
+
+        LockSlaveMirror(SocketChannel sc) {
+            this.sc = sc;
+        }
+
+        private void sendCommand(String cmd, String... params)
+            throws IOException
+        {
+            for (String s: params) {
+                cmd += " " + s;
+            }
+            cmd += TERMINATOR;
+
+            ByteBuffer buf = Charset.defaultCharset().encode(cmd);
+            while (buf.hasRemaining()) {
+                sc.write(buf);
+            }
+
+            // wait for ack
+            buf = ByteBuffer.allocate(1);
+            int n = sc.read(buf);
+            if (n != 1)
+                throw new RuntimeException("Reply expected");
+            if (buf.get(0) != TERMINATOR)
+                throw new RuntimeException("Terminated expected");
+        }
+
+        LockSlaveMirror open(String file) throws IOException {
+            sendCommand(OPEN_CMD, file);
+            return this;
+        }
+
+        void close() throws IOException {
+            sendCommand(CLOSE_CMD);
+        }
+
+        LockSlaveMirror lock() throws IOException {
+            sendCommand(LOCK_CMD);
+            return this;
+        }
+
+
+        LockSlaveMirror lock(long position, long size, boolean shared)
+            throws IOException
+        {
+            sendCommand(LOCK_CMD, position + "," + size + "," + shared);
+            return this;
+        }
+
+        LockSlaveMirror unlock() throws IOException {
+            sendCommand(UNLOCK_CMD);
+            return this;
+        }
+
+        void shutdown() throws IOException {
+            sc.close();
+        }
+    }
+
+    // Helper class to direct process output to the parent System.out
+    static class IOHandler implements Runnable {
+        private final InputStream in;
+
+        IOHandler(InputStream in) {
+            this.in = in;
+        }
+
+        static void handle(InputStream in) {
+            IOHandler handler = new IOHandler(in);
+            Thread thr = new Thread(handler);
+            thr.setDaemon(true);
+            thr.start();
+        }
+
+        public void run() {
+            try {
+                byte b[] = new byte[100];
+                for (;;) {
+                    int n = in.read(b);
+                    if (n < 0) return;
+                    for (int i=0; i<n; i++) {
+                        System.out.print((char)b[i]);
+                    }
+                }
+            } catch (IOException ioe) { }
+        }
+    }
+
+    // slave process that responds to simple commands a socket connection
+    static void runLockSlave(int port) throws Exception {
+
+        // establish connection to parent
+        SocketChannel sc = SocketChannel.open(new InetSocketAddress(port));
+        ByteBuffer buf = ByteBuffer.allocateDirect(1024);
+
+        FileChannel fc = null;
+        FileLock fl = null;
+        try {
+            for (;;) {
+
+                // read command (ends with ";")
+                buf.clear();
+                int n, last = 0;
+                do {
+                    n = sc.read(buf);
+                    if (n < 0)
+                        return;
+                    if (n == 0)
+                        throw new AssertionError();
+                    last += n;
+                } while (buf.get(last-1) != TERMINATOR);
+
+                // decode into command and optional parameter
+                buf.flip();
+                String s = Charset.defaultCharset().decode(buf).toString();
+                int sp = s.indexOf(" ");
+                String cmd = (sp < 0) ? s.substring(0, s.length()-1) :
+                    s.substring(0, sp);
+                String param = (sp < 0) ? "" : s.substring(sp+1, s.length()-1);
+
+                // execute
+                if (cmd.equals(OPEN_CMD)) {
+                    if (fc != null)
+                        throw new RuntimeException("File already open");
+                    fc = FileChannel.open(Paths.get(param),READ, WRITE);
+                }
+                if (cmd.equals(CLOSE_CMD)) {
+                    if (fc == null)
+                        throw new RuntimeException("No file open");
+                    fc.close();
+                    fc = null;
+                    fl = null;
+                }
+                if (cmd.equals(LOCK_CMD)) {
+                    if (fl != null)
+                        throw new RuntimeException("Already holding lock");
+
+                    if (param.length() == 0) {
+                        fl = fc.lock();
+                    } else {
+                        String[] values = param.split(",");
+                        if (values.length != 3)
+                            throw new RuntimeException("Lock parameter invalid");
+                        long position = Long.parseLong(values[0]);
+                        long size = Long.parseLong(values[1]);
+                        boolean shared = Boolean.parseBoolean(values[2]);
+                        fl = fc.lock(position, size, shared);
+                    }
+                }
+
+                if (cmd.equals(UNLOCK_CMD)) {
+                    if (fl == null)
+                        throw new RuntimeException("Not holding lock");
+                    fl.release();
+                    fl = null;
+                }
+
+                // send reply
+                byte[] reply = { TERMINATOR };
+                n = sc.write(ByteBuffer.wrap(reply));
+            }
+
+        } finally {
+            sc.close();
+            if (fc != null) fc.close();
+        }
+    }
+}
diff --git a/jdk/test/java/nio/channels/AsynchronousFileChannel/MyThreadFactory.java b/jdk/test/java/nio/channels/AsynchronousFileChannel/MyThreadFactory.java
new file mode 100644
index 0000000..fe6f00c
--- /dev/null
+++ b/jdk/test/java/nio/channels/AsynchronousFileChannel/MyThreadFactory.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.util.concurrent.ThreadFactory;
+import java.util.*;
+
+public class MyThreadFactory implements ThreadFactory {
+
+    private static final Set<Thread> threads = new HashSet<Thread>();
+
+    static boolean created(Thread t) {
+        synchronized (threads) {
+            return threads.contains(t);
+        }
+    }
+
+    public MyThreadFactory() {
+    }
+
+    @Override
+    public Thread newThread(Runnable r) {
+        Thread t = new Thread(r);
+        t.setDaemon(true);
+        synchronized (threads) {
+            threads.add(t);
+        }
+        return t;
+    }
+}
diff --git a/jdk/test/java/nio/channels/AsynchronousServerSocketChannel/Basic.java b/jdk/test/java/nio/channels/AsynchronousServerSocketChannel/Basic.java
new file mode 100644
index 0000000..e0965fb
--- /dev/null
+++ b/jdk/test/java/nio/channels/AsynchronousServerSocketChannel/Basic.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 4607272
+ * @summary Unit test for AsynchronousServerSocketChannel
+ * @run main/timeout=180 Basic
+ */
+
+import java.nio.channels.*;
+import java.net.*;
+import java.io.IOException;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.atomic.AtomicReference;
+
+public class Basic {
+
+    public static void main(String[] args) throws Exception {
+        testBind();
+        testAccept();
+    }
+
+    static void testBind() throws Exception {
+        System.out.println("-- bind --");
+
+        AsynchronousServerSocketChannel ch = AsynchronousServerSocketChannel.open();
+        if (ch.getLocalAddress() != null)
+            throw new RuntimeException("Local address should be 'null'");
+        ch.bind(new InetSocketAddress(0), 20);
+
+        // check local address after binding
+        InetSocketAddress local = (InetSocketAddress)ch.getLocalAddress();
+        if (local.getPort() == 0)
+            throw new RuntimeException("Unexpected port");
+        if (!local.getAddress().isAnyLocalAddress())
+            throw new RuntimeException("Not bound to a wildcard address");
+
+        // try to re-bind
+        try {
+            ch.bind(new InetSocketAddress(0));
+            throw new RuntimeException("AlreadyBoundException expected");
+        } catch (AlreadyBoundException x) {
+        }
+        ch.close();
+
+        // check ClosedChannelException
+        ch = AsynchronousServerSocketChannel.open();
+        ch.close();
+        try {
+            ch.bind(new InetSocketAddress(0));
+            throw new RuntimeException("ClosedChannelException  expected");
+        } catch (ClosedChannelException  x) {
+        }
+    }
+
+    static void testAccept() throws Exception {
+        System.out.println("-- accept --");
+
+        final AsynchronousServerSocketChannel listener =
+            AsynchronousServerSocketChannel.open().bind(new InetSocketAddress(0));
+
+        InetAddress lh = InetAddress.getLocalHost();
+        int port = ((InetSocketAddress)(listener.getLocalAddress())).getPort();
+        final InetSocketAddress isa = new InetSocketAddress(lh, port);
+
+        // establish a few loopback connections
+        for (int i=0; i<100; i++) {
+            SocketChannel sc = SocketChannel.open(isa);
+            AsynchronousSocketChannel ch = listener.accept().get();
+            sc.close();
+            ch.close();
+        }
+
+       final AtomicReference<Throwable> exception = new AtomicReference<Throwable>();
+
+        // start accepting
+        listener.accept(null, new CompletionHandler<AsynchronousSocketChannel,Void>() {
+            public void completed(AsynchronousSocketChannel ch, Void att) {
+                try {
+                    ch.close();
+                } catch (IOException ignore) { }
+            }
+            public void failed(Throwable exc, Void att) {
+                exception.set(exc);
+            }
+            public void cancelled(Void att) {
+            }
+        });
+
+        // check AcceptPendingException
+        try {
+            listener.accept();
+            throw new RuntimeException("AcceptPendingException expected");
+        } catch (AcceptPendingException x) {
+        }
+
+        // asynchronous close
+        listener.close();
+        while (exception.get() == null)
+            Thread.sleep(100);
+        if (!(exception.get() instanceof AsynchronousCloseException))
+            throw new RuntimeException("AsynchronousCloseException expected");
+
+        // once closed when a further attemt should throw ClosedChannelException
+        try {
+            listener.accept().get();
+            throw new RuntimeException("ExecutionException expected");
+        } catch (ExecutionException x) {
+            if (!(x.getCause() instanceof ClosedChannelException))
+                throw new RuntimeException("Cause of ClosedChannelException expected");
+        } catch (InterruptedException x) {
+        }
+
+    }
+}
diff --git a/jdk/test/java/nio/channels/AsynchronousServerSocketChannel/WithSecurityManager.java b/jdk/test/java/nio/channels/AsynchronousServerSocketChannel/WithSecurityManager.java
new file mode 100644
index 0000000..86c76cf
--- /dev/null
+++ b/jdk/test/java/nio/channels/AsynchronousServerSocketChannel/WithSecurityManager.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 4607272
+ * @summary Unit test for AsynchronousServerServerSocketChannel
+ * @build WithSecurityManager
+ * @run main/othervm WithSecurityManager allow
+ * @run main/othervm WithSecurityManager deny
+ */
+
+import java.nio.file.Paths;
+import java.nio.channels.*;
+import java.net.*;
+import java.util.concurrent.*;
+
+public class WithSecurityManager {
+    public static void main(String[] args) throws Exception {
+        boolean allow = false;
+        String policy = (args[0].equals("allow")) ? "java.policy.allow" :
+            "java.policy.deny";
+
+        String testSrc = System.getProperty("test.src");
+        if (testSrc == null)
+            testSrc = ".";
+
+        System.setProperty("java.security.policy",
+            Paths.get(testSrc).resolve(policy).toString());
+        System.setSecurityManager(new SecurityManager());
+
+        AsynchronousServerSocketChannel listener =
+            AsynchronousServerSocketChannel.open().bind(new InetSocketAddress(0));
+
+        InetAddress lh = InetAddress.getLocalHost();
+        int port = ((InetSocketAddress)(listener.getLocalAddress())).getPort();
+
+        // establish and accept connection
+        SocketChannel sc = SocketChannel.open(new InetSocketAddress(lh, port));
+        Future<AsynchronousSocketChannel> result = listener.accept();
+
+        if (allow) {
+            // no security exception
+            result.get().close();
+        } else {
+            try {
+                result.get();
+            } catch (ExecutionException x) {
+                if (!(x.getCause() instanceof SecurityException))
+                    throw new RuntimeException("SecurityException expected");
+            }
+        }
+
+        sc.close();
+        listener.close();
+    }
+}
diff --git a/jdk/test/java/nio/channels/AsynchronousServerSocketChannel/java.policy.allow b/jdk/test/java/nio/channels/AsynchronousServerSocketChannel/java.policy.allow
new file mode 100644
index 0000000..73da4b0
--- /dev/null
+++ b/jdk/test/java/nio/channels/AsynchronousServerSocketChannel/java.policy.allow
@@ -0,0 +1,3 @@
+grant {
+    permission java.net.SocketPermission "*:1024-", "accept,connect,resolve";
+};
diff --git a/jdk/test/java/nio/channels/AsynchronousServerSocketChannel/java.policy.deny b/jdk/test/java/nio/channels/AsynchronousServerSocketChannel/java.policy.deny
new file mode 100644
index 0000000..00b9cb0
--- /dev/null
+++ b/jdk/test/java/nio/channels/AsynchronousServerSocketChannel/java.policy.deny
@@ -0,0 +1,3 @@
+grant {
+    permission java.net.SocketPermission "*:1024-", "connect,resolve";
+};
diff --git a/jdk/test/java/nio/channels/AsynchronousSocketChannel/Basic.java b/jdk/test/java/nio/channels/AsynchronousSocketChannel/Basic.java
new file mode 100644
index 0000000..8b140f1
--- /dev/null
+++ b/jdk/test/java/nio/channels/AsynchronousSocketChannel/Basic.java
@@ -0,0 +1,805 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 4607272
+ * @summary Unit test for AsynchronousSocketChannel
+ * @run main/timeout=600 Basic
+ */
+
+import java.nio.ByteBuffer;
+import java.nio.channels.*;
+import static java.net.StandardSocketOption.*;
+import java.net.*;
+import java.util.Random;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.*;
+import java.io.IOException;
+
+public class Basic {
+    static final Random rand = new Random();
+
+    public static void main(String[] args) throws Exception {
+        testBind();
+        testSocketOptions();
+        testConnect();
+        testCloseWhenPending();
+        testCancel();
+        testRead1();
+        testRead2();
+        testRead3();
+        testWrite1();
+        testWrite2();
+        testTimeout();
+        testShutdown();
+    }
+
+    static class Server {
+        private final ServerSocketChannel ssc;
+        private final InetSocketAddress address;
+
+        Server() throws IOException {
+            ssc = ServerSocketChannel.open().bind(new InetSocketAddress(0));
+
+            InetAddress lh = InetAddress.getLocalHost();
+            int port = ((InetSocketAddress)(ssc.getLocalAddress())).getPort();
+            address = new InetSocketAddress(lh, port);
+        }
+
+        InetSocketAddress address() {
+            return address;
+        }
+
+        SocketChannel accept() throws IOException {
+            return ssc.accept();
+        }
+
+        void close() {
+            try {
+                ssc.close();
+            } catch (IOException ignore) { }
+        }
+
+    }
+
+    static void testBind() throws Exception {
+        System.out.println("-- bind --");
+
+        AsynchronousSocketChannel ch = AsynchronousSocketChannel.open();
+        if (ch.getLocalAddress() != null)
+            throw new RuntimeException("Local address should be 'null'");
+        ch.bind(new InetSocketAddress(0));
+
+        // check local address after binding
+        InetSocketAddress local = (InetSocketAddress)ch.getLocalAddress();
+        if (local.getPort() == 0)
+            throw new RuntimeException("Unexpected port");
+        if (!local.getAddress().isAnyLocalAddress())
+            throw new RuntimeException("Not bound to a wildcard address");
+
+        // try to re-bind
+        try {
+            ch.bind(new InetSocketAddress(0));
+            throw new RuntimeException("AlreadyBoundException expected");
+        } catch (AlreadyBoundException x) {
+        }
+        ch.close();
+
+        // check ClosedChannelException
+        ch = AsynchronousSocketChannel.open();
+        ch.close();
+        try {
+            ch.bind(new InetSocketAddress(0));
+            throw new RuntimeException("ClosedChannelException  expected");
+        } catch (ClosedChannelException  x) {
+        }
+    }
+
+    static void testSocketOptions() throws Exception {
+        System.out.println("-- socket options --");
+
+        AsynchronousSocketChannel ch = AsynchronousSocketChannel.open()
+            .setOption(SO_RCVBUF, 128*1024)
+            .setOption(SO_SNDBUF, 128*1024)
+            .setOption(SO_REUSEADDR, true)
+            .bind(new InetSocketAddress(0));
+
+        // default values
+        if ((Boolean)ch.getOption(SO_KEEPALIVE))
+            throw new RuntimeException("Default of SO_KEEPALIVE should be 'false'");
+        if ((Boolean)ch.getOption(TCP_NODELAY))
+            throw new RuntimeException("Default of TCP_NODELAY should be 'false'");
+
+        // set and check
+        if (!(Boolean)ch.setOption(SO_KEEPALIVE, true).getOption(SO_KEEPALIVE))
+            throw new RuntimeException("SO_KEEPALIVE did not change");
+        if (!(Boolean)ch.setOption(TCP_NODELAY, true).getOption(TCP_NODELAY))
+            throw new RuntimeException("SO_KEEPALIVE did not change");
+
+        // read others (can't check as actual value is implementation dependent)
+        ch.getOption(SO_RCVBUF);
+        ch.getOption(SO_SNDBUF);
+
+        ch.close();
+    }
+
+    static void testConnect() throws Exception {
+        System.out.println("-- connect --");
+
+        Server server = new Server();
+        AsynchronousSocketChannel ch = AsynchronousSocketChannel.open();
+        ch.connect(server.address()).get();
+
+        // check local address
+        if (ch.getLocalAddress() == null)
+            throw new RuntimeException("Not bound to local address");
+
+        // check remote address
+        InetSocketAddress remote = (InetSocketAddress)ch.getRemoteAddress();
+        if (remote.getPort() != server.address().getPort())
+            throw new RuntimeException("Connected to unexpected port");
+        if (!remote.getAddress().equals(server.address().getAddress()))
+            throw new RuntimeException("Connected to unexpected address");
+
+        // try to connect again
+        try {
+            ch.connect(server.address()).get();
+            throw new RuntimeException("AlreadyConnectedException expected");
+        } catch (AlreadyConnectedException x) {
+        }
+        ch.close();
+
+        // check that connect fails with ClosedChannelException)
+        ch = AsynchronousSocketChannel.open();
+        ch.close();
+        try {
+            ch.connect(server.address()).get();
+            throw new RuntimeException("ExecutionException expected");
+        } catch (ExecutionException x) {
+            if (!(x.getCause() instanceof ClosedChannelException))
+                throw new RuntimeException("Cause of ClosedChannelException expected");
+        }
+        final AtomicReference<Throwable> connectException =
+            new AtomicReference<Throwable>();
+        ch.connect(server.address(), null, new CompletionHandler<Void,Void>() {
+            public void completed(Void result, Void att) {
+            }
+            public void failed(Throwable exc, Void att) {
+                connectException.set(exc);
+            }
+            public void cancelled(Void att) {
+            }
+        });
+        while (connectException.get() == null) {
+            Thread.sleep(100);
+        }
+        if (!(connectException.get() instanceof ClosedChannelException))
+            throw new RuntimeException("ClosedChannelException expected");
+
+        System.out.println("-- connect to non-existent host --");
+
+        // test failure
+        InetAddress badHost = InetAddress.getByName("1.2.3.4");
+        if (!badHost.isReachable(10*1000)) {
+
+            ch = AsynchronousSocketChannel.open();
+            try {
+                ch.connect(new InetSocketAddress(badHost, 9876)).get();
+                throw new RuntimeException("Connection should not be established");
+            } catch (ExecutionException x) {
+            }
+            if (ch.isOpen())
+                throw new RuntimeException("Channel should be closed");
+        }
+
+        server.close();
+    }
+
+    static void testCloseWhenPending() throws Exception {
+        System.out.println("-- asynchronous close when connecting --");
+
+        AsynchronousSocketChannel ch;
+
+        // asynchronous close while connecting
+        InetAddress rh = InetAddress.getByName("1.2.3.4");
+        if (!rh.isReachable(3000)) {
+            InetSocketAddress isa = new InetSocketAddress(rh, 1234);
+
+            ch = AsynchronousSocketChannel.open();
+            Future<Void> result = ch.connect(isa);
+
+            // give time to initiate the connect (SYN)
+            Thread.sleep(50);
+
+            // close
+            ch.close();
+
+            // check that AsynchronousCloseException is thrown
+            try {
+                result.get();
+                throw new RuntimeException("Should not connect");
+            } catch (ExecutionException x) {
+                if (!(x.getCause() instanceof AsynchronousCloseException))
+                    throw new RuntimeException(x);
+            }
+        }
+
+        System.out.println("-- asynchronous close when reading --");
+
+        Server server = new Server();
+        ch = AsynchronousSocketChannel.open();
+        ch.connect(server.address()).get();
+
+        ByteBuffer dst = ByteBuffer.allocateDirect(100);
+        Future<Integer> result = ch.read(dst);
+
+        // attempt a second read - should fail with ReadPendingException
+        ByteBuffer buf = ByteBuffer.allocateDirect(100);
+        try {
+            ch.read(buf);
+            throw new RuntimeException("ReadPendingException expected");
+        } catch (ReadPendingException x) {
+        }
+
+        // close channel (should cause initial read to complete)
+        ch.close();
+
+        // check that AsynchronousCloseException is thrown
+        try {
+            result.get();
+            throw new RuntimeException("Should not read");
+        } catch (ExecutionException x) {
+            if (!(x.getCause() instanceof AsynchronousCloseException))
+                throw new RuntimeException(x);
+        }
+
+        System.out.println("-- asynchronous close when writing --");
+
+        ch = AsynchronousSocketChannel.open();
+        ch.connect(server.address()).get();
+
+        final AtomicReference<Throwable> writeException =
+            new AtomicReference<Throwable>();
+
+        // write bytes to fill socket buffer
+        ch.write(genBuffer(), ch, new CompletionHandler<Integer,AsynchronousSocketChannel>() {
+            public void completed(Integer result, AsynchronousSocketChannel ch) {
+                ch.write(genBuffer(), ch, this);
+            }
+            public void failed(Throwable x, AsynchronousSocketChannel ch) {
+                writeException.set(x);
+            }
+            public void cancelled(AsynchronousSocketChannel ch) {
+            }
+        });
+
+        // give time for socket buffer to fill up.
+        Thread.sleep(5*1000);
+
+        //  attempt a concurrent write - should fail with WritePendingException
+        try {
+            ch.write(genBuffer());
+            throw new RuntimeException("WritePendingException expected");
+        } catch (WritePendingException x) {
+        }
+
+        // close channel - should cause initial write to complete
+        ch.close();
+
+        // wait for exception
+        while (writeException.get() == null) {
+            Thread.sleep(100);
+        }
+        if (!(writeException.get() instanceof AsynchronousCloseException))
+            throw new RuntimeException("AsynchronousCloseException expected");
+
+        server.close();
+    }
+
+    static void testCancel() throws Exception {
+        System.out.println("-- cancel --");
+
+        Server server = new Server();
+
+        for (int i=0; i<2; i++) {
+            boolean mayInterruptIfRunning = (i == 0) ? false : true;
+
+            // establish loopback connection
+            AsynchronousSocketChannel ch = AsynchronousSocketChannel.open();
+            ch.connect(server.address()).get();
+            SocketChannel peer = server.accept();
+
+            // start read operation
+            final CountDownLatch latch = new CountDownLatch(1);
+            ByteBuffer buf = ByteBuffer.allocate(1);
+            Future<Integer> res = ch.read(buf, null,
+                new CompletionHandler<Integer,Void>() {
+                    public void completed(Integer result, Void att) {
+                    }
+                    public void failed(Throwable exc, Void att) {
+                    }
+                    public void cancelled(Void att) {
+                        latch.countDown();
+                    }
+            });
+
+            // cancel operation
+            boolean cancelled = res.cancel(mayInterruptIfRunning);
+
+            // check post-conditions
+            if (!res.isDone())
+                throw new RuntimeException("isDone should return true");
+            if (res.isCancelled() != cancelled)
+                throw new RuntimeException("isCancelled not consistent");
+            try {
+                res.get();
+                throw new RuntimeException("CancellationException expected");
+            } catch (CancellationException x) {
+            }
+            try {
+                res.get(1, TimeUnit.SECONDS);
+                throw new RuntimeException("CancellationException expected");
+            } catch (CancellationException x) {
+            }
+
+            // check that completion handler executed.
+            latch.await();
+
+            ch.close();
+            peer.close();
+        }
+
+        server.close();
+    }
+
+    static void testRead1() throws Exception {
+        System.out.println("-- read (1) --");
+
+        Server server = new Server();
+        final AsynchronousSocketChannel ch = AsynchronousSocketChannel.open();
+        ch.connect(server.address()).get();
+
+        // read with 0 bytes remaining should complete immediately
+        ByteBuffer buf = ByteBuffer.allocate(1);
+        buf.put((byte)0);
+        int n = ch.read(buf).get();
+        if (n != 0)
+            throw new RuntimeException("0 expected");
+
+        // write bytes and close connection
+        SocketChannel sc = server.accept();
+        ByteBuffer src = genBuffer();
+        sc.setOption(StandardSocketOption.SO_SNDBUF, src.remaining());
+        while (src.hasRemaining())
+            sc.write(src);
+        sc.close();
+
+        // reads should complete immediately
+        final ByteBuffer dst = ByteBuffer.allocateDirect(src.capacity() + 100);
+        final CountDownLatch latch = new CountDownLatch(1);
+        ch.read(dst, null, new CompletionHandler<Integer,Void>() {
+            public void completed(Integer result, Void att) {
+                int n = result;
+                if (n > 0) {
+                    ch.read(dst, null, this);
+                } else {
+                    latch.countDown();
+                }
+            }
+            public void failed(Throwable exc, Void att) {
+            }
+            public void cancelled(Void att) {
+            }
+        });
+
+        latch.await();
+
+        // check buffers
+        src.flip();
+        dst.flip();
+        if (!src.equals(dst)) {
+            throw new RuntimeException("Contents differ");
+        }
+
+        // close channel
+        ch.close();
+
+        // check read fails with ClosedChannelException
+        try {
+            ch.read(dst).get();
+            throw new RuntimeException("ExecutionException expected");
+        } catch (ExecutionException x) {
+            if (!(x.getCause() instanceof ClosedChannelException))
+                throw new RuntimeException("Cause of ClosedChannelException expected");
+        }
+
+        server.close();
+    }
+
+    static void testRead2() throws Exception {
+        System.out.println("-- read (2) --");
+
+        Server server = new Server();
+
+        final AsynchronousSocketChannel ch = AsynchronousSocketChannel.open();
+        ch.connect(server.address()).get();
+        SocketChannel sc = server.accept();
+
+        ByteBuffer src = genBuffer();
+
+        // read until the buffer is full
+        final ByteBuffer dst = ByteBuffer.allocateDirect(src.capacity());
+        final CountDownLatch latch = new CountDownLatch(1);
+        ch.read(dst, null, new CompletionHandler<Integer,Void>() {
+            public void completed(Integer result, Void att) {
+                if (dst.hasRemaining()) {
+                    ch.read(dst, null, this);
+                } else {
+                    latch.countDown();
+                }
+            }
+            public void failed(Throwable exc, Void att) {
+            }
+            public void cancelled(Void att) {
+            }
+        });
+
+        // trickle the writing
+        do {
+            int rem = src.remaining();
+            int size = (rem <= 100) ? rem : 50 + rand.nextInt(rem - 100);
+            ByteBuffer buf = ByteBuffer.allocate(size);
+            for (int i=0; i<size; i++)
+                buf.put(src.get());
+            buf.flip();
+            Thread.sleep(50 + rand.nextInt(1500));
+            while (buf.hasRemaining())
+                sc.write(buf);
+        } while (src.hasRemaining());
+
+        // wait until ascynrhonous reading has completed
+        latch.await();
+
+        // check buffers
+        src.flip();
+        dst.flip();
+        if (!src.equals(dst)) {
+           throw new RuntimeException("Contents differ");
+        }
+
+        sc.close();
+        ch.close();
+        server.close();
+    }
+
+    // exercise scattering read
+    static void testRead3() throws Exception {
+        System.out.println("-- read (3) --");
+
+        Server server = new Server();
+        final AsynchronousSocketChannel ch = AsynchronousSocketChannel.open();
+        ch.connect(server.address()).get();
+        SocketChannel sc = server.accept();
+
+        ByteBuffer[] dsts = new ByteBuffer[3];
+        for (int i=0; i<dsts.length; i++) {
+            dsts[i] = ByteBuffer.allocateDirect(100);
+        }
+
+        // scattering read that completes ascynhronously
+        final CountDownLatch latch = new CountDownLatch(1);
+        ch.read(dsts, 0, dsts.length, 0L, TimeUnit.SECONDS, null,
+            new CompletionHandler<Long,Void>() {
+                public void completed(Long result, Void att) {
+                    long n = result;
+                    if (n <= 0)
+                        throw new RuntimeException("No bytes read");
+                    latch.countDown();
+                }
+                public void failed(Throwable exc, Void att) {
+                }
+                public void cancelled(Void att) {
+                }
+        });
+
+        // write some bytes
+        sc.write(genBuffer());
+
+        // read should now complete
+        latch.await();
+
+        // write more bytes
+        sc.write(genBuffer());
+
+        // read should complete immediately
+        for (int i=0; i<dsts.length; i++) {
+            dsts[i].rewind();
+        }
+        long n = ch
+            .read(dsts, 0, dsts.length, 0L, TimeUnit.SECONDS, null, null).get();
+        if (n <= 0)
+            throw new RuntimeException("No bytes read");
+
+        ch.close();
+        sc.close();
+        server.close();
+    }
+
+    static void testWrite1() throws Exception {
+        System.out.println("-- write (1) --");
+
+        Server server = new Server();
+        final AsynchronousSocketChannel ch = AsynchronousSocketChannel.open();
+        ch.connect(server.address()).get();
+        SocketChannel sc = server.accept();
+
+        // write with 0 bytes remaining should complete immediately
+        ByteBuffer buf = ByteBuffer.allocate(1);
+        buf.put((byte)0);
+        int n = ch.write(buf).get();
+        if (n != 0)
+            throw new RuntimeException("0 expected");
+
+        // write all bytes and close connection when done
+        final ByteBuffer src = genBuffer();
+        ch.write(src, null, new CompletionHandler<Integer,Void>() {
+            public void completed(Integer result, Void att) {
+                if (src.hasRemaining()) {
+                    ch.write(src, null, this);
+                } else {
+                    try {
+                        ch.close();
+                    } catch (IOException ignore) { }
+                }
+            }
+            public void failed(Throwable exc, Void att) {
+            }
+            public void cancelled(Void att) {
+            }
+        });
+
+        // read to EOF or buffer full
+        ByteBuffer dst = ByteBuffer.allocateDirect(src.capacity() + 100);
+        do {
+            n = sc.read(dst);
+        } while (n > 0);
+        sc.close();
+
+        // check buffers
+        src.flip();
+        dst.flip();
+        if (!src.equals(dst)) {
+            throw new RuntimeException("Contents differ");
+        }
+
+        // check write fails with ClosedChannelException
+        try {
+            ch.read(dst).get();
+            throw new RuntimeException("ExecutionException expected");
+        } catch (ExecutionException x) {
+            if (!(x.getCause() instanceof ClosedChannelException))
+                throw new RuntimeException("Cause of ClosedChannelException expected");
+        }
+
+        server.close();
+    }
+
+    // exercise gathering write
+    static void testWrite2() throws Exception {
+        System.out.println("-- write (2) --");
+
+        Server server = new Server();
+        final AsynchronousSocketChannel ch = AsynchronousSocketChannel.open();
+        ch.connect(server.address()).get();
+        SocketChannel sc = server.accept();
+
+        // write buffers (should complete immediately)
+        ByteBuffer[] srcs = genBuffers(1);
+        long n = ch
+            .write(srcs, 0, srcs.length, 0L, TimeUnit.SECONDS, null, null).get();
+        if (n <= 0)
+            throw new RuntimeException("No bytes written");
+
+        // set to true to signal that no more buffers should be written
+        final AtomicBoolean continueWriting = new AtomicBoolean(true);
+
+        // number of bytes written
+        final AtomicLong bytesWritten = new AtomicLong(n);
+
+        // write until socket buffer is full so as to create the conditions
+        // for when a write does not complete immediately
+        srcs = genBuffers(1);
+        ch.write(srcs, 0, srcs.length, 0L, TimeUnit.SECONDS, null,
+            new CompletionHandler<Long,Void>() {
+                public void completed(Long result, Void att) {
+                    long n = result;
+                    if (n <= 0)
+                        throw new RuntimeException("No bytes written");
+                    bytesWritten.addAndGet(n);
+                    if (continueWriting.get()) {
+                        ByteBuffer[] srcs = genBuffers(8);
+                        ch.write(srcs, 0, srcs.length, 0L, TimeUnit.SECONDS,
+                            null, this);
+                    }
+                }
+                public void failed(Throwable exc, Void att) {
+                }
+                public void cancelled(Void att) {
+                }
+        });
+
+        // give time for socket buffer to fill up.
+        Thread.sleep(5*1000);
+
+        // signal handler to stop further writing
+        continueWriting.set(false);
+
+        // read until done
+        ByteBuffer buf = ByteBuffer.allocateDirect(4096);
+        long total = 0L;
+        do {
+            n = sc.read(buf);
+            if (n <= 0)
+                throw new RuntimeException("No bytes read");
+            buf.rewind();
+            total += n;
+        } while (total < bytesWritten.get());
+
+        ch.close();
+        sc.close();
+        server.close();
+    }
+
+    static void testShutdown() throws Exception {
+        System.out.println("-- shutdown--");
+
+        Server server = new Server();
+        AsynchronousSocketChannel ch = AsynchronousSocketChannel.open();
+        ch.connect(server.address()).get();
+        SocketChannel sc = server.accept();
+
+        ByteBuffer buf = ByteBuffer.allocateDirect(1000);
+        int n;
+
+        // check read
+        ch.shutdownInput();
+        n = ch.read(buf).get();
+        if (n != -1)
+            throw new RuntimeException("-1 expected");
+        // check full with full buffer
+        buf.put(new byte[100]);
+        n = ch.read(buf).get();
+        if (n != -1)
+            throw new RuntimeException("-1 expected");
+
+        // check write
+        ch.shutdownOutput();
+        try {
+            ch.write(buf).get();
+            throw new RuntimeException("ClosedChannelException expected");
+        } catch (ExecutionException x) {
+            if (!(x.getCause() instanceof ClosedChannelException))
+                throw new RuntimeException("ClosedChannelException expected");
+        }
+
+        sc.close();
+        ch.close();
+        server.close();
+    }
+
+    static void testTimeout() throws Exception {
+        Server server = new Server();
+        AsynchronousSocketChannel ch = AsynchronousSocketChannel.open();
+        ch.connect(server.address()).get();
+
+        System.out.println("-- timeout when reading --");
+
+        // this read should timeout
+        ByteBuffer dst = ByteBuffer.allocate(512);
+        try {
+            ch.read(dst, 3, TimeUnit.SECONDS, null, null).get();
+            throw new RuntimeException("Read did not timeout");
+        } catch (ExecutionException x) {
+            if (!(x.getCause() instanceof InterruptedByTimeoutException))
+                throw new RuntimeException("InterruptedByTimeoutException expected");
+        }
+
+        // after a timeout then further reading should throw unspecified runtime exception
+        boolean exceptionThrown = false;
+        try {
+            ch.read(dst);
+        } catch (RuntimeException x) {
+            exceptionThrown = true;
+        }
+        if (!exceptionThrown)
+            throw new RuntimeException("RuntimeException expected after timeout.");
+
+
+        System.out.println("-- timeout when writing --");
+
+        final AtomicReference<Throwable> writeException = new AtomicReference<Throwable>();
+
+        final long timeout = 5;
+        final TimeUnit unit = TimeUnit.SECONDS;
+
+        // write bytes to fill socket buffer
+        ch.write(genBuffer(), timeout, unit, ch,
+            new CompletionHandler<Integer,AsynchronousSocketChannel>()
+        {
+            public void completed(Integer result, AsynchronousSocketChannel ch) {
+                ch.write(genBuffer(), timeout, unit, ch, this);
+            }
+            public void failed(Throwable exc, AsynchronousSocketChannel ch) {
+                writeException.set(exc);
+            }
+            public void cancelled(AsynchronousSocketChannel ch) {
+            }
+        });
+
+        // wait for exception
+        while (writeException.get() == null) {
+            Thread.sleep(100);
+        }
+        if (!(writeException.get() instanceof InterruptedByTimeoutException))
+            throw new RuntimeException("InterruptedByTimeoutException expected");
+
+        // after a timeout then further writing should throw unspecified runtime exception
+        exceptionThrown = false;
+        try {
+            ch.write(genBuffer());
+        } catch (RuntimeException x) {
+            exceptionThrown = true;
+        }
+        if (!exceptionThrown)
+            throw new RuntimeException("RuntimeException expected after timeout.");
+
+        ch.close();
+    }
+
+   // returns ByteBuffer with random bytes
+   static ByteBuffer genBuffer() {
+       int size = 1024 + rand.nextInt(16000);
+       byte[] buf = new byte[size];
+       rand.nextBytes(buf);
+       boolean useDirect = rand.nextBoolean();
+       if (useDirect) {
+           ByteBuffer bb = ByteBuffer.allocateDirect(buf.length);
+           bb.put(buf);
+           bb.flip();
+           return bb;
+       } else {
+           return ByteBuffer.wrap(buf);
+       }
+   }
+
+   // return ByteBuffer[] with random bytes
+   static ByteBuffer[] genBuffers(int max) {
+       int len = 1;
+       if (max > 1)
+           len += rand.nextInt(max);
+       ByteBuffer[] bufs = new ByteBuffer[len];
+       for (int i=0; i<len; i++)
+           bufs[i] = genBuffer();
+       return bufs;
+   }
+}
diff --git a/jdk/test/java/nio/channels/AsynchronousSocketChannel/Leaky.java b/jdk/test/java/nio/channels/AsynchronousSocketChannel/Leaky.java
new file mode 100644
index 0000000..3ac1821
--- /dev/null
+++ b/jdk/test/java/nio/channels/AsynchronousSocketChannel/Leaky.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 4607272
+ * @summary Unit test for AsynchronousSocketChannel
+ * @run main/othervm -XX:+DisableExplicitGC -mx64m Leaky
+ */
+
+import java.nio.ByteBuffer;
+import java.nio.channels.*;
+import java.net.*;
+import java.util.concurrent.Future;
+
+/**
+ * Heap buffers must be substituted with direct buffers when doing I/O. This
+ * test creates a scenario on Windows that challenges the per-thread buffer
+ * cache and quickly leads to an OutOfMemoryError if temporary buffers are
+ * not returned to the native heap.
+ */
+
+public class Leaky {
+
+    static final int K = 1024;
+
+    static class Connection {
+        private final AsynchronousSocketChannel client;
+        private final SocketChannel peer;
+        private final ByteBuffer dst;
+        private Future<Integer> readResult;
+
+        Connection() throws Exception {
+            ServerSocketChannel ssc =
+                ServerSocketChannel.open().bind(new InetSocketAddress(0));
+            InetAddress lh = InetAddress.getLocalHost();
+            int port = ((InetSocketAddress)(ssc.getLocalAddress())).getPort();
+            SocketAddress remote = new InetSocketAddress(lh, port);
+            client = AsynchronousSocketChannel.open();
+            client.connect(remote).get();
+            peer = ssc.accept();
+            ssc.close();
+            dst = ByteBuffer.allocate(K*K);
+        }
+
+        void startRead() {
+            dst.clear();
+            readResult = client.read(dst);
+        }
+
+        void write() throws Exception {
+            peer.write(ByteBuffer.wrap("X".getBytes()));
+        }
+
+        void finishRead() throws Exception {
+            readResult.get();
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        final int CONNECTION_COUNT = 10;
+        Connection[] connections = new Connection[CONNECTION_COUNT];
+        for (int i=0; i<CONNECTION_COUNT; i++) {
+            connections[i] = new Connection();
+        }
+
+        for (int i=0; i<1024; i++) {
+            // initiate reads
+            for (Connection conn: connections) {
+                conn.startRead();
+            }
+
+            // write data so that the read can complete
+            for (Connection conn: connections) {
+                conn.write();
+            }
+
+            // complete read
+            for (Connection conn: connections) {
+                conn.finishRead();
+            }
+        }
+    }
+}
diff --git a/jdk/test/java/nio/channels/Channels/Basic2.java b/jdk/test/java/nio/channels/Channels/Basic2.java
new file mode 100644
index 0000000..46a1b02
--- /dev/null
+++ b/jdk/test/java/nio/channels/Channels/Basic2.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 4607272
+ * @summary Test Channels methods for interoperability between streams and
+ *     asynchronous byte channels
+ */
+
+import java.net.*;
+import java.io.*;
+import java.nio.channels.*;
+import java.util.Random;
+
+public class Basic2 {
+
+    static final Random rand = new Random();
+
+    public static void main(String[] args) throws Exception {
+        // establish loopback connection
+        AsynchronousServerSocketChannel listener =
+            AsynchronousServerSocketChannel.open().bind(new InetSocketAddress(0));
+        int port = ((InetSocketAddress)(listener.getLocalAddress())).getPort();
+        InetSocketAddress isa =
+            new InetSocketAddress(InetAddress.getLocalHost(), port);
+        AsynchronousSocketChannel ch1 = AsynchronousSocketChannel.open();
+        ch1.connect(isa).get();
+        AsynchronousSocketChannel ch2 = listener.accept().get();
+
+        // start thread to write to stream
+        Writer writer = new Writer(Channels.newOutputStream(ch1));
+        Thread writerThread = new Thread(writer);
+        writerThread.start();
+
+        // start thread to read from stream
+        Reader reader = new Reader(Channels.newInputStream(ch2));
+        Thread readerThread = new Thread(reader);
+        readerThread.start();
+
+        // wait for threads to complete
+        writerThread.join();
+        readerThread.join();
+
+        // check that reader received what we expected
+        if (reader.total() != writer.total())
+            throw new RuntimeException("Unexpected number of bytes read");
+        if (reader.hash() != writer.hash())
+            throw new RuntimeException("Hash incorrect for bytes read");
+
+        // channels should be closed
+        if (ch1.isOpen() || ch2.isOpen())
+            throw new RuntimeException("Channels should be closed");
+    }
+
+    static class Reader implements Runnable {
+        private final InputStream in;
+        private volatile int total;
+        private volatile int hash;
+
+        Reader(InputStream in) {
+            this.in = in;
+        }
+
+        public void run() {
+            try {
+                int n;
+                do {
+                    // random offset/len
+                    byte[] buf = new byte[128 + rand.nextInt(128)];
+                    int len, off;
+                    if (rand.nextBoolean()) {
+                        len = buf.length;
+                        off = 0;
+                        n = in.read(buf);
+                    } else {
+                        len = 1 + rand.nextInt(64);
+                        off = rand.nextInt(64);
+                        n = in.read(buf, off, len);
+                    }
+                    if (n > len)
+                        throw new RuntimeException("Too many bytes read");
+                    if (n > 0) {
+                        total += n;
+                        for (int i=0; i<n; i++) {
+                            int value = buf[off + i];
+                            hash = hash ^ value;
+                        }
+                    }
+                } while (n > 0);
+                in.close();
+
+            } catch (IOException x) {
+                x.printStackTrace();
+            }
+        }
+
+        int total() { return total; }
+        int hash() { return hash; }
+    }
+
+    static class Writer implements Runnable {
+        private final OutputStream out;
+        private final int total;
+        private volatile int hash;
+
+        Writer(OutputStream out) {
+            this.out = out;
+            this.total = 50*1000 + rand.nextInt(50*1000);
+        }
+
+        public void run() {
+            hash = 0;
+            int rem = total;
+            try {
+                do {
+                    byte[] buf = new byte[1 + rand.nextInt(rem)];
+                    int off, len;
+
+                    // write random bytes
+                    if (rand.nextBoolean()) {
+                        off = 0;
+                        len = buf.length;
+                    } else {
+                        off = rand.nextInt(buf.length);
+                        int r = buf.length - off;
+                        len = (r <= 1) ? 1 : (1 + rand.nextInt(r));
+                    }
+                    for (int i=0; i<len; i++) {
+                        byte value = (byte)rand.nextInt(256);
+                        buf[off + i] = value;
+                        hash = hash ^ value;
+                    }
+                    if ((off == 0) && (len == buf.length)) {
+                        out.write(buf);
+                    } else {
+                        out.write(buf, off, len);
+                    }
+                    rem -= len;
+                } while (rem > 0);
+
+                // close stream when done
+                out.close();
+
+            } catch (IOException x) {
+                x.printStackTrace();
+            }
+        }
+
+        int total() { return total; }
+        int hash() { return hash; }
+    }
+}
diff --git a/jdk/test/java/nio/channels/DatagramChannel/BasicMulticastTests.java b/jdk/test/java/nio/channels/DatagramChannel/BasicMulticastTests.java
index 03b5daa..6928bcd 100644
--- a/jdk/test/java/nio/channels/DatagramChannel/BasicMulticastTests.java
+++ b/jdk/test/java/nio/channels/DatagramChannel/BasicMulticastTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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
@@ -64,11 +64,11 @@
         // check key
         if (!key.isValid())
             throw new RuntimeException("key is not valid");
-        if (!key.getGroup().equals(group))
+        if (!key.group().equals(group))
             throw new RuntimeException("group is incorrect");
-        if (!key.getNetworkInterface().equals(nif))
+        if (!key.networkInterface().equals(nif))
             throw new RuntimeException("network interface is incorrect");
-        if (key.getSourceAddress() != null)
+        if (key.sourceAddress() != null)
             throw new RuntimeException("key is source specific");
 
         // drop membership
@@ -86,11 +86,11 @@
             }
             if (!key.isValid())
                 throw new RuntimeException("key is not valid");
-            if (!key.getGroup().equals(group))
+            if (!key.group().equals(group))
                 throw new RuntimeException("group is incorrect");
-            if (!key.getNetworkInterface().equals(nif))
+            if (!key.networkInterface().equals(nif))
                 throw new RuntimeException("network interface is incorrect");
-            if (!key.getSourceAddress().equals(source))
+            if (!key.sourceAddress().equals(source))
                 throw new RuntimeException("key's source address incorrect");
 
             // drop membership
diff --git a/jdk/test/java/nio/channels/DatagramChannel/SocketOptionTests.java b/jdk/test/java/nio/channels/DatagramChannel/SocketOptionTests.java
index e4e85b1..3df7bbb 100644
--- a/jdk/test/java/nio/channels/DatagramChannel/SocketOptionTests.java
+++ b/jdk/test/java/nio/channels/DatagramChannel/SocketOptionTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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
@@ -49,7 +49,7 @@
         DatagramChannel dc = DatagramChannel.open();
 
         // check supported options
-        Set<SocketOption<?>> options = dc.options();
+        Set<SocketOption<?>> options = dc.supportedOptions();
         List<? extends SocketOption<?>> expected = Arrays.asList(SO_SNDBUF, SO_RCVBUF,
             SO_REUSEADDR, SO_BROADCAST, IP_TOS, IP_MULTICAST_IF, IP_MULTICAST_TTL,
             IP_MULTICAST_LOOP);
diff --git a/jdk/test/java/nio/channels/ServerSocketChannel/SocketOptionTests.java b/jdk/test/java/nio/channels/ServerSocketChannel/SocketOptionTests.java
index 6c4a443..cba99e0 100644
--- a/jdk/test/java/nio/channels/ServerSocketChannel/SocketOptionTests.java
+++ b/jdk/test/java/nio/channels/ServerSocketChannel/SocketOptionTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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
@@ -48,7 +48,7 @@
         ServerSocketChannel ssc = ServerSocketChannel.open();
 
         // check supported options
-        Set<SocketOption<?>> options = ssc.options();
+        Set<SocketOption<?>> options = ssc.supportedOptions();
         if (!options.contains(SO_REUSEADDR))
             throw new RuntimeException("SO_REUSEADDR should be supported");
         if (!options.contains(SO_RCVBUF))
diff --git a/jdk/test/java/nio/channels/SocketChannel/SocketOptionTests.java b/jdk/test/java/nio/channels/SocketChannel/SocketOptionTests.java
index b6fadce..abcb974 100644
--- a/jdk/test/java/nio/channels/SocketChannel/SocketOptionTests.java
+++ b/jdk/test/java/nio/channels/SocketChannel/SocketOptionTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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
@@ -48,7 +48,7 @@
         SocketChannel sc = SocketChannel.open();
 
         // check supported options
-        Set<SocketOption<?>> options = sc.options();
+        Set<SocketOption<?>> options = sc.supportedOptions();
         List<? extends SocketOption> expected = Arrays.asList(SO_SNDBUF, SO_RCVBUF,
             SO_KEEPALIVE, SO_REUSEADDR, SO_LINGER, TCP_NODELAY);
         for (SocketOption opt: expected) {
diff --git a/jdk/test/java/nio/channels/etc/NetworkChannelTests.java b/jdk/test/java/nio/channels/etc/NetworkChannelTests.java
index 5f03453..2a29bce 100644
--- a/jdk/test/java/nio/channels/etc/NetworkChannelTests.java
+++ b/jdk/test/java/nio/channels/etc/NetworkChannelTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2007-2009 Sun Microsystems, Inc.  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
@@ -103,13 +103,14 @@
 
         // closed
         ch.close();
-        if (ch.getLocalAddress() != null) {
-            throw new RuntimeException("Local address return when closed");
-        }
+        try {
+            ch.getLocalAddress();
+            throw new RuntimeException("ClosedChannelException expected");
+        } catch (ClosedChannelException e) { }
     }
 
     /**
-     * Exercise getConnectedAddress method (SocketChannel only)
+     * Exercise getRemoteAddress method (SocketChannel only)
      */
     static void connectedAddressTests() throws IOException {
         ServerSocketChannel ssc = ServerSocketChannel.open()
@@ -121,19 +122,21 @@
         SocketChannel sc = SocketChannel.open();
 
         // not connected
-        if (sc.getConnectedAddress() != null)
-            throw new RuntimeException("getConnectedAddress returned address when not connected");
+        if (sc.getRemoteAddress() != null)
+            throw new RuntimeException("getRemoteAddress returned address when not connected");
 
         // connected
         sc.connect(server);
-        SocketAddress remote = sc.getConnectedAddress();
+        SocketAddress remote = sc.getRemoteAddress();
         if (!remote.equals(server))
-            throw new RuntimeException("getConnectedAddress returned incorrect address");
+            throw new RuntimeException("getRemoteAddress returned incorrect address");
 
         // closed
         sc.close();
-        if (sc.getConnectedAddress() != null)
-            throw new RuntimeException("getConnectedAddress returned address when closed");
+        try {
+            sc.getRemoteAddress();
+            throw new RuntimeException("ClosedChannelException expected");
+        } catch (ClosedChannelException e) { }
 
         ssc.close();
     }
diff --git a/jdk/test/java/nio/channels/spi/AsynchronousChannelProvider/CheckProvider.java b/jdk/test/java/nio/channels/spi/AsynchronousChannelProvider/CheckProvider.java
new file mode 100644
index 0000000..4f6d848
--- /dev/null
+++ b/jdk/test/java/nio/channels/spi/AsynchronousChannelProvider/CheckProvider.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.nio.channels.spi.AsynchronousChannelProvider;
+
+public class CheckProvider {
+    public static void main(String[] args) {
+        Class<?> c = AsynchronousChannelProvider.provider().getClass();
+
+        String expected = args[0];
+        String actual = c.getName();
+
+        if (!actual.equals(expected))
+            throw new RuntimeException("Provider is of type '" + actual +
+                "', expected '" + expected + "'");
+
+    }
+}
diff --git a/jdk/test/java/nio/channels/spi/AsynchronousChannelProvider/META-INF/services/java.nio.channels.spi.AsynchronousChannelProvider b/jdk/test/java/nio/channels/spi/AsynchronousChannelProvider/META-INF/services/java.nio.channels.spi.AsynchronousChannelProvider
new file mode 100644
index 0000000..6b3e87e
--- /dev/null
+++ b/jdk/test/java/nio/channels/spi/AsynchronousChannelProvider/META-INF/services/java.nio.channels.spi.AsynchronousChannelProvider
@@ -0,0 +1 @@
+Provider1
diff --git a/jdk/test/java/nio/channels/spi/AsynchronousChannelProvider/Provider1.java b/jdk/test/java/nio/channels/spi/AsynchronousChannelProvider/Provider1.java
new file mode 100644
index 0000000..fc6036a
--- /dev/null
+++ b/jdk/test/java/nio/channels/spi/AsynchronousChannelProvider/Provider1.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.nio.channels.spi.AsynchronousChannelProvider;
+import java.nio.channels.*;
+import java.net.ProtocolFamily;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.ThreadFactory;
+import java.io.IOException;
+
+public class Provider1 extends AsynchronousChannelProvider {
+    public Provider1() {
+    }
+
+    @Override
+    public AsynchronousChannelGroup openAsynchronousChannelGroup(int nThreads, ThreadFactory factorry)
+        throws IOException
+    {
+        throw new RuntimeException();
+    }
+
+    @Override
+    public AsynchronousChannelGroup openAsynchronousChannelGroup(ExecutorService executor, int initialSize)
+        throws IOException
+    {
+        throw new RuntimeException();
+    }
+
+    @Override
+    public AsynchronousSocketChannel openAsynchronousSocketChannel
+        (AsynchronousChannelGroup group) throws IOException
+    {
+        throw new RuntimeException();
+    }
+
+    @Override
+    public AsynchronousServerSocketChannel openAsynchronousServerSocketChannel
+        (AsynchronousChannelGroup group) throws IOException
+    {
+        throw new RuntimeException();
+    }
+
+    @Override
+    public AsynchronousDatagramChannel openAsynchronousDatagramChannel
+        (ProtocolFamily family, AsynchronousChannelGroup group) throws IOException
+    {
+        throw new RuntimeException();
+    }
+}
diff --git a/jdk/test/java/nio/channels/spi/AsynchronousChannelProvider/Provider2.java b/jdk/test/java/nio/channels/spi/AsynchronousChannelProvider/Provider2.java
new file mode 100644
index 0000000..a42c12f
--- /dev/null
+++ b/jdk/test/java/nio/channels/spi/AsynchronousChannelProvider/Provider2.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.nio.channels.spi.AsynchronousChannelProvider;
+import java.nio.channels.*;
+import java.net.ProtocolFamily;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.ThreadFactory;
+import java.io.IOException;
+
+public class Provider2 extends AsynchronousChannelProvider {
+    public Provider2() {
+    }
+
+    @Override
+    public AsynchronousChannelGroup openAsynchronousChannelGroup
+        (int nThreads, ThreadFactory threadFactory) throws IOException
+    {
+        throw new RuntimeException();
+    }
+
+    @Override
+    public AsynchronousChannelGroup openAsynchronousChannelGroup
+        (ExecutorService executor, int initialSize) throws IOException
+    {
+        throw new RuntimeException();
+    }
+
+    @Override
+    public AsynchronousSocketChannel openAsynchronousSocketChannel
+        (AsynchronousChannelGroup group) throws IOException
+    {
+        throw new RuntimeException();
+    }
+
+    @Override
+    public AsynchronousServerSocketChannel openAsynchronousServerSocketChannel
+        (AsynchronousChannelGroup group) throws IOException
+    {
+        throw new RuntimeException();
+    }
+
+    @Override
+    public AsynchronousDatagramChannel openAsynchronousDatagramChannel
+        (ProtocolFamily family, AsynchronousChannelGroup group) throws IOException
+    {
+        throw new RuntimeException();
+    }
+}
diff --git a/jdk/test/java/nio/channels/spi/AsynchronousChannelProvider/custom_provider.sh b/jdk/test/java/nio/channels/spi/AsynchronousChannelProvider/custom_provider.sh
new file mode 100644
index 0000000..13fb2a2f
--- /dev/null
+++ b/jdk/test/java/nio/channels/spi/AsynchronousChannelProvider/custom_provider.sh
@@ -0,0 +1,71 @@
+#
+# Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
+# @test
+# @summary Unit test for java.nio.channels.spi.AsynchronousChannelProvider
+# @build Provider1 Provider2 CheckProvider
+# @run shell custom_provider.sh
+
+# if TESTJAVA isn't set then we assume an interactive run.
+
+if [ -z "$TESTJAVA" ]; then
+    TESTSRC=.
+    TESTCLASSES=.
+    JAVA=java
+else
+    JAVA="${TESTJAVA}/bin/java"
+fi
+
+OS=`uname -s`
+case "$OS" in
+    Windows_* )
+        CLASSPATH="${TESTCLASSES};${TESTSRC}"
+        ;;
+    * )
+        CLASSPATH=${TESTCLASSES}:${TESTSRC}
+        ;;
+esac
+export CLASSPATH
+
+failures=0
+
+go() {
+    echo ''
+    $JAVA $1 $2 $3 2>&1
+    if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
+}
+
+# Run the tests
+
+go CheckProvider Provider1
+go -Djava.nio.channels.spi.AsynchronousChannelProvider=Provider2 CheckProvider \
+  Provider2
+
+#
+# Results
+#
+echo ''
+if [ $failures -gt 0 ];
+  then echo "$failures test(s) failed";
+  else echo "All test(s) passed"; fi
+exit $failures
diff --git a/jdk/test/java/nio/file/DirectoryStream/Basic.java b/jdk/test/java/nio/file/DirectoryStream/Basic.java
new file mode 100644
index 0000000..b92447d
--- /dev/null
+++ b/jdk/test/java/nio/file/DirectoryStream/Basic.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 4313887
+ * @summary Unit test for java.nio.file.DirectoryStream
+ * @library ..
+ */
+
+import java.nio.file.*;
+import java.util.*;
+import java.io.IOException;
+
+public class Basic {
+    static boolean found;
+
+    static void doTest(final Path dir) throws IOException {
+        DirectoryStream<Path> stream;
+
+        // test that directory is empty
+        Files.withDirectory(dir, new FileAction<FileRef>() {
+            public void invoke(FileRef entry) {
+                throw new RuntimeException("directory not empty");
+            }
+        });
+
+        // create file in directory
+        final Path foo = Paths.get("foo");
+        dir.resolve(foo).createFile();
+
+        // iterate over directory and check there is one entry
+        found = false;
+        Files.withDirectory(dir, new FileAction<Path>() {
+            public void invoke(Path entry) {
+                if (entry.getName().equals(foo)) {
+                    if (found)
+                        throw new RuntimeException("entry already found");
+                    found = true;
+                } else {
+                    throw new RuntimeException("entry " + entry.getName() +
+                        " not expected");
+                }
+            }
+        });
+        if (!found)
+            throw new RuntimeException("entry not found");
+
+        // check filtering: f* should match foo
+        DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
+            private PathMatcher matcher =
+                dir.getFileSystem().getPathMatcher("glob:f*");
+            public boolean accept(Path file) {
+                return matcher.matches(file);
+            }
+        };
+        Files.withDirectory(dir, filter, new FileAction<Path>() {
+            public void invoke(Path entry) {
+                if (!entry.getName().equals(foo))
+                    throw new RuntimeException("entry not expected");
+            }
+        });
+
+        // check filtering: z* should not match any files
+        filter = new DirectoryStream.Filter<Path>() {
+            private PathMatcher matcher =
+                dir.getFileSystem().getPathMatcher("glob:z*");
+            public boolean accept(Path file) {
+                return matcher.matches(file);
+            }
+        };
+        Files.withDirectory(dir, filter, new FileAction<FileRef>() {
+            public void invoke(FileRef entry) {
+                throw new RuntimeException("no matching entries expected");
+            }
+        });
+
+        // check that exception or error thrown by filter is not thrown
+        // by newDirectoryStream or iterator method.
+        stream = dir.newDirectoryStream(new DirectoryStream.Filter<Path>() {
+            public boolean accept(Path file) {
+                throw new RuntimeException("Should not be visible");
+            }
+        });
+        try {
+            stream.iterator();
+        } finally {
+            stream.close();
+        }
+
+        // test NotDirectoryException
+        try {
+            dir.resolve(foo).newDirectoryStream();
+            throw new RuntimeException("NotDirectoryException not thrown");
+        } catch (NotDirectoryException x) {
+        }
+
+        // test iterator remove method
+        stream = dir.newDirectoryStream();
+        Iterator<Path> i = stream.iterator();
+        while (i.hasNext()) {
+            Path entry = i.next();
+            if (!entry.getName().equals(foo))
+                throw new RuntimeException("entry not expected");
+            i.remove();
+        }
+        stream.close();
+
+        // test IllegalStateException
+        stream =  dir.newDirectoryStream();
+        i = stream.iterator();
+        try {
+            stream.iterator();
+            throw new RuntimeException("IllegalStateException not thrown as expected");
+        } catch (IllegalStateException x) {
+        }
+        stream.close();
+        try {
+            stream.iterator();
+            throw new RuntimeException("IllegalStateException not thrown as expected");
+        } catch (IllegalStateException x) {
+        }
+        try {
+            i.hasNext();
+            throw new RuntimeException("ConcurrentModificationException not thrown as expected");
+        } catch (ConcurrentModificationException x) {
+            Throwable t = x.getCause();
+            if (!(t instanceof IllegalStateException))
+                throw new RuntimeException("Cause is not IllegalStateException as expected");
+        }
+        try {
+            i.next();
+            throw new RuntimeException("IllegalStateException not thrown as expected");
+        } catch (ConcurrentModificationException x) {
+            Throwable t = x.getCause();
+            if (!(t instanceof IllegalStateException))
+                throw new RuntimeException("Cause is not IllegalStateException as expected");
+        }
+    }
+
+    public static void main(String[] args) throws IOException {
+        Path dir = TestUtil.createTemporaryDirectory();
+        try {
+            doTest(dir);
+        } finally {
+            TestUtil.removeAll(dir);
+        }
+    }
+}
diff --git a/jdk/test/java/nio/file/DirectoryStream/DriveLetter.java b/jdk/test/java/nio/file/DirectoryStream/DriveLetter.java
new file mode 100644
index 0000000..92159f5
--- /dev/null
+++ b/jdk/test/java/nio/file/DirectoryStream/DriveLetter.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 6808647
+ * @summary Checks that a DirectoryStream's iterator returns the expected
+ *    path when opening a directory by specifying only the drive letter.
+ * @library ..
+ */
+
+import java.nio.file.*;
+import java.io.File;
+import java.io.IOException;
+
+public class DriveLetter {
+
+    public static void main(String[] args) throws IOException {
+        String os = System.getProperty("os.name");
+        if (!os.startsWith("Windows")) {
+            System.out.println("This is Windows specific test");
+            return;
+        }
+        String here = System.getProperty("user.dir");
+        if (here.length() < 2 || here.charAt(1) != ':')
+            throw new RuntimeException("Unable to determine drive letter");
+
+        // create temporary file in current directory
+        File tempFile = File.createTempFile("foo", "tmp", new File(here));
+        try {
+            // we should expect C:foo.tmp to be returned by iterator
+            String drive = here.substring(0, 2);
+            Path expected = Paths.get(drive).resolve(tempFile.getName());
+
+            boolean found = false;
+            DirectoryStream<Path> stream = Paths.get(drive).newDirectoryStream();
+            try {
+                for (Path file : stream) {
+                    if (file.equals(expected)) {
+                        found = true;
+                        break;
+                    }
+                }
+            } finally {
+                stream.close();
+            }
+            if (!found)
+                throw new RuntimeException("Temporary file not found???");
+
+        } finally {
+            tempFile.delete();
+        }
+    }
+}
diff --git a/jdk/test/java/nio/file/DirectoryStream/Filters.java b/jdk/test/java/nio/file/DirectoryStream/Filters.java
new file mode 100644
index 0000000..ea539c9
--- /dev/null
+++ b/jdk/test/java/nio/file/DirectoryStream/Filters.java
@@ -0,0 +1,241 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 4313887
+ * @summary Unit test for java.nio.file.DirectoryStreamFilters
+ * @library ..
+ */
+
+import java.nio.file.*;
+import static java.nio.file.DirectoryStreamFilters.*;
+import java.nio.file.attribute.Attributes;
+import java.io.*;
+import java.util.*;
+
+public class Filters {
+    static final Random rand = new Random();
+
+    // returns a filter that only accepts files that are larger than a given size
+    static DirectoryStream.Filter<FileRef> newMinimumSizeFilter(final long min) {
+        return new DirectoryStream.Filter<FileRef>() {
+            public boolean accept(FileRef file) {
+                try {
+                    long size = Attributes.readBasicFileAttributes(file).size();
+                    return size >= min;
+                } catch (IOException e) {
+                    throw new IOError(e);
+                }
+            }
+        };
+    }
+
+    // returns a filter that only accepts files that are matched by a given glob
+    static DirectoryStream.Filter<Path> newGlobFilter(final String glob) {
+        return new DirectoryStream.Filter<Path>() {
+            PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:"+ glob);
+            public boolean accept(Path file) {
+                return matcher.matches(file.getName());
+            }
+        };
+    }
+
+    static final int BIG_FILE_THRESHOLD = 8192;
+
+    static int totalCount;
+    static int htmlCount;
+    static int bigAndHtmlCount;
+    static int bigOrHtmlCount;
+
+    // generates random files in the test directory and initializes the counts
+    static void setup(Path dir) throws IOException {
+        // create 10-26 files.
+        totalCount = 10 + rand.nextInt(17);
+        char firstChar = 'A';
+        for (int i=0; i<totalCount; i++) {
+            boolean isHtml = rand.nextBoolean();
+            boolean isBig = rand.nextBoolean();
+            if (isHtml) {
+                htmlCount++;
+                if (isBig) bigAndHtmlCount++;
+            }
+            if (isHtml || isBig)
+                bigOrHtmlCount++;
+            String name;
+            if (isHtml) {
+                name = firstChar + ".html";
+            } else {
+                name = firstChar + ".tmp";
+            }
+            firstChar++;
+            int size = rand.nextInt(BIG_FILE_THRESHOLD);
+            if (isBig)
+                size += BIG_FILE_THRESHOLD;
+            Path file = dir.resolve(name);
+            OutputStream out = file.newOutputStream();
+            try {
+                if (size > 0)
+                    out.write(new byte[size]);
+            } finally {
+                out.close();
+            }
+            System.out.format("Created %s, size %d byte(s)\n", name, size);
+        }
+    }
+
+    static boolean isHtml(Path file) {
+        return file.toString().endsWith(".html");
+    }
+
+    static boolean isBig(Path file) throws IOException {
+        long size = Attributes.readBasicFileAttributes(file).size();
+        return size >= BIG_FILE_THRESHOLD;
+    }
+
+    static void checkCount(int expected, int actual) {
+        if (actual != expected)
+            throw new RuntimeException("'" + expected +
+                "' entries expected, actual: " + actual);
+    }
+
+    static void doTests(Path dir) throws IOException {
+        final List<DirectoryStream.Filter<Path>> emptyList = Collections.emptyList();
+
+        // list containing two filters
+        List<DirectoryStream.Filter<? super Path>> filters =
+            new ArrayList<DirectoryStream.Filter<? super Path>>();
+        filters.add(newMinimumSizeFilter(BIG_FILE_THRESHOLD));
+        filters.add(newGlobFilter("*.html"));
+
+        int accepted;
+        DirectoryStream<Path> stream;
+
+        System.out.println("Test: newContentTypeFilter");
+        accepted = 0;
+        stream = dir.newDirectoryStream(newContentTypeFilter("text/html"));
+        try {
+            for (Path entry: stream) {
+                if (!isHtml(entry))
+                    throw new RuntimeException("html file expected");
+                accepted++;
+            }
+        } finally {
+            stream.close();
+        }
+        checkCount(htmlCount, accepted);
+
+        System.out.println("Test: allOf with list of filters");
+        accepted = 0;
+        stream = dir.newDirectoryStream(allOf(filters));
+        try {
+            for (Path entry: stream) {
+                if (!isHtml(entry))
+                    throw new RuntimeException("html file expected");
+                if (!isBig(entry))
+                    throw new RuntimeException("big file expected");
+                accepted++;
+            }
+        } finally {
+            stream.close();
+        }
+        checkCount(bigAndHtmlCount, accepted);
+
+        System.out.println("Test: allOf with empty list");
+        accepted = 0;
+        stream = dir.newDirectoryStream(allOf(emptyList));
+        try {
+            for (Path entry: stream) {
+                accepted++;
+            }
+        } finally {
+            stream.close();
+        }
+        checkCount(totalCount, accepted);
+
+        System.out.println("Test: anyOf with list of filters");
+        accepted = 0;
+        stream = dir.newDirectoryStream(anyOf(filters));
+        try {
+            for (Path entry: stream) {
+                if (!isHtml(entry) && !isBig(entry))
+                    throw new RuntimeException("html or big file expected");
+                accepted++;
+            }
+        } finally {
+            stream.close();
+        }
+        checkCount(bigOrHtmlCount, accepted);
+
+        System.out.println("Test: anyOf with empty list");
+        accepted = 0;
+        stream = dir.newDirectoryStream(anyOf(emptyList));
+        try {
+            for (Path entry: stream) {
+                accepted++;
+            }
+        } finally {
+            stream.close();
+        }
+        checkCount(0, accepted);
+
+        System.out.println("Test: complementOf");
+        accepted = 0;
+        stream = dir.newDirectoryStream(complementOf(newGlobFilter("*.html")));
+        try {
+            for (Path entry: stream) {
+                accepted++;
+            }
+        } finally {
+            stream.close();
+        }
+        checkCount(totalCount-htmlCount, accepted);
+
+        System.out.println("Test: nulls");
+        try {
+            newContentTypeFilter(null);
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException npe) { }
+        try {
+            allOf(null);
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException npe) { }
+        try {
+            anyOf(null);
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException npe) { }
+        try {
+            complementOf(null);
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException npe) { }
+    }
+
+    public static void main(String[] args) throws IOException {
+        Path dir = TestUtil.createTemporaryDirectory();
+        try {
+            setup(dir);
+            doTests(dir);
+        } finally {
+            TestUtil.removeAll(dir);
+        }
+    }
+}
diff --git a/jdk/test/java/nio/file/DirectoryStream/SecureDS.java b/jdk/test/java/nio/file/DirectoryStream/SecureDS.java
new file mode 100644
index 0000000..98367d8
--- /dev/null
+++ b/jdk/test/java/nio/file/DirectoryStream/SecureDS.java
@@ -0,0 +1,370 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 4313887
+ * @summary Unit test for java.nio.file.SecureDirectoryStream
+ * @library ..
+ */
+
+import java.nio.file.*;
+import static java.nio.file.StandardOpenOption.*;
+import static java.nio.file.LinkOption.*;
+import java.nio.file.attribute.*;
+import java.nio.channels.*;
+import java.io.IOException;
+import java.util.*;
+
+public class SecureDS {
+    static boolean supportsLinks;
+
+    public static void main(String[] args) throws IOException {
+        Path dir = TestUtil.createTemporaryDirectory();
+        try {
+            DirectoryStream stream = dir.newDirectoryStream();
+            stream.close();
+            if (!(stream instanceof SecureDirectoryStream)) {
+                System.out.println("SecureDirectoryStream not supported.");
+                return;
+            }
+
+            supportsLinks = TestUtil.supportsLinks(dir);
+
+            // run tests
+            doBasicTests(dir);
+            doMoveTests(dir);
+            miscTests(dir);
+
+        } finally {
+            TestUtil.removeAll(dir);
+        }
+    }
+
+    // Exercise each of SecureDirectoryStream's method (except move)
+    static void doBasicTests(Path dir) throws IOException {
+        Path dir1 = dir.resolve("dir1").createDirectory();
+        Path dir2 = dir.resolve("dir2");
+
+        // create a file, directory, and two sym links in the directory
+        Path fileEntry = Paths.get("myfile");
+        dir1.resolve(fileEntry).createFile();
+        Path dirEntry = Paths.get("mydir");
+        dir1.resolve(dirEntry).createDirectory();
+        // myfilelink -> myfile
+        Path link1Entry = Paths.get("myfilelink");
+        if (supportsLinks)
+            dir1.resolve(link1Entry).createSymbolicLink(fileEntry);
+        // mydirlink -> mydir
+        Path link2Entry = Paths.get("mydirlink");
+        if (supportsLinks)
+            dir1.resolve(link2Entry).createSymbolicLink(dirEntry);
+
+        // open directory and then move it so that it is no longer accessible
+        // via its original path.
+        SecureDirectoryStream stream =
+            (SecureDirectoryStream)dir1.newDirectoryStream();
+        dir1.moveTo(dir2);
+
+        // Test: iterate over all entries
+        int count = 0;
+        for (Path entry: stream) { count++; }
+        assertTrue(count == (supportsLinks ? 4 : 2));
+
+        // Test: getFileAttributeView to access directory's attributes
+        assertTrue(stream
+            .getFileAttributeView(BasicFileAttributeView.class)
+                .readAttributes()
+                    .isDirectory());
+
+        // Test: dynamic access to directory's attributes
+        BasicFileAttributeView view = stream.
+            getFileAttributeView(BasicFileAttributeView.class);
+        Map<String,?> attrs = view.readAttributes("*");
+        assertTrue((Boolean)attrs.get("isDirectory"));
+        attrs = view.readAttributes("isRegularFile", "size");
+        assertTrue(!(Boolean)attrs.get("isRegularFile"));
+        assertTrue((Long)attrs.get("size") >= 0);
+        int linkCount = (Integer)view.getAttribute("linkCount");
+        assertTrue(linkCount > 0);
+        view.setAttribute("lastModifiedTime", 0L);
+
+        // Test: getFileAttributeView to access attributes of entries
+        assertTrue(stream
+            .getFileAttributeView(fileEntry, BasicFileAttributeView.class)
+                .readAttributes()
+                    .isRegularFile());
+        assertTrue(stream
+            .getFileAttributeView(fileEntry, BasicFileAttributeView.class, NOFOLLOW_LINKS)
+                .readAttributes()
+                    .isRegularFile());
+        assertTrue(stream
+            .getFileAttributeView(dirEntry, BasicFileAttributeView.class)
+                .readAttributes()
+                    .isDirectory());
+        assertTrue(stream
+            .getFileAttributeView(dirEntry, BasicFileAttributeView.class, NOFOLLOW_LINKS)
+                .readAttributes()
+                    .isDirectory());
+        if (supportsLinks) {
+            assertTrue(stream
+                .getFileAttributeView(link1Entry, BasicFileAttributeView.class)
+                    .readAttributes()
+                        .isRegularFile());
+            assertTrue(stream
+                .getFileAttributeView(link1Entry, BasicFileAttributeView.class, NOFOLLOW_LINKS)
+                    .readAttributes()
+                        .isSymbolicLink());
+            assertTrue(stream
+                .getFileAttributeView(link2Entry, BasicFileAttributeView.class)
+                    .readAttributes()
+                        .isDirectory());
+            assertTrue(stream
+                .getFileAttributeView(link2Entry, BasicFileAttributeView.class, NOFOLLOW_LINKS)
+                    .readAttributes()
+                        .isSymbolicLink());
+        }
+
+        // Test: dynamic access to entry attributes
+        view = stream
+             .getFileAttributeView(fileEntry, PosixFileAttributeView.class, NOFOLLOW_LINKS);
+        if (view != null) {
+            attrs = view.readAttributes("owner", "size");
+            UserPrincipal owner = (UserPrincipal)attrs.get("owner");
+            assertTrue(owner != null);
+            assertTrue((Long)attrs.get("size") >= 0L);
+            view.setAttribute("lastAccessTime", 0L);
+        }
+
+        // Test: newByteChannel
+        Set<StandardOpenOption> opts = Collections.emptySet();
+        stream.newByteChannel(fileEntry, opts).close();
+        if (supportsLinks) {
+            stream.newByteChannel(link1Entry, opts).close();
+            try {
+                Set<OpenOption> mixed = new HashSet<OpenOption>();
+                mixed.add(READ);
+                mixed.add(NOFOLLOW_LINKS);
+                stream.newByteChannel(link1Entry, mixed).close();
+                shouldNotGetHere();
+            } catch (IOException x) { }
+        }
+
+        // Test: newDirectoryStream
+        stream.newDirectoryStream(dirEntry, true, null).close();
+        stream.newDirectoryStream(dirEntry, false, null).close();
+        if (supportsLinks) {
+            stream.newDirectoryStream(link2Entry, true, null).close();
+            try {
+                stream.newDirectoryStream(link2Entry, false, null).close();
+                shouldNotGetHere();
+            } catch (IOException x) { }
+        }
+
+        // Test: delete
+        if (supportsLinks) {
+            stream.deleteFile(link1Entry);
+            stream.deleteFile(link2Entry);
+        }
+        stream.deleteDirectory(dirEntry);
+        stream.deleteFile(fileEntry);
+
+        // Test: remove
+        // (requires resetting environment to get new iterator)
+        stream.close();
+        dir2.moveTo(dir1);
+        dir1.resolve(fileEntry).createFile();
+        stream = (SecureDirectoryStream)dir1.newDirectoryStream();
+        dir1.moveTo(dir2);
+        Iterator<Path> iter = stream.iterator();
+        int removed = 0;
+        while (iter.hasNext()) {
+            iter.next();
+            iter.remove();
+            removed++;
+        }
+        assertTrue(removed == 1);
+
+        // clean-up
+        stream.close();
+        dir2.delete();
+    }
+
+    // Exercise SecureDirectoryStream's move method
+    static void doMoveTests(Path dir) throws IOException {
+        Path dir1 = dir.resolve("dir1").createDirectory();
+        Path dir2 = dir.resolve("dir2").createDirectory();
+
+        // create dir1/myfile, dir1/mydir, dir1/mylink
+        Path fileEntry = Paths.get("myfile");
+        dir1.resolve(fileEntry).createFile();
+        Path dirEntry = Paths.get("mydir");
+        dir1.resolve(dirEntry).createDirectory();
+        Path linkEntry = Paths.get("mylink");
+        if (supportsLinks)
+            dir1.resolve(linkEntry).createSymbolicLink(Paths.get("missing"));
+
+        // target name
+        Path target = Paths.get("newfile");
+
+        // open stream to both directories
+        SecureDirectoryStream stream1 =
+            (SecureDirectoryStream)dir1.newDirectoryStream();
+        SecureDirectoryStream stream2 =
+            (SecureDirectoryStream)dir2.newDirectoryStream();
+
+        // Test: move dir1/myfile -> dir2/newfile
+        stream1.move(fileEntry, stream2, target);
+        assertTrue(dir1.resolve(fileEntry).notExists());
+        assertTrue(dir2.resolve(target).exists());
+        stream2.deleteFile(target);
+
+        // Test: move dir1/mydir -> dir2/newfile
+        stream1.move(dirEntry, stream2, target);
+        assertTrue(dir1.resolve(dirEntry).notExists());
+        assertTrue(dir2.resolve(target).exists());
+        stream2.deleteDirectory(target);
+
+        // Test: move dir1/mylink -> dir2/newfile
+        if (supportsLinks) {
+            stream1.move(linkEntry, stream2, target);
+            assertTrue(dir2.resolve(target)
+                .getFileAttributeView(BasicFileAttributeView.class, NOFOLLOW_LINKS)
+                .readAttributes()
+                .isSymbolicLink());
+            stream2.deleteFile(target);
+        }
+
+        // Test: move between devices
+        String testDirAsString = System.getProperty("test.dir");
+        if (testDirAsString != null) {
+            Path testDir = Paths.get(testDirAsString);
+            if (!dir1.getFileStore().equals(testDir.getFileStore())) {
+                SecureDirectoryStream ts =
+                    (SecureDirectoryStream)testDir.newDirectoryStream();
+                dir1.resolve(fileEntry).createFile();
+                try {
+                    stream1.move(fileEntry, ts, target);
+                    shouldNotGetHere();
+                } catch (AtomicMoveNotSupportedException x) { }
+                ts.close();
+                stream1.deleteFile(fileEntry);
+            }
+        }
+
+        // clean-up
+        dir1.delete();
+        dir2.delete();
+    }
+
+    // null and ClosedDirectoryStreamException
+    static void miscTests(Path dir) throws IOException {
+        Path file = Paths.get("file");
+        dir.resolve(file).createFile();
+
+        SecureDirectoryStream stream =
+            (SecureDirectoryStream)dir.newDirectoryStream();
+
+        // NullPointerException
+        try {
+            stream.getFileAttributeView(null);
+            shouldNotGetHere();
+        } catch (NullPointerException x) { }
+        try {
+            stream.getFileAttributeView(null, BasicFileAttributeView.class);
+            shouldNotGetHere();
+        } catch (NullPointerException x) { }
+        try {
+            stream.getFileAttributeView(file, null);
+            shouldNotGetHere();
+        } catch (NullPointerException x) { }
+        try {
+            stream.newByteChannel(null, EnumSet.of(CREATE,WRITE));
+            shouldNotGetHere();
+        } catch (NullPointerException x) { }
+        try {
+            stream.newByteChannel(null, EnumSet.of(CREATE,WRITE,null));
+            shouldNotGetHere();
+        } catch (NullPointerException x) { }
+        try {
+            stream.newByteChannel(file, null);
+            shouldNotGetHere();
+        } catch (NullPointerException x) { }
+        try {
+            stream.move(null, stream, file);
+            shouldNotGetHere();
+        } catch (NullPointerException x) { }
+        try {
+            stream.move(file, null, file);
+            shouldNotGetHere();
+        } catch (NullPointerException x) { }
+        try {
+            stream.move(file, stream, null);
+            shouldNotGetHere();
+        } catch (NullPointerException x) { }
+        try {
+            stream.newDirectoryStream(null, true, null);
+            shouldNotGetHere();
+        } catch (NullPointerException x) { }
+        try {
+            stream.deleteFile(null);
+            shouldNotGetHere();
+        } catch (NullPointerException x) { }
+        try {
+            stream.deleteDirectory(null);
+            shouldNotGetHere();
+        } catch (NullPointerException x) { }
+
+        // close stream
+        stream.close();
+        stream.close();     // should be no-op
+
+        // ClosedDirectoryStreamException
+        try {
+            stream.newDirectoryStream(file, true, null);
+            shouldNotGetHere();
+        } catch (ClosedDirectoryStreamException x) { }
+        try {
+            stream.newByteChannel(file, EnumSet.of(READ));
+            shouldNotGetHere();
+        } catch (ClosedDirectoryStreamException x) { }
+        try {
+            stream.move(file, stream, file);
+            shouldNotGetHere();
+        } catch (ClosedDirectoryStreamException x) { }
+        try {
+            stream.deleteFile(file);
+            shouldNotGetHere();
+        } catch (ClosedDirectoryStreamException x) { }
+
+        // clean-up
+        dir.resolve(file).delete();
+    }
+
+    static void assertTrue(boolean b) {
+        if (!b) throw new RuntimeException("Assertion failed");
+    }
+
+    static void shouldNotGetHere() {
+        assertTrue(false);
+    }
+}
diff --git a/jdk/test/java/nio/file/FileStore/Basic.java b/jdk/test/java/nio/file/FileStore/Basic.java
new file mode 100644
index 0000000..604795d
--- /dev/null
+++ b/jdk/test/java/nio/file/FileStore/Basic.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 4313887
+ * @summary Unit test for java.nio.file.FileStore
+ * @library ..
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.io.IOException;
+import java.util.*;
+
+public class Basic {
+
+    public static void main(String[] args) throws IOException {
+        Path dir = TestUtil.createTemporaryDirectory();
+        try {
+            doTests(dir);
+        } finally {
+            TestUtil.removeAll(dir);
+        }
+    }
+
+    static void assertTrue(boolean okay) {
+        if (!okay)
+            throw new RuntimeException("Assertion failed");
+    }
+
+    static void doTests(Path dir) throws IOException {
+        /**
+         * Test: Directory should be on FileStore that is writable
+         */
+        assertTrue(!dir.getFileStore().isReadOnly());
+
+        /**
+         * Test: Two files should have the same FileStore
+         */
+        FileStore store1 = dir.resolve("foo").createFile().getFileStore();
+        FileStore store2 = dir.resolve("bar").createFile().getFileStore();
+        assertTrue(store1.equals(store2));
+        assertTrue(store2.equals(store1));
+        assertTrue(store1.hashCode() == store2.hashCode());
+
+        /**
+         * Test: File and FileStore attributes
+         */
+        assertTrue(store1.supportsFileAttributeView("basic"));
+
+        /**
+         * Test: Enumerate all FileStores
+         */
+        FileStore prev = null;
+        for (FileStore store: FileSystems.getDefault().getFileStores()) {
+            System.out.format("%s (name=%s type=%s)\n", store, store.name(),
+                store.type());
+
+            // check space attributes
+            Attributes.readFileStoreSpaceAttributes(store);
+
+            // two distinct FileStores should not be equal
+            assertTrue(!store.equals(prev));
+            prev = store;
+        }
+    }
+}
diff --git a/jdk/test/java/nio/file/FileSystem/Basic.java b/jdk/test/java/nio/file/FileSystem/Basic.java
new file mode 100644
index 0000000..8df7c1e
--- /dev/null
+++ b/jdk/test/java/nio/file/FileSystem/Basic.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 4313887
+ * @summary Unit test for java.nio.file.FileSystem
+ * @library ..
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.io.IOException;
+
+/**
+ * Simple santity checks for java.nio.file.FileSystem
+ */
+public class Basic {
+
+    static void check(boolean okay, String msg) {
+        if (!okay)
+            throw new RuntimeException(msg);
+    }
+
+    static void checkSupported(FileSystem fs, String... views) {
+        for (String view: views) {
+            check(fs.supportedFileAttributeViews().contains(view),
+                "support for '" + view + "' expected");
+        }
+    }
+
+    public static void main(String[] args) throws IOException {
+        FileSystem fs = FileSystems.getDefault();
+
+        // close should throw UOE
+        try {
+            fs.close();
+            throw new RuntimeException("UnsupportedOperationException expected");
+        } catch (UnsupportedOperationException e) { }
+        check(fs.isOpen(), "should be open");
+
+        check(!fs.isReadOnly(), "should provide read-write access");
+
+        check(fs.provider().getScheme().equals("file"),
+            "should use 'file' scheme");
+
+        // santity check method - need to re-visit this in future as I/O errors
+        // are possible
+        for (FileStore store: fs.getFileStores()) {
+            System.out.println(store);
+        }
+
+        // sanity check supportedFileAttributeViews
+        checkSupported(fs, "basic");
+        String os = System.getProperty("os.name");
+        if (os.equals("SunOS"))
+            checkSupported(fs, "posix", "unix", "owner", "acl", "xattr");
+        if (os.equals("Linux"))
+            checkSupported(fs, "posix", "unix", "owner", "dos", "xattr");
+        if (os.equals("Windows"))
+            checkSupported(fs, "owner", "dos", "acl", "xattr");
+    }
+}
diff --git a/jdk/test/java/nio/file/Files/ContentType.java b/jdk/test/java/nio/file/Files/ContentType.java
new file mode 100644
index 0000000..a0a5afc
--- /dev/null
+++ b/jdk/test/java/nio/file/Files/ContentType.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.nio.file.*;
+import java.io.*;
+
+/**
+ * Uses Files.probeContentType to probe html file and custom file type.
+ */
+
+public class ContentType {
+
+    static FileRef createHtmlFile() throws IOException {
+        Path file = File.createTempFile("foo", ".html").toPath();
+        OutputStream out = file.newOutputStream();
+        try {
+            out.write("<html><body>foo</body></html>".getBytes());
+        } finally {
+            out.close();
+        }
+
+        return file;
+    }
+
+    static FileRef createUnknownFile() throws IOException {
+        return File.createTempFile("unknown", "unknown-file-type-789").toPath();
+    }
+
+    static FileRef createGrapeFile() throws IOException {
+        return File.createTempFile("red", ".grape").toPath();
+    }
+
+    public static void main(String[] args) throws IOException {
+
+        // exercise default file type detector
+        FileRef file = createHtmlFile();
+        try {
+            String type = Files.probeContentType(file);
+            if (type == null) {
+                System.err.println("Content type cannot be determined - test skipped");
+            } else {
+                if (!type.equals("text/html"))
+                    throw new RuntimeException("Unexpected type: " + type);
+            }
+        } finally {
+            TestUtil.deleteUnchecked(file);
+        }
+        file = createUnknownFile();
+        try {
+            String type = Files.probeContentType(file);
+            if (type != null)
+                 throw new RuntimeException(file + " should not be recognized as:" +
+                     type);
+        } finally {
+            TestUtil.deleteUnchecked(file);
+        }
+
+        // exercise custom file type detector
+        file = createGrapeFile();
+        try {
+            String type = Files.probeContentType(file);
+            if (type == null)
+                throw new RuntimeException("Custom file type detector not installed?");
+            if (!type.equals("grape/unknown"))
+                throw new RuntimeException("Unexpected type: " + type);
+        } finally {
+            TestUtil.deleteUnchecked(file);
+        }
+
+    }
+}
diff --git a/jdk/test/java/nio/file/Files/CreateFileTree.java b/jdk/test/java/nio/file/Files/CreateFileTree.java
new file mode 100644
index 0000000..17549a7e
--- /dev/null
+++ b/jdk/test/java/nio/file/Files/CreateFileTree.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.nio.file.*;
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * Creates a file tree with possible cycles caused by symbolic links
+ * to ancestor directories.
+ */
+
+public class CreateFileTree {
+
+    static final Random rand = new Random();
+
+    public static Path createTemporaryDirectory() throws IOException {
+        Path tmpdir = Paths.get(System.getProperty("java.io.tmpdir"));
+        Path dir;
+        do {
+            dir = tmpdir.resolve("name" + rand.nextInt());
+        } while (dir.exists());
+        dir.createDirectory();
+        return dir;
+    }
+
+    public static void main(String[] args) throws IOException {
+        Path top = createTemporaryDirectory();
+        if (!top.isAbsolute())
+            top = top.toAbsolutePath();
+
+        List<Path> dirs = new ArrayList<Path>();
+
+        // create tree
+        Queue<Path> queue = new ArrayDeque<Path>();
+        queue.add(top);
+        int total = 1 + rand.nextInt(20);
+        int n = 0;
+        Path dir;
+        while (((dir = queue.poll()) != null) && (n < total)) {
+            int r = Math.min((total-n), (1+rand.nextInt(3)));
+            for (int i=0; i<r; i++) {
+                String name = "dir" + (++n);
+                Path subdir = dir.resolve(name).createDirectory();
+                queue.offer(subdir);
+                dirs.add(subdir);
+            }
+        }
+        assert dirs.size() >= 2;
+
+        // create a few regular files in the file tree
+        int files = dirs.size() * 3;
+        for (int i=0; i<files; i++) {
+            String name = "file" + (i+1);
+            int x = rand.nextInt(dirs.size());
+            dirs.get(x).resolve(name).createFile();
+        }
+
+        // create a few sym links in the file tree so as to create cycles
+        int links = 1 + rand.nextInt(5);
+        for (int i=0; i<links; i++) {
+            int x = rand.nextInt(dirs.size());
+            int y;
+            do {
+                y = rand.nextInt(dirs.size());
+            } while (y != x);
+            String name = "link" + (i+1);
+            Path link = dirs.get(x).resolve(name);
+            Path target = dirs.get(y);
+            link.createSymbolicLink(target);
+        }
+
+        // done
+        System.out.println(top);
+    }
+}
diff --git a/jdk/test/java/nio/file/Files/ForceLoad.java b/jdk/test/java/nio/file/Files/ForceLoad.java
new file mode 100644
index 0000000..b6fe84c
--- /dev/null
+++ b/jdk/test/java/nio/file/Files/ForceLoad.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 4313887
+ * @summary Test library dependencies by invoking Files.probeContentType
+ *     before other methods that would cause nio.dll to be loaded.
+ */
+
+import java.nio.file.*;
+import java.io.IOException;
+
+public class ForceLoad {
+
+    public static void main(String[] args) throws IOException {
+        Files.probeContentType(Paths.get("."));
+    }
+}
diff --git a/jdk/test/java/nio/file/Files/META-INF/services/java.nio.file.spi.FileTypeDetector b/jdk/test/java/nio/file/Files/META-INF/services/java.nio.file.spi.FileTypeDetector
new file mode 100644
index 0000000..ccd6ac7
--- /dev/null
+++ b/jdk/test/java/nio/file/Files/META-INF/services/java.nio.file.spi.FileTypeDetector
@@ -0,0 +1 @@
+SimpleFileTypeDetector
diff --git a/jdk/test/java/nio/file/Files/Misc.java b/jdk/test/java/nio/file/Files/Misc.java
new file mode 100644
index 0000000..dde74a4
--- /dev/null
+++ b/jdk/test/java/nio/file/Files/Misc.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 4313887
+ * @summary Unit test for java.nio.file.Files for miscellenous cases not
+ *   covered by other tests
+ * @library ..
+ */
+
+import java.nio.file.*;
+import java.io.IOException;
+import java.util.*;
+
+public class Misc {
+
+    static void npeExpected() {
+        throw new RuntimeException("NullPointerException expected");
+    }
+
+    public static void main(String[] args) throws IOException {
+        try {
+            Files.probeContentType(null);
+            npeExpected();
+        } catch (NullPointerException e) {
+        }
+
+        try {
+            Files.withDirectory(null, "*", new FileAction<Path>() {
+                public void invoke(Path entry) {
+                }
+            });
+            npeExpected();
+        } catch (NullPointerException e) {
+        }
+
+       try {
+            Files.withDirectory(Paths.get("."), (String)null, new FileAction<Path>() {
+                public void invoke(Path entry) {
+                }
+            });
+            npeExpected();
+        } catch (NullPointerException e) {
+        }
+
+        try {
+            Files.withDirectory(Paths.get("."), "*", null);
+            npeExpected();
+        } catch (NullPointerException e) {
+        }
+
+        // test propogation of IOException
+        Path tmpdir = TestUtil.createTemporaryDirectory();
+        try {
+            tmpdir.resolve("foo").createFile();
+            try {
+                Files.withDirectory(tmpdir, new FileAction<Path>() {
+                    public void invoke(Path entry) throws IOException {
+                        throw new IOException();
+                    }
+                });
+                throw new RuntimeException("IOException expected");
+            } catch (IOException e) {
+            }
+        } finally {
+            TestUtil.removeAll(tmpdir);
+        }
+
+        try {
+            Files.walkFileTree(null, EnumSet.noneOf(FileVisitOption.class),
+                Integer.MAX_VALUE, new SimpleFileVisitor<Path>(){});
+            npeExpected();
+        } catch (NullPointerException e) {
+        }
+
+        try {
+            Files.walkFileTree(Paths.get("."), null, Integer.MAX_VALUE,
+                new SimpleFileVisitor<Path>(){});
+            npeExpected();
+        } catch (NullPointerException e) {
+        }
+
+        try {
+            Files.walkFileTree(Paths.get("."), EnumSet.noneOf(FileVisitOption.class),
+                -1, new SimpleFileVisitor<Path>(){});
+            throw new RuntimeException("IllegalArgumentExpected expected");
+        } catch (IllegalArgumentException e) {
+        }
+
+        try {
+            Set<FileVisitOption> opts = new HashSet<FileVisitOption>(1);
+            opts.add(null);
+            Files.walkFileTree(Paths.get("."), opts, Integer.MAX_VALUE,
+                new SimpleFileVisitor<Path>(){});
+            npeExpected();
+        } catch (NullPointerException e) {
+        }
+
+        try {
+            Files.walkFileTree(Paths.get("."), EnumSet.noneOf(FileVisitOption.class),
+                Integer.MAX_VALUE, null);
+            npeExpected();
+        } catch (NullPointerException e) {
+        }
+    }
+}
diff --git a/jdk/test/java/nio/file/Files/PrintFileTree.java b/jdk/test/java/nio/file/Files/PrintFileTree.java
new file mode 100644
index 0000000..dc2c49f
--- /dev/null
+++ b/jdk/test/java/nio/file/Files/PrintFileTree.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * Invokes Files.walkFileTree to traverse a file tree and prints
+ * each of the directories and files. The -L option causes symbolic
+ * links to be followed.
+ */
+
+public class PrintFileTree {
+
+    public static void main(String[] args) throws Exception {
+        boolean followLinks = false;
+        Path dir;
+
+        if (args[0].equals("-L")) {
+            followLinks = true;
+            dir = Paths.get(args[1]);
+        } else {
+            dir = Paths.get(args[0]);
+        }
+
+        Set<FileVisitOption> options = new HashSet<FileVisitOption>();
+        if (followLinks)
+            options.add(FileVisitOption.FOLLOW_LINKS);
+
+        Files.walkFileTree(dir, options, Integer.MAX_VALUE, new FileVisitor<FileRef>() {
+            public FileVisitResult preVisitDirectory(FileRef dir) {
+                System.out.println(dir);
+                return FileVisitResult.CONTINUE;
+            }
+            public FileVisitResult preVisitDirectoryFailed(FileRef dir, IOException exc) {
+                exc.printStackTrace();
+                return FileVisitResult.CONTINUE;
+            }
+            public FileVisitResult visitFile(FileRef file, BasicFileAttributes attrs) {
+                System.out.println(file);
+                return FileVisitResult.CONTINUE;
+            }
+            public FileVisitResult postVisitDirectory(FileRef dir, IOException exc) {
+                if (exc != null) {
+                    exc.printStackTrace();
+                    return FileVisitResult.TERMINATE;
+                }
+                return FileVisitResult.CONTINUE;
+            }
+            public FileVisitResult visitFileFailed(FileRef file, IOException exc) {
+                exc.printStackTrace();
+                return FileVisitResult.TERMINATE;
+            }
+        });
+    }
+}
diff --git a/jdk/test/java/nio/file/Files/SimpleFileTypeDetector.java b/jdk/test/java/nio/file/Files/SimpleFileTypeDetector.java
new file mode 100644
index 0000000..0b66706
--- /dev/null
+++ b/jdk/test/java/nio/file/Files/SimpleFileTypeDetector.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.nio.file.*;
+import java.nio.file.spi.FileTypeDetector;
+import java.io.*;
+
+
+public class SimpleFileTypeDetector extends FileTypeDetector {
+    public SimpleFileTypeDetector() {
+    }
+
+    public String probeContentType(FileRef file) throws IOException {
+
+        System.out.println("probe " + file + "...");
+
+        if (file instanceof Path) {
+            String name = ((Path)file).toString();
+            if (name.endsWith(".grape")) {
+                return "grape/unknown";
+            }
+        }
+
+        // unknown
+        return null;
+    }
+}
diff --git a/jdk/test/java/nio/file/Files/SkipSiblings.java b/jdk/test/java/nio/file/Files/SkipSiblings.java
new file mode 100644
index 0000000..e852455
--- /dev/null
+++ b/jdk/test/java/nio/file/Files/SkipSiblings.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * Unit test for Files.walkFileTree to test SKIP_SIBLINGS return value.
+ */
+
+public class SkipSiblings {
+
+    static final Random rand = new Random();
+    static final Set<Path> skipped = new HashSet<Path>();
+
+    // check if this path's directory has been skipped
+    static void check(Path path) {
+        if (skipped.contains(path.getParent()))
+            throw new RuntimeException(path + " should not have been visited");
+    }
+
+    // indicates if the siblings of this path should be skipped
+    static boolean skip(Path path) {
+        Path parent = path.getParent();
+        if (parent != null && rand.nextBoolean()) {
+            skipped.add(parent);
+            return true;
+        }
+        return false;
+    }
+
+    public static void main(String[] args) throws Exception {
+        Path dir = Paths.get(args[0]);
+
+        Files.walkFileTree(dir, new FileVisitor<Path>() {
+            public FileVisitResult preVisitDirectory(Path dir) {
+                check(dir);
+                if (skip(dir))
+                    return FileVisitResult.SKIP_SIBLINGS;
+                return FileVisitResult.CONTINUE;
+            }
+            public FileVisitResult preVisitDirectoryFailed(Path dir, IOException exc) {
+                throw new RuntimeException(exc);
+            }
+
+            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
+                check(file);
+                if (skip(file))
+                    return FileVisitResult.SKIP_SIBLINGS;
+                return FileVisitResult.CONTINUE;
+            }
+            public FileVisitResult postVisitDirectory(Path dir, IOException x) {
+                if (x != null)
+                    throw new RuntimeException(x);
+                check(dir);
+                return FileVisitResult.CONTINUE;
+            }
+            public FileVisitResult visitFileFailed(Path file, IOException x) {
+                throw new RuntimeException(x);
+            }
+        });
+    }
+}
diff --git a/jdk/test/java/nio/file/Files/TerminateWalk.java b/jdk/test/java/nio/file/Files/TerminateWalk.java
new file mode 100644
index 0000000..82fc8ed
--- /dev/null
+++ b/jdk/test/java/nio/file/Files/TerminateWalk.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * Unit test for Files.walkFileTree to test TERMINATE return value
+ */
+
+public class TerminateWalk {
+
+    static final Random rand = new Random();
+    static boolean terminated;
+
+    static FileVisitResult maybeTerminate() {
+        if (terminated)
+            throw new RuntimeException("FileVisitor invoked after termination");
+        if (rand.nextInt(10) == 0) {
+            terminated = true;
+            return FileVisitResult.TERMINATE;
+        } else {
+            return FileVisitResult.CONTINUE;
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        Path dir = Paths.get(args[0]);
+
+        Files.walkFileTree(dir, new FileVisitor<Path>() {
+            public FileVisitResult preVisitDirectory(Path dir) {
+                return maybeTerminate();
+            }
+            public FileVisitResult preVisitDirectoryFailed(Path dir, IOException exc) {
+                return maybeTerminate();
+            }
+            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
+                return maybeTerminate();
+            }
+            public FileVisitResult postVisitDirectory(Path dir, IOException x) {
+                return maybeTerminate();
+            }
+            public FileVisitResult visitFileFailed(Path file, IOException x) {
+                return maybeTerminate();
+            }
+        });
+    }
+}
diff --git a/jdk/test/java/nio/file/Files/content_type.sh b/jdk/test/java/nio/file/Files/content_type.sh
new file mode 100644
index 0000000..46f4626
--- /dev/null
+++ b/jdk/test/java/nio/file/Files/content_type.sh
@@ -0,0 +1,71 @@
+#
+# Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
+# @test
+# @bug 4313887
+# @summary Unit test for probeContentType method
+# @library ..
+# @build ContentType SimpleFileTypeDetector
+# @run shell content_type.sh
+
+# if TESTJAVA isn't set then we assume an interactive run.
+
+if [ -z "$TESTJAVA" ]; then
+    TESTSRC=.
+    TESTCLASSES=.
+    JAVA=java
+else
+    JAVA="${TESTJAVA}/bin/java"
+fi
+
+OS=`uname -s`
+case "$OS" in
+    Windows_* )
+        CLASSPATH="${TESTCLASSES};${TESTSRC}"
+        ;;
+    * )
+        CLASSPATH=${TESTCLASSES}:${TESTSRC}
+        ;;
+esac
+export CLASSPATH
+
+failures=0
+
+go() {
+    echo ''
+    $JAVA $1 $2 $3 2>&1
+    if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
+}
+
+# Run the test
+
+go ContentType
+
+#
+# Results
+#
+echo ''
+if [ $failures -gt 0 ];
+  then echo "$failures test(s) failed";
+  else echo "All test(s) passed"; fi
+exit $failures
diff --git a/jdk/test/java/nio/file/Files/walk_file_tree.sh b/jdk/test/java/nio/file/Files/walk_file_tree.sh
new file mode 100644
index 0000000..73022d3
--- /dev/null
+++ b/jdk/test/java/nio/file/Files/walk_file_tree.sh
@@ -0,0 +1,86 @@
+#
+# Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
+# @test
+# @bug 4313887
+# @summary Unit test for walkFileTree method
+# @build CreateFileTree PrintFileTree SkipSiblings TerminateWalk
+# @run shell walk_file_tree.sh
+
+# if TESTJAVA isn't set then we assume an interactive run.
+
+if [ -z "$TESTJAVA" ]; then
+    TESTSRC=.
+    TESTCLASSES=.
+    JAVA=java
+else
+    JAVA="${TESTJAVA}/bin/java"
+fi
+
+OS=`uname -s`
+case "$OS" in
+    Windows_* )
+        echo "This test does not run on Windows" 
+        exit 0
+        ;;
+    * )
+        CLASSPATH=${TESTCLASSES}:${TESTSRC}
+        ;;
+esac
+export CLASSPATH
+
+# create the file tree
+ROOT=`$JAVA CreateFileTree`
+if [ $? != 0 ]; then exit 1; fi
+
+failures=0
+
+# print the file tree and compare output with find(1)
+$JAVA PrintFileTree "$ROOT" > out1
+find "$ROOT" > out2
+diff out1 out2
+if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
+
+# repeat test following links (use -follow instead of -L
+# to allow running on older systems)
+$JAVA PrintFileTree -L "$ROOT" > out1
+find "$ROOT" -follow > out2
+diff out1 out2
+if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
+
+# test SKIP_SIBLINGS
+$JAVA SkipSiblings "$ROOT"
+if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
+
+# test TERMINATE
+$JAVA TerminateWalk "$ROOT"
+if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
+
+# clean-up
+rm -r "$ROOT"
+
+echo ''
+if [ $failures -gt 0 ];
+  then echo "$failures test(s) failed";
+  else echo "Test passed"; fi
+exit $failures
diff --git a/jdk/test/java/nio/file/Path/CopyAndMove.java b/jdk/test/java/nio/file/Path/CopyAndMove.java
new file mode 100644
index 0000000..4e4c75f
--- /dev/null
+++ b/jdk/test/java/nio/file/Path/CopyAndMove.java
@@ -0,0 +1,983 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 4313887
+ * @summary Unit test for java.nio.file.Path copyTo/moveTo methods
+ * @library ..
+ */
+
+import java.nio.ByteBuffer;
+import java.nio.file.*;
+import static java.nio.file.StandardCopyOption.*;
+import static java.nio.file.LinkOption.*;
+import java.nio.file.attribute.*;
+import java.io.*;
+import java.util.*;
+
+public class CopyAndMove {
+    static final Random rand = new Random();
+    static boolean heads() { return rand.nextBoolean(); }
+    static boolean supportsLinks;
+
+    public static void main(String[] args) throws Exception {
+        Path dir1 = TestUtil.createTemporaryDirectory();
+        try {
+            supportsLinks = TestUtil.supportsLinks(dir1);
+
+            // Exercise copyTo
+            doCopyTests(dir1);
+
+            // Exercise moveTo
+            // if test.dir differs to temporary file system then can test
+            // moving between devices
+            String testDir = System.getProperty("test.dir");
+            Path dir2 = (testDir != null) ? Paths.get(testDir) : dir1;
+            doMoveTests(dir1, dir2);
+
+        } finally {
+            TestUtil.removeAll(dir1);
+        }
+    }
+
+    static void checkBasicAttributes(BasicFileAttributes attrs1,
+                                     BasicFileAttributes attrs2)
+    {
+        // check file type
+        assertTrue(attrs1.isRegularFile() == attrs2.isRegularFile());
+        assertTrue(attrs1.isDirectory() == attrs2.isDirectory());
+        assertTrue(attrs1.isSymbolicLink() == attrs2.isSymbolicLink());
+        assertTrue(attrs1.isOther() == attrs2.isOther());
+
+        // check last modified time (assume millisecond precision)
+        long time1 = attrs1.resolution().toMillis(attrs1.lastModifiedTime());
+        long time2 = attrs1.resolution().toMillis(attrs2.lastModifiedTime());
+        assertTrue(time1 == time2);
+
+        // check size
+        if (attrs1.isRegularFile())
+            assertTrue(attrs1.size() == attrs2.size());
+    }
+
+    static void checkPosixAttributes(PosixFileAttributes attrs1,
+                                     PosixFileAttributes attrs2)
+    {
+        assertTrue(attrs1.permissions().equals(attrs2.permissions()));
+        assertTrue(attrs1.owner().equals(attrs2.owner()));
+        assertTrue(attrs1.group().equals(attrs2.group()));
+    }
+
+    static void checkDosAttributes(DosFileAttributes attrs1,
+                                   DosFileAttributes attrs2)
+    {
+        assertTrue(attrs1.isReadOnly() == attrs2.isReadOnly());
+        assertTrue(attrs1.isHidden() == attrs2.isHidden());
+        assertTrue(attrs1.isArchive() == attrs2.isArchive());
+        assertTrue(attrs1.isSystem() == attrs2.isSystem());
+    }
+
+    static void checkUserDefinedFileAttributes(Map<String,ByteBuffer> attrs1,
+                                     Map<String,ByteBuffer> attrs2)
+    {
+        assert attrs1.size() == attrs2.size();
+        for (String name: attrs1.keySet()) {
+            ByteBuffer bb1 = attrs1.get(name);
+            ByteBuffer bb2 = attrs2.get(name);
+            assertTrue(bb2 != null);
+            assertTrue(bb1.equals(bb2));
+        }
+    }
+
+    static Map<String,ByteBuffer> readUserDefinedFileAttributes(Path file)
+        throws IOException
+    {
+        UserDefinedFileAttributeView view = file
+            .getFileAttributeView(UserDefinedFileAttributeView.class);
+        Map<String,ByteBuffer> result = new HashMap<String,ByteBuffer>();
+        for (String name: view.list()) {
+            int size = view.size(name);
+            ByteBuffer bb = ByteBuffer.allocate(size);
+            int n = view.read(name, bb);
+            assertTrue(n == size);
+            bb.flip();
+            result.put(name, bb);
+        }
+        return result;
+    }
+
+    // move source to target with verification
+    static void moveAndVerify(Path source, Path target, CopyOption... options)
+        throws IOException
+    {
+        // read attributes before file is moved
+        BasicFileAttributes basicAttributes = null;
+        PosixFileAttributes posixAttributes = null;
+        DosFileAttributes dosAttributes = null;
+        Map<String,ByteBuffer> namedAttributes = null;
+
+        // get file attributes of source file
+        String os = System.getProperty("os.name");
+        if (os.equals("SunOS") || os.equals("Linux")) {
+            posixAttributes = Attributes.readPosixFileAttributes(source, NOFOLLOW_LINKS);
+            basicAttributes = posixAttributes;
+        }
+        if (os.startsWith("Windows")) {
+            dosAttributes = Attributes.readDosFileAttributes(source, NOFOLLOW_LINKS);
+            basicAttributes = dosAttributes;
+        }
+        if (basicAttributes == null)
+            basicAttributes = Attributes.readBasicFileAttributes(source, NOFOLLOW_LINKS);
+
+        // hash file contents if regular file
+        int hash = (basicAttributes.isRegularFile()) ? computeHash(source) : 0;
+
+        // record link target if symbolic link
+        Path linkTarget = null;
+        if (basicAttributes.isSymbolicLink())
+            linkTarget = source.readSymbolicLink();
+
+        // read named attributes if available (and file is not a sym link)
+        if (!basicAttributes.isSymbolicLink() &&
+            source.getFileStore().supportsFileAttributeView("xattr"))
+        {
+            namedAttributes = readUserDefinedFileAttributes(source);
+        }
+
+        // move file
+        source.moveTo(target, options);
+
+        // verify source does not exist
+        assertTrue(source.notExists());
+
+        // verify file contents
+        if (basicAttributes.isRegularFile()) {
+            if (computeHash(target) != hash)
+                throw new RuntimeException("Failed to verify move of regular file");
+        }
+
+        // verify link target
+        if (basicAttributes.isSymbolicLink()) {
+            if (!target.readSymbolicLink().equals(linkTarget))
+                throw new RuntimeException("Failed to verify move of symbolic link");
+        }
+
+        // verify basic attributes
+        checkBasicAttributes(basicAttributes,
+            Attributes.readBasicFileAttributes(target, NOFOLLOW_LINKS));
+
+        // verify POSIX attributes
+        if (posixAttributes != null && !basicAttributes.isSymbolicLink()) {
+            checkPosixAttributes(posixAttributes,
+                Attributes.readPosixFileAttributes(target, NOFOLLOW_LINKS));
+        }
+
+        // verify DOS attributes
+        if (dosAttributes != null && !basicAttributes.isSymbolicLink()) {
+            checkDosAttributes(dosAttributes,
+                Attributes.readDosFileAttributes(target, NOFOLLOW_LINKS));
+        }
+
+        // verify named attributes
+        if (namedAttributes != null &&
+            target.getFileStore().supportsFileAttributeView("xattr"))
+        {
+            checkUserDefinedFileAttributes(namedAttributes, readUserDefinedFileAttributes(target));
+        }
+    }
+
+    /**
+     * Tests all possible ways to invoke moveTo
+     */
+    static void doMoveTests(Path dir1, Path dir2) throws IOException {
+        Path source, target, entry;
+
+        boolean sameDevice = dir1.getFileStore().equals(dir2.getFileStore());
+
+        // -- regular file --
+
+        /**
+         * Test: move regular file, target does not exist
+         */
+        source = createSourceFile(dir1);
+        target = getTargetFile(dir1);
+        moveAndVerify(source, target);
+        target.delete();
+
+        /**
+         * Test: move regular file, target exists
+         */
+        source = createSourceFile(dir1);
+        target = getTargetFile(dir1).createFile();
+        try {
+            moveAndVerify(source, target);
+            throw new RuntimeException("FileAlreadyExistsException expected");
+        } catch (FileAlreadyExistsException x) {
+        }
+        target.delete();
+        target.createDirectory();
+        try {
+            moveAndVerify(source, target);
+            throw new RuntimeException("FileAlreadyExistsException expected");
+        } catch (FileAlreadyExistsException x) {
+        }
+        source.delete();
+        target.delete();
+
+        /**
+         * Test: move regular file, target does not exist
+         */
+        source = createSourceFile(dir1);
+        target = getTargetFile(dir1);
+        moveAndVerify(source, target, REPLACE_EXISTING);
+        target.delete();
+
+        /**
+         * Test: move regular file, target exists
+         */
+        source = createSourceFile(dir1);
+        target = getTargetFile(dir1).createFile();
+        moveAndVerify(source, target, REPLACE_EXISTING);
+        target.delete();
+
+        /**
+         * Test: move regular file, target exists and is empty directory
+         */
+        source = createSourceFile(dir1);
+        target = getTargetFile(dir1).createDirectory();
+        moveAndVerify(source, target, REPLACE_EXISTING);
+        target.delete();
+
+        /**
+         * Test: move regular file, target exists and is non-empty directory
+         */
+        source = createSourceFile(dir1);
+        target = getTargetFile(dir1).createDirectory();
+        entry = target.resolve("foo").createFile();
+        try {
+            moveAndVerify(source, target);
+            throw new RuntimeException("FileAlreadyExistsException expected");
+        } catch (FileAlreadyExistsException x) {
+        }
+        entry.delete();
+        source.delete();
+        target.delete();
+
+        /**
+         * Test atomic move of regular file (same file store)
+         */
+        source = createSourceFile(dir1);
+        target = getTargetFile(dir1);
+        moveAndVerify(source, target, ATOMIC_MOVE);
+        target.delete();
+
+        /**
+         * Test atomic move of regular file (different file store)
+         */
+        if (!sameDevice) {
+            source = createSourceFile(dir1);
+            target = getTargetFile(dir2);
+            try {
+                moveAndVerify(source, target, ATOMIC_MOVE);
+                throw new RuntimeException("AtomicMoveNotSupportedException expected");
+            } catch (AtomicMoveNotSupportedException x) {
+            }
+            source.delete();
+        }
+
+        // -- directories --
+
+        /*
+         * Test: move empty directory, target does not exist
+         */
+        source = createSourceDirectory(dir1);
+        target = getTargetFile(dir1);
+        moveAndVerify(source, target);
+        target.delete();
+
+        /**
+         * Test: move empty directory, target exists
+         */
+        source = createSourceDirectory(dir1);
+        target = getTargetFile(dir1).createFile();
+        try {
+            moveAndVerify(source, target);
+            throw new RuntimeException("FileAlreadyExistsException expected");
+        } catch (FileAlreadyExistsException x) {
+        }
+        target.delete();
+        target.createDirectory();
+        try {
+            moveAndVerify(source, target);
+            throw new RuntimeException("FileAlreadyExistsException expected");
+        } catch (FileAlreadyExistsException x) {
+        }
+        source.delete();
+        target.delete();
+
+        /**
+         * Test: move empty directory, target does not exist
+         */
+        source = createSourceDirectory(dir1);
+        target = getTargetFile(dir1);
+        moveAndVerify(source, target, REPLACE_EXISTING);
+        target.delete();
+
+        /**
+         * Test: move empty directory, target exists
+         */
+        source = createSourceDirectory(dir1);
+        target = getTargetFile(dir1).createFile();
+        moveAndVerify(source, target, REPLACE_EXISTING);
+        target.delete();
+
+        /**
+         * Test: move empty, target exists and is empty directory
+         */
+        source = createSourceDirectory(dir1);
+        target = getTargetFile(dir1).createDirectory();
+        moveAndVerify(source, target, REPLACE_EXISTING);
+        target.delete();
+
+        /**
+         * Test: move empty directory, target exists and is non-empty directory
+         */
+        source = createSourceDirectory(dir1);
+        target = getTargetFile(dir1).createDirectory();
+        entry = target.resolve("foo").createFile();
+        try {
+            moveAndVerify(source, target, REPLACE_EXISTING);
+            throw new RuntimeException("FileAlreadyExistsException expected");
+        } catch (FileAlreadyExistsException x) {
+        }
+        entry.delete();
+        source.delete();
+        target.delete();
+
+        /**
+         * Test: move non-empty directory (same file system)
+         */
+        source = createSourceDirectory(dir1);
+        source.resolve("foo").createFile();
+        target = getTargetFile(dir1);
+        moveAndVerify(source, target);
+        target.resolve("foo").delete();
+        target.delete();
+
+        /**
+         * Test: move non-empty directory (different file store)
+         */
+        if (!sameDevice) {
+            source = createSourceDirectory(dir1);
+            source.resolve("foo").createFile();
+            target = getTargetFile(dir2);
+            try {
+                moveAndVerify(source, target);
+                throw new RuntimeException("IOException expected");
+            } catch (IOException x) {
+            }
+            source.resolve("foo").delete();
+            source.delete();
+        }
+
+        /**
+         * Test atomic move of directory (same file store)
+         */
+        source = createSourceDirectory(dir1);
+        source.resolve("foo").createFile();
+        target = getTargetFile(dir1);
+        moveAndVerify(source, target, ATOMIC_MOVE);
+        target.resolve("foo").delete();
+        target.delete();
+
+        // -- symbolic links --
+
+        /**
+         * Test: Move symbolic link to file, target does not exist
+         */
+        if (supportsLinks) {
+            Path tmp = createSourceFile(dir1);
+            source = dir1.resolve("link").createSymbolicLink(tmp);
+            target = getTargetFile(dir1);
+            moveAndVerify(source, target);
+            target.delete();
+            tmp.delete();
+        }
+
+        /**
+         * Test: Move symbolic link to directory, target does not exist
+         */
+        if (supportsLinks) {
+            source = dir1.resolve("link").createSymbolicLink(dir2);
+            target = getTargetFile(dir1);
+            moveAndVerify(source, target);
+            target.delete();
+        }
+
+        /**
+         * Test: Move broken symbolic link, target does not exists
+         */
+        if (supportsLinks) {
+            Path tmp = Paths.get("doesnotexist");
+            source = dir1.resolve("link").createSymbolicLink(tmp);
+            target = getTargetFile(dir1);
+            moveAndVerify(source, target);
+            target.delete();
+        }
+
+        /**
+         * Test: Move symbolic link, target exists
+         */
+        if (supportsLinks) {
+            source = dir1.resolve("link").createSymbolicLink(dir2);
+            target = getTargetFile(dir1).createFile();
+            try {
+                moveAndVerify(source, target);
+                throw new RuntimeException("FileAlreadyExistsException expected");
+            } catch (FileAlreadyExistsException x) {
+            }
+            source.delete();
+            target.delete();
+        }
+
+        /**
+         * Test: Move regular file, target exists
+         */
+        if (supportsLinks) {
+            source = dir1.resolve("link").createSymbolicLink(dir2);
+            target = getTargetFile(dir1).createFile();
+            moveAndVerify(source, target, REPLACE_EXISTING);
+            target.delete();
+        }
+
+        /**
+         * Test: move symbolic link, target exists and is empty directory
+         */
+        if (supportsLinks) {
+            source = dir1.resolve("link").createSymbolicLink(dir2);
+            target = getTargetFile(dir1).createDirectory();
+            moveAndVerify(source, target, REPLACE_EXISTING);
+            target.delete();
+        }
+
+        /**
+         * Test: symbolic link, target exists and is non-empty directory
+         */
+        if (supportsLinks) {
+            source = dir1.resolve("link").createSymbolicLink(dir2);
+            target = getTargetFile(dir1).createDirectory();
+            entry = target.resolve("foo").createFile();
+            try {
+                moveAndVerify(source, target);
+                throw new RuntimeException("FileAlreadyExistsException expected");
+            } catch (FileAlreadyExistsException x) {
+            }
+            entry.delete();
+            source.delete();
+            target.delete();
+        }
+
+        /**
+         * Test atomic move of symbolic link (same file store)
+         */
+        if (supportsLinks) {
+            source = dir1.resolve("link").createSymbolicLink(dir1);
+            target = getTargetFile(dir1).createFile();
+            moveAndVerify(source, target, REPLACE_EXISTING);
+            target.delete();
+        }
+
+        // -- misc. tests --
+
+        /**
+         * Test nulls
+         */
+        source = createSourceFile(dir1);
+        target = getTargetFile(dir1);
+        try {
+            source.moveTo(null);
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException x) { }
+        try {
+            source.moveTo(target, (CopyOption[])null);
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException x) { }
+        try {
+            CopyOption[] opts = { REPLACE_EXISTING, null };
+            source.moveTo(target, opts);
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException x) { }
+        source.delete();
+
+        /**
+         * Test UOE
+         */
+        source = createSourceFile(dir1);
+        target = getTargetFile(dir1);
+        try {
+            source.moveTo(target, new CopyOption() { });
+        } catch (UnsupportedOperationException x) { }
+        try {
+            source.moveTo(target, REPLACE_EXISTING,  new CopyOption() { });
+        } catch (UnsupportedOperationException x) { }
+        source.delete();
+    }
+
+    // copy source to target with verification
+    static void copyAndVerify(Path source, Path target, CopyOption... options)
+        throws IOException
+    {
+        source.copyTo(target, options);
+
+        // get attributes of source and target file to verify copy
+        boolean followLinks = true;
+        LinkOption[] linkOptions = new LinkOption[0];
+        boolean copyAttributes = false;
+        for (CopyOption opt : options) {
+            if (opt == NOFOLLOW_LINKS) {
+                followLinks = false;
+                linkOptions = new LinkOption[] { NOFOLLOW_LINKS };
+            }
+            if (opt == COPY_ATTRIBUTES)
+                copyAttributes = true;
+        }
+        BasicFileAttributes basicAttributes = Attributes
+            .readBasicFileAttributes(source, linkOptions);
+
+        // check hash if regular file
+        if (basicAttributes.isRegularFile())
+            assertTrue(computeHash(source) == computeHash(target));
+
+        // check link target if symbolic link
+        if (basicAttributes.isSymbolicLink())
+            assert( source.readSymbolicLink().equals(target.readSymbolicLink()));
+
+        // check that attributes are copied
+        if (copyAttributes && followLinks) {
+            checkBasicAttributes(basicAttributes,
+                Attributes.readBasicFileAttributes(source, linkOptions));
+
+            // check POSIX attributes are copied
+            String os = System.getProperty("os.name");
+            if (os.equals("SunOS") || os.equals("Linux")) {
+                checkPosixAttributes(
+                    Attributes.readPosixFileAttributes(source, linkOptions),
+                    Attributes.readPosixFileAttributes(target, linkOptions));
+            }
+
+            // check DOS attributes are copied
+            if (os.startsWith("Windows")) {
+                checkDosAttributes(
+                    Attributes.readDosFileAttributes(source, linkOptions),
+                    Attributes.readDosFileAttributes(target, linkOptions));
+            }
+
+            // check named attributes are copied
+            if (followLinks &&
+                source.getFileStore().supportsFileAttributeView("xattr") &&
+                target.getFileStore().supportsFileAttributeView("xattr"))
+            {
+                checkUserDefinedFileAttributes(readUserDefinedFileAttributes(source),
+                                     readUserDefinedFileAttributes(target));
+            }
+        }
+    }
+
+    /**
+     * Tests all possible ways to invoke copyTo
+     */
+    static void doCopyTests(Path dir) throws IOException {
+        Path source, target, link, entry;
+
+        // -- regular file --
+
+        /**
+         * Test: move regular file, target does not exist
+         */
+        source = createSourceFile(dir);
+        target = getTargetFile(dir);
+        copyAndVerify(source, target);
+        source.delete();
+        target.delete();
+
+        /**
+         * Test: copy regular file, target exists
+         */
+        source = createSourceFile(dir);
+        target = getTargetFile(dir).createFile();
+        try {
+            copyAndVerify(source, target);
+            throw new RuntimeException("FileAlreadyExistsException expected");
+        } catch (FileAlreadyExistsException x) {
+        }
+        target.delete();
+        target.createDirectory();
+        try {
+            copyAndVerify(source, target);
+            throw new RuntimeException("FileAlreadyExistsException expected");
+        } catch (FileAlreadyExistsException x) {
+        }
+        source.delete();
+        target.delete();
+
+        /**
+         * Test: copy regular file, target does not exist
+         */
+        source = createSourceFile(dir);
+        target = getTargetFile(dir);
+        copyAndVerify(source, target, REPLACE_EXISTING);
+        source.delete();
+        target.delete();
+
+        /**
+         * Test: copy regular file, target exists
+         */
+        source = createSourceFile(dir);
+        target = getTargetFile(dir).createFile();
+        copyAndVerify(source, target, REPLACE_EXISTING);
+        source.delete();
+        target.delete();
+
+        /**
+         * Test: copy regular file, target exists and is empty directory
+         */
+        source = createSourceFile(dir);
+        target = getTargetFile(dir).createDirectory();
+        copyAndVerify(source, target, REPLACE_EXISTING);
+        source.delete();
+        target.delete();
+
+        /**
+         * Test: copy regular file, target exists and is non-empty directory
+         */
+        source = createSourceFile(dir);
+        target = getTargetFile(dir).createDirectory();
+        entry = target.resolve("foo").createFile();
+        try {
+            copyAndVerify(source, target);
+            throw new RuntimeException("FileAlreadyExistsException expected");
+        } catch (FileAlreadyExistsException x) {
+        }
+        entry.delete();
+        source.delete();
+        target.delete();
+
+        /**
+         * Test: copy regular file + attributes
+         */
+        source = createSourceFile(dir);
+        target = getTargetFile(dir);
+        copyAndVerify(source, target, COPY_ATTRIBUTES);
+        source.delete();
+        target.delete();
+
+
+        // -- directory --
+
+        /*
+         * Test: copy directory, target does not exist
+         */
+        source = createSourceDirectory(dir);
+        target = getTargetFile(dir);
+        copyAndVerify(source, target);
+        source.delete();
+        target.delete();
+
+        /**
+         * Test: copy directory, target exists
+         */
+        source = createSourceDirectory(dir);
+        target = getTargetFile(dir).createFile();
+        try {
+            copyAndVerify(source, target);
+            throw new RuntimeException("FileAlreadyExistsException expected");
+        } catch (FileAlreadyExistsException x) {
+        }
+        target.delete();
+        target.createDirectory();
+        try {
+            copyAndVerify(source, target);
+            throw new RuntimeException("FileAlreadyExistsException expected");
+        } catch (FileAlreadyExistsException x) {
+        }
+        source.delete();
+        target.delete();
+
+        /**
+         * Test: copy directory, target does not exist
+         */
+        source = createSourceDirectory(dir);
+        target = getTargetFile(dir);
+        copyAndVerify(source, target, REPLACE_EXISTING);
+        source.delete();
+        target.delete();
+
+        /**
+         * Test: copy directory, target exists
+         */
+        source = createSourceDirectory(dir);
+        target = getTargetFile(dir).createFile();
+        copyAndVerify(source, target, REPLACE_EXISTING);
+        source.delete();
+        target.delete();
+
+        /**
+         * Test: copy directory, target exists and is empty directory
+         */
+        source = createSourceDirectory(dir);
+        target = getTargetFile(dir).createDirectory();
+        copyAndVerify(source, target, REPLACE_EXISTING);
+        source.delete();
+        target.delete();
+
+        /**
+         * Test: copy directory, target exists and is non-empty directory
+         */
+        source = createSourceDirectory(dir);
+        target = getTargetFile(dir).createDirectory();
+        entry = target.resolve("foo").createFile();
+        try {
+            copyAndVerify(source, target, REPLACE_EXISTING);
+            throw new RuntimeException("FileAlreadyExistsException expected");
+        } catch (FileAlreadyExistsException x) {
+        }
+        entry.delete();
+        source.delete();
+        target.delete();
+
+        /*
+         * Test: copy directory + attributes
+         */
+        source = createSourceDirectory(dir);
+        target = getTargetFile(dir);
+        copyAndVerify(source, target, COPY_ATTRIBUTES);
+        source.delete();
+        target.delete();
+
+        // -- symbolic links --
+
+        /**
+         * Test: Follow link
+         */
+        if (supportsLinks) {
+            source = createSourceFile(dir);
+            link = dir.resolve("link").createSymbolicLink(source);
+            target = getTargetFile(dir);
+            copyAndVerify(link, target);
+            link.delete();
+            source.delete();
+        }
+
+        /**
+         * Test: Copy link (to file)
+         */
+        if (supportsLinks) {
+            source = createSourceFile(dir);
+            link = dir.resolve("link").createSymbolicLink(source);
+            target = getTargetFile(dir);
+            copyAndVerify(link, target, NOFOLLOW_LINKS);
+            link.delete();
+            source.delete();
+        }
+
+        /**
+         * Test: Copy link (to directory)
+         */
+        if (supportsLinks) {
+            source = dir.resolve("mydir").createDirectory();
+            link = dir.resolve("link").createSymbolicLink(source);
+            target = getTargetFile(dir);
+            copyAndVerify(link, target, NOFOLLOW_LINKS);
+            link.delete();
+            source.delete();
+        }
+
+        /**
+         * Test: Copy broken link
+         */
+        if (supportsLinks) {
+            assertTrue(source.notExists());
+            link = dir.resolve("link").createSymbolicLink(source);
+            target = getTargetFile(dir);
+            copyAndVerify(link, target, NOFOLLOW_LINKS);
+            link.delete();
+        }
+
+        /**
+         * Test: Copy link to UNC (Windows only)
+         */
+        if (supportsLinks &&
+            System.getProperty("os.name").startsWith("Windows"))
+        {
+            Path unc = Paths.get("\\\\rialto\\share\\file");
+            link = dir.resolve("link").createSymbolicLink(unc);
+            target = getTargetFile(dir);
+            copyAndVerify(link, target, NOFOLLOW_LINKS);
+            link.delete();
+        }
+
+        // -- misc. tests --
+
+        /**
+         * Test nulls
+         */
+        source = createSourceFile(dir);
+        target = getTargetFile(dir);
+        try {
+            source.copyTo(null);
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException x) { }
+        try {
+            source.copyTo(target, (CopyOption[])null);
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException x) { }
+        try {
+            CopyOption[] opts = { REPLACE_EXISTING, null };
+            source.copyTo(target, opts);
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException x) { }
+        source.delete();
+
+        /**
+         * Test UOE
+         */
+        source = createSourceFile(dir);
+        target = getTargetFile(dir);
+        try {
+            source.copyTo(target, new CopyOption() { });
+        } catch (UnsupportedOperationException x) { }
+        try {
+            source.copyTo(target, REPLACE_EXISTING,  new CopyOption() { });
+        } catch (UnsupportedOperationException x) { }
+        source.delete();
+    }
+
+
+    static void assertTrue(boolean value) {
+        if (!value)
+            throw new RuntimeException("Assertion failed");
+    }
+
+    // computes simple hash of the given file
+    static int computeHash(Path file) throws IOException {
+        int h = 0;
+
+        InputStream in = file.newInputStream();
+        try {
+            byte[] buf = new byte[1024];
+            int n;
+            do {
+                n = in.read(buf);
+                for (int i=0; i<n; i++) {
+                    h = 31*h + (buf[i] & 0xff);
+                }
+            } while (n > 0);
+        } finally {
+            in.close();
+        }
+        return h;
+    }
+
+    // create file of random size in given directory
+    static Path createSourceFile(Path dir) throws IOException {
+        String name = "source" + Integer.toString(rand.nextInt());
+        Path file = dir.resolve(name).createFile();
+        byte[] bytes = new byte[rand.nextInt(128*1024)];
+        rand.nextBytes(bytes);
+        OutputStream out = file.newOutputStream();
+        try {
+            out.write(bytes);
+        } finally {
+            out.close();
+        }
+        randomizeAttributes(file);
+        return file;
+    }
+
+    // create directory in the given directory
+    static Path createSourceDirectory(Path dir) throws IOException {
+        String name = "sourcedir" + Integer.toString(rand.nextInt());
+        Path subdir = dir.resolve(name).createDirectory();
+        randomizeAttributes(subdir);
+        return subdir;
+    }
+
+    // "randomize" the file attributes of the given file.
+    static void randomizeAttributes(Path file) throws IOException {
+        String os = System.getProperty("os.name");
+        boolean isWindows = os.startsWith("Windows");
+        boolean isUnix = os.equals("SunOS") || os.equals("Linux");
+        boolean isDirectory = Attributes.readBasicFileAttributes(file, NOFOLLOW_LINKS)
+            .isDirectory();
+
+        if (isUnix) {
+            Set<PosixFilePermission> perms = Attributes
+                .readPosixFileAttributes(file, NOFOLLOW_LINKS).permissions();
+            PosixFilePermission[] toChange = {
+                PosixFilePermission.GROUP_READ,
+                PosixFilePermission.GROUP_WRITE,
+                PosixFilePermission.GROUP_EXECUTE,
+                PosixFilePermission.OTHERS_READ,
+                PosixFilePermission.OTHERS_WRITE,
+                PosixFilePermission.OTHERS_EXECUTE
+            };
+            for (PosixFilePermission perm: toChange) {
+                if (heads()) {
+                    perms.add(perm);
+                } else {
+                    perms.remove(perm);
+                }
+            }
+            Attributes.setPosixFilePermissions(file, perms);
+        }
+
+        if (isWindows) {
+            DosFileAttributeView view = file
+                .getFileAttributeView(DosFileAttributeView.class, NOFOLLOW_LINKS);
+            // only set or unset the hidden attribute
+            view.setHidden(heads());
+        }
+
+        boolean addUserDefinedFileAttributes = heads() &&
+            file.getFileStore().supportsFileAttributeView("xattr");
+
+        // remove this when copying a direcory copies its named streams
+        if (isWindows && isDirectory) addUserDefinedFileAttributes = false;
+
+        if (addUserDefinedFileAttributes) {
+            UserDefinedFileAttributeView view = file
+                .getFileAttributeView(UserDefinedFileAttributeView.class);
+            int n = rand.nextInt(16);
+            while (n > 0) {
+                byte[] value = new byte[1 + rand.nextInt(100)];
+                view.write("user." + Integer.toString(n), ByteBuffer.wrap(value));
+                n--;
+            }
+        }
+    }
+
+    // create name for file in given directory
+    static Path getTargetFile(Path dir) throws IOException {
+        String name = "target" + Integer.toString(rand.nextInt());
+        return dir.resolve(name);
+    }
+ }
diff --git a/jdk/test/java/nio/file/Path/DeleteOnClose.java b/jdk/test/java/nio/file/Path/DeleteOnClose.java
new file mode 100644
index 0000000..8bc0e85
--- /dev/null
+++ b/jdk/test/java/nio/file/Path/DeleteOnClose.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.nio.file.*;
+import static java.nio.file.StandardOpenOption.*;
+import java.io.*;
+import java.util.*;
+
+public class DeleteOnClose {
+
+    public static void main(String[] args) throws IOException {
+        // open file but do not close it. Its existance will be checked by
+        // the calling script.
+        Paths.get(args[0]).newByteChannel(READ, WRITE, DELETE_ON_CLOSE);
+
+        // check temporary file has been deleted after closing it
+        Path file = File.createTempFile("blah", "tmp").toPath();
+        file.newByteChannel(READ, WRITE, DELETE_ON_CLOSE).close();
+        if (file.exists())
+            throw new RuntimeException("Temporary file was not deleted");
+
+        Path dir = TestUtil.createTemporaryDirectory();
+        try {
+            // check that DELETE_ON_CLOSE fails when file is a sym link
+            if (TestUtil.supportsLinks(dir)) {
+                file = dir.resolve("foo").createFile();
+                Path link = dir.resolve("link").createSymbolicLink(file);
+                try {
+                    link.newByteChannel(READ, WRITE, DELETE_ON_CLOSE);
+                    throw new RuntimeException("IOException expected");
+                } catch (IOException ignore) { }
+            }
+
+            // check that DELETE_ON_CLOSE works with files created via open
+            // directories
+            DirectoryStream stream = dir.newDirectoryStream();
+            try {
+                if (stream instanceof SecureDirectoryStream) {
+                    SecureDirectoryStream secure = (SecureDirectoryStream)stream;
+                    file = Paths.get("foo");
+
+                    Set<OpenOption> opts = new HashSet<OpenOption>();
+                    opts.add(WRITE);
+                    opts.add(DELETE_ON_CLOSE);
+                    secure.newByteChannel(file, opts).close();
+
+                    if (dir.resolve(file).exists())
+                        throw new RuntimeException("File not deleted");
+                }
+            } finally {
+                stream.close();
+            }
+        } finally {
+            TestUtil.removeAll(dir);
+        }
+    }
+}
diff --git a/jdk/test/java/nio/file/Path/InterruptCopy.java b/jdk/test/java/nio/file/Path/InterruptCopy.java
new file mode 100644
index 0000000..d796222
--- /dev/null
+++ b/jdk/test/java/nio/file/Path/InterruptCopy.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 4313887
+ * @summary Unit test for Sun-specific ExtendedCopyOption.INTERRUPTIBLE option
+ * @library ..
+ * @run main/othervm -XX:-UseVMInterruptibleIO InterruptCopy
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.Attributes;
+import java.io.*;
+import java.util.concurrent.*;
+import com.sun.nio.file.ExtendedCopyOption;
+
+public class InterruptCopy {
+
+    private static final long FILE_SIZE_TO_COPY = 512 * 1024 * 1024;
+    private static final int DELAY_IN_MS = 500;
+
+    public static void main(String[] args) throws Exception {
+        Path dir = TestUtil.createTemporaryDirectory();
+        try {
+            FileStore store = dir.getFileStore();
+            System.out.format("Checking space (%s)\n", store);
+            long usableSpace = Attributes
+                .readFileStoreSpaceAttributes(store).usableSpace();
+            if (usableSpace < 2*FILE_SIZE_TO_COPY) {
+                System.out.println("Insufficient disk space to run test.");
+                return;
+            }
+            doTest(dir);
+        } finally {
+            TestUtil.removeAll(dir);
+        }
+    }
+
+    static void doTest(Path dir) throws Exception {
+        final Path source = dir.resolve("foo");
+        final Path target = dir.resolve("bar");
+
+        // create source file (don't create it as sparse file because we
+        // require the copy to take a long time)
+        System.out.println("Creating source file...");
+        byte[] buf = new byte[32*1024];
+        long total = 0;
+        OutputStream out = source.newOutputStream();
+        try {
+            do {
+                out.write(buf);
+                total += buf.length;
+            } while (total < FILE_SIZE_TO_COPY);
+        } finally {
+            out.close();
+        }
+        System.out.println("Source file created.");
+
+        ScheduledExecutorService pool =
+            Executors.newSingleThreadScheduledExecutor();
+        try {
+            // copy source to target in main thread, interrupting it after a delay
+            final Thread me = Thread.currentThread();
+            pool.schedule(new Runnable() {
+                public void run() {
+                    me.interrupt();
+                }}, DELAY_IN_MS, TimeUnit.MILLISECONDS);
+            System.out.println("Copying file...");
+            try {
+                source.copyTo(target, ExtendedCopyOption.INTERRUPTIBLE);
+                throw new RuntimeException("Copy completed (this is not expected)");
+            } catch (IOException e) {
+                boolean interrupted = Thread.interrupted();
+                if (!interrupted)
+                    throw new RuntimeException("Interrupt status was not set");
+                System.out.println("Copy failed (this is expected)");
+            }
+
+            // copy source to target via task in thread pool, interrupting it after
+            // a delay using cancel(true)
+            Future<Void> result = pool.submit(new Callable<Void>() {
+                public Void call() throws IOException {
+                    System.out.println("Copying file...");
+                    source.copyTo(target, ExtendedCopyOption.INTERRUPTIBLE,
+                        StandardCopyOption.REPLACE_EXISTING);
+                    return null;
+                }
+            });
+            Thread.sleep(DELAY_IN_MS);
+            boolean cancelled = result.cancel(true);
+            if (!cancelled)
+                result.get();
+            System.out.println("Copy cancelled.");
+        } finally {
+            pool.shutdown();
+            pool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
+        }
+    }
+}
diff --git a/jdk/test/java/nio/file/Path/Links.java b/jdk/test/java/nio/file/Path/Links.java
new file mode 100644
index 0000000..3b0d6da
--- /dev/null
+++ b/jdk/test/java/nio/file/Path/Links.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 4313887
+ * @summary Unit test for java.nio.file.Path createSymbolicLink,
+ *     readSymbolicLink, and createLink methods
+ * @library ..
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.io.*;
+import java.util.*;
+
+public class Links {
+
+    static final boolean isWindows =
+        System.getProperty("os.name").startsWith("Windows");
+
+    static void assertTrue(boolean okay) {
+        if (!okay)
+            throw new RuntimeException("Assertion failed");
+    }
+
+    /**
+     * Exercise createSymbolicLink and readLink methods
+     */
+    static void testSymLinks(Path dir) throws IOException {
+        Path link = dir.resolve("link");
+
+        // Check if sym links are supported
+        try {
+            link.createSymbolicLink(Paths.get("foo"));
+            link.delete();
+        } catch (UnsupportedOperationException x) {
+            // sym links not supported
+            return;
+        } catch (IOException x) {
+            // probably insufficient privileges to create sym links (Windows)
+            return;
+        }
+
+        // Test links to various targets
+        String[] windowsTargets =
+            { "foo", "C:\\foo", "\\foo", "\\\\server\\share\\foo" };
+        String[] otherTargets = { "relative", "/absolute" };
+
+        String[] targets = (isWindows) ? windowsTargets : otherTargets;
+        for (String s: targets) {
+            Path target = Paths.get(s);
+            link.createSymbolicLink(target);
+            try {
+                assertTrue(link.readSymbolicLink().equals(target));
+            } finally {
+                link.delete();
+            }
+        }
+    }
+
+    /**
+     * Exercise createLink method
+     */
+    static void testHardLinks(Path dir) throws IOException {
+        Path foo = dir.resolve("foo").createFile();
+        try {
+            Path bar;
+            try {
+                bar = dir.resolve("bar").createLink(foo);
+            } catch (UnsupportedOperationException x) {
+                return;
+            } catch (IOException x) {
+                // probably insufficient privileges (Windows)
+                return;
+            }
+            try {
+                Object key1 = Attributes
+                    .readBasicFileAttributes(foo).fileKey();
+                Object key2 = Attributes
+                    .readBasicFileAttributes(bar).fileKey();
+                assertTrue((key1 == null) || (key1.equals(key2)));
+
+// Testing of linkCount disabled until linkCount method removed frmo
+// BasicFileAttributes
+/*
+                assertTrue(Attributes
+                    .readBasicFileAttributes(foo).linkCount() >= 2);
+                assertTrue(Attributes
+                    .readBasicFileAttributes(bar).linkCount() >= 2);
+*/
+
+            } finally {
+                bar.delete();
+            }
+
+
+        } finally {
+            foo.delete();
+        }
+    }
+
+    public static void main(String[] args) throws IOException {
+        Path dir = TestUtil.createTemporaryDirectory();
+        try {
+            testSymLinks(dir);
+            testHardLinks(dir);
+
+            // repeat tests on Windows with long path
+            if (isWindows) {
+                Path dirWithLongPath = null;
+                try {
+                    dirWithLongPath = TestUtil.createDirectoryWithLongPath(dir);
+                } catch (IOException x) {
+                    System.out.println("Unable to create long path: " + x);
+                }
+                if (dirWithLongPath != null) {
+                    System.out.println("");
+                    System.out.println("** REPEAT TESTS WITH LONG PATH **");
+                    testSymLinks(dirWithLongPath);
+                    testHardLinks(dirWithLongPath);
+                }
+            }
+        } finally {
+            TestUtil.removeAll(dir);
+        }
+    }
+}
diff --git a/jdk/test/java/nio/file/Path/Misc.java b/jdk/test/java/nio/file/Path/Misc.java
new file mode 100644
index 0000000..ba6640f
--- /dev/null
+++ b/jdk/test/java/nio/file/Path/Misc.java
@@ -0,0 +1,389 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 4313887
+ * @summary Unit test for java.nio.file.Path for miscellenous methods not
+ *   covered by other tests
+ * @library ..
+ */
+
+import java.nio.file.*;
+import static java.nio.file.LinkOption.*;
+import java.nio.file.attribute.*;
+import java.io.*;
+import java.util.*;
+
+public class Misc {
+    static final boolean isWindows =
+        System.getProperty("os.name").startsWith("Windows");
+    static boolean supportsLinks;
+
+    public static void main(String[] args) throws IOException {
+        Path dir = TestUtil.createTemporaryDirectory();
+        try {
+            supportsLinks = TestUtil.supportsLinks(dir);
+
+            // equals and hashCode methods
+            equalsAndHashCode();
+
+            // checkAccess method
+            checkAccessTests(dir);
+
+            // getFileAttributeView methods
+            getFileAttributeViewTests(dir);
+
+            // toRealPath method
+            toRealPathTests(dir);
+
+            // isSameFile method
+            isSameFileTests(dir);
+
+            // isHidden method
+            isHiddenTests(dir);
+
+        } finally {
+            TestUtil.removeAll(dir);
+        }
+    }
+
+    /**
+     * Exercise equals and hashCode methods
+     */
+    static void equalsAndHashCode() {
+
+        Path thisFile = Paths.get("this");
+        Path thatFile = Paths.get("that");
+
+        assertTrue(thisFile.equals(thisFile));
+        assertTrue(!thisFile.equals(thatFile));
+
+        assertTrue(!thisFile.equals(null));
+        assertTrue(!thisFile.equals(new Object()));
+
+        Path likeThis = Paths.get("This");
+        if (isWindows) {
+            // case insensitive
+            assertTrue(thisFile.equals(likeThis));
+            assertTrue(thisFile.hashCode() == likeThis.hashCode());
+        } else {
+            // case senstive
+            assertTrue(!thisFile.equals(likeThis));
+        }
+    }
+
+    /**
+     * Exercise checkAccess method
+     */
+    static void checkAccessTests(Path dir) throws IOException {
+        final Path file = dir.resolve("foo").createFile();
+
+        /**
+         * Test: This directory should readable and writable
+         */
+        dir.checkAccess();
+        dir.checkAccess(AccessMode.READ);
+        dir.checkAccess(AccessMode.WRITE);
+        dir.checkAccess(AccessMode.READ, AccessMode.WRITE);
+
+        /**
+         * Test: File does not exist
+         */
+        Path doesNotExist = dir.resolve("thisDoesNotExists");
+        try {
+            doesNotExist.checkAccess();
+            throw new RuntimeException("NoSuchFileException expected");
+        } catch (NoSuchFileException x) {
+        }
+        try {
+            doesNotExist.checkAccess(AccessMode.READ);
+            throw new RuntimeException("NoSuchFileException expected");
+        } catch (NoSuchFileException x) {
+        }
+        try {
+            doesNotExist.checkAccess(AccessMode.WRITE);
+            throw new RuntimeException("NoSuchFileException expected");
+        } catch (NoSuchFileException x) {
+        }
+        try {
+            doesNotExist.checkAccess(AccessMode.EXECUTE);
+            throw new RuntimeException("NoSuchFileException expected");
+        } catch (NoSuchFileException x) {
+        }
+
+        /**
+         * Test: Edit ACL to deny WRITE and EXECUTE
+         */
+        AclFileAttributeView view = file
+            .getFileAttributeView(AclFileAttributeView.class);
+        if (view != null &&
+            file.getFileStore().supportsFileAttributeView("acl"))
+        {
+            UserPrincipal owner = view.getOwner();
+            List<AclEntry> acl = view.getAcl();
+
+            // Insert entry to deny WRITE and EXECUTE
+            AclEntry entry = AclEntry.newBuilder()
+                .setType(AclEntryType.DENY)
+                .setPrincipal(owner)
+                .setPermissions(AclEntryPermission.WRITE_DATA,
+                    AclEntryPermission.EXECUTE)
+                .build();
+            acl.add(0, entry);
+            view.setAcl(acl);
+
+            try {
+                file.checkAccess(AccessMode.WRITE);
+                throw new RuntimeException("AccessDeniedException expected");
+            } catch (AccessDeniedException x) {
+            }
+
+            try {
+                file.checkAccess(AccessMode.EXECUTE);
+                throw new RuntimeException("AccessDeniedException expected");
+            } catch (AccessDeniedException x) {
+            }
+
+
+            // Restore ACL
+            acl.remove(0);
+            view.setAcl(acl);
+        }
+
+        /**
+         * Test: Windows DOS read-only attribute
+         */
+        if (isWindows) {
+            DosFileAttributeView dview =
+                file.getFileAttributeView(DosFileAttributeView.class);
+            dview.setReadOnly(true);
+            try {
+                file.checkAccess(AccessMode.WRITE);
+                throw new RuntimeException("AccessDeniedException expected");
+            } catch (AccessDeniedException x) {
+            }
+            dview.setReadOnly(false);
+
+            // Read-only attribute does not make direcory read-only
+            dview = dir.getFileAttributeView(DosFileAttributeView.class);
+            boolean save = dview.readAttributes().isReadOnly();
+            dview.setReadOnly(true);
+            dir.checkAccess(AccessMode.WRITE);
+            dview.setReadOnly(save);
+        }
+
+        /**
+         * Test: null
+         */
+        try {
+            file.checkAccess((AccessMode)null);
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException ignore) { }
+
+        // clean-up
+        file.delete();
+    }
+
+    /**
+     * Exercise getFileAttributeFile methods
+     */
+    static void getFileAttributeViewTests(Path dir) {
+        assertTrue(dir.getFileAttributeView(BasicFileAttributeView.class)
+            instanceof BasicFileAttributeView);
+        assertTrue(dir.getFileAttributeView(BasicFileAttributeView.class, NOFOLLOW_LINKS)
+            instanceof BasicFileAttributeView);
+        assertTrue(dir.getFileAttributeView("basic")
+            instanceof BasicFileAttributeView);
+        assertTrue(dir.getFileAttributeView("basic", NOFOLLOW_LINKS)
+            instanceof BasicFileAttributeView);
+        assertTrue(dir.getFileAttributeView(BogusFileAttributeView.class) == null);
+        assertTrue(dir.getFileAttributeView("bogus") == null);
+        try {
+            dir.getFileAttributeView((Class<FileAttributeView>)null);
+        } catch (NullPointerException ignore) { }
+        try {
+            dir.getFileAttributeView(BasicFileAttributeView.class, (LinkOption[])null);
+        } catch (NullPointerException ignore) { }
+        try {
+            dir.getFileAttributeView(BasicFileAttributeView.class, (LinkOption)null);
+        } catch (NullPointerException ignore) { }
+        try {
+            dir.getFileAttributeView((String)null);
+        } catch (NullPointerException ignore) { }
+        try {
+            dir.getFileAttributeView("basic", (LinkOption[])null);
+        } catch (NullPointerException ignore) { }
+        try {
+            dir.getFileAttributeView("basic", (LinkOption)null);
+        } catch (NullPointerException ignore) { }
+
+    }
+    interface BogusFileAttributeView extends FileAttributeView { }
+
+    /**
+     * Exercise toRealPath method
+     */
+    static void toRealPathTests(Path dir) throws IOException {
+        final Path file = dir.resolve("foo").createFile();
+        final Path link = dir.resolve("link");
+
+        /**
+         * Test: toRealPath(true) will access same file as toRealPath(false)
+         */
+        assertTrue(file.toRealPath(true).isSameFile(file.toRealPath(false)));
+
+        /**
+         * Test: toRealPath(true) should resolve links
+         */
+        if (supportsLinks) {
+            link.createSymbolicLink(file.toAbsolutePath());
+            assertTrue(link.toRealPath(true).equals(file.toRealPath(true)));
+            link.delete();
+        }
+
+
+        /**
+         * Test: toRealPath(false) should not resolve links
+         */
+        if (supportsLinks) {
+            link.createSymbolicLink(file.toAbsolutePath());
+            assertTrue(link.toRealPath(false).getName().equals(link.getName()));
+            link.delete();
+        }
+
+        /**
+         * Test: toRealPath should eliminate "."
+         */
+        assertTrue(dir.resolve(".").toRealPath(true).equals(dir.toRealPath(true)));
+        assertTrue(dir.resolve(".").toRealPath(false).equals(dir.toRealPath(false)));
+
+        /**
+         * Test: toRealPath should eliminate ".." when it doesn't follow a
+         *       symbolic link
+         */
+        Path subdir = dir.resolve("subdir").createDirectory();
+        assertTrue(subdir.resolve("..").toRealPath(true).equals(dir.toRealPath(true)));
+        assertTrue(subdir.resolve("..").toRealPath(false).equals(dir.toRealPath(false)));
+        subdir.delete();
+
+        // clean-up
+        file.delete();
+    }
+
+    /**
+     * Exercise isSameFile method
+     */
+    static void isSameFileTests(Path dir) throws IOException {
+        Path thisFile = dir.resolve("thisFile");
+        Path thatFile = dir.resolve("thatFile");
+
+        /**
+         * Test: isSameFile for self and null
+         */
+        assertTrue(thisFile.isSameFile(thisFile));
+        assertTrue(!thisFile.isSameFile(null));
+
+        /**
+         * Test: Neither files exist
+         */
+        try {
+            thisFile.isSameFile(thatFile);
+            throw new RuntimeException("IOException not thrown");
+        } catch (IOException x) {
+        }
+        try {
+            thatFile.isSameFile(thisFile);
+            throw new RuntimeException("IOException not thrown");
+        } catch (IOException x) {
+        }
+
+        thisFile.createFile();
+        try {
+            /**
+             * Test: One file exists
+             */
+            try {
+                thisFile.isSameFile(thatFile);
+                throw new RuntimeException("IOException not thrown");
+            } catch (IOException x) {
+            }
+            try {
+                thatFile.isSameFile(thisFile);
+                throw new RuntimeException("IOException not thrown");
+            } catch (IOException x) {
+            }
+
+            thatFile.createFile();
+
+            /**
+             * Test: Both file exists
+             */
+            try {
+                assertTrue(!thisFile.isSameFile(thatFile));
+                assertTrue(!thatFile.isSameFile(thisFile));
+            } finally {
+                TestUtil.deleteUnchecked(thatFile);
+            }
+
+            /**
+             * Test: Symbolic links
+             */
+            if (supportsLinks) {
+                thatFile.createSymbolicLink(thisFile);
+                try {
+                    assertTrue(thisFile.isSameFile(thatFile));
+                    assertTrue(thatFile.isSameFile(thisFile));
+                } finally {
+                    TestUtil.deleteUnchecked(thatFile);
+                }
+            }
+        } finally {
+            thisFile.delete(false);
+        }
+    }
+
+    /**
+     * Exercise isHidden method
+     */
+    static void isHiddenTests(Path dir) throws IOException {
+        assertTrue(!dir.isHidden());
+
+        Path file = dir.resolve(".foo");
+        if (isWindows) {
+            file.createFile();
+            try {
+                Attributes.setAttribute(file, "dos:hidden", true);
+                assertTrue(file.isHidden());
+            } finally {
+                file.delete();
+            }
+        } else {
+            assertTrue(file.isHidden());
+        }
+    }
+
+    static void assertTrue(boolean okay) {
+        if (!okay)
+            throw new RuntimeException("Assertion Failed");
+    }
+}
diff --git a/jdk/test/java/nio/file/Path/PathOps.java b/jdk/test/java/nio/file/Path/PathOps.java
new file mode 100644
index 0000000..231123c
--- /dev/null
+++ b/jdk/test/java/nio/file/Path/PathOps.java
@@ -0,0 +1,752 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 4313887
+ * @summary Unit test for java.nio.file.Path path operations
+ */
+
+import java.nio.file.*;
+
+public class PathOps {
+
+    static final java.io.PrintStream out = System.out;
+
+    private String input;
+    private Path path;
+    private Exception exc;
+
+    private PathOps(String s) {
+        out.println();
+        input = s;
+        try {
+            path = FileSystems.getDefault().getPath(s);
+            out.format("%s -> %s", s, path);
+        } catch (Exception x) {
+            exc = x;
+            out.format("%s -> %s", s, x);
+        }
+        out.println();
+    }
+
+    Path path() {
+        return path;
+    }
+
+    void fail() {
+        throw new RuntimeException("PathOps failed");
+    }
+
+    void checkPath() {
+        if (path == null) {
+            throw new InternalError("path is null");
+        }
+    }
+
+    void check(Object result, String expected) {
+        out.format("\tExpected: %s\n", expected);
+        out.format("\tActual: %s\n",  result);
+        if (result == null) {
+            if (expected == null) return;
+        } else {
+            // compare string representations
+            if (expected != null && result.toString().equals(expected.toString()))
+                return;
+        }
+        fail();
+    }
+
+    void check(Object result, boolean expected) {
+        check(result, Boolean.toString(expected));
+    }
+
+    PathOps root(String expected) {
+        out.println("check root");
+        checkPath();
+        check(path.getRoot(), expected);
+        return this;
+    }
+
+    PathOps parent(String expected) {
+        out.println("check parent");
+        checkPath();
+        check(path.getParent(), expected);
+        return this;
+    }
+
+    PathOps name(String expected) {
+        out.println("check name");
+        checkPath();
+        check(path.getName(), expected);
+        return this;
+    }
+
+    PathOps element(int index, String expected) {
+        out.format("check element %d\n", index);
+        checkPath();
+        check(path.getName(index), expected);
+        return this;
+    }
+
+    PathOps subpath(int startIndex, int endIndex, String expected) {
+        out.format("test subpath(%d,%d)\n", startIndex, endIndex);
+        checkPath();
+        check(path.subpath(startIndex, endIndex), expected);
+        return this;
+    }
+
+    PathOps starts(String prefix) {
+        out.format("test startsWith with %s\n", prefix);
+        checkPath();
+        Path s = FileSystems.getDefault().getPath(prefix);
+        check(path.startsWith(s), true);
+        return this;
+    }
+
+    PathOps notStarts(String prefix) {
+        out.format("test not startsWith with %s\n", prefix);
+        checkPath();
+        Path s = FileSystems.getDefault().getPath(prefix);
+        check(path.startsWith(s), false);
+        return this;
+    }
+
+    PathOps ends(String suffix) {
+        out.format("test endsWith %s\n", suffix);
+        checkPath();
+        Path s = FileSystems.getDefault().getPath(suffix);
+        check(path.endsWith(s), true);
+        return this;
+    }
+
+    PathOps notEnds(String suffix) {
+        out.format("test not endsWith %s\n", suffix);
+        checkPath();
+        Path s = FileSystems.getDefault().getPath(suffix);
+        check(path.endsWith(s), false);
+        return this;
+    }
+
+    PathOps absolute() {
+        out.println("check path is absolute");
+        checkPath();
+        check(path.isAbsolute(), true);
+        return this;
+    }
+
+    PathOps notAbsolute() {
+        out.println("check path is not absolute");
+        checkPath();
+        check(path.isAbsolute(), false);
+        return this;
+    }
+
+    PathOps resolve(String other, String expected) {
+        out.format("test resolve %s\n", other);
+        checkPath();
+        check(path.resolve(other), expected);
+        return this;
+    }
+
+    PathOps relativize(String other, String expected) {
+        out.format("test relativize %s\n", other);
+        checkPath();
+        Path that = FileSystems.getDefault().getPath(other);
+        check(path.relativize(that), expected);
+        return this;
+    }
+
+    PathOps normalize(String expected) {
+        out.println("check normalized path");
+        checkPath();
+        check(path.normalize(), expected);
+        return this;
+    }
+
+    PathOps string(String expected) {
+        out.println("check string representation");
+        checkPath();
+        check(path, expected);
+        return this;
+    }
+
+    PathOps invalid() {
+        if (!(exc instanceof InvalidPathException)) {
+            out.println("InvalidPathException not thrown as expected");
+            fail();
+        }
+        return this;
+    }
+
+    static PathOps test(String s) {
+        return new PathOps(s);
+    }
+
+    // -- PathOpss --
+
+    static void header(String s) {
+        out.println();
+        out.println();
+        out.println("-- " + s + " --");
+    }
+
+    static void doWindowsTests() {
+        header("Windows specific tests");
+
+        // all components present
+        test("C:\\a\\b\\c")
+            .root("C:\\")
+            .parent("C:\\a\\b")
+            .name("c");
+        test("C:a\\b\\c")
+            .root("C:")
+            .parent("C:a\\b")
+            .name("c");
+        test("\\\\server\\share\\a")
+            .root("\\\\server\\share\\")
+            .parent("\\\\server\\share\\")
+            .name("a");
+
+        // root component only
+        test("C:\\")
+            .root("C:\\")
+            .parent(null)
+            .name(null);
+        test("C:")
+            .root("C:")
+            .parent(null)
+            .name(null);
+        test("\\\\server\\share\\")
+            .root("\\\\server\\share\\")
+            .parent(null)
+            .name(null);
+
+        // no root component
+        test("a\\b")
+            .root(null)
+            .parent("a")
+            .name("b");
+
+        // name component only
+        test("foo")
+            .root(null)
+            .parent(null)
+            .name("foo");
+
+        // startsWith
+        test("C:\\")
+            .starts("C:\\")
+            .starts("c:\\")
+            .notStarts("C")
+            .notStarts("C:");
+        test("C:")
+            .starts("C:")
+            .starts("c:")
+            .notStarts("C");
+        test("\\")
+            .starts("\\");
+        test("C:\\foo\\bar")
+            .starts("C:\\")
+            .starts("C:\\foo")
+            .starts("C:\\FOO")
+            .starts("C:\\foo\\bar")
+            .starts("C:\\Foo\\Bar")
+            .notStarts("C:")
+            .notStarts("C")
+            .notStarts("C:foo");
+        test("\\foo\\bar")
+            .starts("\\")
+            .starts("\\foo")
+            .starts("\\foO")
+            .starts("\\foo\\bar")
+            .starts("\\fOo\\BaR")
+            .notStarts("foo")
+            .notStarts("foo\\bar");
+        test("foo\\bar")
+            .starts("foo")
+            .starts("foo\\bar")
+            .notStarts("\\");
+        test("\\\\server\\share")
+            .starts("\\\\server\\share")
+            .starts("\\\\server\\share\\")
+            .notStarts("\\");
+
+        // endsWith
+        test("C:\\")
+            .ends("C:\\")
+            .ends("c:\\")
+            .notEnds("\\");
+        test("C:")
+            .ends("C:")
+            .ends("c:");
+        test("\\")
+            .ends("\\");
+        test("C:\\foo\\bar")
+            .ends("bar")
+            .ends("BAR")
+            .ends("foo\\bar")
+            .ends("Foo\\Bar")
+            .ends("C:\\foo\\bar")
+            .ends("c:\\foO\\baR")
+            .notEnds("r")
+            .notEnds("\\foo\\bar");
+        test("\\foo\\bar")
+            .ends("bar")
+            .ends("BaR")
+            .ends("foo\\bar")
+            .ends("foO\\baR")
+            .ends("\\foo\\bar")
+            .ends("\\Foo\\Bar")
+            .notEnds("oo\\bar");
+        test("foo\\bar")
+            .ends("bar")
+            .ends("BAR")
+            .ends("foo\\bar")
+            .ends("Foo\\Bar")
+            .notEnds("ar");
+        test("\\\\server\\share")
+            .ends("\\\\server\\share")
+            .ends("\\\\server\\share\\")
+            .notEnds("shared")
+            .notEnds("\\");
+
+        // elements
+        test("C:\\a\\b\\c")
+            .element(0, "a")
+            .element(1, "b")
+            .element(2, "c");
+        test("foo.bar\\gus.alice")
+            .element(0, "foo.bar")
+            .element(1, "gus.alice");
+
+        // subpath
+        test("C:\\foo")
+            .subpath(0, 1, "foo");
+        test("C:foo")
+            .subpath(0, 1, "foo");
+        test("foo")
+            .subpath(0, 1, "foo");
+        test("C:\\foo\\bar\\gus")
+            .subpath(0, 1, "foo")
+            .subpath(0, 2, "foo\\bar")
+            .subpath(0, 3, "foo\\bar\\gus")
+            .subpath(1, 2, "bar")
+            .subpath(1, 3, "bar\\gus")
+            .subpath(2, 3, "gus");
+        test("\\\\server\\share\\foo")
+            .subpath(0, 1, "foo");
+
+        // isAbsolute
+        test("foo").notAbsolute();
+        test("C:").notAbsolute();
+        test("C:\\").absolute();
+        test("C:\\abc").absolute();
+        test("\\\\server\\share\\").absolute();
+
+        // resolve
+        test("C:\\")
+            .resolve("foo", "C:\\foo")
+            .resolve("D:\\bar", "D:\\bar")
+            .resolve("\\\\server\\share\\bar", "\\\\server\\share\\bar")
+            .resolve("C:foo", "C:\\foo")
+            .resolve("D:foo", "D:foo");
+        test("\\")
+            .resolve("foo", "\\foo")
+            .resolve("D:bar", "D:bar")
+            .resolve("C:\\bar", "C:\\bar")
+            .resolve("\\\\server\\share\\bar", "\\\\server\\share\\bar")
+            .resolve("\\foo", "\\foo");
+        test("\\foo")
+            .resolve("bar", "\\foo\\bar")
+            .resolve("D:bar", "D:bar")
+            .resolve("C:\\bar", "C:\\bar")
+            .resolve("\\\\server\\share\\bar", "\\\\server\\share\\bar")
+            .resolve("\\bar", "\\bar");
+        test("foo")
+            .resolve("bar", "foo\\bar")
+            .resolve("D:\\bar", "D:\\bar")
+            .resolve("\\\\server\\share\\bar", "\\\\server\\share\\bar")
+            .resolve("C:bar", "C:bar")
+            .resolve("D:foo", "D:foo");
+        test("C:")
+            .resolve("foo", "C:foo");
+        test("\\\\server\\share\\foo")
+            .resolve("bar", "\\\\server\\share\\foo\\bar")
+            .resolve("\\bar", "\\\\server\\share\\bar")
+            .resolve("D:\\bar", "D:\\bar")
+            .resolve("\\\\other\\share\\bar", "\\\\other\\share\\bar")
+            .resolve("D:bar", "D:bar");
+
+        // relativize
+        test("foo\\bar")
+            .relativize("foo\\bar", null)
+            .relativize("foo", "..");
+        test("C:\\a\\b\\c")
+            .relativize("C:\\a", "..\\..");
+        test("\\\\server\\share\\foo")
+            .relativize("\\\\server\\share\\bar", "..\\bar");
+
+        // normalize
+        test("C:\\")
+            .normalize("C:\\");
+        test("C:\\.")
+            .normalize("C:\\");
+        test("C:\\..")
+            .normalize("C:\\");
+        test("\\\\server\\share")
+            .normalize("\\\\server\\share\\");
+        test("\\\\server\\share\\.")
+            .normalize("\\\\server\\share\\");
+        test("\\\\server\\share\\..")
+            .normalize("\\\\server\\share\\");
+        test("C:")
+            .normalize("C:");
+        test("C:.")
+            .normalize("C:");
+        test("C:..")
+            .normalize("C:..");
+        test("\\")
+            .normalize("\\");
+        test("\\.")
+            .normalize("\\");
+        test("\\..")
+            .normalize("\\");
+        test("foo")
+            .normalize("foo");
+        test("foo\\.")
+            .normalize("foo");
+        test("foo\\..")
+            .normalize(null);
+        test("C:\\foo")
+            .normalize("C:\\foo");
+        test("C:\\foo\\.")
+            .normalize("C:\\foo");
+        test("C:\\.\\foo")
+            .normalize("C:\\foo");
+        test("C:\\foo\\..")
+            .normalize("C:\\");
+        test("C:\\..\\foo")
+            .normalize("C:\\foo");
+        test("\\\\server\\share\\foo")
+            .normalize("\\\\server\\share\\foo");
+        test("\\\\server\\share\\foo\\.")
+            .normalize("\\\\server\\share\\foo");
+        test("\\\\server\\share\\.\\foo")
+            .normalize("\\\\server\\share\\foo");
+        test("\\\\server\\share\\foo\\..")
+            .normalize("\\\\server\\share\\");
+        test("\\\\server\\share\\..\\foo")
+            .normalize("\\\\server\\share\\foo");
+        test("C:foo")
+            .normalize("C:foo");
+        test("C:foo\\.")
+            .normalize("C:foo");
+        test("C:.\\foo")
+            .normalize("C:foo");
+        test("C:foo\\..")
+            .normalize("C:");
+        test("C:..\\foo")
+            .normalize("C:..\\foo");
+        test("\\foo")
+            .normalize("\\foo");
+        test("\\foo\\.")
+            .normalize("\\foo");
+        test("\\.\\foo")
+            .normalize("\\foo");
+        test("\\foo\\..")
+            .normalize("\\");
+        test("\\..\\foo")
+            .normalize("\\foo");
+        test(".")
+            .normalize(null);
+        test("..")
+            .normalize("..");
+        test("\\..\\..")
+            .normalize("\\");
+        test("..\\..\\foo")
+            .normalize("..\\..\\foo");
+        test("foo\\bar\\..")
+            .normalize("foo");
+        test("foo\\bar\\.\\..")
+            .normalize("foo");
+        test("foo\\bar\\gus\\..\\..")
+            .normalize("foo");
+        test(".\\foo\\.\\bar\\.\\gus\\..\\.\\..")
+            .normalize("foo");
+
+        // UNC corner cases
+        test("\\\\server\\share\\")
+            .root("\\\\server\\share\\")
+            .parent(null)
+            .name(null);
+        test("\\\\server")
+            .invalid();
+        test("\\\\server\\")
+            .invalid();
+        test("\\\\server\\share")
+            .root("\\\\server\\share\\")
+            .parent(null)
+            .name(null);
+
+        // invalid
+        test(":\\foo")
+            .invalid();
+        test("C::")
+            .invalid();
+        test("C:\\?")           // invalid character
+            .invalid();
+        test("C:\\*")           // invalid character
+            .invalid();
+        test("C:\\abc\u0001\\foo")
+            .invalid();
+        test("C:\\\u0019\\foo")
+            .invalid();
+        test("\\\\server\u0019\\share")
+            .invalid();
+        test("\\\\server\\share\u0019")
+            .invalid();
+        test("foo\u0000\bar")
+            .invalid();
+        test("C:\\foo ")                // trailing space
+             .invalid();
+        test("C:\\foo \\bar")
+            .invalid();
+        //test("C:\\foo.")              // trailing dot
+            //.invalid();
+        //test("C:\\foo...\\bar")
+            //.invalid();
+
+        // normalization at construction time (remove redundant and replace slashes)
+        test("C:/a/b/c")
+            .string("C:\\a\\b\\c")
+            .root("C:\\")
+            .parent("C:\\a\\b");
+        test("C://a//b//c")
+            .string("C:\\a\\b\\c")
+            .root("C:\\")
+            .parent("C:\\a\\b");
+
+        // hashCode
+        header("hashCode");
+        int h1 = test("C:\\foo").path().hashCode();
+        int h2 = test("c:\\FOO").path().hashCode();
+        if (h1 != h2)
+            throw new RuntimeException("PathOps failed");
+    }
+
+    static void doUnixTests() {
+        header("Unix specific tests");
+
+        // all components
+        test("/a/b/c")
+            .root("/")
+            .parent("/a/b")
+            .name("c");
+
+        // root component only
+        test("/")
+            .root("/")
+            .parent(null)
+            .name(null);
+
+        // no root component
+        test("a/b")
+            .root(null)
+            .parent("a")
+            .name("b");
+
+        // name component only
+        test("foo")
+            .root(null)
+            .parent(null)
+            .name("foo");
+
+        // startsWith
+        test("/")
+            .starts("/")
+            .notStarts("/foo");
+        test("/foo")
+            .starts("/")
+            .starts("/foo")
+            .notStarts("/f");
+        test("/foo/bar")
+            .starts("/")
+            .starts("/foo")
+            .starts("/foo/bar")
+            .notStarts("/f")
+            .notStarts("foo")
+            .notStarts("foo/bar");
+        test("foo")
+            .starts("foo")
+            .notStarts("f");
+        test("foo/bar")
+            .starts("foo")
+            .starts("foo/bar")
+            .notStarts("f")
+            .notStarts("/foo")
+            .notStarts("/foo/bar");
+
+        // endsWith
+        test("/")
+            .ends("/")
+            .notEnds("foo")
+            .notEnds("/foo");
+        test("/foo")
+            .ends("foo")
+            .ends("/foo")
+            .notEnds("/");
+        test("/foo/bar")
+            .ends("bar")
+            .ends("foo/bar")
+            .ends("/foo/bar")
+            .notEnds("/bar");
+        test("foo")
+            .ends("foo");
+        test("foo/bar")
+            .ends("bar")
+            .ends("foo/bar");
+
+        // elements
+        test("a/b/c")
+            .element(0,"a")
+            .element(1,"b")
+            .element(2,"c");
+
+        // isAbsolute
+        test("/")
+            .absolute();
+        test("/tmp")
+            .absolute();
+        test("tmp")
+            .notAbsolute();
+
+        // resolve
+        test("/tmp")
+            .resolve("foo", "/tmp/foo")
+            .resolve("/foo", "/foo");
+        test("tmp")
+            .resolve("foo", "tmp/foo")
+            .resolve("/foo", "/foo");
+
+        // relativize
+        test("/a/b/c")
+            .relativize("/a/b/c", null)
+            .relativize("/a/b/c/d/e", "d/e")
+            .relativize("/a/x", "../../x");
+
+        // normalize
+        test("/")
+            .normalize("/");
+        test("foo")
+            .normalize("foo");
+        test("/foo")
+            .normalize("/foo");
+        test(".")
+            .normalize(null);
+        test("..")
+            .normalize("..");
+        test("/..")
+            .normalize("/");
+        test("/../..")
+            .normalize("/");
+        test("foo/.")
+            .normalize("foo");
+        test("./foo")
+            .normalize("foo");
+        test("foo/..")
+            .normalize(null);
+        test("../foo")
+            .normalize("../foo");
+        test("../../foo")
+            .normalize("../../foo");
+        test("foo/bar/..")
+            .normalize("foo");
+        test("foo/bar/gus/../..")
+            .normalize("foo");
+        test("/foo/bar/gus/../..")
+            .normalize("/foo");
+
+        // invalid
+        test("foo\u0000\bar")
+            .invalid();
+
+        // normalization
+        test("//foo//bar")
+            .string("/foo/bar")
+            .root("/")
+            .parent("/foo")
+            .name("bar");
+    }
+
+    static void npes() {
+        header("NullPointerException");
+
+        Path path = FileSystems.getDefault().getPath("foo");
+
+        try {
+            path.resolve((String)null);
+            throw new RuntimeException("NullPointerException not thrown");
+        } catch (NullPointerException npe) {
+        }
+
+        try {
+            path.relativize(null);
+            throw new RuntimeException("NullPointerException not thrown");
+        } catch (NullPointerException npe) {
+        }
+
+        try {
+            path.compareTo(null);
+            throw new RuntimeException("NullPointerException not thrown");
+        } catch (NullPointerException npe) {
+        }
+
+        try {
+            path.startsWith(null);
+            throw new RuntimeException("NullPointerException not thrown");
+        } catch (NullPointerException npe) {
+        }
+
+        try {
+            path.endsWith(null);
+            throw new RuntimeException("NullPointerException not thrown");
+        } catch (NullPointerException npe) {
+        }
+
+    }
+
+    public static void main(String[] args) {
+        // all platforms
+        npes();
+
+        // operating system specific
+        String osname = System.getProperty("os.name");
+        if (osname.startsWith("Windows")) {
+            doWindowsTests();
+        }
+        if (osname.equals("SunOS") || osname.equals("Linux")) {
+            doUnixTests();
+        }
+
+    }
+}
diff --git a/jdk/test/java/nio/file/Path/SBC.java b/jdk/test/java/nio/file/Path/SBC.java
new file mode 100644
index 0000000..724c870
--- /dev/null
+++ b/jdk/test/java/nio/file/Path/SBC.java
@@ -0,0 +1,468 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 4313887
+ * @summary Unit test for java.nio.file.Path.newByteChannel
+ * @library ..
+ */
+
+import java.nio.ByteBuffer;
+import java.nio.file.*;
+import static java.nio.file.StandardOpenOption.*;
+import static com.sun.nio.file.ExtendedOpenOption.*;
+import java.nio.file.attribute.FileAttribute;
+import java.nio.channels.*;
+import java.io.IOException;
+import java.util.*;
+
+public class SBC {
+
+    static boolean supportsLinks;
+
+    public static void main(String[] args) throws Exception {
+        Path dir = TestUtil.createTemporaryDirectory();
+        try {
+            supportsLinks = TestUtil.supportsLinks(dir);
+
+            // open options
+            createTests(dir);
+            appendTests(dir);
+            truncateExistingTests(dir);
+            noFollowLinksTests(dir);
+
+            // SeekableByteChannel methods
+            sizeTruncatePositionTests(dir);
+
+            // platform specific
+            if (System.getProperty("os.name").startsWith("Windows"))
+                dosSharingOptionTests(dir);
+
+            // misc. tests
+            badCombinations(dir);
+            unsupportedOptions(dir);
+            nullTests(dir);
+
+        } finally {
+            TestUtil.removeAll(dir);
+        }
+    }
+
+    // test CREATE and CREATE_NEW options
+    static void createTests(Path dir) throws Exception {
+        Path file = dir.resolve("foo");
+
+        // CREATE
+        try {
+            // create file (no existing file)
+            file.newByteChannel(CREATE, WRITE).close();
+            if (file.notExists())
+                throw new RuntimeException("File not created");
+
+            // create file (existing file)
+            file.newByteChannel(CREATE, WRITE).close();
+
+            // create file where existing file is a sym link
+            if (supportsLinks) {
+                Path link = dir.resolve("link").createSymbolicLink(file);
+                try {
+                    // file already exists
+                    link.newByteChannel(CREATE, WRITE).close();
+
+                    // file does not exist
+                    file.delete();
+                    link.newByteChannel(CREATE, WRITE).close();
+                    if (file.notExists())
+                        throw new RuntimeException("File not created");
+
+                } finally {
+                    TestUtil.deleteUnchecked(link);
+                }
+            }
+
+        } finally {
+            TestUtil.deleteUnchecked(file);
+        }
+
+        // CREATE_NEW
+        try {
+            // create file
+            file.newByteChannel(CREATE_NEW, WRITE).close();
+            if (file.notExists())
+                throw new RuntimeException("File not created");
+
+            // create should fail
+            try {
+                SeekableByteChannel sbc =
+                    file.newByteChannel(CREATE_NEW, WRITE);
+                sbc.close();
+                throw new RuntimeException("FileAlreadyExistsException not thrown");
+            } catch (FileAlreadyExistsException x) { }
+
+            // create should fail
+            if (supportsLinks) {
+                Path link = dir.resolve("link");
+                Path target = dir.resolve("thisDoesNotExist");
+                link.createSymbolicLink(target);
+                try {
+
+                    try {
+                        SeekableByteChannel sbc =
+                            file.newByteChannel(CREATE_NEW, WRITE);
+                        sbc.close();
+                        throw new RuntimeException("FileAlreadyExistsException not thrown");
+                    } catch (FileAlreadyExistsException x) { }
+
+                } finally {
+                    TestUtil.deleteUnchecked(link);
+                }
+            }
+
+
+        } finally {
+            TestUtil.deleteUnchecked(file);
+        }
+
+        // CREATE_NEW + SPARSE
+        try {
+            SeekableByteChannel sbc = file
+                .newByteChannel(CREATE_NEW, WRITE, SPARSE);
+            try {
+                final long hole = 2L * 1024L * 1024L * 1024L;
+                sbc.position(hole);
+                write(sbc, "hello");
+                long size = sbc.size();
+                if (size != (hole + 5))
+                    throw new RuntimeException("Unexpected size");
+            } finally {
+                sbc.close();
+            }
+        } finally {
+            TestUtil.deleteUnchecked(file);
+        }
+    }
+
+    // test APPEND option
+    static void appendTests(Path dir) throws Exception {
+        Path file = dir.resolve("foo");
+        try {
+            // "hello there" should be written to file
+            SeekableByteChannel sbc = file
+                .newByteChannel(CREATE_NEW, WRITE, APPEND);
+            try {
+                write(sbc, "hello ");
+                sbc.position(0L);
+                write(sbc, "there");
+            } finally {
+                sbc.close();
+            }
+
+            // check file
+            Scanner s = new Scanner(file);
+            try {
+                String line = s.nextLine();
+                if (!line.equals("hello there"))
+                    throw new RuntimeException("Unexpected file contents");
+            } finally {
+                s.close();
+            }
+
+            // check that read is not allowed
+            sbc = file.newByteChannel(APPEND);
+            try {
+                sbc.read(ByteBuffer.allocate(100));
+            } catch (NonReadableChannelException x) {
+            } finally {
+                sbc.close();
+            }
+        } finally {
+            // clean-up
+            TestUtil.deleteUnchecked(file);
+        }
+    }
+
+    // test TRUNCATE_EXISTING option
+    static void truncateExistingTests(Path dir) throws Exception {
+        Path file = dir.resolve("foo");
+        try {
+            SeekableByteChannel sbc =
+                file.newByteChannel(CREATE_NEW, WRITE);
+            try {
+                write(sbc, "Have a nice day!");
+            } finally {
+                sbc.close();
+            }
+
+            // re-open with truncate option
+            // write short message and check
+            sbc = file.newByteChannel(WRITE, TRUNCATE_EXISTING);
+            try {
+                write(sbc, "Hello there!");
+            } finally {
+                sbc.close();
+            }
+            Scanner s = new Scanner(file);
+            try {
+                String line = s.nextLine();
+                if (!line.equals("Hello there!"))
+                    throw new RuntimeException("Unexpected file contents");
+            } finally {
+                s.close();
+            }
+
+            // re-open with create + truncate option
+            // check file is of size 0L
+            sbc = file.newByteChannel(WRITE, CREATE, TRUNCATE_EXISTING);
+            try {
+                long size = ((FileChannel)sbc).size();
+                if (size != 0L)
+                    throw new RuntimeException("File not truncated");
+            } finally {
+                sbc.close();
+            }
+
+        } finally {
+            // clean-up
+            TestUtil.deleteUnchecked(file);
+        }
+
+    }
+
+    // test NOFOLLOW_LINKS option
+    static void noFollowLinksTests(Path dir) throws Exception {
+        if (!supportsLinks)
+            return;
+        Path file = dir.resolve("foo").createFile();
+        try {
+            // ln -s foo link
+            Path link = dir.resolve("link").createSymbolicLink(file);
+
+            // open with NOFOLLOW_LINKS option
+            try {
+                link.newByteChannel(READ, LinkOption.NOFOLLOW_LINKS);
+                throw new RuntimeException();
+            } catch (IOException x) {
+            } finally {
+                TestUtil.deleteUnchecked(link);
+            }
+
+        } finally {
+            // clean-up
+            TestUtil.deleteUnchecked(file);
+        }
+    }
+
+    // test size/truncate/position methods
+    static void sizeTruncatePositionTests(Path dir) throws Exception {
+        Path file = dir.resolve("foo");
+        try {
+            SeekableByteChannel sbc = file
+                .newByteChannel(CREATE_NEW, READ, WRITE);
+            try {
+                if (sbc.size() != 0L)
+                    throw new RuntimeException("Unexpected size");
+
+                // check size
+                write(sbc, "hello");
+                if (sbc.size() != 5L)
+                    throw new RuntimeException("Unexpected size");
+
+                // truncate (size and position should change)
+                sbc.truncate(4L);
+                if (sbc.size() != 4L)
+                    throw new RuntimeException("Unexpected size");
+                if (sbc.position() != 4L)
+                    throw new RuntimeException("Unexpected position");
+
+                // truncate (position should not change)
+                sbc.position(2L).truncate(3L);
+                if (sbc.size() != 3L)
+                    throw new RuntimeException("Unexpected size");
+                if (sbc.position() != 2L)
+                    throw new RuntimeException("Unexpected position");
+            } finally {
+                sbc.close();
+            }
+        } finally {
+            TestUtil.deleteUnchecked(file);
+        }
+    }
+
+    // Windows specific options for the use by applications that really want
+    // to use legacy DOS sharing options
+    static void dosSharingOptionTests(Path dir) throws Exception {
+        Path file = dir.resolve("foo").createFile();
+        try {
+            SeekableByteChannel ch;
+
+            // no sharing
+            ch = file.newByteChannel(READ,
+                NOSHARE_READ, NOSHARE_WRITE, NOSHARE_DELETE);
+            try {
+                try {
+                    file.newByteChannel(READ);
+                    throw new RuntimeException("Sharing violation expected");
+                } catch (IOException ignore) { }
+                try {
+                    file.newByteChannel(WRITE);
+                    throw new RuntimeException("Sharing violation expected");
+                } catch (IOException ignore) { }
+                try {
+                    file.delete();
+                    throw new RuntimeException("Sharing violation expected");
+                } catch (IOException ignore) { }
+            } finally {
+                ch.close();
+            }
+
+            // read allowed
+            ch = file.newByteChannel(READ, NOSHARE_WRITE, NOSHARE_DELETE);
+            try {
+                file.newByteChannel(READ).close();
+                try {
+                    file.newByteChannel(WRITE);
+                    throw new RuntimeException("Sharing violation expected");
+                } catch (IOException ignore) { }
+                try {
+                    file.delete();
+                    throw new RuntimeException("Sharing violation expected");
+                } catch (IOException ignore) { }
+            } finally {
+                ch.close();
+            }
+
+            // write allowed
+            ch = file.newByteChannel(READ, NOSHARE_READ, NOSHARE_DELETE);
+            try {
+                try {
+                    file.newByteChannel(READ);
+                    throw new RuntimeException("Sharing violation expected");
+                } catch (IOException ignore) { }
+                file.newByteChannel(WRITE).close();
+                try {
+                    file.delete();
+                    throw new RuntimeException("Sharing violation expected");
+                } catch (IOException ignore) { }
+            } finally {
+                ch.close();
+            }
+
+            // delete allowed
+            ch = file.newByteChannel(READ, NOSHARE_READ, NOSHARE_WRITE);
+            try {
+                try {
+                    file.newByteChannel(READ);
+                    throw new RuntimeException("Sharing violation expected");
+                } catch (IOException ignore) { }
+                try {
+                    file.newByteChannel(WRITE);
+                    throw new RuntimeException("Sharing violation expected");
+                } catch (IOException ignore) { }
+                file.delete();
+            } finally {
+                ch.close();
+            }
+
+        } finally {
+            TestUtil.deleteUnchecked(file);
+        }
+    }
+
+    // invalid combinations of options
+    static void badCombinations(Path dir) throws Exception {
+        Path file = dir.resolve("bad");
+
+        try {
+            file.newByteChannel(READ, APPEND);
+            throw new RuntimeException("IllegalArgumentException expected");
+        } catch (IllegalArgumentException x) { }
+
+        try {
+            file.newByteChannel(WRITE, APPEND, TRUNCATE_EXISTING);
+            throw new RuntimeException("IllegalArgumentException expected");
+        } catch (IllegalArgumentException x) { }
+    }
+
+    // unsupported operations
+    static void unsupportedOptions(Path dir) throws Exception {
+        Path file = dir.resolve("bad");
+
+        OpenOption badOption = new OpenOption() { };
+        try {
+            file.newByteChannel(badOption);
+            throw new RuntimeException("UnsupportedOperationException expected");
+        } catch (UnsupportedOperationException e) { }
+        try {
+            file.newByteChannel(READ, WRITE, badOption);
+            throw new RuntimeException("UnsupportedOperationException expected");
+        } catch (UnsupportedOperationException e) { }
+    }
+
+    // null handling
+    static void nullTests(Path dir) throws Exception {
+        Path file = dir.resolve("foo");
+
+        try {
+            file.newByteChannel((OpenOption[])null);
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException x) { }
+
+        try {
+            OpenOption[] opts = { READ, null };
+            file.newByteChannel(opts);
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException x) { }
+
+        try {
+            file.newByteChannel((Set<OpenOption>)null);
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException x) { }
+
+        try {
+            Set<OpenOption> opts = new HashSet<OpenOption>();
+            opts.add(READ);
+            opts.add(null);
+            file.newByteChannel(opts);
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException x) { }
+
+        try {
+            EnumSet<StandardOpenOption> opts = EnumSet.of(READ);
+            file.newByteChannel(opts, (FileAttribute[])null);
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException x) { }
+
+        try {
+            EnumSet<StandardOpenOption> opts = EnumSet.of(READ);
+            FileAttribute[] attrs = { null };
+            file.newByteChannel(opts, attrs);
+            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException x) { }
+    }
+
+    static void write(WritableByteChannel wbc, String msg) throws IOException {
+        ByteBuffer buf = ByteBuffer.wrap(msg.getBytes());
+        while (buf.hasRemaining())
+            wbc.write(buf);
+    }
+}
diff --git a/jdk/test/java/nio/file/Path/TemporaryFiles.java b/jdk/test/java/nio/file/Path/TemporaryFiles.java
new file mode 100644
index 0000000..6a9d28d
--- /dev/null
+++ b/jdk/test/java/nio/file/Path/TemporaryFiles.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.nio.file.*;
+import static java.nio.file.StandardOpenOption.*;
+import java.nio.file.attribute.*;
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Set;
+
+public class TemporaryFiles {
+
+    static void checkFile(Path file) throws IOException {
+        // check file is in temporary directory
+        Path tmpdir = Paths.get(System.getProperty("java.io.tmpdir"));
+        if (!file.getParent().equals(tmpdir))
+            throw new RuntimeException("Not in temporary directory");
+
+        // check that file can be opened for reading and writing
+        file.newByteChannel(READ).close();
+        file.newByteChannel(WRITE).close();
+        file.newByteChannel(READ,WRITE).close();
+
+        // check file permissions are 0600 or more secure
+        if (file.getFileStore().supportsFileAttributeView("posix")) {
+            Set<PosixFilePermission> perms = Attributes
+                .readPosixFileAttributes(file).permissions();
+            perms.remove(PosixFilePermission.OWNER_READ);
+            perms.remove(PosixFilePermission.OWNER_WRITE);
+            if (!perms.isEmpty())
+                throw new RuntimeException("Temporary file is not secure");
+        }
+    }
+
+    public static void main(String[] args) throws IOException {
+        Path file = File.createTempFile("blah", null, false).toPath();
+        try {
+            checkFile(file);
+        } finally {
+            TestUtil.deleteUnchecked(file);
+        }
+
+        // temporary file with deleteOnExit
+        file = File.createTempFile("blah", "tmp", true).toPath();
+        checkFile(file);
+        // write path to temporary file to file so that calling script can
+        // check that it is deleted
+        OutputStream out = Paths.get(args[0]).newOutputStream();
+        try {
+            out.write(file.toString().getBytes());
+        } finally {
+            out.close();
+        }
+    }
+}
diff --git a/jdk/test/java/nio/file/Path/UriImportExport.java b/jdk/test/java/nio/file/Path/UriImportExport.java
new file mode 100644
index 0000000..5604231
--- /dev/null
+++ b/jdk/test/java/nio/file/Path/UriImportExport.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 4313887
+ * @summary Unit test for java.nio.file.Path
+ */
+
+import java.nio.file.*;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.io.PrintStream;
+
+public class UriImportExport {
+
+    static final PrintStream log = System.out;
+    static int failures = 0;
+
+    static void test(String fn, String expected) {
+        log.println();
+        Path p = Paths.get(fn);
+        log.println(p);
+        URI u = p.toUri();
+        log.println("  --> " + u);
+        if (expected != null && !(u.toString().equals(expected))) {
+            log.println("FAIL: Expected " + expected);
+            failures++;
+            return;
+        }
+        Path q = Paths.get(u);
+        log.println("  --> " + q);
+        if (!p.toAbsolutePath().equals(q)) {
+            log.println("FAIL: Expected " + p + ", got " + q);
+            failures++;
+            return;
+        }
+    }
+
+    static void test(String fn) {
+        test(fn, null);
+    }
+
+    public static void main(String[] args) throws Exception {
+        test("foo");
+        test("/foo");
+        test("/foo bar");
+
+        String osname = System.getProperty("os.name");
+        if (osname.startsWith("Windows")) {
+            test("C:\\foo");
+            test("C:foo");
+            test("\\\\rialto.dublin.com\\share\\");
+            test("\\\\fe80--203-baff-fe5a-749ds1.ipv6-literal.net\\share\\missing",
+                "file://[fe80::203:baff:fe5a:749d%1]/share/missing");
+        }
+
+        if (failures > 0)
+            throw new RuntimeException(failures + " test(s) failed");
+    }
+}
diff --git a/jdk/test/java/nio/file/Path/delete_on_close.sh b/jdk/test/java/nio/file/Path/delete_on_close.sh
new file mode 100644
index 0000000..198e99d
--- /dev/null
+++ b/jdk/test/java/nio/file/Path/delete_on_close.sh
@@ -0,0 +1,61 @@
+#
+# Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
+# @test
+# @bug 4313887
+# @summary Unit test for DELETE_ON_CLOSE open option
+# @library ..
+# @build DeleteOnClose
+# @run shell delete_on_close.sh
+
+# if TESTJAVA isn't set then we assume an interactive run.
+
+if [ -z "$TESTJAVA" ]; then
+    TESTSRC=.
+    TESTCLASSES=.
+    JAVA=java
+else
+    JAVA="${TESTJAVA}/bin/java"
+fi
+
+OS=`uname -s`
+case "$OS" in
+    Windows_* )
+        CLASSPATH="${TESTCLASSES};${TESTSRC}"
+        ;;
+    * )
+        CLASSPATH=${TESTCLASSES}:${TESTSRC}
+        ;;
+esac
+export CLASSPATH
+
+TMPFILE="$$.tmp"
+touch $TMPFILE
+$JAVA DeleteOnClose $TMPFILE 2>&1
+if [ $? != 0 ]; then exit 1; fi
+if [ -f $TMPFILE ]; then
+    echo "$TMPFILE was not deleted"
+    exit 1
+fi
+
+exit 0
diff --git a/jdk/test/java/nio/file/Path/temporary_files.sh b/jdk/test/java/nio/file/Path/temporary_files.sh
new file mode 100644
index 0000000..552dcfd
--- /dev/null
+++ b/jdk/test/java/nio/file/Path/temporary_files.sh
@@ -0,0 +1,65 @@
+#
+# Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
+# @test
+# @bug 4313887
+# @summary Unit test for File.createTempFile (to be be moved to test/java/io/File)
+# @library ..
+# @build TemporaryFiles
+# @run shell temporary_files.sh
+
+# if TESTJAVA isn't set then we assume an interactive run.
+
+if [ -z "$TESTJAVA" ]; then
+    TESTSRC=.
+    TESTCLASSES=.
+    JAVA=java
+else
+    JAVA="${TESTJAVA}/bin/java"
+fi
+
+OS=`uname -s`
+case "$OS" in
+    Windows_* )
+        CLASSPATH="${TESTCLASSES};${TESTSRC}"
+        ;;
+    * )
+        CLASSPATH=${TESTCLASSES}:${TESTSRC}
+        ;;
+esac
+export CLASSPATH
+
+TMPFILENAME="$$.tmp"
+$JAVA TemporaryFiles $TMPFILENAME 2>&1
+if [ $? != 0 ]; then exit 1; fi
+if [ ! -f $TMPFILENAME ]; then
+    echo "$TMPFILENAME not found"
+    exit 1
+fi
+TMPFILE=`cat $TMPFILENAME`
+if [ -f $TMPFILE ]; then
+    echo "$TMPFILE not deleted"
+    exit 1
+fi
+
+exit 0
diff --git a/jdk/test/java/nio/file/PathMatcher/Basic.java b/jdk/test/java/nio/file/PathMatcher/Basic.java
new file mode 100644
index 0000000..16efcf0
--- /dev/null
+++ b/jdk/test/java/nio/file/PathMatcher/Basic.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 4313887
+ * @summary Unit test for java.nio.file.PathMatcher
+ */
+
+import java.nio.file.*;
+import java.util.regex.PatternSyntaxException;
+
+public class Basic {
+    static int failures;
+
+    static void match(String name, String pattern, boolean expectedToMatch) {
+        System.out.format("%s -> %s", name, pattern);
+        Path file = Paths.get(name);
+        boolean matched =  file.getFileSystem()
+            .getPathMatcher("glob:" + pattern).matches(file);
+        if (matched)
+            System.out.print(" (matched)");
+        else
+            System.out.print(" (no match)");
+        if (matched != expectedToMatch) {
+            System.out.println(" ==> UNEXPECTED RESULT!");
+            failures++;
+        } else {
+            System.out.println(" OKAY");
+        }
+    }
+
+    static void assertMatch(String path, String pattern) {
+        match(path, pattern, true);
+    }
+
+    static void assertNotMatch(String path, String pattern) {
+        match(path, pattern, false);
+    }
+
+    static void assertBadPattern(String path, String pattern) {
+        System.out.format("Compile bad pattern %s\t", pattern);
+        try {
+            FileSystems.getDefault().getPathMatcher("glob:" + pattern);
+            System.out.println("Compiled ==> UNEXPECTED RESULT!");
+            failures++;
+        } catch (PatternSyntaxException e) {
+            System.out.println("Failed to compile ==> OKAY");
+        }
+    }
+
+    public static void main(String[] args) {
+        // basic
+        assertMatch("foo.html", "foo.html");
+        assertNotMatch("foo.html", "foo.htm");
+        assertNotMatch("foo.html", "bar.html");
+
+        // match zero or more characters
+        assertMatch("foo.html", "f*");
+        assertMatch("foo.html", "*.html");
+        assertMatch("foo.html", "foo.html*");
+        assertMatch("foo.html", "*foo.html");
+        assertMatch("foo.html", "*foo.html*");
+        assertNotMatch("foo.html", "*.htm");
+        assertNotMatch("foo.html", "f.*");
+
+        // match one character
+        assertMatch("foo.html", "?oo.html");
+        assertMatch("foo.html", "??o.html");
+        assertMatch("foo.html", "???.html");
+        assertMatch("foo.html", "???.htm?");
+        assertNotMatch("foo.html", "foo.???");
+
+        // group of subpatterns
+        assertMatch("foo.html", "foo{.html,.class}");
+        assertMatch("foo.html", "foo.{class,html}");
+        assertNotMatch("foo.html", "foo{.htm,.class}");
+
+        // bracket expressions
+        assertMatch("foo.html", "[f]oo.html");
+        assertMatch("foo.html", "[e-g]oo.html");
+        assertMatch("foo.html", "[abcde-g]oo.html");
+        assertMatch("foo.html", "[abcdefx-z]oo.html");
+        assertMatch("foo.html", "[!a]oo.html");
+        assertMatch("foo.html", "[!a-e]oo.html");
+        assertMatch("foo-bar", "foo[-a-z]bar");     // match dash
+        assertMatch("foo.html", "foo[!-]html");     // match !dash
+
+        // groups of subpattern with bracket expressions
+        assertMatch("foo.html", "[f]oo.{[h]tml,class}");
+        assertMatch("foo.html", "foo.{[a-z]tml,class}");
+        assertMatch("foo.html", "foo.{[!a-e]tml,.class}");
+
+        // assume special characters are allowed in file names
+        assertMatch("{foo}.html", "\\{foo*");
+        assertMatch("{foo}.html", "*\\}.html");
+        assertMatch("[foo].html", "\\[foo*");
+        assertMatch("[foo].html", "*\\].html");
+
+        // errors
+        assertBadPattern("foo.html", "*[a--z]");            // bad range
+        assertBadPattern("foo.html", "*[a--]");             // bad range
+        assertBadPattern("foo.html", "*[a-z");              // missing ]
+        assertBadPattern("foo.html", "*{class,java");       // missing }
+        assertBadPattern("foo.html", "*.{class,{.java}}");  // nested group
+        assertBadPattern("foo.html", "*.html\\");           // nothing to escape
+
+        // platform specific
+        if (System.getProperty("os.name").startsWith("Windows")) {
+            assertMatch("C:\\foo", "C:\\\\f*");
+            assertMatch("C:\\FOO", "c:\\\\f*");
+            assertMatch("C:\\foo\\bar\\gus", "C:\\\\**\\\\gus");
+            assertMatch("C:\\foo\\bar\\gus", "C:\\\\**");
+        } else {
+            assertMatch("/tmp/foo", "/tmp/*");
+            assertMatch("/tmp/foo/bar", "/tmp/**");
+
+            // some special characters not allowed on Windows
+            assertMatch("myfile?", "myfile\\?");
+            assertMatch("one\\two", "one\\\\two");
+            assertMatch("one*two", "one\\*two");
+        }
+
+
+
+        // regex syntax
+        {
+            String pattern = ".*\\.html";
+            System.out.format("Test regex pattern: %s", pattern);
+            Path file = Paths.get("foo.html");
+            boolean matched =  file.getFileSystem()
+                .getPathMatcher("regex:" + pattern).matches(file);
+            if (matched) {
+                System.out.println(" OKAY");
+            } else {
+                System.out.println(" ==> UNEXPECTED RESULT!");
+                failures++;
+            }
+        }
+
+        // unknown syntax
+        try {
+            System.out.format("Test unknown syntax");
+            FileSystems.getDefault().getPathMatcher("grep:foo");
+            System.out.println(" ==> NOT EXPECTED TO COMPILE");
+            failures++;
+        } catch (UnsupportedOperationException e) {
+            System.out.println(" OKAY");
+        }
+
+        if (failures > 0)
+            throw new RuntimeException(failures +
+                " sub-test(s) failed - see log for details");
+    }
+}
diff --git a/jdk/test/java/nio/file/TestUtil.java b/jdk/test/java/nio/file/TestUtil.java
new file mode 100644
index 0000000..c19e28f
--- /dev/null
+++ b/jdk/test/java/nio/file/TestUtil.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.Random;
+import java.io.IOException;
+
+public class TestUtil {
+    private TestUtil() {
+    }
+
+    public static Path createTemporaryDirectory() throws IOException {
+        Path tmpdir = Paths.get(System.getProperty("java.io.tmpdir"));
+        Random r = new Random();
+
+        Path dir;
+        do {
+            dir = tmpdir.resolve("name" + r.nextInt());
+        } while (dir.exists());
+        return dir.createDirectory();
+    }
+
+    static void removeAll(Path dir) {
+        Files.walkFileTree(dir, new FileVisitor<Path>() {
+            @Override
+            public FileVisitResult preVisitDirectory(Path dir) {
+                return FileVisitResult.CONTINUE;
+            }
+            @Override
+            public FileVisitResult preVisitDirectoryFailed(Path dir, IOException exc) {
+                System.err.format("Error occured accessing directory %s\n", dir, exc);
+                return FileVisitResult.CONTINUE;
+            }
+            @Override
+            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
+                try {
+                    file.delete(false);
+                } catch (IOException x) {
+                    System.err.format("Unable to delete %s: %s\n", file, x);
+                }
+                return FileVisitResult.CONTINUE;
+            }
+            @Override
+            public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
+                try {
+                    dir.delete(false);
+                } catch (IOException x) {
+                    System.err.format("Unable to delete %s: %s\n", dir, x);
+                }
+                return FileVisitResult.CONTINUE;
+            }
+            @Override
+            public FileVisitResult visitFileFailed(Path file, IOException exc) {
+                System.err.format("Unable to visit %s: %s\n", file, exc);
+                return FileVisitResult.CONTINUE;
+            }
+        });
+    }
+
+    static void deleteUnchecked(FileRef file) {
+        try {
+            file.delete();
+        } catch (IOException exc) {
+            System.err.format("Unable to delete %s: %s\n", file, exc);
+        }
+    }
+
+    /**
+     * Creates a directory tree in the given directory so that the total
+     * size of the path is more than 2k in size. This is used for long
+     * path tests on Windows.
+     */
+    static Path createDirectoryWithLongPath(Path dir)
+        throws IOException
+    {
+        StringBuilder sb = new StringBuilder();
+        for (int i=0; i<240; i++) {
+            sb.append('A');
+        }
+        String name = sb.toString();
+        do {
+            dir = dir.resolve(name).resolve(".");
+            dir.createDirectory();
+        } while (dir.toString().length() < 2048);
+        return dir;
+    }
+
+    /**
+     * Returns true if symbolic links are supported
+     */
+    static boolean supportsLinks(Path dir) {
+        Path link = dir.resolve("testlink");
+        Path target = dir.resolve("testtarget");
+        try {
+            link.createSymbolicLink(target);
+            target.delete(false);
+            return true;
+        } catch (UnsupportedOperationException x) {
+            return false;
+        } catch (IOException x) {
+            return false;
+        }
+    }
+}
diff --git a/jdk/test/java/nio/file/WatchService/Basic.java b/jdk/test/java/nio/file/WatchService/Basic.java
new file mode 100644
index 0000000..60c18d7
--- /dev/null
+++ b/jdk/test/java/nio/file/WatchService/Basic.java
@@ -0,0 +1,493 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 4313887
+ * @summary Unit test for java.nio.file.WatchService
+ * @library ..
+ * @run main/timeout=120 Basic
+ */
+
+import java.nio.file.*;
+import static java.nio.file.StandardWatchEventKind.*;
+import java.nio.file.attribute.*;
+import java.io.*;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Unit test for WatchService that exercises all methods in various scenarios.
+ */
+
+public class Basic {
+
+    static void createFile(Path file) throws IOException {
+        file.newOutputStream().close();
+    }
+
+    static void takeExpectedKey(WatchService watcher, WatchKey expected) {
+        System.out.println("take events...");
+        WatchKey key;
+        try {
+            key = watcher.take();
+        } catch (InterruptedException x) {
+            // not expected
+            throw new RuntimeException(x);
+        }
+        if (key != expected)
+            throw new RuntimeException("removed unexpected key");
+    }
+
+    static void checkExpectedEvent(Iterable<WatchEvent<?>> events,
+                                   WatchEvent.Kind<?> expectedKind,
+                                   Object expectedContext)
+    {
+        WatchEvent<?> event = events.iterator().next();
+        System.out.format("got event: type=%s, count=%d, context=%s\n",
+            event.kind(), event.count(), event.context());
+        if (event.kind() != expectedKind)
+            throw new RuntimeException("unexpected event");
+        if (!expectedContext.equals(event.context()))
+            throw new RuntimeException("unexpected context");
+    }
+
+    /**
+     * Simple test of each of the standard events
+     */
+    static void testEvents(Path dir) throws IOException {
+        System.out.println("-- Standard Events --");
+
+        FileSystem fs = FileSystems.getDefault();
+        Path name = fs.getPath("foo");
+
+        WatchService watcher = fs.newWatchService();
+        try {
+            // --- ENTRY_CREATE ---
+
+            // register for event
+            System.out.format("register %s for ENTRY_CREATE\n", dir);
+            WatchKey myKey = dir.register(watcher,
+                new WatchEvent.Kind<?>[]{ ENTRY_CREATE });
+
+            // create file
+            Path file = dir.resolve("foo");
+            System.out.format("create %s\n", file);
+            createFile(file);
+
+            // remove key and check that we got the ENTRY_CREATE event
+            takeExpectedKey(watcher, myKey);
+            checkExpectedEvent(myKey.pollEvents(),
+                StandardWatchEventKind.ENTRY_CREATE, name);
+
+            System.out.println("reset key");
+            if (!myKey.reset())
+                throw new RuntimeException("key has been cancalled");
+
+            System.out.println("OKAY");
+
+            // --- ENTRY_DELETE ---
+
+            System.out.format("register %s for ENTRY_DELETE\n", dir);
+            WatchKey deleteKey = dir.register(watcher,
+                new WatchEvent.Kind<?>[]{ ENTRY_DELETE });
+            if (deleteKey != myKey)
+                throw new RuntimeException("register did not return existing key");
+
+            System.out.format("delete %s\n", file);
+            file.delete(false);
+            takeExpectedKey(watcher, myKey);
+            checkExpectedEvent(myKey.pollEvents(),
+                StandardWatchEventKind.ENTRY_DELETE, name);
+
+            System.out.println("reset key");
+            if (!myKey.reset())
+                throw new RuntimeException("key has been cancalled");
+
+            System.out.println("OKAY");
+
+            // create the file for the next test
+            createFile(file);
+
+            // --- ENTRY_MODIFY ---
+
+            System.out.format("register %s for ENTRY_MODIFY\n", dir);
+            WatchKey newKey = dir.register(watcher,
+                new WatchEvent.Kind<?>[]{ ENTRY_MODIFY });
+            if (newKey != myKey)
+                throw new RuntimeException("register did not return existing key");
+
+            System.out.format("update: %s\n", file);
+            OutputStream out = file.newOutputStream(EnumSet.of(StandardOpenOption.APPEND));
+            try {
+                out.write("I am a small file".getBytes("UTF-8"));
+            } finally {
+                out.close();
+            }
+
+            // remove key and check that we got the ENTRY_MODIFY event
+            takeExpectedKey(watcher, myKey);
+            checkExpectedEvent(myKey.pollEvents(),
+                StandardWatchEventKind.ENTRY_MODIFY, name);
+            System.out.println("OKAY");
+
+            // done
+            file.delete(false);
+
+        } finally {
+            watcher.close();
+        }
+    }
+
+    /**
+     * Check that a cancelled key will never be queued
+     */
+    static void testCancel(Path dir) throws IOException {
+        System.out.println("-- Cancel --");
+
+        WatchService watcher = FileSystems.getDefault().newWatchService();
+        try {
+
+            System.out.format("register %s for events\n", dir);
+            WatchKey myKey = dir.register(watcher,
+                new WatchEvent.Kind<?>[]{ ENTRY_CREATE });
+
+            System.out.println("cancel key");
+            myKey.cancel();
+
+            // create a file in the directory
+            Path file = dir.resolve("mars");
+            System.out.format("create: %s\n", file);
+            createFile(file);
+
+            // poll for keys - there will be none
+            System.out.println("poll...");
+            try {
+                WatchKey key = watcher.poll(3000, TimeUnit.MILLISECONDS);
+                if (key != null)
+                    throw new RuntimeException("key should not be queued");
+            } catch (InterruptedException x) {
+                throw new RuntimeException(x);
+            }
+
+            // done
+            file.delete(false);
+
+            System.out.println("OKAY");
+
+        } finally {
+            watcher.close();
+        }
+    }
+
+    /**
+     * Check that deleting a registered directory causes the key to be
+     * cancelled and queued.
+     */
+    static void testAutomaticCancel(Path dir) throws IOException {
+        System.out.println("-- Automatic Cancel --");
+
+        Path subdir = dir.resolve("bar").createDirectory();
+
+        WatchService watcher = FileSystems.getDefault().newWatchService();
+        try {
+
+            System.out.format("register %s for events\n", subdir);
+            WatchKey myKey = subdir.register(watcher,
+                new WatchEvent.Kind<?>[]{ ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY });
+
+            System.out.format("delete: %s\n", subdir);
+            subdir.delete(false);
+            takeExpectedKey(watcher, myKey);
+
+            System.out.println("reset key");
+            if (myKey.reset())
+                throw new RuntimeException("Key was not cancelled");
+            if (myKey.isValid())
+                throw new RuntimeException("Key is still valid");
+
+            System.out.println("OKAY");
+
+        } finally {
+            watcher.close();
+        }
+    }
+
+    /**
+     * Asynchronous close of watcher causes blocked threads to wakeup
+     */
+    static void testWakeup(Path dir) throws IOException {
+        System.out.println("-- Wakeup Tests --");
+        final WatchService watcher = FileSystems.getDefault().newWatchService();
+        Runnable r = new Runnable() {
+            public void run() {
+                try {
+                    Thread.sleep(5000);
+                    System.out.println("close WatchService...");
+                    watcher.close();
+                } catch (InterruptedException x) {
+                    x.printStackTrace();
+                } catch (IOException x) {
+                    x.printStackTrace();
+                }
+            }
+        };
+
+        // start thread to close watch service after delay
+        new Thread(r).start();
+
+        try {
+            System.out.println("take...");
+            watcher.take();
+            throw new RuntimeException("ClosedWatchServiceException not thrown");
+        } catch (InterruptedException x) {
+            throw new RuntimeException(x);
+        } catch (ClosedWatchServiceException  x) {
+            System.out.println("ClosedWatchServiceException thrown");
+        }
+
+        System.out.println("OKAY");
+    }
+
+    /**
+     * Simple test to check exceptions and other cases
+     */
+    @SuppressWarnings("unchecked")
+    static void testExceptions(Path dir) throws IOException {
+        System.out.println("-- Exceptions and other simple tests --");
+
+        WatchService watcher = FileSystems.getDefault().newWatchService();
+        try {
+
+            // Poll tests
+
+            WatchKey key;
+            System.out.println("poll...");
+            key = watcher.poll();
+            if (key != null)
+                throw new RuntimeException("no keys registered");
+
+            System.out.println("poll with timeout...");
+            try {
+                long start = System.currentTimeMillis();
+                key = watcher.poll(3000, TimeUnit.MILLISECONDS);
+                if (key != null)
+                    throw new RuntimeException("no keys registered");
+                long waited = System.currentTimeMillis() - start;
+                if (waited < 2900)
+                    throw new RuntimeException("poll was too short");
+            } catch (InterruptedException x) {
+                throw new RuntimeException(x);
+            }
+
+            // IllegalArgumentException
+            System.out.println("IllegalArgumentException tests...");
+            try {
+                dir.register(watcher, new WatchEvent.Kind<?>[]{ } );
+                throw new RuntimeException("IllegalArgumentException not thrown");
+            } catch (IllegalArgumentException x) {
+            }
+            try {
+                // OVERFLOW is ignored so this is equivalent to the empty set
+                dir.register(watcher, new WatchEvent.Kind<?>[]{ OVERFLOW });
+                throw new RuntimeException("IllegalArgumentException not thrown");
+            } catch (IllegalArgumentException x) {
+            }
+
+            // UnsupportedOperationException
+            try {
+                dir.register(watcher, new WatchEvent.Kind<?>[]{
+                             new WatchEvent.Kind<Object>() {
+                                @Override public String name() { return "custom"; }
+                                @Override public Class<Object> type() { return Object.class; }
+                             }});
+            } catch (UnsupportedOperationException x) {
+            }
+            try {
+                dir.register(watcher,
+                             new WatchEvent.Kind<?>[]{ ENTRY_CREATE },
+                             new WatchEvent.Modifier() {
+                                 @Override public String name() { return "custom"; }
+                             });
+                throw new RuntimeException("UnsupportedOperationException not thrown");
+            } catch (UnsupportedOperationException x) {
+            }
+
+            // NullPointerException
+            System.out.println("NullPointerException tests...");
+            try {
+                dir.register(null, new WatchEvent.Kind<?>[]{ ENTRY_CREATE });
+                throw new RuntimeException("NullPointerException not thrown");
+            } catch (NullPointerException x) {
+            }
+            try {
+                dir.register(watcher, new WatchEvent.Kind<?>[]{ null });
+                throw new RuntimeException("NullPointerException not thrown");
+            } catch (NullPointerException x) {
+            }
+            try {
+                dir.register(watcher, new WatchEvent.Kind<?>[]{ ENTRY_CREATE },
+                    (WatchEvent.Modifier)null);
+                throw new RuntimeException("NullPointerException not thrown");
+            } catch (NullPointerException x) {
+            }
+        } finally {
+            watcher.close();
+        }
+
+        // -- ClosedWatchServiceException --
+
+        System.out.println("ClosedWatchServiceException tests...");
+
+        try {
+            watcher.poll();
+            throw new RuntimeException("ClosedWatchServiceException not thrown");
+        } catch (ClosedWatchServiceException  x) {
+        }
+
+        // assume that poll throws exception immediately
+        long start = System.currentTimeMillis();
+        try {
+            watcher.poll(10000, TimeUnit.MILLISECONDS);
+            throw new RuntimeException("ClosedWatchServiceException not thrown");
+        } catch (InterruptedException x) {
+            throw new RuntimeException(x);
+        } catch (ClosedWatchServiceException  x) {
+            long waited = System.currentTimeMillis() - start;
+            if (waited > 5000)
+                throw new RuntimeException("poll was too long");
+        }
+
+        try {
+            watcher.take();
+            throw new RuntimeException("ClosedWatchServiceException not thrown");
+        } catch (InterruptedException x) {
+            throw new RuntimeException(x);
+        } catch (ClosedWatchServiceException  x) {
+        }
+
+        try {
+            dir.register(watcher, new WatchEvent.Kind<?>[]{ ENTRY_CREATE });
+             throw new RuntimeException("ClosedWatchServiceException not thrown");
+        } catch (ClosedWatchServiceException  x) {
+        }
+
+        System.out.println("OKAY");
+    }
+
+    /**
+     * Test that directory can be registered with more than one watch service
+     * and that events don't interfere with each other
+     */
+    static void testTwoWatchers(Path dir) throws IOException {
+        System.out.println("-- Two watchers test --");
+
+        FileSystem fs = FileSystems.getDefault();
+        WatchService watcher1 = fs.newWatchService();
+        WatchService watcher2 = fs.newWatchService();
+        try {
+            Path name1 = fs.getPath("gus1");
+            Path name2 = fs.getPath("gus2");
+
+            // create gus1
+            Path file1 = dir.resolve(name1);
+            System.out.format("create %s\n", file1);
+            createFile(file1);
+
+            // register with both watch services (different events)
+            System.out.println("register for different events");
+            WatchKey key1 = dir.register(watcher1,
+                new WatchEvent.Kind<?>[]{ ENTRY_CREATE });
+            WatchKey key2 = dir.register(watcher2,
+                new WatchEvent.Kind<?>[]{ ENTRY_DELETE });
+
+            if (key1 == key2)
+                throw new RuntimeException("keys should be different");
+
+            // create gus2
+            Path file2 = dir.resolve(name2);
+            System.out.format("create %s\n", file2);
+            createFile(file2);
+
+            // check that key1 got ENTRY_CREATE
+            takeExpectedKey(watcher1, key1);
+            checkExpectedEvent(key1.pollEvents(),
+                StandardWatchEventKind.ENTRY_CREATE, name2);
+
+            // check that key2 got zero events
+            WatchKey key = watcher2.poll();
+            if (key != null)
+                throw new RuntimeException("key not expected");
+
+            // delete gus1
+            file1.delete(false);
+
+            // check that key2 got ENTRY_DELETE
+            takeExpectedKey(watcher2, key2);
+            checkExpectedEvent(key2.pollEvents(),
+                StandardWatchEventKind.ENTRY_DELETE, name1);
+
+            // check that key1 got zero events
+            key = watcher1.poll();
+            if (key != null)
+                throw new RuntimeException("key not expected");
+
+            // reset for next test
+            key1.reset();
+            key2.reset();
+
+            // change registration with watcher2 so that they are both
+            // registered for the same event
+            System.out.println("register for same event");
+            key2 = dir.register(watcher2, new WatchEvent.Kind<?>[]{ ENTRY_CREATE });
+
+            // create file and key2 should be queued
+            System.out.format("create %s\n", file1);
+            createFile(file1);
+            takeExpectedKey(watcher2, key2);
+            checkExpectedEvent(key2.pollEvents(),
+                StandardWatchEventKind.ENTRY_CREATE, name1);
+
+            System.out.println("OKAY");
+
+        } finally {
+            watcher2.close();
+            watcher1.close();
+        }
+    }
+
+    public static void main(String[] args) throws IOException {
+        Path dir = TestUtil.createTemporaryDirectory();
+        try {
+
+            testEvents(dir);
+            testCancel(dir);
+            testAutomaticCancel(dir);
+            testWakeup(dir);
+            testExceptions(dir);
+            testTwoWatchers(dir);
+
+        } finally {
+            TestUtil.removeAll(dir);
+        }
+    }
+}
diff --git a/jdk/test/java/nio/file/WatchService/FileTreeModifier.java b/jdk/test/java/nio/file/WatchService/FileTreeModifier.java
new file mode 100644
index 0000000..741c86d
--- /dev/null
+++ b/jdk/test/java/nio/file/WatchService/FileTreeModifier.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 4313887
+ * @summary Sanity test for Sun-specific FILE_TREE watch event modifier
+ * @library ..
+ */
+
+import java.nio.file.*;
+import static java.nio.file.StandardWatchEventKind.*;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.*;
+import java.util.concurrent.*;
+import static com.sun.nio.file.ExtendedWatchEventModifier.*;
+
+public class FileTreeModifier {
+
+    static void checkExpectedEvent(WatchService watcher,
+                                   WatchEvent.Kind<?> expectedType,
+                                   Object expectedContext)
+    {
+        WatchKey key;
+        try {
+            key = watcher.take();
+        } catch (InterruptedException x) {
+            // should not happen
+            throw new RuntimeException(x);
+        }
+        WatchEvent<?> event = key.pollEvents().iterator().next();
+        System.out.format("Event: type=%s, count=%d, context=%s\n",
+            event.kind(), event.count(), event.context());
+        if (event.kind() != expectedType)
+            throw new RuntimeException("unexpected event");
+        if (!expectedContext.equals(event.context()))
+            throw new RuntimeException("unexpected context");
+    }
+
+    static void doTest(Path top) throws IOException {
+        FileSystem fs = top.getFileSystem();
+        WatchService watcher = fs.newWatchService();
+
+        // create directories
+        Path subdir = top
+           .resolve("a").createDirectory()
+           .resolve("b").createDirectory()
+           .resolve("c").createDirectory();
+
+        // Test ENTRY_CREATE with FILE_TREE modifier.
+
+        WatchKey key = top.register(watcher,
+            new WatchEvent.Kind<?>[]{ ENTRY_CREATE }, FILE_TREE);
+
+        // create file in a/b/c and check we get create event
+        Path file = subdir.resolve("foo").createFile();
+        checkExpectedEvent(watcher, ENTRY_CREATE, top.relativize(file));
+        key.reset();
+
+        // Test ENTRY_DELETE with FILE_TREE modifier.
+
+        WatchKey k = top.register(watcher,
+            new WatchEvent.Kind<?>[]{ ENTRY_DELETE }, FILE_TREE);
+        if (k != key)
+            throw new RuntimeException("Existing key not returned");
+
+        // delete a/b/c/foo and check we get delete event
+        file.delete(false);
+        checkExpectedEvent(watcher, ENTRY_DELETE, top.relativize(file));
+        key.reset();
+
+        // Test changing registration to ENTRY_CREATE without modifier
+
+        k = top.register(watcher, new WatchEvent.Kind<?>[]{ ENTRY_CREATE });
+        if (k != key)
+            throw new RuntimeException("Existing key not returned");
+
+        // create a/b/c/foo
+        file.createFile();
+
+        // check that key is not queued
+        try {
+            k = watcher.poll(3, TimeUnit.SECONDS);
+        } catch (InterruptedException e) {
+            throw new RuntimeException();
+        }
+        if (k != null)
+            throw new RuntimeException("WatchKey not expected to be polled");
+
+        // create bar and check we get create event
+        file = top.resolve("bar").createFile();
+        checkExpectedEvent(watcher, ENTRY_CREATE, top.relativize(file));
+        key.reset();
+
+        // Test changing registration to <all> with FILE_TREE modifier
+
+        k = top.register(watcher,
+            new WatchEvent.Kind<?>[]{ ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY },
+            FILE_TREE);
+        if (k != key)
+            throw new RuntimeException("Existing key not returned");
+
+        // modify bar and check we get modify event
+        OutputStream out = file.newOutputStream();
+        try {
+            out.write("Double shot expresso please".getBytes("UTF-8"));
+        } finally {
+            out.close();
+        }
+        checkExpectedEvent(watcher, ENTRY_MODIFY, top.relativize(file));
+        key.reset();
+    }
+
+
+    public static void main(String[] args) throws IOException {
+        if (!System.getProperty("os.name").startsWith("Windows")) {
+            System.out.println("This is Windows-only test at this time!");
+            return;
+        }
+
+        Path dir = TestUtil.createTemporaryDirectory();
+        try {
+            doTest(dir);
+        } finally {
+            TestUtil.removeAll(dir);
+        }
+    }
+}
diff --git a/jdk/test/java/nio/file/WatchService/SensitivityModifier.java b/jdk/test/java/nio/file/WatchService/SensitivityModifier.java
new file mode 100644
index 0000000..62aedee
--- /dev/null
+++ b/jdk/test/java/nio/file/WatchService/SensitivityModifier.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 4313887
+ * @summary Sanity test for Sun-specific sensitivyt level watch event modifier
+ * @library ..
+ * @run main/timeout=330 Basic
+ */
+
+import java.nio.file.*;
+import static java.nio.file.StandardWatchEventKind.*;
+import java.io.OutputStream;
+import java.io.IOException;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+import com.sun.nio.file.SensitivityWatchEventModifier;
+
+public class SensitivityModifier {
+
+    static final Random rand = new Random();
+
+    static void register(Path[] dirs, WatchService watcher) throws IOException {
+        SensitivityWatchEventModifier[] sensitivtives =
+            SensitivityWatchEventModifier.values();
+        for (int i=0; i<dirs.length; i++) {
+            SensitivityWatchEventModifier sensivity =
+                sensitivtives[ rand.nextInt(sensitivtives.length) ];
+            Path dir = dirs[i];
+            dir.register(watcher, new WatchEvent.Kind<?>[]{ ENTRY_MODIFY }, sensivity);
+        }
+    }
+
+    static void doTest(Path top) throws Exception {
+        FileSystem fs = top.getFileSystem();
+        WatchService watcher = fs.newWatchService();
+
+        // create directories and files
+        int nDirs = 5 + rand.nextInt(20);
+        int nFiles = 50 + rand.nextInt(50);
+        Path[] dirs = new Path[nDirs];
+        Path[] files = new Path[nFiles];
+        for (int i=0; i<nDirs; i++) {
+            dirs[i] = top.resolve("dir" + i).createDirectory();
+        }
+        for (int i=0; i<nFiles; i++) {
+            Path dir = dirs[rand.nextInt(nDirs)];
+            files[i] = dir.resolve("file" + i).createFile();
+        }
+
+        // register the directories (random sensitivity)
+        register(dirs, watcher);
+
+        // sleep a bit here to ensure that modification to the first file
+        // can be detected by polling implementations (ie: last modified time
+        // may not change otherwise).
+        try { Thread.sleep(1000); } catch (InterruptedException e) { }
+
+        // modify files and check that events are received
+        for (int i=0; i<10; i++) {
+            Path file = files[rand.nextInt(nFiles)];
+            System.out.println("Modify: " + file);
+            OutputStream out = file.newOutputStream();
+            try {
+                out.write(new byte[100]);
+            } finally {
+                out.close();
+            }
+            System.out.println("Waiting for event...");
+            WatchKey key = watcher.take();
+            WatchEvent<?> event = key.pollEvents().iterator().next();
+            if (event.kind() != ENTRY_MODIFY)
+                throw new RuntimeException("Unexpected event: " + event);
+            Path name = ((WatchEvent<Path>)event).context();
+            if (!name.equals(file.getName()))
+                throw new RuntimeException("Unexpected context: " + name);
+            System.out.println("Event OK");
+
+            // drain events (to avoid interference)
+            do {
+                key.reset();
+                key = watcher.poll(1, TimeUnit.SECONDS);
+            } while (key != null);
+
+            // re-register the directories to force changing their sensitivity
+            // level
+            register(dirs, watcher);
+        }
+
+        // done
+        watcher.close();
+    }
+
+    public static void main(String[] args) throws Exception {
+        Path dir = TestUtil.createTemporaryDirectory();
+        try {
+            doTest(dir);
+        } finally {
+            TestUtil.removeAll(dir);
+        }
+    }
+}
diff --git a/jdk/test/java/nio/file/WatchService/WithSecurityManager.java b/jdk/test/java/nio/file/WatchService/WithSecurityManager.java
new file mode 100644
index 0000000..c227585
--- /dev/null
+++ b/jdk/test/java/nio/file/WatchService/WithSecurityManager.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 4313887
+ * @summary Unit test for Watchable#register's permission checks
+ * @build WithSecurityManager
+ * @run main/othervm WithSecurityManager denyAll.policy - fail
+ * @run main/othervm WithSecurityManager denyAll.policy tree fail
+ * @run main/othervm WithSecurityManager grantDirOnly.policy - pass
+ * @run main/othervm WithSecurityManager grantDirOnly.policy tree fail
+ * @run main/othervm WithSecurityManager grantDirAndOneLevel.policy - pass
+ * @run main/othervm WithSecurityManager grantDirAndOneLevel.policy tree fail
+ * @run main/othervm WithSecurityManager grantDirAndTree.policy - pass
+ * @run main/othervm WithSecurityManager grantDirAndTree.policy tree pass
+ */
+
+import java.nio.file.*;
+import java.io.IOException;
+import com.sun.nio.file.ExtendedWatchEventModifier;
+
+public class WithSecurityManager {
+
+    public static void main(String[] args) throws IOException {
+        String policyFile = args[0];
+        boolean recursive = args[1].equals("tree");
+        boolean expectedToFail = args[2].equals("fail");
+
+        // install security manager with the given policy file
+        String testSrc = System.getProperty("test.src");
+        if (testSrc == null)
+            throw new RuntimeException("This test must be run by jtreg");
+        Path dir = Paths.get(testSrc);
+        System.setProperty("java.security.policy", dir.resolve(policyFile).toString());
+        System.setSecurityManager(new SecurityManager());
+
+        // initialize optional modifier
+        WatchEvent.Modifier[] modifiers;
+        if (recursive) {
+            modifiers = new WatchEvent.Modifier[1];
+            modifiers[0] = ExtendedWatchEventModifier.FILE_TREE;
+        } else {
+            modifiers = new WatchEvent.Modifier[0];
+        }
+
+        // attempt to register directory
+        try {
+            dir.register(dir.getFileSystem().newWatchService(),
+                         new WatchEvent.Kind<?>[]{ StandardWatchEventKind.ENTRY_CREATE },
+                         modifiers);
+            if (expectedToFail)
+                throw new RuntimeException("SecurityException not thrown");
+        } catch (SecurityException e) {
+            if (!expectedToFail)
+                throw e;
+        } catch (UnsupportedOperationException e) {
+            // FILE_TREE modifier only supported on some platforms
+            if (!recursive)
+                throw new RuntimeException(e);
+            System.out.println("FILE_TREE option not supported");
+        }
+    }
+}
diff --git a/jdk/test/java/nio/file/WatchService/denyAll.policy b/jdk/test/java/nio/file/WatchService/denyAll.policy
new file mode 100644
index 0000000..3250094
--- /dev/null
+++ b/jdk/test/java/nio/file/WatchService/denyAll.policy
@@ -0,0 +1,3 @@
+// policy file that does not grant any permissions
+grant {
+};
diff --git a/jdk/test/java/nio/file/WatchService/grantDirAndOneLevel.policy b/jdk/test/java/nio/file/WatchService/grantDirAndOneLevel.policy
new file mode 100644
index 0000000..1a34646
--- /dev/null
+++ b/jdk/test/java/nio/file/WatchService/grantDirAndOneLevel.policy
@@ -0,0 +1,5 @@
+// policy file that grants read access to source directory and its entries
+grant {
+    permission java.io.FilePermission "${test.src}", "read";
+    permission java.io.FilePermission "${test.src}${file.separator}*", "read";
+};
diff --git a/jdk/test/java/nio/file/WatchService/grantDirAndTree.policy b/jdk/test/java/nio/file/WatchService/grantDirAndTree.policy
new file mode 100644
index 0000000..85bc0d0
--- /dev/null
+++ b/jdk/test/java/nio/file/WatchService/grantDirAndTree.policy
@@ -0,0 +1,5 @@
+// policy file that grants read access to source directory and all descendants
+grant {
+    permission java.io.FilePermission "${test.src}", "read";
+    permission java.io.FilePermission "${test.src}${file.separator}-", "read";
+};
diff --git a/jdk/test/java/nio/file/WatchService/grantDirOnly.policy b/jdk/test/java/nio/file/WatchService/grantDirOnly.policy
new file mode 100644
index 0000000..fca1539
--- /dev/null
+++ b/jdk/test/java/nio/file/WatchService/grantDirOnly.policy
@@ -0,0 +1,4 @@
+// policy file that grants read access to source directory
+grant {
+    permission java.io.FilePermission "${test.src}", "read";
+};
diff --git a/jdk/test/java/nio/file/attribute/AclFileAttributeView/Basic.java b/jdk/test/java/nio/file/attribute/AclFileAttributeView/Basic.java
new file mode 100644
index 0000000..3a99607
--- /dev/null
+++ b/jdk/test/java/nio/file/attribute/AclFileAttributeView/Basic.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 4313887
+ * @summary Unit test for java.nio.file.attribute.AclFileAttribueView
+ * @library ../..
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.io.IOException;
+import java.util.*;
+
+import static java.nio.file.attribute.AclEntryType.*;
+import static java.nio.file.attribute.AclEntryPermission.*;
+import static java.nio.file.attribute.AclEntryFlag.*;
+
+public class Basic {
+
+    static void printAcl(List<AclEntry> acl) {
+        for (AclEntry entry: acl) {
+            System.out.format("  %s%n", entry);
+        }
+    }
+
+    // sanity check read and writing ACL
+    static void testReadWrite(Path dir) throws IOException {
+        Path file = dir.resolve("foo");
+        if (file.notExists())
+            file.createFile();
+
+        AclFileAttributeView view = file
+            .getFileAttributeView(AclFileAttributeView.class);
+
+        // print existing ACL
+        List<AclEntry> acl = view.getAcl();
+        System.out.println(" -- current ACL --");
+        printAcl(acl);
+
+        // insert entry to grant owner read access
+        UserPrincipal owner = view.getOwner();
+        AclEntry entry = AclEntry.newBuilder()
+            .setType(ALLOW)
+            .setPrincipal(owner)
+            .setPermissions(READ_DATA, READ_ATTRIBUTES)
+            .build();
+        System.out.println(" -- insert (entry 0) --");
+        System.out.format("  %s%n", entry);
+        acl.add(0, entry);
+        view.setAcl(acl);
+
+        // re-ACL and check entry
+        List<AclEntry> newacl = view.getAcl();
+        System.out.println(" -- current ACL --");
+        printAcl(acl);
+        if (!newacl.get(0).equals(entry)) {
+            throw new RuntimeException("Entry 0 is not expected");
+        }
+
+        // if PosixFileAttributeView then repeat test with OWNER@
+        if (file.getFileStore().supportsFileAttributeView("posix")) {
+            owner = file.getFileSystem().getUserPrincipalLookupService()
+                .lookupPrincipalByName("OWNER@");
+            entry = AclEntry.newBuilder(entry).setPrincipal(owner).build();
+
+            System.out.println(" -- replace (entry 0) --");
+            System.out.format("  %s%n", entry);
+
+            acl.set(0, entry);
+            view.setAcl(acl);
+            newacl = view.getAcl();
+            System.out.println(" -- current ACL --");
+            printAcl(acl);
+            if (!newacl.get(0).equals(entry)) {
+                throw new RuntimeException("Entry 0 is not expected");
+            }
+        }
+    }
+
+    static FileAttribute<List<AclEntry>> asAclAttribute(final List<AclEntry> acl) {
+        return new FileAttribute<List<AclEntry>>() {
+            public String name() { return "acl:acl"; }
+            public List<AclEntry> value() { return acl; }
+        };
+    }
+
+    static void assertEquals(List<AclEntry> actual, List<AclEntry> expected) {
+        if (!actual.equals(expected)) {
+            System.err.format("Actual: %s\n", actual);
+            System.err.format("Expected: %s\n", expected);
+            throw new RuntimeException("ACL not expected");
+        }
+    }
+
+    // sanity check create a file or directory with initial ACL
+    static void testCreateFile(Path dir) throws IOException {
+        UserPrincipal user = Attributes.getOwner(dir);
+
+        // create file with initial ACL
+        System.out.println("-- create file with initial ACL --");
+        Path file = dir.resolve("gus");
+        List<AclEntry> fileAcl = Arrays.asList(
+            AclEntry.newBuilder()
+                .setType(AclEntryType.ALLOW)
+                .setPrincipal(user)
+                .setPermissions(SYNCHRONIZE, READ_DATA, WRITE_DATA,
+                    READ_ATTRIBUTES, READ_ACL, WRITE_ATTRIBUTES, DELETE)
+                .build());
+        file.createFile(asAclAttribute(fileAcl));
+        assertEquals(Attributes.getAcl(file), fileAcl);
+
+        // create directory with initial ACL
+        System.out.println("-- create directory with initial ACL --");
+        Path subdir = dir.resolve("stuff");
+        List<AclEntry> dirAcl = Arrays.asList(
+            AclEntry.newBuilder()
+                .setType(AclEntryType.ALLOW)
+                .setPrincipal(user)
+                .setPermissions(SYNCHRONIZE, ADD_FILE, DELETE)
+                .build(),
+            AclEntry.newBuilder(fileAcl.get(0))
+                .setFlags(FILE_INHERIT)
+                .build());
+        subdir.createDirectory(asAclAttribute(dirAcl));
+        assertEquals(Attributes.getAcl(subdir), dirAcl);
+    }
+
+    public static void main(String[] args) throws IOException {
+        Path dir = TestUtil.createTemporaryDirectory();
+        try {
+            if (!dir.getFileStore().supportsFileAttributeView("acl")) {
+                System.out.println("ACLs not supported - test skipped!");
+                return;
+            }
+            testReadWrite(dir);
+
+            // only currently feasible on Windows
+            if (System.getProperty("os.name").startsWith("Windows"))
+                testCreateFile(dir);
+
+        } finally {
+            TestUtil.removeAll(dir);
+        }
+    }
+}
diff --git a/jdk/test/java/nio/file/attribute/Attributes/Basic.java b/jdk/test/java/nio/file/attribute/Attributes/Basic.java
new file mode 100644
index 0000000..8dfde80
--- /dev/null
+++ b/jdk/test/java/nio/file/attribute/Attributes/Basic.java
@@ -0,0 +1,254 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 4313887
+ * @summary Unit test for java.nio.file.attribute.Attributes
+ * @library ../..
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.io.IOException;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Exercises getAttribute/setAttribute/readAttributes methods.
+ */
+
+public class Basic {
+
+    static void assertTrue(boolean okay) {
+        if (!okay)
+            throw new RuntimeException("Assertion Failed");
+    }
+
+    static void checkEqual(Object o1, Object o2) {
+        if (o1 == null) {
+            assertTrue(o2 == null);
+        } else {
+            assertTrue (o1.equals(o2));
+        }
+    }
+
+    // Exercise getAttribute/setAttribute/readAttributes on basic attributes
+    static void checkBasicAttributes(FileRef file, BasicFileAttributes attrs)
+        throws IOException
+    {
+        // getAttribute
+        checkEqual(attrs.size(), Attributes.getAttribute(file, "size"));
+        checkEqual(attrs.lastModifiedTime(),
+                   Attributes.getAttribute(file, "basic:lastModifiedTime"));
+        checkEqual(attrs.lastAccessTime(),
+                   Attributes.getAttribute(file, "lastAccessTime"));
+        checkEqual(attrs.creationTime(),
+                   Attributes.getAttribute(file, "basic:creationTime"));
+        assertTrue((Boolean)Attributes.getAttribute(file, "isRegularFile"));
+        assertTrue(!(Boolean)Attributes.getAttribute(file, "basic:isDirectory"));
+        assertTrue(!(Boolean)Attributes.getAttribute(file, "isSymbolicLink"));
+        assertTrue(!(Boolean)Attributes.getAttribute(file, "basic:isOther"));
+        checkEqual(attrs.linkCount(),
+                   (Integer)Attributes.getAttribute(file, "linkCount"));
+        checkEqual(attrs.fileKey(), Attributes.getAttribute(file, "basic:fileKey"));
+
+        // setAttribute
+        if (attrs.resolution() == TimeUnit.MILLISECONDS) {
+            long modTime = attrs.lastModifiedTime();
+            Attributes.setAttribute(file, "basic:lastModifiedTime", 0L);
+            assertTrue(Attributes.readBasicFileAttributes(file).lastModifiedTime() == 0L);
+            Attributes.setAttribute(file, "lastModifiedTime", modTime);
+            assertTrue(Attributes.readBasicFileAttributes(file).lastModifiedTime() == modTime);
+        }
+
+        // readAttributes
+        Map<String,?> map;
+        map = Attributes.readAttributes(file, "*");
+        assertTrue(map.size() >= 11);
+        checkEqual(attrs.isRegularFile(), map.get("isRegularFile")); // check one
+
+        map = Attributes.readAttributes(file, "basic:*");
+        assertTrue(map.size() >= 11);
+        checkEqual(attrs.lastAccessTime(), map.get("lastAccessTime")); // check one
+
+        map = Attributes.readAttributes(file, "size,lastModifiedTime");
+        assertTrue(map.size() == 2);
+        checkEqual(attrs.size(), map.get("size"));
+        checkEqual(attrs.lastModifiedTime(), map.get("lastModifiedTime"));
+
+        map = Attributes.readAttributes(file,
+            "basic:lastModifiedTime,lastAccessTime,linkCount,ShouldNotExist");
+        assertTrue(map.size() == 3);
+        checkEqual(attrs.lastModifiedTime(), map.get("lastModifiedTime"));
+        checkEqual(attrs.lastAccessTime(), map.get("lastAccessTime"));
+        checkEqual(attrs.lastAccessTime(), map.get("lastAccessTime"));
+    }
+
+    // Exercise getAttribute/setAttribute/readAttributes on posix attributes
+    static void checkPosixAttributes(FileRef file, PosixFileAttributes attrs)
+        throws IOException
+    {
+        checkBasicAttributes(file, attrs);
+
+        // getAttribute
+        checkEqual(attrs.permissions(),
+                   Attributes.getAttribute(file, "posix:permissions"));
+        checkEqual(attrs.owner(),
+                   Attributes.getAttribute(file, "posix:owner"));
+        checkEqual(attrs.group(),
+                   Attributes.getAttribute(file, "posix:group"));
+
+        // setAttribute
+        Set<PosixFilePermission> orig = attrs.permissions();
+        Set<PosixFilePermission> newPerms = new HashSet<PosixFilePermission>(orig);
+        newPerms.remove(PosixFilePermission.OTHERS_READ);
+        newPerms.remove(PosixFilePermission.OTHERS_WRITE);
+        newPerms.remove(PosixFilePermission.OTHERS_EXECUTE);
+        Attributes.setAttribute(file, "posix:permissions", newPerms);
+        checkEqual(Attributes.readPosixFileAttributes(file).permissions(), newPerms);
+        Attributes.setAttribute(file, "posix:permissions", orig);
+        checkEqual(Attributes.readPosixFileAttributes(file).permissions(), orig);
+        Attributes.setAttribute(file, "posix:owner", attrs.owner());
+        Attributes.setAttribute(file, "posix:group", attrs.group());
+
+        // readAttributes
+        Map<String,?> map;
+        map = Attributes.readAttributes(file, "posix:*");
+        assertTrue(map.size() >= 14);
+        checkEqual(attrs.permissions(), map.get("permissions")); // check one
+
+        map = Attributes.readAttributes(file, "posix:size,owner,ShouldNotExist");
+        assertTrue(map.size() == 2);
+        checkEqual(attrs.size(), map.get("size"));
+        checkEqual(attrs.owner(), map.get("owner"));
+    }
+
+    // Exercise getAttribute/setAttribute/readAttributes on unix attributes
+    static void checkUnixAttributes(FileRef file) throws IOException {
+        // getAttribute
+        int mode = (Integer)Attributes.getAttribute(file, "unix:mode");
+        long ino = (Long)Attributes.getAttribute(file, "unix:ino");
+        long dev = (Long)Attributes.getAttribute(file, "unix:dev");
+        long rdev = (Long)Attributes.getAttribute(file, "unix:rdev");
+        int uid = (Integer)Attributes.getAttribute(file, "unix:uid");
+        int gid = (Integer)Attributes.getAttribute(file, "unix:gid");
+        long ctime = (Long)Attributes.getAttribute(file, "unix:ctime");
+
+        // readAttributes
+        Map<String,?> map;
+        map = Attributes.readAttributes(file, "unix:*");
+        assertTrue(map.size() >= 21);
+
+        map = Attributes.readAttributes(file, "unix:size,uid,gid,ShouldNotExist");
+        assertTrue(map.size() == 3);
+        checkEqual(map.get("size"),
+                   Attributes.readBasicFileAttributes(file).size());
+    }
+
+    // Exercise getAttribute/setAttribute/readAttributes on dos attributes
+    static void checkDosAttributes(FileRef file, DosFileAttributes attrs)
+        throws IOException
+    {
+        checkBasicAttributes(file, attrs);
+
+        // getAttribute
+        checkEqual(attrs.isReadOnly(),
+                   Attributes.getAttribute(file, "dos:readonly"));
+        checkEqual(attrs.isHidden(),
+                   Attributes.getAttribute(file, "dos:hidden"));
+        checkEqual(attrs.isSystem(),
+                   Attributes.getAttribute(file, "dos:system"));
+        checkEqual(attrs.isArchive(),
+                   Attributes.getAttribute(file, "dos:archive"));
+
+        // setAttribute
+        boolean value;
+
+        value = attrs.isReadOnly();
+        Attributes.setAttribute(file, "dos:readonly", !value);
+        checkEqual(Attributes.readDosFileAttributes(file).isReadOnly(), !value);
+        Attributes.setAttribute(file, "dos:readonly", value);
+        checkEqual(Attributes.readDosFileAttributes(file).isReadOnly(), value);
+
+        value = attrs.isHidden();
+        Attributes.setAttribute(file, "dos:hidden", !value);
+        checkEqual(Attributes.readDosFileAttributes(file).isHidden(), !value);
+        Attributes.setAttribute(file, "dos:hidden", value);
+        checkEqual(Attributes.readDosFileAttributes(file).isHidden(), value);
+
+        value = attrs.isSystem();
+        Attributes.setAttribute(file, "dos:system", !value);
+        checkEqual(Attributes.readDosFileAttributes(file).isSystem(), !value);
+        Attributes.setAttribute(file, "dos:system", value);
+        checkEqual(Attributes.readDosFileAttributes(file).isSystem(), value);
+
+        value = attrs.isArchive();
+        Attributes.setAttribute(file, "dos:archive", !value);
+        checkEqual(Attributes.readDosFileAttributes(file).isArchive(), !value);
+        Attributes.setAttribute(file, "dos:archive", value);
+        checkEqual(Attributes.readDosFileAttributes(file).isArchive(), value);
+
+        // readAttributes
+        Map<String,?> map;
+        map = Attributes.readAttributes(file, "dos:*");
+        assertTrue(map.size() >= 15);
+        checkEqual(attrs.isReadOnly(), map.get("readonly")); // check one
+
+        map = Attributes.readAttributes(file, "dos:size,hidden,ShouldNotExist");
+        assertTrue(map.size() == 2);
+        checkEqual(attrs.size(), map.get("size"));
+        checkEqual(attrs.isHidden(), map.get("hidden"));
+    }
+
+    static void doTests(Path dir) throws IOException {
+        Path file = dir.resolve("foo").createFile();
+        FileStore store = file.getFileStore();
+        try {
+            checkBasicAttributes(file,
+                Attributes.readBasicFileAttributes(file));
+
+            if (store.supportsFileAttributeView("posix"))
+                checkPosixAttributes(file,
+                    Attributes.readPosixFileAttributes(file));
+
+            if (store.supportsFileAttributeView("unix"))
+                checkUnixAttributes(file);
+
+            if (store.supportsFileAttributeView("dos"))
+                checkDosAttributes(file,
+                    Attributes.readDosFileAttributes(file));
+        } finally {
+            file.delete();
+        }
+    }
+
+
+    public static void main(String[] args) throws IOException {
+        Path dir = TestUtil.createTemporaryDirectory();
+        try {
+            doTests(dir);
+        } finally {
+            TestUtil.removeAll(dir);
+        }
+    }
+}
diff --git a/jdk/test/java/nio/file/attribute/BasicFileAttributeView/Basic.java b/jdk/test/java/nio/file/attribute/BasicFileAttributeView/Basic.java
new file mode 100644
index 0000000..1cc192f
--- /dev/null
+++ b/jdk/test/java/nio/file/attribute/BasicFileAttributeView/Basic.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 4313887
+ * @summary Unit test for java.nio.file.attribute.BasicFileAttributeView
+ * @library ../..
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import java.io.*;
+
+public class Basic {
+
+    static void check(boolean okay, String msg) {
+        if (!okay)
+            throw new RuntimeException(msg);
+    }
+
+    static void checkAttributesOfDirectory(Path dir)
+        throws IOException
+    {
+        BasicFileAttributes attrs = Attributes.readBasicFileAttributes(dir);
+        check(attrs.isDirectory(), "is a directory");
+        check(!attrs.isRegularFile(), "is not a regular file");
+        check(!attrs.isSymbolicLink(), "is not a link");
+        check(!attrs.isOther(), "is not other");
+        check(attrs.linkCount() >= 1, "should be at least 1");
+
+        // last-modified-time should match java.io.File
+        if (attrs.resolution() == TimeUnit.MILLISECONDS) {
+            File f = new File(dir.toString());
+            check(f.lastModified() == attrs.lastModifiedTime(),
+                "last-modified time should be the same");
+        }
+    }
+
+    static void checkAttributesOfFile(Path dir, Path file)
+        throws IOException
+    {
+        BasicFileAttributes attrs = Attributes.readBasicFileAttributes(file);
+        check(attrs.isRegularFile(), "is a regular file");
+        check(!attrs.isDirectory(), "is not a directory");
+        check(!attrs.isSymbolicLink(), "is not a link");
+        check(!attrs.isOther(), "is not other");
+        check(attrs.linkCount() >= 1, "should be at least 1");
+
+        // size and last-modified-time should match java.io.File
+        File f = new File(file.toString());
+        check(f.length() == attrs.size(), "size should be the same");
+        if (attrs.resolution() == TimeUnit.MILLISECONDS) {
+            check(f.lastModified() == attrs.lastModifiedTime(),
+                "last-modified time should be the same");
+        }
+
+        // copy last-modified time and file create time from directory to file,
+        // re-read attribtues, and check they match
+        BasicFileAttributeView view =
+            file.getFileAttributeView(BasicFileAttributeView.class);
+        BasicFileAttributes dirAttrs = Attributes.readBasicFileAttributes(dir);
+        view.setTimes(dirAttrs.lastModifiedTime(), null, null, dirAttrs.resolution());
+        if (dirAttrs.creationTime() != -1L) {
+            view.setTimes(null, null, dirAttrs.creationTime(), dirAttrs.resolution());
+        }
+        attrs = view.readAttributes();
+        check(attrs.lastModifiedTime() == dirAttrs.lastModifiedTime(),
+            "last-modified time should be equal");
+        if (dirAttrs.creationTime() != -1L) {
+            check(attrs.creationTime() == dirAttrs.creationTime(),
+                "create time should be the same");
+        }
+
+        // security tests
+        check (!(attrs instanceof PosixFileAttributes),
+            "should not be able to cast to PosixFileAttributes");
+    }
+
+    static void checkAttributesOfLink(Path link)
+        throws IOException
+    {
+        BasicFileAttributes attrs = Attributes
+            .readBasicFileAttributes(link, LinkOption.NOFOLLOW_LINKS);
+        check(attrs.isSymbolicLink(), "is a link");
+        check(!attrs.isDirectory(), "is a directory");
+        check(!attrs.isRegularFile(), "is not a regular file");
+        check(!attrs.isOther(), "is not other");
+        check(attrs.linkCount() >= 1, "should be at least 1");
+    }
+
+    static void attributeReadWriteTests(Path dir)
+        throws IOException
+    {
+        // create file
+        Path file = dir.resolve("foo");
+        OutputStream out = file.newOutputStream();
+        try {
+            out.write("this is not an empty file".getBytes("UTF-8"));
+        } finally {
+            out.close();
+        }
+
+        // check attributes of directory and file
+        checkAttributesOfDirectory(dir);
+        checkAttributesOfFile(dir, file);
+
+        // symbolic links may be supported
+        Path link = dir.resolve("link");
+        try {
+            link.createSymbolicLink( file );
+        } catch (UnsupportedOperationException x) {
+            return;
+        } catch (IOException x) {
+            return;
+        }
+        checkAttributesOfLink(link);
+    }
+
+    public static void main(String[] args) throws IOException {
+        // create temporary directory to run tests
+        Path dir = TestUtil.createTemporaryDirectory();
+        try {
+            attributeReadWriteTests(dir);
+        } finally {
+            TestUtil.removeAll(dir);
+        }
+    }
+}
diff --git a/jdk/test/java/nio/file/attribute/DosFileAttributeView/Basic.java b/jdk/test/java/nio/file/attribute/DosFileAttributeView/Basic.java
new file mode 100644
index 0000000..3c8a296
--- /dev/null
+++ b/jdk/test/java/nio/file/attribute/DosFileAttributeView/Basic.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 4313887
+ * @summary Unit test for java.nio.file.attribute.DosFileAttributeView
+ * @library ../..
+ */
+
+import java.nio.file.*;
+import static java.nio.file.LinkOption.*;
+import java.nio.file.attribute.*;
+import java.util.*;
+import java.io.IOException;
+
+public class Basic {
+
+    static void check(boolean okay) {
+        if (!okay)
+            throw new RuntimeException("Test failed");
+    }
+
+    // exercise each setter/getter method, leaving all attributes unset
+    static void testAttributes(DosFileAttributeView view) throws IOException {
+        view.setReadOnly(true);
+        check(view.readAttributes().isReadOnly());
+        view.setReadOnly(false);
+        check(!view.readAttributes().isReadOnly());
+        view.setHidden(true);
+        check(view.readAttributes().isHidden());
+        view.setHidden(false);
+        check(!view.readAttributes().isHidden());
+        view.setArchive(true);
+        check(view.readAttributes().isArchive());
+        view.setArchive(false);
+        check(!view.readAttributes().isArchive());
+        view.setSystem(true);
+        check(view.readAttributes().isSystem());
+        view.setSystem(false);
+        check(!view.readAttributes().isSystem());
+    }
+
+    // set the value of all attributes
+    static void setAll(DosFileAttributeView view, boolean value)
+        throws IOException
+    {
+        view.setReadOnly(value);
+        view.setHidden(value);
+        view.setArchive(value);
+        view.setSystem(value);
+    }
+
+    // read and write FAT attributes
+    static void readWriteTests(Path dir) throws IOException {
+
+        // create "foo" and test that we can read/write each FAT attribute
+        Path file = dir.resolve("foo");
+        file.newOutputStream().close();
+        try {
+            testAttributes(file
+                .getFileAttributeView(DosFileAttributeView.class));
+
+            // Following tests use a symbolic link so skip if not supported
+            if (!TestUtil.supportsLinks(dir))
+                return;
+
+            Path link = dir.resolve("link").createSymbolicLink(file);
+
+            // test following links
+            testAttributes(link
+                .getFileAttributeView(DosFileAttributeView.class));
+
+            // test not following links
+            try {
+                try {
+                    testAttributes(link
+                        .getFileAttributeView(DosFileAttributeView.class, NOFOLLOW_LINKS));
+                } catch (IOException x) {
+                    // access to link attributes not supported
+                    return;
+                }
+
+                // set all attributes on link
+                // run test on target of link (which leaves them all un-set)
+                // check that attributes of link remain all set
+                setAll(link
+                    .getFileAttributeView(DosFileAttributeView.class, NOFOLLOW_LINKS), true);
+                testAttributes(link
+                    .getFileAttributeView(DosFileAttributeView.class));
+                DosFileAttributes attrs = Attributes.readDosFileAttributes(link, NOFOLLOW_LINKS);
+                check(attrs.isReadOnly());
+                check(attrs.isHidden());
+                check(attrs.isArchive());
+                check(attrs.isSystem());
+                setAll(link
+                    .getFileAttributeView(DosFileAttributeView.class, NOFOLLOW_LINKS), false);
+
+                // set all attributes on target
+                // run test on link (which leaves them all un-set)
+                // check that attributes of target remain all set
+                setAll(link
+                    .getFileAttributeView(DosFileAttributeView.class), true);
+                testAttributes(link
+                    .getFileAttributeView(DosFileAttributeView.class, NOFOLLOW_LINKS));
+                attrs = Attributes.readDosFileAttributes(link);
+                check(attrs.isReadOnly());
+                check(attrs.isHidden());
+                check(attrs.isArchive());
+                check(attrs.isSystem());
+                setAll(link
+                    .getFileAttributeView(DosFileAttributeView.class), false);
+            } finally {
+                TestUtil.deleteUnchecked(link);
+            }
+        } finally {
+            TestUtil.deleteUnchecked(file);
+        }
+    }
+
+    public static void main(String[] args) throws IOException {
+        // create temporary directory to run tests
+        Path dir = TestUtil.createTemporaryDirectory();
+
+        try {
+            // skip test if DOS file attributes not supported
+            if (!dir.getFileStore().supportsFileAttributeView("dos")) {
+                System.out.println("DOS file attribute not supported.");
+                return;
+            }
+            readWriteTests(dir);
+        } finally {
+            TestUtil.removeAll(dir);
+        }
+    }
+}
diff --git a/jdk/test/java/nio/file/attribute/FileStoreAttributeView/Basic.java b/jdk/test/java/nio/file/attribute/FileStoreAttributeView/Basic.java
new file mode 100644
index 0000000..993e8c1
--- /dev/null
+++ b/jdk/test/java/nio/file/attribute/FileStoreAttributeView/Basic.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 4313887
+ * @summary Unit test for java.nio.file.attribute.FileStoreAttributeView
+ * @library ../..
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.io.File;
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * Simple unit test for FileStoreAttributeView that checks that the disk space
+ * attribtues are "close" to the equivalent values reported by java.io.File.
+ */
+
+public class Basic {
+
+    static final long K = 1024L;
+    static final long G = 1024L * 1024L * 1024L;
+
+    /**
+     * Print out the disk space information for the given file system
+     */
+    static void printFileStore(FileStore fs) throws IOException {
+        FileStoreSpaceAttributeView view =
+            fs.getFileStoreAttributeView(FileStoreSpaceAttributeView.class);
+        FileStoreSpaceAttributes attrs = view.readAttributes();
+
+        long total = attrs.totalSpace() / K;
+        long used = (attrs.totalSpace() - attrs.unallocatedSpace()) / K;
+        long avail = attrs.usableSpace() / K;
+
+        String s = fs.toString();
+        if (s.length() > 20) {
+            System.out.println(s);
+            s = "";
+        }
+        System.out.format("%-20s %12d %12d %12d\n", s, total, used, avail);
+    }
+
+    /**
+     * Check that two values are within 1GB of each other
+     */
+    static void checkWithin1GB(long value1, long value2) {
+        long diff = Math.abs(value1 - value2);
+        if (diff > G)
+            throw new RuntimeException("values differ by more than 1GB");
+    }
+
+    /**
+     * Check disk space on the file system of the given file
+     */
+    static void checkSpace(Path file) throws IOException {
+        System.out.println(" -- check space -- ");
+        System.out.println(file);
+
+        FileStore fs = file.getFileStore();
+        System.out.format("Filesystem: %s\n", fs);
+
+        // get values reported by java.io.File
+        File f = new File(file.toString());
+        long total = f.getTotalSpace();
+        long free = f.getFreeSpace();
+        long usable = f.getUsableSpace();
+        System.out.println("java.io.File");
+        System.out.format("    Total: %d\n", total);
+        System.out.format("     Free: %d\n", free);
+        System.out.format("   Usable: %d\n", usable);
+
+        // get values reported by the FileStoreSpaceAttributeView
+        FileStoreSpaceAttributes attrs = fs
+            .getFileStoreAttributeView(FileStoreSpaceAttributeView.class)
+            .readAttributes();
+        System.out.println("java.nio.file.FileStoreSpaceAttributeView:");
+        System.out.format("    Total: %d\n", attrs.totalSpace());
+        System.out.format("     Free: %d\n", attrs.unallocatedSpace());
+        System.out.format("   Usable: %d\n", attrs.usableSpace());
+
+        // check values are "close"
+        checkWithin1GB(total, attrs.totalSpace());
+        checkWithin1GB(free, attrs.unallocatedSpace());
+        checkWithin1GB(usable, attrs.usableSpace());
+
+        // get values by name (and in bulk)
+        FileStoreAttributeView view = fs.getFileStoreAttributeView("space");
+        checkWithin1GB(total, (Long)view.getAttribute("totalSpace"));
+        checkWithin1GB(free, (Long)view.getAttribute("unallocatedSpace"));
+        checkWithin1GB(usable, (Long)view.getAttribute("usableSpace"));
+        Map<String,?> map = view.readAttributes("*");
+        checkWithin1GB(total, (Long)map.get("totalSpace"));
+        checkWithin1GB(free, (Long)map.get("unallocatedSpace"));
+        checkWithin1GB(usable, (Long)map.get("usableSpace"));
+        map = view.readAttributes("totalSpace", "unallocatedSpace", "usableSpace");
+        checkWithin1GB(total, (Long)map.get("totalSpace"));
+        checkWithin1GB(free, (Long)map.get("unallocatedSpace"));
+        checkWithin1GB(usable, (Long)map.get("usableSpace"));
+    }
+
+    /**
+     * Check (Windows-specific) volume attributes
+     */
+    static void checkVolumeAttributes() throws IOException {
+        System.out.println(" -- volumes -- ");
+        for (FileStore store: FileSystems.getDefault().getFileStores()) {
+            FileStoreAttributeView view = store.getFileStoreAttributeView("volume");
+            if (view == null)
+                continue;
+            Map<String,?> attrs = view.readAttributes("*");
+            int vsn = (Integer)attrs.get("vsn");
+            boolean compressed = (Boolean)attrs.get("compressed");
+            boolean removable = (Boolean)attrs.get("removable");
+            boolean cdrom = (Boolean)attrs.get("cdrom");
+            String type;
+            if (removable) type = "removable";
+            else if (cdrom) type = "cdrom";
+            else type = "unknown";
+            System.out.format("%s (%s) vsn:%x compressed:%b%n", store.name(),
+                type, vsn, compressed);
+        }
+
+    }
+
+    public static void main(String[] args) throws IOException {
+        // print out the disk space information for all file systems
+        FileSystem fs = FileSystems.getDefault();
+        for (FileStore store: fs.getFileStores()) {
+            printFileStore(store);
+        }
+
+        Path dir = TestUtil.createTemporaryDirectory();
+        try {
+            // check space using directory
+            checkSpace(dir);
+
+            // check space using file
+            Path file = dir.resolve("foo").createFile();
+            checkSpace(file);
+
+            // volume attributes (Windows specific)
+            checkVolumeAttributes();
+
+        } finally {
+            TestUtil.removeAll(dir);
+        }
+    }
+}
diff --git a/jdk/test/java/nio/file/attribute/PosixFileAttributeView/Basic.java b/jdk/test/java/nio/file/attribute/PosixFileAttributeView/Basic.java
new file mode 100644
index 0000000..2ee059b
--- /dev/null
+++ b/jdk/test/java/nio/file/attribute/PosixFileAttributeView/Basic.java
@@ -0,0 +1,398 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 4313887
+ * @summary Unit test for java.nio.file.attribute.PosixFileAttributeView
+ * @library ../..
+ */
+
+import java.nio.file.*;
+import static java.nio.file.LinkOption.*;
+import java.nio.file.attribute.*;
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * Unit test for PosixFileAttributeView, passing silently if this attribute
+ * view is not available.
+ */
+
+public class Basic {
+
+    /**
+     * Use view to update permission to the given mode and check that the
+     * permissions have been updated.
+     */
+    static void testPermissions(PosixFileAttributeView view, String mode)
+        throws IOException
+    {
+        System.out.format("change mode: %s\n", mode);
+        Set<PosixFilePermission> perms = PosixFilePermissions.fromString(mode);
+
+        // change permissions and re-read them.
+        view.setPermissions(perms);
+        Set<PosixFilePermission> current = view.readAttributes().permissions();
+        if (!current.equals(perms)) {
+            throw new RuntimeException("Actual permissions: " +
+                PosixFilePermissions.toString(current) + ", expected: " +
+                PosixFilePermissions.toString(perms));
+        }
+
+        // repeat test using setAttribute/getAttribute
+        view.setAttribute("permissions", perms);
+        current = (Set<PosixFilePermission>)view.getAttribute("permissions");
+        if (!current.equals(perms)) {
+            throw new RuntimeException("Actual permissions: " +
+                PosixFilePermissions.toString(current) + ", expected: " +
+                PosixFilePermissions.toString(perms));
+        }
+    }
+
+    /**
+     * Check that the actual permissions of a file match or make it more
+     * secure than requested
+     */
+    static void checkSecure(Set<PosixFilePermission> requested,
+                            Set<PosixFilePermission> actual)
+    {
+        for (PosixFilePermission perm: actual) {
+            if (!requested.contains(perm)) {
+                throw new RuntimeException("Actual permissions: " +
+                    PosixFilePermissions.toString(actual) + ", requested: " +
+                    PosixFilePermissions.toString(requested) +
+                    " - file is less secure than requested");
+            }
+        }
+    }
+
+    /**
+     * Create file with given mode and check that the file is created with a
+     * mode that is not less secure
+     */
+    static void createWithPermissions(Path file,
+                                      String mode)
+        throws IOException
+    {
+        Set<PosixFilePermission> requested = PosixFilePermissions.fromString(mode);
+        FileAttribute<Set<PosixFilePermission>> attr =
+            PosixFilePermissions.asFileAttribute(requested);
+        System.out.format("create file with mode: %s\n", mode);
+
+        EnumSet<StandardOpenOption> options = EnumSet.of(StandardOpenOption.CREATE_NEW,
+            StandardOpenOption.WRITE);
+        file.newOutputStream(options, attr).close();
+        try {
+            checkSecure(requested,  file
+                .getFileAttributeView(PosixFileAttributeView.class)
+                .readAttributes()
+                .permissions());
+        } finally {
+            file.delete(false);
+        }
+
+        System.out.format("create directory with mode: %s\n", mode);
+        file.createDirectory(attr);
+        try {
+            checkSecure(requested,  file
+                .getFileAttributeView(PosixFileAttributeView.class)
+                .readAttributes()
+                .permissions());
+        } finally {
+            file.delete(false);
+        }
+    }
+
+    /**
+     * Test the setPermissions/permissions methods.
+     */
+    static void permissionTests(Path dir)
+        throws IOException
+    {
+        System.out.println("-- Permission Tests  --");
+
+        // create file and test updating and reading its permissions
+        Path file = dir.resolve("foo");
+        System.out.format("create %s\n", file);
+        file.newOutputStream().close();
+        try {
+            // get initial permissions so that we can restore them later
+            PosixFileAttributeView view = file
+                .getFileAttributeView(PosixFileAttributeView.class);
+            Set<PosixFilePermission> save = view.readAttributes()
+                .permissions();
+
+            // test various modes
+            try {
+                testPermissions(view, "---------");
+                testPermissions(view, "r--------");
+                testPermissions(view, "-w-------");
+                testPermissions(view, "--x------");
+                testPermissions(view, "rwx------");
+                testPermissions(view, "---r-----");
+                testPermissions(view, "----w----");
+                testPermissions(view, "-----x---");
+                testPermissions(view, "---rwx---");
+                testPermissions(view, "------r--");
+                testPermissions(view, "-------w-");
+                testPermissions(view, "--------x");
+                testPermissions(view, "------rwx");
+                testPermissions(view, "r--r-----");
+                testPermissions(view, "r--r--r--");
+                testPermissions(view, "rw-rw----");
+                testPermissions(view, "rwxrwx---");
+                testPermissions(view, "rw-rw-r--");
+                testPermissions(view, "r-xr-x---");
+                testPermissions(view, "r-xr-xr-x");
+                testPermissions(view, "rwxrwxrwx");
+            } finally {
+                view.setPermissions(save);
+            }
+        } finally {
+            file.delete(false);
+        }
+
+        // create link (to file that doesn't exist) and test reading of
+        // permissions
+        if (TestUtil.supportsLinks(dir)) {
+            Path link = dir.resolve("link");
+            System.out.format("create link %s\n", link);
+            link.createSymbolicLink(file);
+            try {
+                PosixFileAttributes attrs = Attributes
+                    .readPosixFileAttributes(link, NOFOLLOW_LINKS);
+                if (!attrs.isSymbolicLink()) {
+                    throw new RuntimeException("not a link");
+                }
+            } finally {
+                link.delete(false);
+            }
+        }
+
+        System.out.println("OKAY");
+    }
+
+    /**
+     * Test creating a file and directory with initial permissios
+     */
+    static void createTests(Path dir)
+        throws IOException
+    {
+        System.out.println("-- Create Tests  --");
+
+        Path file = dir.resolve("foo");
+
+        createWithPermissions(file, "---------");
+        createWithPermissions(file, "r--------");
+        createWithPermissions(file, "-w-------");
+        createWithPermissions(file, "--x------");
+        createWithPermissions(file, "rwx------");
+        createWithPermissions(file, "---r-----");
+        createWithPermissions(file, "----w----");
+        createWithPermissions(file, "-----x---");
+        createWithPermissions(file, "---rwx---");
+        createWithPermissions(file, "------r--");
+        createWithPermissions(file, "-------w-");
+        createWithPermissions(file, "--------x");
+        createWithPermissions(file, "------rwx");
+        createWithPermissions(file, "r--r-----");
+        createWithPermissions(file, "r--r--r--");
+        createWithPermissions(file, "rw-rw----");
+        createWithPermissions(file, "rwxrwx---");
+        createWithPermissions(file, "rw-rw-r--");
+        createWithPermissions(file, "r-xr-x---");
+        createWithPermissions(file, "r-xr-xr-x");
+        createWithPermissions(file, "rwxrwxrwx");
+
+        System.out.println("OKAY");
+    }
+
+    /**
+     * Test setOwner/setGroup methods - this test simply exercises the
+     * methods to avoid configuration.
+     */
+    static void ownerTests(Path dir)
+        throws IOException
+    {
+        System.out.println("-- Owner Tests  --");
+
+        Path file = dir.resolve("gus");
+        System.out.format("create %s\n", file);
+
+        file.newOutputStream().close();
+        try {
+
+            // read attributes of directory to get owner/group
+            PosixFileAttributeView view = file
+                .getFileAttributeView(PosixFileAttributeView.class);
+            PosixFileAttributes attrs = view.readAttributes();
+
+            // set to existing owner/group
+            view.setOwner(attrs.owner());
+            view.setGroup(attrs.group());
+
+            // repeat test using setAttribute
+            Map<String,?> map = view.readAttributes("owner","group");
+            view.setAttribute("owner", map.get("owner"));
+            view.setAttribute("group", map.get("group"));
+
+        } finally {
+            file.delete(false);
+        }
+
+        System.out.println("OKAY");
+    }
+
+    /**
+     * Test the lookupPrincipalByName/lookupPrincipalByGroupName methods
+     */
+    static void lookupPrincipalTests(Path dir)
+        throws IOException
+    {
+        System.out.println("-- Lookup UserPrincipal Tests --");
+
+        UserPrincipalLookupService lookupService = dir.getFileSystem()
+            .getUserPrincipalLookupService();
+
+        // read attributes of directory to get owner/group
+        PosixFileAttributes attrs = Attributes.readPosixFileAttributes(dir);
+
+        // lookup owner and check it matches file's owner
+        System.out.format("lookup: %s\n", attrs.owner().getName());
+        try {
+            UserPrincipal owner = lookupService.lookupPrincipalByName(attrs.owner().getName());
+            if (owner instanceof GroupPrincipal)
+                throw new RuntimeException("owner is a group?");
+            if (!owner.equals(attrs.owner()))
+                throw new RuntimeException("owner different from file owner");
+        } catch (UserPrincipalNotFoundException x) {
+            System.out.println("user not found - test skipped");
+        }
+
+        // lookup group and check it matches file's group-owner
+        System.out.format("lookup group: %s\n", attrs.group().getName());
+        try {
+            GroupPrincipal group = lookupService.lookupPrincipalByGroupName(attrs.group().getName());
+            if (!group.equals(attrs.group()))
+                throw new RuntimeException("group different from file group-owner");
+        } catch (UserPrincipalNotFoundException x) {
+            System.out.println("group not found - test skipped");
+        }
+
+        // test that UserPrincipalNotFoundException is thrown
+        String invalidPrincipal = "scumbag99";
+        try {
+            System.out.format("lookup: %s\n", invalidPrincipal);
+            lookupService.lookupPrincipalByName(invalidPrincipal);
+            throw new RuntimeException("'" + invalidPrincipal + "' is a valid user?");
+        } catch (UserPrincipalNotFoundException x) {
+        }
+        try {
+            System.out.format("lookup group: %s\n", invalidPrincipal);
+            lookupService.lookupPrincipalByGroupName("idonotexist");
+            throw new RuntimeException("'" + invalidPrincipal + "' is a valid group?");
+        } catch (UserPrincipalNotFoundException x) {
+        }
+        System.out.println("OKAY");
+    }
+
+    /**
+     * Test various exceptions are thrown as expected
+     */
+    @SuppressWarnings("unchecked")
+    static void exceptionsTests(Path dir)
+        throws IOException
+    {
+        System.out.println("-- Exceptions --");
+
+        PosixFileAttributeView view = dir
+            .getFileAttributeView(PosixFileAttributeView.class);
+
+        // NullPointerException
+        try {
+            view.setOwner(null);
+            throw new RuntimeException("NullPointerException not thrown");
+        } catch (NullPointerException x) {
+        }
+        try {
+            view.setGroup(null);
+            throw new RuntimeException("NullPointerException not thrown");
+        } catch (NullPointerException x) {
+        }
+
+        UserPrincipalLookupService lookupService = dir.getFileSystem()
+            .getUserPrincipalLookupService();
+        try {
+            lookupService.lookupPrincipalByName(null);
+            throw new RuntimeException("NullPointerException not thrown");
+        } catch (NullPointerException x) {
+        }
+        try {
+            lookupService.lookupPrincipalByGroupName(null);
+            throw new RuntimeException("NullPointerException not thrown");
+        } catch (NullPointerException x) {
+        }
+        try {
+            view.setPermissions(null);
+            throw new RuntimeException("NullPointerException not thrown");
+        } catch (NullPointerException x) {
+        }
+        try {
+            Set<PosixFilePermission> perms = new HashSet<PosixFilePermission>();
+            perms.add(null);
+            view.setPermissions(perms);
+            throw new RuntimeException("NullPointerException not thrown");
+        }  catch (NullPointerException x) {
+        }
+
+        // ClassCastException
+        try {
+            Set perms = new HashSet();  // raw type
+            perms.add(new Object());
+            view.setPermissions(perms);
+            throw new RuntimeException("ClassCastException not thrown");
+        }  catch (ClassCastException x) {
+        }
+
+        System.out.println("OKAY");
+    }
+
+    public static void main(String[] args) throws IOException {
+        Path dir = TestUtil.createTemporaryDirectory();
+        try {
+            if (!dir.getFileStore().supportsFileAttributeView("posix")) {
+                System.out.println("PosixFileAttributeView not supported");
+                return;
+            }
+
+            permissionTests(dir);
+            createTests(dir);
+            ownerTests(dir);
+            lookupPrincipalTests(dir);
+            exceptionsTests(dir);
+
+        } finally {
+            TestUtil.removeAll(dir);
+        }
+    }
+}
diff --git a/jdk/test/java/nio/file/attribute/UserDefinedFileAttributeView/Basic.java b/jdk/test/java/nio/file/attribute/UserDefinedFileAttributeView/Basic.java
new file mode 100644
index 0000000..ffdb5b8
--- /dev/null
+++ b/jdk/test/java/nio/file/attribute/UserDefinedFileAttributeView/Basic.java
@@ -0,0 +1,273 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 4313887
+ * @summary Unit test for java.nio.file.attribute.UserDefinedFileAttributeView
+ * @library ../..
+ */
+
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+import java.nio.file.*;
+import static java.nio.file.LinkOption.*;
+import java.nio.file.attribute.*;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Random;
+import java.io.IOException;
+
+public class Basic {
+
+    private static Random rand = new Random();
+
+    private static final String ATTR_NAME = "mime_type";
+    private static final String ATTR_VALUE = "text/plain";
+    private static final String ATTR_VALUE2 = "text/html";
+
+    static interface Task {
+        void run() throws Exception;
+    }
+
+    static void tryCatch(Class<? extends Throwable> ex, Task task) {
+        boolean caught = false;
+        try {
+            task.run();
+        } catch (Throwable x) {
+            if (ex.isAssignableFrom(x.getClass())) {
+                caught = true;
+            } else {
+                throw new RuntimeException(x);
+            }
+        }
+        if (!caught)
+            throw new RuntimeException(ex.getName() + " expected");
+    }
+
+    static void expectNullPointerException(Task task) {
+        tryCatch(NullPointerException.class, task);
+    }
+
+    static boolean hasAttribute(UserDefinedFileAttributeView view, String attr)
+        throws IOException
+    {
+        for (String name: view.list()) {
+            if (name.equals(ATTR_NAME))
+                return true;
+        }
+        return false;
+    }
+
+    static void test(Path file, LinkOption... options) throws IOException {
+        final UserDefinedFileAttributeView view = file
+            .getFileAttributeView(UserDefinedFileAttributeView.class, options);
+        ByteBuffer buf = rand.nextBoolean() ?
+            ByteBuffer.allocate(100) : ByteBuffer.allocateDirect(100);
+
+        // Test: write
+        buf.put(ATTR_VALUE.getBytes()).flip();
+        int size = buf.remaining();
+        int nwrote = view.write(ATTR_NAME, buf);
+        if (nwrote != size)
+            throw new RuntimeException("Unexpected number of bytes written");
+
+        // Test: size
+        if (view.size(ATTR_NAME) != size)
+            throw new RuntimeException("Unexpected size");
+
+        // Test: read
+        buf.clear();
+        int nread = view.read(ATTR_NAME, buf);
+        if (nread != size)
+            throw new RuntimeException("Unexpected number of bytes read");
+        buf.flip();
+        String value = Charset.defaultCharset().decode(buf).toString();
+        if (!value.equals(ATTR_VALUE))
+            throw new RuntimeException("Unexpected attribute value");
+
+        // Test: read with insufficient space
+        tryCatch(IOException.class, new Task() {
+            public void run() throws IOException {
+                view.read(ATTR_NAME, ByteBuffer.allocateDirect(1));
+            }});
+
+        // Test: replace value
+        buf.clear();
+        buf.put(ATTR_VALUE2.getBytes()).flip();
+        size = buf.remaining();
+        view.write(ATTR_NAME, buf);
+        if (view.size(ATTR_NAME) != size)
+            throw new RuntimeException("Unexpected size");
+
+        // Test: list
+        if (!hasAttribute(view, ATTR_NAME))
+            throw new RuntimeException("Attribute name not in list");
+
+        // Test: delete
+        view.delete(ATTR_NAME);
+        if (hasAttribute(view, ATTR_NAME))
+            throw new RuntimeException("Attribute name in list");
+
+        // Test: dynamic access
+        byte[] valueAsBytes = ATTR_VALUE.getBytes();
+        view.setAttribute(ATTR_NAME, valueAsBytes);
+        byte[] actualAsBytes = (byte[])view.getAttribute(ATTR_NAME);
+        if (!Arrays.equals(valueAsBytes, actualAsBytes))
+            throw new RuntimeException("Unexpected attribute value");
+        Map<String,?> map = view.readAttributes(ATTR_NAME);
+        if (!Arrays.equals(valueAsBytes, (byte[])map.get(ATTR_NAME)))
+            throw new RuntimeException("Unexpected attribute value");
+        map = view.readAttributes(ATTR_NAME, "*");
+        if (!Arrays.equals(valueAsBytes, (byte[])map.get(ATTR_NAME)))
+            throw new RuntimeException("Unexpected attribute value");
+        map = view.readAttributes("DoesNotExist");
+        if (!map.isEmpty())
+            throw new RuntimeException("Map expected to be empty");
+    }
+
+    static void miscTests(Path file) throws IOException {
+        final UserDefinedFileAttributeView view = file
+            .getFileAttributeView(UserDefinedFileAttributeView.class);
+        view.write(ATTR_NAME, ByteBuffer.wrap(ATTR_VALUE.getBytes()));
+
+        // NullPointerException
+        final ByteBuffer buf = ByteBuffer.allocate(100);
+
+        expectNullPointerException(new Task() {
+            public void run() throws IOException {
+                view.read(null, buf);
+            }});
+        expectNullPointerException(new Task() {
+            public void run() throws IOException {
+                view.read(ATTR_NAME, null);
+            }});
+        expectNullPointerException(new Task() {
+            public void run() throws IOException {
+                view.write(null, buf);
+            }});
+        expectNullPointerException(new Task() {
+            public void run() throws IOException {
+               view.write(ATTR_NAME, null);
+            }});
+        expectNullPointerException(new Task() {
+            public void run() throws IOException {
+                view.size(null);
+            }});
+        expectNullPointerException(new Task() {
+            public void run() throws IOException {
+                view.delete(null);
+            }});
+        expectNullPointerException(new Task() {
+            public void run() throws IOException {
+                view.getAttribute(null);
+            }});
+        expectNullPointerException(new Task() {
+            public void run() throws IOException {
+                view.setAttribute(ATTR_NAME, null);
+            }});
+        expectNullPointerException(new Task() {
+            public void run() throws IOException {
+                view.setAttribute(null, new byte[0]);
+            }});
+         expectNullPointerException(new Task() {
+            public void run() throws IOException {
+               view.readAttributes(null);
+            }});
+        expectNullPointerException(new Task() {
+            public void run() throws IOException {
+                view.readAttributes("*", (String[])null);
+            }});
+        expectNullPointerException(new Task() {
+            public void run() throws IOException {
+                view.readAttributes("*", ATTR_NAME, null);
+            }});
+
+        // Read-only buffer
+        tryCatch(IllegalArgumentException.class, new Task() {
+            public void run() throws IOException {
+                ByteBuffer buf = ByteBuffer.wrap(ATTR_VALUE.getBytes()).asReadOnlyBuffer();
+                view.write(ATTR_NAME, buf);
+                buf.flip();
+                view.read(ATTR_NAME, buf);
+            }});
+
+        // Zero bytes remaining
+        tryCatch(IOException.class, new Task() {
+            public void run() throws IOException {
+                ByteBuffer buf = buf = ByteBuffer.allocateDirect(100);
+                buf.position(buf.capacity());
+                view.read(ATTR_NAME, buf);
+            }});
+    }
+
+    public static void main(String[] args) throws IOException {
+        // create temporary directory to run tests
+        Path dir = TestUtil.createTemporaryDirectory();
+        try {
+            if (!dir.getFileStore().supportsFileAttributeView("xattr")) {
+                System.out.println("UserDefinedFileAttributeView not supported - skip test");
+                return;
+            }
+
+            // test access to user defined attributes of regular file
+            Path file = dir.resolve("foo.html").createFile();
+            try {
+                test(file);
+            } finally {
+                file.delete();
+            }
+
+            // test access to user define attributes of directory
+            file = dir.resolve("foo").createDirectory();
+            try {
+                test(file);
+            } finally {
+                file.delete();
+            }
+
+            // test access to user defined attributes of sym link
+            if (TestUtil.supportsLinks(dir)) {
+                Path target = dir.resolve("doesnotexist");
+                Path link = dir.resolve("link").createSymbolicLink(target);
+                try {
+                    test(link, NOFOLLOW_LINKS);
+                } catch (IOException x) {
+                    // access to attributes of sym link may not be supported
+                } finally {
+                    link.delete();
+                }
+            }
+
+            // misc. tests
+            try {
+                file = dir.resolve("foo.txt").createFile();
+                miscTests(dir);
+            } finally {
+                file.delete();
+            }
+
+        } finally {
+            TestUtil.removeAll(dir);
+        }
+    }
+ }
diff --git a/jdk/test/java/nio/file/spi/SetDefaultProvider.java b/jdk/test/java/nio/file/spi/SetDefaultProvider.java
new file mode 100644
index 0000000..fa600b0
--- /dev/null
+++ b/jdk/test/java/nio/file/spi/SetDefaultProvider.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 4313887
+ * @summary Unit test for java.nio.file.spi.FileSystemProvider
+ * @build TestProvider SetDefaultProvider
+ * @run main/othervm -Djava.nio.file.spi.DefaultFileSystemProvider=TestProvider SetDefaultProvider
+ */
+
+import java.nio.file.*;
+import java.nio.file.spi.*;
+
+public class SetDefaultProvider {
+    public static void main(String[] args) throws Exception {
+        Class<?> c = FileSystems.getDefault().provider().getClass();
+
+        Class<?> expected = Class.forName("TestProvider", false,
+            ClassLoader.getSystemClassLoader());
+
+        if (c != expected)
+            throw new RuntimeException();
+    }
+}
diff --git a/jdk/test/java/nio/file/spi/TestProvider.java b/jdk/test/java/nio/file/spi/TestProvider.java
new file mode 100644
index 0000000..a6868ac
--- /dev/null
+++ b/jdk/test/java/nio/file/spi/TestProvider.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.nio.file.spi.FileSystemProvider;
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.net.URI;
+import java.util.*;
+import java.io.IOException;
+
+public class TestProvider extends FileSystemProvider {
+
+    private final FileSystem theFileSystem;
+
+    public TestProvider(FileSystemProvider defaultProvider) {
+        theFileSystem = new TestFileSystem(this);
+
+    }
+
+    @Override
+    public String getScheme() {
+        return "file";
+    }
+
+    @Override
+    public FileSystem newFileSystem(URI uri, Map<String,?> env) {
+        throw new RuntimeException("not implemented");
+    }
+
+    @Override
+    public FileSystem getFileSystem(URI uri) {
+        return theFileSystem;
+    }
+
+    @Override
+    public Path getPath(URI uri) {
+        throw new RuntimeException("not implemented");
+    }
+
+    static class TestFileSystem extends FileSystem {
+        private final TestProvider provider;
+
+        TestFileSystem(TestProvider provider) {
+            this.provider = provider;
+        }
+
+        @Override
+        public FileSystemProvider provider() {
+            return provider;
+        }
+
+        @Override
+        public void close() throws IOException {
+            throw new RuntimeException("not implemented");
+        }
+
+        @Override
+        public boolean isOpen() {
+            throw new RuntimeException("not implemented");
+        }
+
+        @Override
+        public boolean isReadOnly() {
+            throw new RuntimeException("not implemented");
+        }
+
+        @Override
+        public String getSeparator() {
+            throw new RuntimeException("not implemented");
+        }
+
+        @Override
+        public Iterable<Path> getRootDirectories() {
+            throw new RuntimeException("not implemented");
+        }
+
+        @Override
+        public Iterable<FileStore> getFileStores() {
+            throw new RuntimeException("not implemented");
+        }
+
+        @Override
+        public Set<String> supportedFileAttributeViews() {
+            throw new RuntimeException("not implemented");
+        }
+
+        @Override
+        public Path getPath(String path) {
+            throw new RuntimeException("not implemented");
+        }
+
+        @Override
+        public PathMatcher getPathMatcher(String syntaxAndPattern) {
+            throw new RuntimeException("not implemented");
+        }
+
+        @Override
+        public UserPrincipalLookupService getUserPrincipalLookupService() {
+            throw new RuntimeException("not implemented");
+        }
+
+        @Override
+        public WatchService newWatchService() throws IOException {
+            throw new RuntimeException("not implemented");
+        }
+    }
+
+}
diff --git a/jdk/test/java/security/cert/CertificateFactory/BadX509CertData.java b/jdk/test/java/security/cert/CertificateFactory/BadX509CertData.java
index 6141afd..87f8131 100644
--- a/jdk/test/java/security/cert/CertificateFactory/BadX509CertData.java
+++ b/jdk/test/java/security/cert/CertificateFactory/BadX509CertData.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2009 Sun Microsystems, Inc.  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,7 +40,7 @@
         InputStream is = new ByteArrayInputStream(data.getBytes("ISO8859_1"));
         try {
             Certificate cert = factory.generateCertificate(is);
-        } catch (CertificateParsingException ce) {
+        } catch (CertificateException ce) {
             return;
         }
         throw new Exception("CertificateFactory.generateCertificate() did "
diff --git a/jdk/test/java/security/cert/CertificateFactory/openssl/OpenSSLCert.java b/jdk/test/java/security/cert/CertificateFactory/openssl/OpenSSLCert.java
new file mode 100644
index 0000000..5ea5b0b
--- /dev/null
+++ b/jdk/test/java/security/cert/CertificateFactory/openssl/OpenSSLCert.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+/*
+ * @test
+ * @bug 6535697
+ * @summary keytool can be more flexible on format of PEM-encoded
+ *  X.509 certificates
+ */
+
+import java.io.*;
+import java.util.Arrays;
+import java.security.cert.CertificateFactory;
+
+public class OpenSSLCert {
+    static final String OUTFILE = "6535697.test";
+
+    public static void main(String[] args) throws Exception {
+        test("open");
+        test("pem");
+        test("open", "open");
+        test("open", "pem");
+        test("pem", "pem");
+        test("pem", "open");
+        test("open", "pem", "open");
+        test("pem", "open", "pem");
+    }
+
+    static void test(String... files) throws Exception {
+        FileOutputStream fout = new FileOutputStream(OUTFILE);
+        for (String file: files) {
+            FileInputStream fin = new FileInputStream(
+                new File(System.getProperty("test.src", "."), file));
+            byte[] buffer = new byte[4096];
+            while (true) {
+                int len = fin.read(buffer);
+                if (len < 0) break;
+                fout.write(buffer, 0, len);
+            }
+            fin.close();
+        }
+        fout.close();
+        System.out.println("Testing " + Arrays.toString(files) + "...");
+        if (CertificateFactory.getInstance("X509")
+                .generateCertificates(new FileInputStream(OUTFILE))
+                .size() != files.length) {
+            throw new Exception("Not same number");
+        }
+    }
+}
diff --git a/jdk/test/java/security/cert/CertificateFactory/openssl/open b/jdk/test/java/security/cert/CertificateFactory/openssl/open
new file mode 100644
index 0000000..c9b0d5e
--- /dev/null
+++ b/jdk/test/java/security/cert/CertificateFactory/openssl/open
@@ -0,0 +1,72 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 1174535938 (0x4601ff02)
+        Signature Algorithm: dsaWithSHA1
+        Issuer: C=EA, ST=Moon, L=Backside, O=A-B-C, OU=Office, CN=Me
+        Validity
+            Not Before: Mar 22 03:58:58 2007 GMT
+            Not After : Jun 20 03:58:58 2007 GMT
+        Subject: C=EA, ST=Moon, L=Backside, O=A-B-C, OU=Office, CN=Me
+        Subject Public Key Info:
+            Public Key Algorithm: dsaEncryption
+            DSA Public Key:
+                pub:
+                    00:c5:ce:e8:be:f0:de:27:9c:88:92:21:28:cf:a5:
+                    38:8d:c1:5f:e5:90:d2:0b:ea:d4:12:ca:86:b8:04:
+                    57:1d:41:74:3e:52:2d:87:b8:76:7b:d2:95:d7:67:
+                    30:76:35:47:fb:e9:86:bf:05:3f:9b:f2:6e:3a:96:
+                    9a:58:e1:05:44:78:02:31:ee:5f:67:6c:44:d2:95:
+                    8f:72:62:a4:3e:27:1c:f3:94:8a:1e:0b:98:4c:c0:
+                    9c:f4:3d:17:6d:36:e4:a0:12:04:01:e4:38:9e:bd:
+                    86:99:7b:84:43:9b:58:68:ef:ce:3d:85:e3:93:d1:
+                    1f:1a:18:a4:1e:59:ca:80:2e
+                P:
+                    00:fd:7f:53:81:1d:75:12:29:52:df:4a:9c:2e:ec:
+                    e4:e7:f6:11:b7:52:3c:ef:44:00:c3:1e:3f:80:b6:
+                    51:26:69:45:5d:40:22:51:fb:59:3d:8d:58:fa:bf:
+                    c5:f5:ba:30:f6:cb:9b:55:6c:d7:81:3b:80:1d:34:
+                    6f:f2:66:60:b7:6b:99:50:a5:a4:9f:9f:e8:04:7b:
+                    10:22:c2:4f:bb:a9:d7:fe:b7:c6:1b:f8:3b:57:e7:
+                    c6:a8:a6:15:0f:04:fb:83:f6:d3:c5:1e:c3:02:35:
+                    54:13:5a:16:91:32:f6:75:f3:ae:2b:61:d7:2a:ef:
+                    f2:22:03:19:9d:d1:48:01:c7
+                Q:
+                    00:97:60:50:8f:15:23:0b:cc:b2:92:b9:82:a2:eb:
+                    84:0b:f0:58:1c:f5
+                G:
+                    00:f7:e1:a0:85:d6:9b:3d:de:cb:bc:ab:5c:36:b8:
+                    57:b9:79:94:af:bb:fa:3a:ea:82:f9:57:4c:0b:3d:
+                    07:82:67:51:59:57:8e:ba:d4:59:4f:e6:71:07:10:
+                    81:80:b4:49:16:71:23:e8:4c:28:16:13:b7:cf:09:
+                    32:8c:c8:a6:e1:3c:16:7a:8b:54:7c:8d:28:e0:a3:
+                    ae:1e:2b:b3:a6:75:91:6e:a3:7f:0b:fa:21:35:62:
+                    f1:fb:62:7a:01:24:3b:cc:a4:f1:be:a8:51:90:89:
+                    a8:83:df:e1:5a:e5:9f:06:92:8b:66:5e:80:7b:55:
+                    25:64:01:4c:3b:fe:cf:49:2a
+        X509v3 extensions:
+            X509v3 Subject Key Identifier:
+                ED:BF:8A:CA:57:05:ED:5C:9A:72:65:69:6C:C1:02:F8:30:02:A4:6B
+    Signature Algorithm: dsaWithSHA1
+        30:2d:02:15:00:85:38:a6:79:d4:70:c8:e1:d8:25:2f:87:f0:
+        74:3d:26:59:4c:71:ef:02:14:15:32:10:1d:c0:d1:ce:18:f4:
+        8b:ea:c0:8b:d7:da:ba:52:3a:0d:f7
+-----BEGIN CERTIFICATE-----
+MIIDGDCCAtWgAwIBAgIERgH/AjALBgcqhkjOOAQDBQAwXTELMAkGA1UEBhMCRUEx
+DTALBgNVBAgTBE1vb24xETAPBgNVBAcTCEJhY2tzaWRlMQ4wDAYDVQQKEwVBLUIt
+QzEPMA0GA1UECxMGT2ZmaWNlMQswCQYDVQQDEwJNZTAeFw0wNzAzMjIwMzU4NTha
+Fw0wNzA2MjAwMzU4NThaMF0xCzAJBgNVBAYTAkVBMQ0wCwYDVQQIEwRNb29uMREw
+DwYDVQQHEwhCYWNrc2lkZTEOMAwGA1UEChMFQS1CLUMxDzANBgNVBAsTBk9mZmlj
+ZTELMAkGA1UEAxMCTWUwggG4MIIBLAYHKoZIzjgEATCCAR8CgYEA/X9TgR11EilS
+30qcLuzk5/YRt1I870QAwx4/gLZRJmlFXUAiUftZPY1Y+r/F9bow9subVWzXgTuA
+HTRv8mZgt2uZUKWkn5/oBHsQIsJPu6nX/rfGG/g7V+fGqKYVDwT7g/bTxR7DAjVU
+E1oWkTL2dfOuK2HXKu/yIgMZndFIAccCFQCXYFCPFSMLzLKSuYKi64QL8Fgc9QKB
+gQD34aCF1ps93su8q1w2uFe5eZSvu/o66oL5V0wLPQeCZ1FZV4661FlP5nEHEIGA
+tEkWcSPoTCgWE7fPCTKMyKbhPBZ6i1R8jSjgo64eK7OmdZFuo38L+iE1YvH7YnoB
+JDvMpPG+qFGQiaiD3+Fa5Z8GkotmXoB7VSVkAUw7/s9JKgOBhQACgYEAxc7ovvDe
+J5yIkiEoz6U4jcFf5ZDSC+rUEsqGuARXHUF0PlIth7h2e9KV12cwdjVH++mGvwU/
+m/JuOpaaWOEFRHgCMe5fZ2xE0pWPcmKkPicc85SKHguYTMCc9D0XbTbkoBIEAeQ4
+nr2GmXuEQ5tYaO/OPYXjk9EfGhikHlnKgC6jITAfMB0GA1UdDgQWBBTtv4rKVwXt
+XJpyZWlswQL4MAKkazALBgcqhkjOOAQDBQADMAAwLQIVAIU4pnnUcMjh2CUvh/B0
+PSZZTHHvAhQVMhAdwNHOGPSL6sCL19q6UjoN9w==
+-----END CERTIFICATE-----
diff --git a/jdk/test/java/security/cert/CertificateFactory/openssl/pem b/jdk/test/java/security/cert/CertificateFactory/openssl/pem
new file mode 100644
index 0000000..8601bf3
--- /dev/null
+++ b/jdk/test/java/security/cert/CertificateFactory/openssl/pem
@@ -0,0 +1,16 @@
+-----BEGIN CERTIFICATE-----
+MIIDGDCCAtWgAwIBAgIERgH/AjALBgcqhkjOOAQDBQAwXTELMAkGA1UEBhMCRUExDTALBgNVBAgT
+BE1vb24xETAPBgNVBAcTCEJhY2tzaWRlMQ4wDAYDVQQKEwVBLUItQzEPMA0GA1UECxMGT2ZmaWNl
+MQswCQYDVQQDEwJNZTAeFw0wNzAzMjIwMzU4NThaFw0wNzA2MjAwMzU4NThaMF0xCzAJBgNVBAYT
+AkVBMQ0wCwYDVQQIEwRNb29uMREwDwYDVQQHEwhCYWNrc2lkZTEOMAwGA1UEChMFQS1CLUMxDzAN
+BgNVBAsTBk9mZmljZTELMAkGA1UEAxMCTWUwggG4MIIBLAYHKoZIzjgEATCCAR8CgYEA/X9TgR11
+EilS30qcLuzk5/YRt1I870QAwx4/gLZRJmlFXUAiUftZPY1Y+r/F9bow9subVWzXgTuAHTRv8mZg
+t2uZUKWkn5/oBHsQIsJPu6nX/rfGG/g7V+fGqKYVDwT7g/bTxR7DAjVUE1oWkTL2dfOuK2HXKu/y
+IgMZndFIAccCFQCXYFCPFSMLzLKSuYKi64QL8Fgc9QKBgQD34aCF1ps93su8q1w2uFe5eZSvu/o6
+6oL5V0wLPQeCZ1FZV4661FlP5nEHEIGAtEkWcSPoTCgWE7fPCTKMyKbhPBZ6i1R8jSjgo64eK7Om
+dZFuo38L+iE1YvH7YnoBJDvMpPG+qFGQiaiD3+Fa5Z8GkotmXoB7VSVkAUw7/s9JKgOBhQACgYEA
+xc7ovvDeJ5yIkiEoz6U4jcFf5ZDSC+rUEsqGuARXHUF0PlIth7h2e9KV12cwdjVH++mGvwU/m/Ju
+OpaaWOEFRHgCMe5fZ2xE0pWPcmKkPicc85SKHguYTMCc9D0XbTbkoBIEAeQ4nr2GmXuEQ5tYaO/O
+PYXjk9EfGhikHlnKgC6jITAfMB0GA1UdDgQWBBTtv4rKVwXtXJpyZWlswQL4MAKkazALBgcqhkjO
+OAQDBQADMAAwLQIVAIU4pnnUcMjh2CUvh/B0PSZZTHHvAhQVMhAdwNHOGPSL6sCL19q6UjoN9w==
+-----END CERTIFICATE-----
diff --git a/jdk/test/java/util/regex/BMPTestCases.txt b/jdk/test/java/util/regex/BMPTestCases.txt
new file mode 100644
index 0000000..c50f496
--- /dev/null
+++ b/jdk/test/java/util/regex/BMPTestCases.txt
@@ -0,0 +1,951 @@
+//
+// Copyright 1999-2009 Sun Microsystems, Inc.  All Rights Reserved.
+// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+//
+// This code is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License version 2 only, as
+// published by the Free Software Foundation.
+//
+// This code is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// version 2 for more details (a copy is included in the LICENSE file that
+// accompanied this code).
+//
+// You should have received a copy of the GNU General Public License version
+// 2 along with this work; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+// CA 95054 USA or visit www.sun.com if you need additional information or
+// have any questions.
+//
+//
+// This file contains test cases with BMP characters for regular expressions.
+// A test case consists of three lines:
+// The first line is a pattern used in the test
+// The second line is the input to search for the pattern in
+// The third line is a concatentation of the match, the number of groups,
+//     and the contents of the first four subexpressions.
+// Empty lines and lines beginning with comment slashes are ignored.
+
+// Test unsetting of backed off groups
+^(\u3042)?\u3042
+\u3042
+true \u3042 1
+
+^(\u3042\u3042(\u3043\u3043)?)+$
+\u3042\u3042\u3043\u3043\u3042\u3042
+true \u3042\u3042\u3043\u3043\u3042\u3042 2 \u3042\u3042 \u3043\u3043
+
+((\u3042|\u3043)?\u3043)+
+\u3043
+true \u3043 2 \u3043
+
+(\u3042\u3042\u3042)?\u3042\u3042\u3042
+\u3042\u3042\u3042
+true \u3042\u3042\u3042 1
+
+^(\u3042(\u3043)?)+$
+\u3042\u3043\u3042
+true \u3042\u3043\u3042 2 \u3042 \u3043
+
+^(\u3042(\u3043(\u3044)?)?)?\u3042\u3043\u3044
+\u3042\u3043\u3044
+true \u3042\u3043\u3044 3
+
+^(\u3042(\u3043(\u3044))).*
+\u3042\u3043\u3044
+true \u3042\u3043\u3044 3 \u3042\u3043\u3044 \u3043\u3044 \u3044
+
+// use of x modifier
+\u3042\u3043\u3044(?x)\u3043la\u3049
+\u3042\u3043\u3044\u3043la\u3049
+true \u3042\u3043\u3044\u3043la\u3049 0
+
+\u3042\u3043\u3044(?x)  bla\u3049
+\u3042\u3043\u3044bla\u3049
+true \u3042\u3043\u3044bla\u3049 0
+
+\u3042\u3043\u3044(?x)  bla\u3049  ble\u3044\u3049
+\u3042\u3043\u3044bla\u3049ble\u3044\u3049
+true \u3042\u3043\u3044bla\u3049ble\u3044\u3049 0
+
+\u3042\u3043\u3044(?x)  bla\u3049 # ignore comment
+\u3042\u3043\u3044bla\u3049
+true \u3042\u3043\u3044bla\u3049 0
+
+// Simple alternation
+\u3042|\u3043
+\u3042
+true \u3042 0
+
+\u3042|\u3043
+\u305B
+false 0
+
+\u3042|\u3043
+\u3043
+true \u3043 0
+
+\u3042|\u3043|\u3044\u3045
+\u3044\u3045
+true \u3044\u3045 0
+
+\u3042|\u3042\u3045
+\u3042\u3045
+true \u3042 0
+
+\u305B(\u3042|\u3042\u3044)\u3043
+\u305B\u3042\u3044\u3043
+true \u305B\u3042\u3044\u3043 1 \u3042\u3044
+
+// Simple char class
+[\u3042\u3043\u3044]+
+\u3042\u3043\u3042\u3043\u3042\u3043
+true \u3042\u3043\u3042\u3043\u3042\u3043 0
+
+[\u3042\u3043\u3044]+
+\u3045\u3046\u3047\u3048
+false 0
+
+[\u3042\u3043\u3044]+[\u3045\u3046\u3047]+[\u3048\u3049\u304A]+
+\u305B\u305B\u305B\u3042\u3042\u3045\u3045\u3048\u3048\u305B\u305B\u305B
+true \u3042\u3042\u3045\u3045\u3048\u3048 0
+
+// Range char class
+[\u3042-\u3048]+
+\u305B\u305B\u305B\u3048\u3048\u3048
+true \u3048\u3048\u3048 0
+
+[\u3042-\u3048]+
+mmm
+false 0
+
+[\u3042-]+
+\u305B\u3042-9\u305B
+true \u3042- 0
+
+[\u3042-\\u4444]+
+\u305B\u3042-9\u305B
+true \u305B\u3042 0
+
+// Negated char class
+[^\u3042\u3043\u3044]+
+\u3042\u3043\u3042\u3043\u3042\u3043
+false 0
+
+[^\u3042\u3043\u3044]+
+\u3042\u3042\u3042\u3043\u3043\u3043\u3044\u3044\u3044\u3045\u3046\u3047\u3048
+true \u3045\u3046\u3047\u3048 0
+
+// Making sure a ^ not in first position matches literal ^
+[\u3042\u3043\u3044^\u3043]
+\u3043
+true \u3043 0
+
+[\u3042\u3043\u3044^\u3043]
+^
+true ^ 0
+
+// Class union and intersection
+[\u3042\u3043\u3044[\u3045\u3046\u3047]]
+\u3043
+true \u3043 0
+
+[\u3042\u3043\u3044[\u3045\u3046\u3047]]
+\u3046
+true \u3046 0
+
+[\u3042-\u3045[0-9][\u304e-\u3051]]
+\u3042
+true \u3042 0
+
+[\u3042-\u3045[0-9][\u304e-\u3051]]
+\u3050
+true \u3050 0
+
+[\u3042-\u3045[0-9][\u304e-\u3051]]
+4
+true 4 0
+
+[\u3042-\u3045[0-9][\u304e-\u3051]]
+\u3046
+false 0
+
+[\u3042-\u3045[0-9][\u304e-\u3051]]
+\u3056
+false 0
+
+[[\u3042-\u3045][0-9][\u304e-\u3051]]
+\u3043
+true \u3043 0
+
+[[\u3042-\u3045][0-9][\u304e-\u3051]]
+\u305B
+false 0
+
+[\u3042-\u3044[\u3045-\u3047[\u3048-\u304A]]]
+\u3042
+true \u3042 0
+
+[\u3042-\u3044[\u3045-\u3047[\u3048-\u304A]]]
+\u3046
+true \u3046 0
+
+[\u3042-\u3044[\u3045-\u3047[\u3048-\u304A]]]
+\u3049
+true \u3049 0
+
+[\u3042-\u3044[\u3045-\u3047[\u3048-\u304A]]]
+m
+false 0
+
+[\u3042-\u3044[\u3045-\u3047[\u3048-\u304A]]m]
+m
+true m 0
+
+[\u3042\u3043\u3044[\u3045\u3046\u3047]\u3048\u3049\u304A]
+\u3042
+true \u3042 0
+
+[\u3042\u3043\u3044[\u3045\u3046\u3047]\u3048\u3049\u304A]
+\u3045
+true \u3045 0
+
+[\u3042\u3043\u3044[\u3045\u3046\u3047]\u3048\u3049\u304A]
+\u3049
+true \u3049 0
+
+[\u3042\u3043\u3044[\u3045\u3046\u3047]\u3048\u3049\u304A]
+w
+false 0
+
+[\u3042-\u3044&&[\u3045-\u3047]]
+\u3042
+false 0
+
+[\u3042-\u3044&&[\u3045-\u3047]]
+\u3046
+false 0
+
+[\u3042-\u3044&&[\u3045-\u3047]]
+\u305B
+false 0
+
+[[\u3042-\u3044]&&[\u3045-\u3047]]
+\u3042
+false 0
+
+[[\u3042-\u3044]&&[\u3045-\u3047]]
+\u3046
+false 0
+
+[[\u3042-\u3044]&&[\u3045-\u3047]]
+\u305B
+false 0
+
+[\u3042-\u3044&&\u3045-\u3047]
+\u3042
+false 0
+
+[\u3042-\u304e&&\u304e-\u305B]
+\u304e
+true \u304e 0
+
+[\u3042-\u304e&&\u304e-\u305B&&\u3042-\u3044]
+\u304e
+false 0
+
+[\u3042-\u304e&&\u304e-\u305B&&\u3042-\u305B]
+\u304e
+true \u304e 0
+
+[[\u3042-\u304e]&&[\u304e-\u305B]]
+\u3042
+false 0
+
+[[\u3042-\u304e]&&[\u304e-\u305B]]
+\u304e
+true \u304e 0
+
+[[\u3042-\u304e]&&[\u304e-\u305B]]
+\u305B
+false 0
+
+[[\u3042-\u304e]&&[^\u3042-\u3044]]
+\u3042
+false 0
+
+[[\u3042-\u304e]&&[^\u3042-\u3044]]
+\u3045
+true \u3045 0
+
+[\u3042-\u304e&&[^\u3042-\u3044]]
+\u3042
+false 0
+
+[\u3042-\u304e&&[^\u3042-\u3044]]
+\u3045
+true \u3045 0
+
+[\u3042-\u3044\u3045-\u3047&&[\u3045-\u3047]]
+\u3042
+false 0
+
+[\u3042-\u3044\u3045-\u3047&&[\u3045-\u3047]]
+\u3046
+true \u3046 0
+
+[[\u3042-\u3044]&&\u3045-\u3047\u3042-\u3044]
+\u3042
+true \u3042 0
+
+[[\u3042-\u3044]&&[\u3045-\u3047][\u3042-\u3044]]
+\u3042
+true \u3042 0
+
+[[\u3042-\u3044][\u3045-\u3047]&&\u3042\u3043\u3044]
+\u3042
+true \u3042 0
+
+[[\u3042-\u3044][\u3045-\u3047]&&\u3042\u3043\u3044[\u3045\u3046\u3047]]
+\u3046
+true \u3046 0
+
+[[\u3042-\u3044]&&[\u3043-\u3045]&&[\u3044-\u3046]]
+\u3042
+false 0
+
+[[\u3042-\u3044]&&[\u3043-\u3045]&&[\u3044-\u3046]]
+\u3044
+true \u3044 0
+
+[[\u3042-\u3044]&&[\u3043-\u3045][\u3044-\u3046]&&[\u3056-\u305B]]
+\u3044
+false 0
+
+[\u3042\u3043\u3044[^\u3043\u3044\u3045]]
+\u3042
+true \u3042 0
+
+[\u3042\u3043\u3044[^\u3043\u3044\u3045]]
+\u3045
+false 0
+
+[\u3042-\u3044&&\u3042-\u3045&&\u3042-\u3046\u3048\u3049\u304A]
+\u3043
+true \u3043 0
+
+[\u3042-\u3044&&\u3042-\u3045&&\u3042-\u3046\u3048\u3049\u304A]
+\u3048
+false 0
+
+[[\u3042[\u3043]]&&[\u3043[\u3042]]]
+\u3042
+true \u3042 0
+
+[[\u3042]&&[\u3043][\u3044][\u3042]&&[^\u3045]]
+\u3042
+true \u3042 0
+
+[[\u3042]&&[b][c][\u3042]&&[^d]]
+\u3042
+true \u3042 0
+
+[[\u3042]&&[\u3043][\u3044][\u3042]&&[^\u3045]]
+\u3045
+false 0
+
+[[[\u3042-\u3045]&&[\u3044-\u3047]]]
+\u3042
+false 0
+
+[[[\u3042-\u3045]&&[\u3044-\u3047]]]
+\u3044
+true \u3044 0
+
+[[[\u3042-\u3045]&&[\u3044-\u3047]]&&[\u3044]]
+\u3044
+true \u3044 0
+
+[[[\u3042-\u3045]&&[\u3044-\u3047]]&&[\u3044]&&\u3044]
+\u3044
+true \u3044 0
+
+[[[\u3042-\u3045]&&[\u3044-\u3047]]&&[\u3044]&&\u3044&&\u3044]
+\u3044
+true \u3044 0
+
+[[[\u3042-\u3045]&&[\u3044-\u3047]]&&[\u3044]&&\u3044&&[\u3044\u3045\u3046]]
+\u3044
+true \u3044 0
+
+[\u305B[\u3042\u3043\u3044&&\u3043\u3044\u3045]]
+\u3044
+true \u3044 0
+
+[\u305B[\u3042\u3043\u3044&&\u3043\u3044\u3045]&&[\u3056-\u305B]]
+\u305B
+true \u305B 0
+
+[\u3059[\u3042\u3043\u3044&&\u3043\u3044\u3045[\u305B]]&&[\u3056-\u305B]]
+\u305B
+false 0
+
+[\u3059[[w\u305B]\u3042\u3043\u3044&&\u3043\u3044\u3045[\u305B]]&&[\u3056-\u305B]]
+\u305B
+true \u305B 0
+
+[[\u3042\u3043\u3044]&&[\u3045\u3046\u3047]\u3042\u3043\u3044]
+\u3042
+true \u3042 0
+
+[[\u3042\u3043\u3044]&&[\u3045\u3046\u3047]\u3059\u305A\u305B[\u3042\u3043\u3044]]
+\u3042
+true \u3042 0
+
+\pL
+\u3042
+true \u3042 0
+
+\pL
+7
+false 0
+
+\p{L}
+\u3042
+true \u3042 0
+
+\p{IsL}
+\u3042
+true \u3042 0
+
+\p{InHiragana}
+\u3042
+true \u3042 0
+
+\p{InHiragana}
+\u0370
+false 0
+
+\pL\u3043\u3044
+\u3042\u3043\u3044
+true \u3042\u3043\u3044 0
+
+\u3042[r\p{InGreek}]\u3044
+\u3042\u0370\u3044
+true \u3042\u0370\u3044 0
+
+\u3042\p{InGreek}
+\u3042\u0370
+true \u3042\u0370 0
+
+\u3042\P{InGreek}
+\u3042\u0370
+false 0
+
+\u3042\P{InGreek}
+\u3042\u3043
+true \u3042\u3043 0
+
+\u3042{^InGreek}
+-
+error
+
+\u3042\p{^InGreek}
+-
+error
+
+\u3042\P{^InGreek}
+-
+error
+
+\u3042\p{InGreek}
+\u3042\u0370
+true \u3042\u0370 0
+
+\u3042[\p{InGreek}]\u3044
+\u3042\u0370\u3044
+true \u3042\u0370\u3044 0
+
+\u3042[\P{InGreek}]\u3044
+\u3042\u0370\u3044
+false 0
+
+\u3042[\P{InGreek}]\u3044
+\u3042\u3043\u3044
+true \u3042\u3043\u3044 0
+
+\u3042[{^InGreek}]\u3044
+\u3042n\u3044
+true \u3042n\u3044 0
+
+\u3042[{^InGreek}]\u3044
+\u3042\u305B\u3044
+false 0
+
+\u3042[\p{^InGreek}]\u3044
+-
+error
+
+\u3042[\P{^InGreek}]\u3044
+-
+error
+
+\u3042[\p{InGreek}]
+\u3042\u0370
+true \u3042\u0370 0
+
+\u3042[r\p{InGreek}]\u3044
+\u3042r\u3044
+true \u3042r\u3044 0
+
+\u3042[\p{InGreek}r]\u3044
+\u3042r\u3044
+true \u3042r\u3044 0
+
+\u3042[r\p{InGreek}]\u3044
+\u3042r\u3044
+true \u3042r\u3044 0
+
+\u3042[^\p{InGreek}]\u3044
+\u3042\u0370\u3044
+false 0
+
+\u3042[^\P{InGreek}]\u3044
+\u3042\u0370\u3044
+true \u3042\u0370\u3044 0
+
+\u3042[\p{InGreek}&&[^\u0370]]\u3044
+\u3042\u0370\u3044
+false 0
+
+// Test the dot metacharacter
+\u3042.\u3044.+
+\u3042#\u3044%&
+true \u3042#\u3044%& 0
+
+\u3042\u3043.
+\u3042\u3043\n
+false 0
+
+(?s)\u3042\u3043.
+\u3042\u3043\n
+true \u3042\u3043\n 0
+
+\u3042[\p{L}&&[\P{InGreek}]]\u3044
+\u3042\u6000\u3044
+true \u3042\u6000\u3044 0
+
+\u3042[\p{L}&&[\P{InGreek}]]\u3044
+\u3042r\u3044
+true \u3042r\u3044 0
+
+\u3042[\p{L}&&[\P{InGreek}]]\u3044
+\u3042\u0370\u3044
+false 0
+
+\u3042\p{InGreek}\u3044
+\u3042\u0370\u3044
+true \u3042\u0370\u3044 0
+
+\u3042\p{Sc}
+\u3042$
+true \u3042$ 0
+
+\W\w\W
+rrrr#\u3048\u3048\u3048
+false 0
+
+\u3042\u3043\u3044[\s\u3045\u3046\u3047]*
+\u3042\u3043\u3044  \u3045\u3046\u3047
+true \u3042\u3043\u3044  \u3045\u3046\u3047 0
+
+\u3042\u3043\u3044[\s\u305A-\u305B]*
+\u3042\u3043\u3044 \u305A \u305B
+true \u3042\u3043\u3044 \u305A \u305B 0
+
+\u3042\u3043\u3044[\u3042-\u3045\s\u304e-\u3051]*
+\u3042\u3043\u3044\u3042\u3042 \u304e\u304f  \u3051
+true \u3042\u3043\u3044\u3042\u3042 \u304e\u304f  \u3051 0
+
+// Test the whitespace escape sequence
+\u3042\u3043\s\u3044
+\u3042\u3043 \u3044
+true \u3042\u3043 \u3044 0
+
+\s\s\s
+\u3043l\u3042\u3049  \u3046rr
+false 0
+
+\S\S\s
+\u3043l\u3042\u3049  \u3046rr
+true \u3042\u3049  0
+
+// Test the digit escape sequence
+\u3042\u3043\d\u3044
+\u3042\u30439\u3044
+true \u3042\u30439\u3044 0
+
+\d\d\d
+\u3043l\u3042\u304945
+false 0
+
+// Test the caret metacharacter
+^\u3042\u3043\u3044
+\u3042\u3043\u3044\u3045\u3046\u3047
+true \u3042\u3043\u3044 0
+
+^\u3042\u3043\u3044
+\u3043\u3044\u3045\u3042\u3043\u3044
+false 0
+
+// Greedy ? metacharacter
+\u3042?\u3043
+\u3042\u3042\u3042\u3042\u3043
+true \u3042\u3043 0
+
+\u3042?\u3043
+\u3043
+true \u3043 0
+
+\u3042?\u3043
+\u3042\u3042\u3042\u3044\u3044\u3044
+false 0
+
+.?\u3043
+\u3042\u3042\u3042\u3042\u3043
+true \u3042\u3043 0
+
+// Reluctant ? metacharacter
+\u3042??\u3043
+\u3042\u3042\u3042\u3042\u3043
+true \u3042\u3043 0
+
+\u3042??\u3043
+\u3043
+true \u3043 0
+
+\u3042??\u3043
+\u3042\u3042\u3042\u3044\u3044\u3044
+false 0
+
+.??\u3043
+\u3042\u3042\u3042\u3042\u3043
+true \u3042\u3043 0
+
+// Possessive ? metacharacter
+\u3042?+\u3043
+\u3042\u3042\u3042\u3042\u3043
+true \u3042\u3043 0
+
+\u3042?+\u3043
+\u3043
+true \u3043 0
+
+\u3042?+\u3043
+\u3042\u3042\u3042\u3044\u3044\u3044
+false 0
+
+.?+\u3043
+\u3042\u3042\u3042\u3042\u3043
+true \u3042\u3043 0
+
+// Greedy + metacharacter
+\u3042+\u3043
+\u3042\u3042\u3042\u3042\u3043
+true \u3042\u3042\u3042\u3042\u3043 0
+
+\u3042+\u3043
+\u3043
+false 0
+
+\u3042+\u3043
+\u3042\u3042\u3042\u3044\u3044\u3044
+false 0
+
+.+\u3043
+\u3042\u3042\u3042\u3042\u3043
+true \u3042\u3042\u3042\u3042\u3043 0
+
+// Reluctant + metacharacter
+\u3042+?\u3043
+\u3042\u3042\u3042\u3042\u3043
+true \u3042\u3042\u3042\u3042\u3043 0
+
+\u3042+?\u3043
+\u3043
+false 0
+
+\u3042+?\u3043
+\u3042\u3042\u3042\u3044\u3044\u3044
+false 0
+
+.+?\u3043
+\u3042\u3042\u3042\u3042\u3043
+true \u3042\u3042\u3042\u3042\u3043 0
+
+// Possessive + metacharacter
+\u3042++\u3043
+\u3042\u3042\u3042\u3042\u3043
+true \u3042\u3042\u3042\u3042\u3043 0
+
+\u3042++\u3043
+\u3043
+false 0
+
+\u3042++\u3043
+\u3042\u3042\u3042\u3044\u3044\u3044
+false 0
+
+.++\u3043
+\u3042\u3042\u3042\u3042\u3043
+false 0
+
+// Greedy Repetition
+\u3042{2,3}
+\u3042
+false 0
+
+\u3042{2,3}
+\u3042\u3042
+true \u3042\u3042 0
+
+\u3042{2,3}
+\u3042\u3042\u3042
+true \u3042\u3042\u3042 0
+
+\u3042{2,3}
+\u3042\u3042\u3042\u3042
+true \u3042\u3042\u3042 0
+
+\u3042{3,}
+\u305B\u305B\u305B\u3042\u3042\u3042\u3042\u305B\u305B\u305B
+true \u3042\u3042\u3042\u3042 0
+
+\u3042{3,}
+\u305B\u305B\u305B\u3042\u3042\u305B\u305B\u305B
+false 0
+
+// Reluctant Repetition
+\u3042{2,3}?
+\u3042
+false 0
+
+\u3042{2,3}?
+\u3042\u3042
+true \u3042\u3042 0
+
+\u3042{2,3}?
+\u3042\u3042\u3042
+true \u3042\u3042 0
+
+\u3042{2,3}?
+\u3042\u3042\u3042\u3042
+true \u3042\u3042 0
+
+// Zero width Positive lookahead
+\u3042\u3043\u3044(?=\u3045)
+\u305B\u305B\u305B\u3042\u3043\u3044\u3045
+true \u3042\u3043\u3044 0
+
+\u3042\u3043\u3044(?=\u3045)
+\u305B\u305B\u305B\u3042\u3043\u3044\u3046\u3045
+false 0
+
+// Zero width Negative lookahead
+\u3042\u3043\u3044(?!\u3045)
+\u305B\u305B\u3042\u3043\u3044\u3045
+false 0
+
+\u3042\u3043\u3044(?!\u3045)
+\u305B\u305B\u3042\u3043\u3044\u3046\u3045
+true \u3042\u3043\u3044 0
+
+// Zero width Positive lookbehind
+\u3042(?<=\u3042)
+###\u3042\u3043\u3044
+true \u3042 0
+
+\u3042(?<=\u3042)
+###\u3043\u3044###
+false 0
+
+// Zero width Negative lookbehind
+(?<!\u3042)\w
+###\u3042\u3043\u3044a###
+true a 0
+
+(?<!\u3042)\u3044
+\u3043\u3044
+true \u3044 0
+
+(?<!\u3042)\u3044
+\u3042\u3044
+false 0
+
+// Nondeterministic group
+(\u3042+\u3043)+
+\u3042\u3043\u3042\u3043\u3042\u3043
+true \u3042\u3043\u3042\u3043\u3042\u3043 1 \u3042\u3043
+
+(\u3042|\u3043)+
+\u3044\u3044\u3044\u3044\u3045
+false 1
+
+// Deterministic group
+(\u3042\u3043)+
+\u3042\u3043\u3042\u3043\u3042\u3043
+true \u3042\u3043\u3042\u3043\u3042\u3043 1 \u3042\u3043
+
+(\u3042\u3043)+
+\u3042\u3044\u3044\u3044\u3044\u3045
+false 1
+
+(\u3042\u3043)*
+\u3042\u3043\u3042\u3043\u3042\u3043
+true \u3042\u3043\u3042\u3043\u3042\u3043 1 \u3042\u3043
+
+(\u3042\u3043)(\u3044\u3045*)
+\u305B\u305B\u305B\u3042\u3043\u3044\u305B\u305B\u305B
+true \u3042\u3043\u3044 2 \u3042\u3043 \u3044
+
+\u3042\u3043\u3044(\u3045)*\u3042\u3043\u3044
+\u3042\u3043\u3044\u3045\u3045\u3045\u3045\u3045\u3042\u3043\u3044
+true \u3042\u3043\u3044\u3045\u3045\u3045\u3045\u3045\u3042\u3043\u3044 1 \u3045
+
+// Back references
+(\u3042*)\u3043\u3044\1
+\u305B\u305B\u305B\u3042\u3042\u3043\u3044\u3042\u3042\u305B\u305B\u305B
+true \u3042\u3042\u3043\u3044\u3042\u3042 1 \u3042\u3042
+
+(\u3042*)\u3043\u3044\1
+\u305B\u305B\u305B\u3042\u3042\u3043\u3044\u3042\u305B\u305B\u305B
+true \u3042\u3043\u3044\u3042 1 \u3042
+
+(\u3048t*)(\u3045\u3045\u3046)*(\u305A\u3056)\1\3(\u3057\u3057)
+\u305B\u305B\u305B\u3048tt\u3045\u3045\u3046\u3045\u3045\u3046\u305A\u3056\u3048tt\u305A\u3056\u3057\u3057\u305B\u305B\u305B
+true \u3048tt\u3045\u3045\u3046\u3045\u3045\u3046\u305A\u3056\u3048tt\u305A\u3056\u3057\u3057 4 \u3048tt \u3045\u3045\u3046 \u305A\u3056 \u3057\u3057
+
+// Greedy * metacharacter
+\u3042*\u3043
+\u3042\u3042\u3042\u3042\u3043
+true \u3042\u3042\u3042\u3042\u3043 0
+
+\u3042*\u3043
+\u3043
+true \u3043 0
+
+\u3042*\u3043
+\u3042\u3042\u3042\u3044\u3044\u3044
+false 0
+
+.*\u3043
+\u3042\u3042\u3042\u3042\u3043
+true \u3042\u3042\u3042\u3042\u3043 0
+
+// Reluctant * metacharacter
+\u3042*?\u3043
+\u3042\u3042\u3042\u3042\u3043
+true \u3042\u3042\u3042\u3042\u3043 0
+
+\u3042*?\u3043
+\u3043
+true \u3043 0
+
+\u3042*?\u3043
+\u3042\u3042\u3042\u3044\u3044\u3044
+false 0
+
+.*?\u3043
+\u3042\u3042\u3042\u3042\u3043
+true \u3042\u3042\u3042\u3042\u3043 0
+
+// Possessive * metacharacter
+\u3042*+\u3043
+\u3042\u3042\u3042\u3042\u3043
+true \u3042\u3042\u3042\u3042\u3043 0
+
+\u3042*+\u3043
+\u3043
+true \u3043 0
+
+\u3042*+\u3043
+\u3042\u3042\u3042\u3044\u3044\u3044
+false 0
+
+.*+\u3043
+\u3042\u3042\u3042\u3042\u3043
+false 0
+
+// Case insensitivity
+(?iu)\uFF46\uFF4F\uFF4F\uFF42\uFF41\uFF52
+\uFF46\uFF2F\uFF4F\uFF42\uFF21\uFF52
+true \uFF46\uFF2F\uFF4F\uFF42\uFF21\uFF52 0
+
+\uFF46(?iu)\uFF4F\uFF4F\uFF42\uFF41\uFF52
+\uFF46\uFF2F\uFF4F\uFF42\uFF21\uFF52
+true \uFF46\uFF2F\uFF4F\uFF42\uFF21\uFF52 0
+
+\uFF46\uFF4F\uFF4F(?iu)\uFF42\uFF41\uFF52
+\uFF46\uFF2F\uFF4F\uFF42\uFF21\uFF52
+false 0
+
+(?iu)\uFF46\uFF4F\uFF4F[\uFF42\uFF41\uFF52]+
+\uFF46\uFF4F\uFF2F\uFF42\uFF21\uFF52
+true \uFF46\uFF4F\uFF2F\uFF42\uFF21\uFF52 0
+
+(?iu)\uFF46\uFF4F\uFF4F[\uFF41-\uFF52]+
+\uFF46\uFF4F\uFF2F\uFF42\uFF21\uFF52
+true \uFF46\uFF4F\uFF2F\uFF42\uFF21\uFF52 0
+
+// Disable metacharacters- test both length <=3 and >3
+// So that the BM optimization is part of test
+\Q***\E\u3042\u3043\u3044
+***\u3042\u3043\u3044
+true ***\u3042\u3043\u3044 0
+
+\u3043l\Q***\E\u3042\u3043\u3044
+\u3043l***\u3042\u3043\u3044
+true \u3043l***\u3042\u3043\u3044 0
+
+\Q***\u3042\u3043\u3044
+***\u3042\u3043\u3044
+true ***\u3042\u3043\u3044 0
+
+\u3043l\u3042\u3049\Q***\E\u3042\u3043\u3044
+\u3043l\u3042\u3049***\u3042\u3043\u3044
+true \u3043l\u3042\u3049***\u3042\u3043\u3044 0
+
+\Q***\u3042\u3043\u3044
+***\u3042\u3043\u3044
+true ***\u3042\u3043\u3044 0
+
+\Q*\u3042\u3043
+*\u3042\u3043
+true *\u3042\u3043 0
+
+\u3043l\u3042\u3049\Q***\u3042\u3043\u3044
+\u3043l\u3042\u3049***\u3042\u3043\u3044
+true \u3043l\u3042\u3049***\u3042\u3043\u3044 0
+
+\u3043l\u3042\Q***\u3042\u3043\u3044
+\u3043l\u3042***\u3042\u3043\u3044
+true \u3043l\u3042***\u3042\u3043\u3044 0
+
+[\043]+
+\u3043l\u3042\u3049\u3043l\u3042\u3049#\u3043le\u3044\u3049
+true # 0
+
+[\042-\044]+
+\u3043l\u3042\u3049\u3043l\u3042\u3049#\u3043le\u3044\u3049
+true # 0
+
+[\u1234-\u1236]
+\u3043l\u3042\u3049\u3043l\u3042\u3049\u1235\u3043le\u3044\u3049
+true \u1235 0
+
+[^\043]*
+\u3043l\u3042\u3049\u3043l\u3042\u3049#\u3043le\u3044\u3049
+true \u3043l\u3042\u3049\u3043l\u3042\u3049 0
diff --git a/jdk/test/java/util/regex/RegExTest.java b/jdk/test/java/util/regex/RegExTest.java
new file mode 100644
index 0000000..29d8b55
--- /dev/null
+++ b/jdk/test/java/util/regex/RegExTest.java
@@ -0,0 +1,3511 @@
+/*
+ * Copyright 1999-2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @summary tests RegExp framework
+ * @author Mike McCloskey
+ * @bug 4481568 4482696 4495089 4504687 4527731 4599621 4631553 4619345
+ * 4630911 4672616 4711773 4727935 4750573 4792284 4803197 4757029 4808962
+ * 4872664 4803179 4892980 4900747 4945394 4938995 4979006 4994840 4997476
+ * 5013885 5003322 4988891 5098443 5110268 6173522 4829857 5027748 6376940
+ * 6358731 6178785 6284152 6231989 6497148 6486934 6233084 6504326 6635133
+ * 6350801 6676425
+ */
+
+import java.util.regex.*;
+import java.util.Random;
+import java.io.*;
+import java.util.*;
+import java.nio.CharBuffer;
+
+/**
+ * This is a test class created to check the operation of
+ * the Pattern and Matcher classes.
+ */
+public class RegExTest {
+
+    private static Random generator = new Random();
+    private static boolean failure = false;
+    private static int failCount = 0;
+
+    /**
+     * Main to interpret arguments and run several tests.
+     *
+     */
+    public static void main(String[] args) throws Exception {
+        // Most of the tests are in a file
+        processFile("TestCases.txt");
+        //processFile("PerlCases.txt");
+        processFile("BMPTestCases.txt");
+        processFile("SupplementaryTestCases.txt");
+
+        // These test many randomly generated char patterns
+        bm();
+        slice();
+
+        // These are hard to put into the file
+        escapes();
+        blankInput();
+
+        // Substitition tests on randomly generated sequences
+        globalSubstitute();
+        stringbufferSubstitute();
+        substitutionBasher();
+
+        // Canonical Equivalence
+        ceTest();
+
+        // Anchors
+        anchorTest();
+
+        // boolean match calls
+        matchesTest();
+        lookingAtTest();
+
+        // Pattern API
+        patternMatchesTest();
+
+        // Misc
+        lookbehindTest();
+        nullArgumentTest();
+        backRefTest();
+        groupCaptureTest();
+        caretTest();
+        charClassTest();
+        emptyPatternTest();
+        findIntTest();
+        group0Test();
+        longPatternTest();
+        octalTest();
+        ampersandTest();
+        negationTest();
+        splitTest();
+        appendTest();
+        caseFoldingTest();
+        commentsTest();
+        unixLinesTest();
+        replaceFirstTest();
+        gTest();
+        zTest();
+        serializeTest();
+        reluctantRepetitionTest();
+        multilineDollarTest();
+        dollarAtEndTest();
+        caretBetweenTerminatorsTest();
+        // This RFE rejected in Tiger numOccurrencesTest();
+        javaCharClassTest();
+        nonCaptureRepetitionTest();
+        notCapturedGroupCurlyMatchTest();
+        escapedSegmentTest();
+        literalPatternTest();
+        literalReplacementTest();
+        regionTest();
+        toStringTest();
+        negatedCharClassTest();
+        findFromTest();
+        boundsTest();
+        unicodeWordBoundsTest();
+        caretAtEndTest();
+        wordSearchTest();
+        hitEndTest();
+        toMatchResultTest();
+        surrogatesInClassTest();
+        namedGroupCaptureTest();
+
+        if (failure)
+            throw new RuntimeException("Failure in the RE handling.");
+        else
+            System.err.println("OKAY: All tests passed.");
+    }
+
+    // Utility functions
+
+    private static String getRandomAlphaString(int length) {
+        StringBuffer buf = new StringBuffer(length);
+        for (int i=0; i<length; i++) {
+            char randChar = (char)(97 + generator.nextInt(26));
+            buf.append(randChar);
+        }
+        return buf.toString();
+    }
+
+    private static void check(Matcher m, String expected) {
+        m.find();
+        if (!m.group().equals(expected))
+            failCount++;
+    }
+
+    private static void check(Matcher m, String result, boolean expected) {
+        m.find();
+        if (m.group().equals(result))
+            failCount += (expected) ? 0 : 1;
+        else
+            failCount += (expected) ? 1 : 0;
+    }
+
+    private static void check(Pattern p, String s, boolean expected) {
+        Matcher matcher = p.matcher(s);
+        if (matcher.find())
+            failCount += (expected) ? 0 : 1;
+        else
+            failCount += (expected) ? 1 : 0;
+    }
+
+    private static void check(String p, char c, boolean expected) {
+        String propertyPattern = expected ? "\\p" + p : "\\P" + p;
+        Pattern pattern = Pattern.compile(propertyPattern);
+        char[] ca = new char[1]; ca[0] = c;
+        Matcher matcher = pattern.matcher(new String(ca));
+        if (!matcher.find())
+            failCount++;
+    }
+
+    private static void check(String p, int codePoint, boolean expected) {
+        String propertyPattern = expected ? "\\p" + p : "\\P" + p;
+        Pattern pattern = Pattern.compile(propertyPattern);
+        char[] ca = Character.toChars(codePoint);
+        Matcher matcher = pattern.matcher(new String(ca));
+        if (!matcher.find())
+            failCount++;
+    }
+
+    private static void check(String p, int flag, String input, String s,
+                              boolean expected)
+    {
+        Pattern pattern = Pattern.compile(p, flag);
+        Matcher matcher = pattern.matcher(input);
+        if (expected)
+            check(matcher, s, expected);
+        else
+            check(pattern, input, false);
+    }
+
+    private static void report(String testName) {
+        int spacesToAdd = 30 - testName.length();
+        StringBuffer paddedNameBuffer = new StringBuffer(testName);
+        for (int i=0; i<spacesToAdd; i++)
+            paddedNameBuffer.append(" ");
+        String paddedName = paddedNameBuffer.toString();
+        System.err.println(paddedName + ": " +
+                           (failCount==0 ? "Passed":"Failed("+failCount+")"));
+        if (failCount > 0)
+            failure = true;
+        failCount = 0;
+    }
+
+    /**
+     * Converts ASCII alphabet characters [A-Za-z] in the given 's' to
+     * supplementary characters. This method does NOT fully take care
+     * of the regex syntax.
+     */
+    private static String toSupplementaries(String s) {
+        int length = s.length();
+        StringBuffer sb = new StringBuffer(length * 2);
+
+        for (int i = 0; i < length; ) {
+            char c = s.charAt(i++);
+            if (c == '\\') {
+                sb.append(c);
+                if (i < length) {
+                    c = s.charAt(i++);
+                    sb.append(c);
+                    if (c == 'u') {
+                        // assume no syntax error
+                        sb.append(s.charAt(i++));
+                        sb.append(s.charAt(i++));
+                        sb.append(s.charAt(i++));
+                        sb.append(s.charAt(i++));
+                    }
+                }
+            } else if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) {
+                sb.append('\ud800').append((char)('\udc00'+c));
+            } else {
+                sb.append(c);
+            }
+        }
+        return sb.toString();
+    }
+
+    // Regular expression tests
+
+    // This is for bug 6178785
+    // Test if an expected NPE gets thrown when passing in a null argument
+    private static boolean check(Runnable test) {
+        try {
+            test.run();
+            failCount++;
+            return false;
+        } catch (NullPointerException npe) {
+            return true;
+        }
+    }
+
+    private static void nullArgumentTest() {
+        check(new Runnable() { public void run() { Pattern.compile(null); }});
+        check(new Runnable() { public void run() { Pattern.matches(null, null); }});
+        check(new Runnable() { public void run() { Pattern.matches("xyz", null);}});
+        check(new Runnable() { public void run() { Pattern.quote(null);}});
+        check(new Runnable() { public void run() { Pattern.compile("xyz").split(null);}});
+        check(new Runnable() { public void run() { Pattern.compile("xyz").matcher(null);}});
+
+        final Matcher m = Pattern.compile("xyz").matcher("xyz");
+        m.matches();
+        check(new Runnable() { public void run() { m.appendTail(null);}});
+        check(new Runnable() { public void run() { m.replaceAll(null);}});
+        check(new Runnable() { public void run() { m.replaceFirst(null);}});
+        check(new Runnable() { public void run() { m.appendReplacement(null, null);}});
+        check(new Runnable() { public void run() { m.reset(null);}});
+        check(new Runnable() { public void run() { Matcher.quoteReplacement(null);}});
+        //check(new Runnable() { public void run() { m.usePattern(null);}});
+
+        report("Null Argument");
+    }
+
+    // This is for bug6635133
+    // Test if surrogate pair in Unicode escapes can be handled correctly.
+    private static void surrogatesInClassTest() throws Exception {
+        Pattern pattern = Pattern.compile("[\\ud834\\udd21-\\ud834\\udd24]");
+        Matcher matcher = pattern.matcher("\ud834\udd22");
+        if (!matcher.find())
+            failCount++;
+    }
+
+    // This is for bug 4988891
+    // Test toMatchResult to see that it is a copy of the Matcher
+    // that is not affected by subsequent operations on the original
+    private static void toMatchResultTest() throws Exception {
+        Pattern pattern = Pattern.compile("squid");
+        Matcher matcher = pattern.matcher(
+            "agiantsquidofdestinyasmallsquidoffate");
+        matcher.find();
+        int matcherStart1 = matcher.start();
+        MatchResult mr = matcher.toMatchResult();
+        if (mr == matcher)
+            failCount++;
+        int resultStart1 = mr.start();
+        if (matcherStart1 != resultStart1)
+            failCount++;
+        matcher.find();
+        int matcherStart2 = matcher.start();
+        int resultStart2 = mr.start();
+        if (matcherStart2 == resultStart2)
+            failCount++;
+        if (resultStart1 != resultStart2)
+            failCount++;
+        MatchResult mr2 = matcher.toMatchResult();
+        if (mr == mr2)
+            failCount++;
+        if (mr2.start() != matcherStart2)
+            failCount++;
+        report("toMatchResult is a copy");
+    }
+
+    // This is for bug 5013885
+    // Must test a slice to see if it reports hitEnd correctly
+    private static void hitEndTest() throws Exception {
+        // Basic test of Slice node
+        Pattern p = Pattern.compile("^squidattack");
+        Matcher m = p.matcher("squack");
+        m.find();
+        if (m.hitEnd())
+            failCount++;
+        m.reset("squid");
+        m.find();
+        if (!m.hitEnd())
+            failCount++;
+
+        // Test Slice, SliceA and SliceU nodes
+        for (int i=0; i<3; i++) {
+            int flags = 0;
+            if (i==1) flags = Pattern.CASE_INSENSITIVE;
+            if (i==2) flags = Pattern.UNICODE_CASE;
+            p = Pattern.compile("^abc", flags);
+            m = p.matcher("ad");
+            m.find();
+            if (m.hitEnd())
+                failCount++;
+            m.reset("ab");
+            m.find();
+            if (!m.hitEnd())
+                failCount++;
+        }
+
+        // Test Boyer-Moore node
+        p = Pattern.compile("catattack");
+        m = p.matcher("attack");
+        m.find();
+        if (!m.hitEnd())
+            failCount++;
+
+        p = Pattern.compile("catattack");
+        m = p.matcher("attackattackattackcatatta");
+        m.find();
+        if (!m.hitEnd())
+            failCount++;
+
+        report("hitEnd from a Slice");
+    }
+
+    // This is for bug 4997476
+    // It is weird code submitted by customer demonstrating a regression
+    private static void wordSearchTest() throws Exception {
+        String testString = new String("word1 word2 word3");
+        Pattern p = Pattern.compile("\\b");
+        Matcher m = p.matcher(testString);
+        int position = 0;
+        int start = 0;
+        while (m.find(position)) {
+            start = m.start();
+            if (start == testString.length())
+                break;
+            if (m.find(start+1)) {
+                position = m.start();
+            } else {
+                position = testString.length();
+            }
+            if (testString.substring(start, position).equals(" "))
+                continue;
+            if (!testString.substring(start, position-1).startsWith("word"))
+                failCount++;
+        }
+        report("Customer word search");
+    }
+
+    // This is for bug 4994840
+    private static void caretAtEndTest() throws Exception {
+        // Problem only occurs with multiline patterns
+        // containing a beginning-of-line caret "^" followed
+        // by an expression that also matches the empty string.
+        Pattern pattern = Pattern.compile("^x?", Pattern.MULTILINE);
+        Matcher matcher = pattern.matcher("\r");
+        matcher.find();
+        matcher.find();
+        report("Caret at end");
+    }
+
+    // This test is for 4979006
+    // Check to see if word boundary construct properly handles unicode
+    // non spacing marks
+    private static void unicodeWordBoundsTest() throws Exception {
+        String spaces = "  ";
+        String wordChar = "a";
+        String nsm = "\u030a";
+
+        assert (Character.getType('\u030a') == Character.NON_SPACING_MARK);
+
+        Pattern pattern = Pattern.compile("\\b");
+        Matcher matcher = pattern.matcher("");
+        // S=other B=word character N=non spacing mark .=word boundary
+        // SS.BB.SS
+        String input = spaces + wordChar + wordChar + spaces;
+        twoFindIndexes(input, matcher, 2, 4);
+        // SS.BBN.SS
+        input = spaces + wordChar +wordChar + nsm + spaces;
+        twoFindIndexes(input, matcher, 2, 5);
+        // SS.BN.SS
+        input = spaces + wordChar + nsm + spaces;
+        twoFindIndexes(input, matcher, 2, 4);
+        // SS.BNN.SS
+        input = spaces + wordChar + nsm + nsm + spaces;
+        twoFindIndexes(input, matcher, 2, 5);
+        // SSN.BB.SS
+        input = spaces + nsm + wordChar + wordChar + spaces;
+        twoFindIndexes(input, matcher, 3, 5);
+        // SS.BNB.SS
+        input = spaces + wordChar + nsm + wordChar + spaces;
+        twoFindIndexes(input, matcher, 2, 5);
+        // SSNNSS
+        input = spaces + nsm + nsm + spaces;
+        matcher.reset(input);
+        if (matcher.find())
+            failCount++;
+        // SSN.BBN.SS
+        input = spaces + nsm + wordChar + wordChar + nsm + spaces;
+        twoFindIndexes(input, matcher, 3, 6);
+
+        report("Unicode word boundary");
+    }
+
+    private static void twoFindIndexes(String input, Matcher matcher, int a,
+                                       int b) throws Exception
+    {
+        matcher.reset(input);
+        matcher.find();
+        if (matcher.start() != a)
+            failCount++;
+        matcher.find();
+        if (matcher.start() != b)
+            failCount++;
+    }
+
+    // This test is for 6284152
+    static void check(String regex, String input, String[] expected) {
+        List<String> result = new ArrayList<String>();
+        Pattern p = Pattern.compile(regex);
+        Matcher m = p.matcher(input);
+        while (m.find()) {
+            result.add(m.group());
+        }
+        if (!Arrays.asList(expected).equals(result))
+            failCount++;
+    }
+
+    private static void lookbehindTest() throws Exception {
+        //Positive
+        check("(?<=%.{0,5})foo\\d",
+              "%foo1\n%bar foo2\n%bar  foo3\n%blahblah foo4\nfoo5",
+              new String[]{"foo1", "foo2", "foo3"});
+
+        //boundary at end of the lookbehind sub-regex should work consistently
+        //with the boundary just after the lookbehind sub-regex
+        check("(?<=.*\\b)foo", "abcd foo", new String[]{"foo"});
+        check("(?<=.*)\\bfoo", "abcd foo", new String[]{"foo"});
+        check("(?<!abc )\\bfoo", "abc foo", new String[0]);
+        check("(?<!abc \\b)foo", "abc foo", new String[0]);
+
+        //Negative
+        check("(?<!%.{0,5})foo\\d",
+              "%foo1\n%bar foo2\n%bar  foo3\n%blahblah foo4\nfoo5",
+              new String[] {"foo4", "foo5"});
+
+        //Positive greedy
+        check("(?<=%b{1,4})foo", "%bbbbfoo", new String[] {"foo"});
+
+        //Positive reluctant
+        check("(?<=%b{1,4}?)foo", "%bbbbfoo", new String[] {"foo"});
+
+        //supplementary
+        check("(?<=%b{1,4})fo\ud800\udc00o", "%bbbbfo\ud800\udc00o",
+              new String[] {"fo\ud800\udc00o"});
+        check("(?<=%b{1,4}?)fo\ud800\udc00o", "%bbbbfo\ud800\udc00o",
+              new String[] {"fo\ud800\udc00o"});
+        check("(?<!%b{1,4})fo\ud800\udc00o", "%afo\ud800\udc00o",
+              new String[] {"fo\ud800\udc00o"});
+        check("(?<!%b{1,4}?)fo\ud800\udc00o", "%afo\ud800\udc00o",
+              new String[] {"fo\ud800\udc00o"});
+        report("Lookbehind");
+    }
+
+    // This test is for 4938995
+    // Check to see if weak region boundaries are transparent to
+    // lookahead and lookbehind constructs
+    private static void boundsTest() throws Exception {
+        String fullMessage = "catdogcat";
+        Pattern pattern = Pattern.compile("(?<=cat)dog(?=cat)");
+        Matcher matcher = pattern.matcher("catdogca");
+        matcher.useTransparentBounds(true);
+        if (matcher.find())
+            failCount++;
+        matcher.reset("atdogcat");
+        if (matcher.find())
+            failCount++;
+        matcher.reset(fullMessage);
+        if (!matcher.find())
+            failCount++;
+        matcher.reset(fullMessage);
+        matcher.region(0,9);
+        if (!matcher.find())
+            failCount++;
+        matcher.reset(fullMessage);
+        matcher.region(0,6);
+        if (!matcher.find())
+            failCount++;
+        matcher.reset(fullMessage);
+        matcher.region(3,6);
+        if (!matcher.find())
+            failCount++;
+        matcher.useTransparentBounds(false);
+        if (matcher.find())
+            failCount++;
+
+        // Negative lookahead/lookbehind
+        pattern = Pattern.compile("(?<!cat)dog(?!cat)");
+        matcher = pattern.matcher("dogcat");
+        matcher.useTransparentBounds(true);
+        matcher.region(0,3);
+        if (matcher.find())
+            failCount++;
+        matcher.reset("catdog");
+        matcher.region(3,6);
+        if (matcher.find())
+            failCount++;
+        matcher.useTransparentBounds(false);
+        matcher.reset("dogcat");
+        matcher.region(0,3);
+        if (!matcher.find())
+            failCount++;
+        matcher.reset("catdog");
+        matcher.region(3,6);
+        if (!matcher.find())
+            failCount++;
+
+        report("Region bounds transparency");
+    }
+
+    // This test is for 4945394
+    private static void findFromTest() throws Exception {
+        String message = "This is 40 $0 message.";
+        Pattern pat = Pattern.compile("\\$0");
+        Matcher match = pat.matcher(message);
+        if (!match.find())
+            failCount++;
+        if (match.find())
+            failCount++;
+        if (match.find())
+            failCount++;
+        report("Check for alternating find");
+    }
+
+    // This test is for 4872664 and 4892980
+    private static void negatedCharClassTest() throws Exception {
+        Pattern pattern = Pattern.compile("[^>]");
+        Matcher matcher = pattern.matcher("\u203A");
+        if (!matcher.matches())
+            failCount++;
+        pattern = Pattern.compile("[^fr]");
+        matcher = pattern.matcher("a");
+        if (!matcher.find())
+            failCount++;
+        matcher.reset("\u203A");
+        if (!matcher.find())
+            failCount++;
+        String s = "for";
+        String result[] = s.split("[^fr]");
+        if (!result[0].equals("f"))
+            failCount++;
+        if (!result[1].equals("r"))
+            failCount++;
+        s = "f\u203Ar";
+        result = s.split("[^fr]");
+        if (!result[0].equals("f"))
+            failCount++;
+        if (!result[1].equals("r"))
+            failCount++;
+
+        // Test adding to bits, subtracting a node, then adding to bits again
+        pattern = Pattern.compile("[^f\u203Ar]");
+        matcher = pattern.matcher("a");
+        if (!matcher.find())
+            failCount++;
+        matcher.reset("f");
+        if (matcher.find())
+            failCount++;
+        matcher.reset("\u203A");
+        if (matcher.find())
+            failCount++;
+        matcher.reset("r");
+        if (matcher.find())
+            failCount++;
+        matcher.reset("\u203B");
+        if (!matcher.find())
+            failCount++;
+
+        // Test subtracting a node, adding to bits, subtracting again
+        pattern = Pattern.compile("[^\u203Ar\u203B]");
+        matcher = pattern.matcher("a");
+        if (!matcher.find())
+            failCount++;
+        matcher.reset("\u203A");
+        if (matcher.find())
+            failCount++;
+        matcher.reset("r");
+        if (matcher.find())
+            failCount++;
+        matcher.reset("\u203B");
+        if (matcher.find())
+            failCount++;
+        matcher.reset("\u203C");
+        if (!matcher.find())
+            failCount++;
+
+        report("Negated Character Class");
+    }
+
+    // This test is for 4628291
+    private static void toStringTest() throws Exception {
+        Pattern pattern = Pattern.compile("b+");
+        if (pattern.toString() != "b+")
+            failCount++;
+        Matcher matcher = pattern.matcher("aaabbbccc");
+        String matcherString = matcher.toString(); // unspecified
+        matcher.find();
+        matcherString = matcher.toString(); // unspecified
+        matcher.region(0,3);
+        matcherString = matcher.toString(); // unspecified
+        matcher.reset();
+        matcherString = matcher.toString(); // unspecified
+        report("toString");
+    }
+
+    // This test is for 4808962
+    private static void literalPatternTest() throws Exception {
+        int flags = Pattern.LITERAL;
+
+        Pattern pattern = Pattern.compile("abc\\t$^", flags);
+        check(pattern, "abc\\t$^", true);
+
+        pattern = Pattern.compile(Pattern.quote("abc\\t$^"));
+        check(pattern, "abc\\t$^", true);
+
+        pattern = Pattern.compile("\\Qa^$bcabc\\E", flags);
+        check(pattern, "\\Qa^$bcabc\\E", true);
+        check(pattern, "a^$bcabc", false);
+
+        pattern = Pattern.compile("\\\\Q\\\\E");
+        check(pattern, "\\Q\\E", true);
+
+        pattern = Pattern.compile("\\Qabc\\Eefg\\\\Q\\\\Ehij");
+        check(pattern, "abcefg\\Q\\Ehij", true);
+
+        pattern = Pattern.compile("\\\\\\Q\\\\E");
+        check(pattern, "\\\\\\\\", true);
+
+        pattern = Pattern.compile(Pattern.quote("\\Qa^$bcabc\\E"));
+        check(pattern, "\\Qa^$bcabc\\E", true);
+        check(pattern, "a^$bcabc", false);
+
+        pattern = Pattern.compile(Pattern.quote("\\Qabc\\Edef"));
+        check(pattern, "\\Qabc\\Edef", true);
+        check(pattern, "abcdef", false);
+
+        pattern = Pattern.compile(Pattern.quote("abc\\Edef"));
+        check(pattern, "abc\\Edef", true);
+        check(pattern, "abcdef", false);
+
+        pattern = Pattern.compile(Pattern.quote("\\E"));
+        check(pattern, "\\E", true);
+
+        pattern = Pattern.compile("((((abc.+?:)", flags);
+        check(pattern, "((((abc.+?:)", true);
+
+        flags |= Pattern.MULTILINE;
+
+        pattern = Pattern.compile("^cat$", flags);
+        check(pattern, "abc^cat$def", true);
+        check(pattern, "cat", false);
+
+        flags |= Pattern.CASE_INSENSITIVE;
+
+        pattern = Pattern.compile("abcdef", flags);
+        check(pattern, "ABCDEF", true);
+        check(pattern, "AbCdEf", true);
+
+        flags |= Pattern.DOTALL;
+
+        pattern = Pattern.compile("a...b", flags);
+        check(pattern, "A...b", true);
+        check(pattern, "Axxxb", false);
+
+        flags |= Pattern.CANON_EQ;
+
+        Pattern p = Pattern.compile("testa\u030a", flags);
+        check(pattern, "testa\u030a", false);
+        check(pattern, "test\u00e5", false);
+
+        // Supplementary character test
+        flags = Pattern.LITERAL;
+
+        pattern = Pattern.compile(toSupplementaries("abc\\t$^"), flags);
+        check(pattern, toSupplementaries("abc\\t$^"), true);
+
+        pattern = Pattern.compile(Pattern.quote(toSupplementaries("abc\\t$^")));
+        check(pattern, toSupplementaries("abc\\t$^"), true);
+
+        pattern = Pattern.compile(toSupplementaries("\\Qa^$bcabc\\E"), flags);
+        check(pattern, toSupplementaries("\\Qa^$bcabc\\E"), true);
+        check(pattern, toSupplementaries("a^$bcabc"), false);
+
+        pattern = Pattern.compile(Pattern.quote(toSupplementaries("\\Qa^$bcabc\\E")));
+        check(pattern, toSupplementaries("\\Qa^$bcabc\\E"), true);
+        check(pattern, toSupplementaries("a^$bcabc"), false);
+
+        pattern = Pattern.compile(Pattern.quote(toSupplementaries("\\Qabc\\Edef")));
+        check(pattern, toSupplementaries("\\Qabc\\Edef"), true);
+        check(pattern, toSupplementaries("abcdef"), false);
+
+        pattern = Pattern.compile(Pattern.quote(toSupplementaries("abc\\Edef")));
+        check(pattern, toSupplementaries("abc\\Edef"), true);
+        check(pattern, toSupplementaries("abcdef"), false);
+
+        pattern = Pattern.compile(toSupplementaries("((((abc.+?:)"), flags);
+        check(pattern, toSupplementaries("((((abc.+?:)"), true);
+
+        flags |= Pattern.MULTILINE;
+
+        pattern = Pattern.compile(toSupplementaries("^cat$"), flags);
+        check(pattern, toSupplementaries("abc^cat$def"), true);
+        check(pattern, toSupplementaries("cat"), false);
+
+        flags |= Pattern.DOTALL;
+
+        // note: this is case-sensitive.
+        pattern = Pattern.compile(toSupplementaries("a...b"), flags);
+        check(pattern, toSupplementaries("a...b"), true);
+        check(pattern, toSupplementaries("axxxb"), false);
+
+        flags |= Pattern.CANON_EQ;
+
+        String t = toSupplementaries("test");
+        p = Pattern.compile(t + "a\u030a", flags);
+        check(pattern, t + "a\u030a", false);
+        check(pattern, t + "\u00e5", false);
+
+        report("Literal pattern");
+    }
+
+    // This test is for 4803179
+    // This test is also for 4808962, replacement parts
+    private static void literalReplacementTest() throws Exception {
+        int flags = Pattern.LITERAL;
+
+        Pattern pattern = Pattern.compile("abc", flags);
+        Matcher matcher = pattern.matcher("zzzabczzz");
+        String replaceTest = "$0";
+        String result = matcher.replaceAll(replaceTest);
+        if (!result.equals("zzzabczzz"))
+            failCount++;
+
+        matcher.reset();
+        String literalReplacement = matcher.quoteReplacement(replaceTest);
+        result = matcher.replaceAll(literalReplacement);
+        if (!result.equals("zzz$0zzz"))
+            failCount++;
+
+        matcher.reset();
+        replaceTest = "\\t$\\$";
+        literalReplacement = matcher.quoteReplacement(replaceTest);
+        result = matcher.replaceAll(literalReplacement);
+        if (!result.equals("zzz\\t$\\$zzz"))
+            failCount++;
+
+        // Supplementary character test
+        pattern = Pattern.compile(toSupplementaries("abc"), flags);
+        matcher = pattern.matcher(toSupplementaries("zzzabczzz"));
+        replaceTest = "$0";
+        result = matcher.replaceAll(replaceTest);
+        if (!result.equals(toSupplementaries("zzzabczzz")))
+            failCount++;
+
+        matcher.reset();
+        literalReplacement = matcher.quoteReplacement(replaceTest);
+        result = matcher.replaceAll(literalReplacement);
+        if (!result.equals(toSupplementaries("zzz$0zzz")))
+            failCount++;
+
+        matcher.reset();
+        replaceTest = "\\t$\\$";
+        literalReplacement = matcher.quoteReplacement(replaceTest);
+        result = matcher.replaceAll(literalReplacement);
+        if (!result.equals(toSupplementaries("zzz\\t$\\$zzz")))
+            failCount++;
+
+        report("Literal replacement");
+    }
+
+    // This test is for 4757029
+    private static void regionTest() throws Exception {
+        Pattern pattern = Pattern.compile("abc");
+        Matcher matcher = pattern.matcher("abcdefabc");
+
+        matcher.region(0,9);
+        if (!matcher.find())
+            failCount++;
+        if (!matcher.find())
+            failCount++;
+        matcher.region(0,3);
+        if (!matcher.find())
+           failCount++;
+        matcher.region(3,6);
+        if (matcher.find())
+           failCount++;
+        matcher.region(0,2);
+        if (matcher.find())
+           failCount++;
+
+        expectRegionFail(matcher, 1, -1);
+        expectRegionFail(matcher, -1, -1);
+        expectRegionFail(matcher, -1, 1);
+        expectRegionFail(matcher, 5, 3);
+        expectRegionFail(matcher, 5, 12);
+        expectRegionFail(matcher, 12, 12);
+
+        pattern = Pattern.compile("^abc$");
+        matcher = pattern.matcher("zzzabczzz");
+        matcher.region(0,9);
+        if (matcher.find())
+            failCount++;
+        matcher.region(3,6);
+        if (!matcher.find())
+           failCount++;
+        matcher.region(3,6);
+        matcher.useAnchoringBounds(false);
+        if (matcher.find())
+           failCount++;
+
+        // Supplementary character test
+        pattern = Pattern.compile(toSupplementaries("abc"));
+        matcher = pattern.matcher(toSupplementaries("abcdefabc"));
+        matcher.region(0,9*2);
+        if (!matcher.find())
+            failCount++;
+        if (!matcher.find())
+            failCount++;
+        matcher.region(0,3*2);
+        if (!matcher.find())
+           failCount++;
+        matcher.region(1,3*2);
+        if (matcher.find())
+           failCount++;
+        matcher.region(3*2,6*2);
+        if (matcher.find())
+           failCount++;
+        matcher.region(0,2*2);
+        if (matcher.find())
+           failCount++;
+        matcher.region(0,2*2+1);
+        if (matcher.find())
+           failCount++;
+
+        expectRegionFail(matcher, 1*2, -1);
+        expectRegionFail(matcher, -1, -1);
+        expectRegionFail(matcher, -1, 1*2);
+        expectRegionFail(matcher, 5*2, 3*2);
+        expectRegionFail(matcher, 5*2, 12*2);
+        expectRegionFail(matcher, 12*2, 12*2);
+
+        pattern = Pattern.compile(toSupplementaries("^abc$"));
+        matcher = pattern.matcher(toSupplementaries("zzzabczzz"));
+        matcher.region(0,9*2);
+        if (matcher.find())
+            failCount++;
+        matcher.region(3*2,6*2);
+        if (!matcher.find())
+           failCount++;
+        matcher.region(3*2+1,6*2);
+        if (matcher.find())
+           failCount++;
+        matcher.region(3*2,6*2-1);
+        if (matcher.find())
+           failCount++;
+        matcher.region(3*2,6*2);
+        matcher.useAnchoringBounds(false);
+        if (matcher.find())
+           failCount++;
+        report("Regions");
+    }
+
+    private static void expectRegionFail(Matcher matcher, int index1,
+                                         int index2)
+    {
+        try {
+            matcher.region(index1, index2);
+            failCount++;
+        } catch (IndexOutOfBoundsException ioobe) {
+            // Correct result
+        } catch (IllegalStateException ise) {
+            // Correct result
+        }
+    }
+
+    // This test is for 4803197
+    private static void escapedSegmentTest() throws Exception {
+
+        Pattern pattern = Pattern.compile("\\Qdir1\\dir2\\E");
+        check(pattern, "dir1\\dir2", true);
+
+        pattern = Pattern.compile("\\Qdir1\\dir2\\\\E");
+        check(pattern, "dir1\\dir2\\", true);
+
+        pattern = Pattern.compile("(\\Qdir1\\dir2\\\\E)");
+        check(pattern, "dir1\\dir2\\", true);
+
+        // Supplementary character test
+        pattern = Pattern.compile(toSupplementaries("\\Qdir1\\dir2\\E"));
+        check(pattern, toSupplementaries("dir1\\dir2"), true);
+
+        pattern = Pattern.compile(toSupplementaries("\\Qdir1\\dir2")+"\\\\E");
+        check(pattern, toSupplementaries("dir1\\dir2\\"), true);
+
+        pattern = Pattern.compile(toSupplementaries("(\\Qdir1\\dir2")+"\\\\E)");
+        check(pattern, toSupplementaries("dir1\\dir2\\"), true);
+
+        report("Escaped segment");
+    }
+
+    // This test is for 4792284
+    private static void nonCaptureRepetitionTest() throws Exception {
+        String input = "abcdefgh;";
+
+        String[] patterns = new String[] {
+            "(?:\\w{4})+;",
+            "(?:\\w{8})*;",
+            "(?:\\w{2}){2,4};",
+            "(?:\\w{4}){2,};",   // only matches the
+            ".*?(?:\\w{5})+;",   //     specified minimum
+            ".*?(?:\\w{9})*;",   //     number of reps - OK
+            "(?:\\w{4})+?;",     // lazy repetition - OK
+            "(?:\\w{4})++;",     // possessive repetition - OK
+            "(?:\\w{2,}?)+;",    // non-deterministic - OK
+            "(\\w{4})+;",        // capturing group - OK
+        };
+
+        for (int i = 0; i < patterns.length; i++) {
+            // Check find()
+            check(patterns[i], 0, input, input, true);
+            // Check matches()
+            Pattern p = Pattern.compile(patterns[i]);
+            Matcher m = p.matcher(input);
+
+            if (m.matches()) {
+                if (!m.group(0).equals(input))
+                    failCount++;
+            } else {
+                failCount++;
+            }
+        }
+
+        report("Non capturing repetition");
+    }
+
+    // This test is for 6358731
+    private static void notCapturedGroupCurlyMatchTest() throws Exception {
+        Pattern pattern = Pattern.compile("(abc)+|(abcd)+");
+        Matcher matcher = pattern.matcher("abcd");
+        if (!matcher.matches() ||
+             matcher.group(1) != null ||
+             !matcher.group(2).equals("abcd")) {
+            failCount++;
+        }
+        report("Not captured GroupCurly");
+    }
+
+    // This test is for 4706545
+    private static void javaCharClassTest() throws Exception {
+        for (int i=0; i<1000; i++) {
+            char c = (char)generator.nextInt();
+            check("{javaLowerCase}", c, Character.isLowerCase(c));
+            check("{javaUpperCase}", c, Character.isUpperCase(c));
+            check("{javaUpperCase}+", c, Character.isUpperCase(c));
+            check("{javaTitleCase}", c, Character.isTitleCase(c));
+            check("{javaDigit}", c, Character.isDigit(c));
+            check("{javaDefined}", c, Character.isDefined(c));
+            check("{javaLetter}", c, Character.isLetter(c));
+            check("{javaLetterOrDigit}", c, Character.isLetterOrDigit(c));
+            check("{javaJavaIdentifierStart}", c,
+                  Character.isJavaIdentifierStart(c));
+            check("{javaJavaIdentifierPart}", c,
+                  Character.isJavaIdentifierPart(c));
+            check("{javaUnicodeIdentifierStart}", c,
+                  Character.isUnicodeIdentifierStart(c));
+            check("{javaUnicodeIdentifierPart}", c,
+                  Character.isUnicodeIdentifierPart(c));
+            check("{javaIdentifierIgnorable}", c,
+                  Character.isIdentifierIgnorable(c));
+            check("{javaSpaceChar}", c, Character.isSpaceChar(c));
+            check("{javaWhitespace}", c, Character.isWhitespace(c));
+            check("{javaISOControl}", c, Character.isISOControl(c));
+            check("{javaMirrored}", c, Character.isMirrored(c));
+
+        }
+
+        // Supplementary character test
+        for (int i=0; i<1000; i++) {
+            int c = generator.nextInt(Character.MAX_CODE_POINT
+                                      - Character.MIN_SUPPLEMENTARY_CODE_POINT)
+                        + Character.MIN_SUPPLEMENTARY_CODE_POINT;
+            check("{javaLowerCase}", c, Character.isLowerCase(c));
+            check("{javaUpperCase}", c, Character.isUpperCase(c));
+            check("{javaUpperCase}+", c, Character.isUpperCase(c));
+            check("{javaTitleCase}", c, Character.isTitleCase(c));
+            check("{javaDigit}", c, Character.isDigit(c));
+            check("{javaDefined}", c, Character.isDefined(c));
+            check("{javaLetter}", c, Character.isLetter(c));
+            check("{javaLetterOrDigit}", c, Character.isLetterOrDigit(c));
+            check("{javaJavaIdentifierStart}", c,
+                  Character.isJavaIdentifierStart(c));
+            check("{javaJavaIdentifierPart}", c,
+                  Character.isJavaIdentifierPart(c));
+            check("{javaUnicodeIdentifierStart}", c,
+                  Character.isUnicodeIdentifierStart(c));
+            check("{javaUnicodeIdentifierPart}", c,
+                  Character.isUnicodeIdentifierPart(c));
+            check("{javaIdentifierIgnorable}", c,
+                  Character.isIdentifierIgnorable(c));
+            check("{javaSpaceChar}", c, Character.isSpaceChar(c));
+            check("{javaWhitespace}", c, Character.isWhitespace(c));
+            check("{javaISOControl}", c, Character.isISOControl(c));
+            check("{javaMirrored}", c, Character.isMirrored(c));
+        }
+
+        report("Java character classes");
+    }
+
+    // This test is for 4523620
+    /*
+    private static void numOccurrencesTest() throws Exception {
+        Pattern pattern = Pattern.compile("aaa");
+
+        if (pattern.numOccurrences("aaaaaa", false) != 2)
+            failCount++;
+        if (pattern.numOccurrences("aaaaaa", true) != 4)
+            failCount++;
+
+        pattern = Pattern.compile("^");
+        if (pattern.numOccurrences("aaaaaa", false) != 1)
+            failCount++;
+        if (pattern.numOccurrences("aaaaaa", true) != 1)
+            failCount++;
+
+        report("Number of Occurrences");
+    }
+    */
+
+    // This test is for 4776374
+    private static void caretBetweenTerminatorsTest() throws Exception {
+        int flags1 = Pattern.DOTALL;
+        int flags2 = Pattern.DOTALL | Pattern.UNIX_LINES;
+        int flags3 = Pattern.DOTALL | Pattern.UNIX_LINES | Pattern.MULTILINE;
+        int flags4 = Pattern.DOTALL | Pattern.MULTILINE;
+
+        check("^....", flags1, "test\ntest", "test", true);
+        check(".....^", flags1, "test\ntest", "test", false);
+        check(".....^", flags1, "test\n", "test", false);
+        check("....^", flags1, "test\r\n", "test", false);
+
+        check("^....", flags2, "test\ntest", "test", true);
+        check("....^", flags2, "test\ntest", "test", false);
+        check(".....^", flags2, "test\n", "test", false);
+        check("....^", flags2, "test\r\n", "test", false);
+
+        check("^....", flags3, "test\ntest", "test", true);
+        check(".....^", flags3, "test\ntest", "test\n", true);
+        check(".....^", flags3, "test\u0085test", "test\u0085", false);
+        check(".....^", flags3, "test\n", "test", false);
+        check(".....^", flags3, "test\r\n", "test", false);
+        check("......^", flags3, "test\r\ntest", "test\r\n", true);
+
+        check("^....", flags4, "test\ntest", "test", true);
+        check(".....^", flags3, "test\ntest", "test\n", true);
+        check(".....^", flags4, "test\u0085test", "test\u0085", true);
+        check(".....^", flags4, "test\n", "test\n", false);
+        check(".....^", flags4, "test\r\n", "test\r", false);
+
+        // Supplementary character test
+        String t = toSupplementaries("test");
+        check("^....", flags1, t+"\n"+t, t, true);
+        check(".....^", flags1, t+"\n"+t, t, false);
+        check(".....^", flags1, t+"\n", t, false);
+        check("....^", flags1, t+"\r\n", t, false);
+
+        check("^....", flags2, t+"\n"+t, t, true);
+        check("....^", flags2, t+"\n"+t, t, false);
+        check(".....^", flags2, t+"\n", t, false);
+        check("....^", flags2, t+"\r\n", t, false);
+
+        check("^....", flags3, t+"\n"+t, t, true);
+        check(".....^", flags3, t+"\n"+t, t+"\n", true);
+        check(".....^", flags3, t+"\u0085"+t, t+"\u0085", false);
+        check(".....^", flags3, t+"\n", t, false);
+        check(".....^", flags3, t+"\r\n", t, false);
+        check("......^", flags3, t+"\r\n"+t, t+"\r\n", true);
+
+        check("^....", flags4, t+"\n"+t, t, true);
+        check(".....^", flags3, t+"\n"+t, t+"\n", true);
+        check(".....^", flags4, t+"\u0085"+t, t+"\u0085", true);
+        check(".....^", flags4, t+"\n", t+"\n", false);
+        check(".....^", flags4, t+"\r\n", t+"\r", false);
+
+        report("Caret between terminators");
+    }
+
+    // This test is for 4727935
+    private static void dollarAtEndTest() throws Exception {
+        int flags1 = Pattern.DOTALL;
+        int flags2 = Pattern.DOTALL | Pattern.UNIX_LINES;
+        int flags3 = Pattern.DOTALL | Pattern.MULTILINE;
+
+        check("....$", flags1, "test\n", "test", true);
+        check("....$", flags1, "test\r\n", "test", true);
+        check(".....$", flags1, "test\n", "test\n", true);
+        check(".....$", flags1, "test\u0085", "test\u0085", true);
+        check("....$", flags1, "test\u0085", "test", true);
+
+        check("....$", flags2, "test\n", "test", true);
+        check(".....$", flags2, "test\n", "test\n", true);
+        check(".....$", flags2, "test\u0085", "test\u0085", true);
+        check("....$", flags2, "test\u0085", "est\u0085", true);
+
+        check("....$.blah", flags3, "test\nblah", "test\nblah", true);
+        check(".....$.blah", flags3, "test\n\nblah", "test\n\nblah", true);
+        check("....$blah", flags3, "test\nblah", "!!!!", false);
+        check(".....$blah", flags3, "test\nblah", "!!!!", false);
+
+        // Supplementary character test
+        String t = toSupplementaries("test");
+        String b = toSupplementaries("blah");
+        check("....$", flags1, t+"\n", t, true);
+        check("....$", flags1, t+"\r\n", t, true);
+        check(".....$", flags1, t+"\n", t+"\n", true);
+        check(".....$", flags1, t+"\u0085", t+"\u0085", true);
+        check("....$", flags1, t+"\u0085", t, true);
+
+        check("....$", flags2, t+"\n", t, true);
+        check(".....$", flags2, t+"\n", t+"\n", true);
+        check(".....$", flags2, t+"\u0085", t+"\u0085", true);
+        check("....$", flags2, t+"\u0085", toSupplementaries("est\u0085"), true);
+
+        check("....$."+b, flags3, t+"\n"+b, t+"\n"+b, true);
+        check(".....$."+b, flags3, t+"\n\n"+b, t+"\n\n"+b, true);
+        check("....$"+b, flags3, t+"\n"+b, "!!!!", false);
+        check(".....$"+b, flags3, t+"\n"+b, "!!!!", false);
+
+        report("Dollar at End");
+    }
+
+    // This test is for 4711773
+    private static void multilineDollarTest() throws Exception {
+        Pattern findCR = Pattern.compile("$", Pattern.MULTILINE);
+        Matcher matcher = findCR.matcher("first bit\nsecond bit");
+        matcher.find();
+        if (matcher.start(0) != 9)
+            failCount++;
+        matcher.find();
+        if (matcher.start(0) != 20)
+            failCount++;
+
+        // Supplementary character test
+        matcher = findCR.matcher(toSupplementaries("first  bit\n second  bit")); // double BMP chars
+        matcher.find();
+        if (matcher.start(0) != 9*2)
+            failCount++;
+        matcher.find();
+        if (matcher.start(0) != 20*2)
+            failCount++;
+
+        report("Multiline Dollar");
+    }
+
+    private static void reluctantRepetitionTest() throws Exception {
+        Pattern p = Pattern.compile("1(\\s\\S+?){1,3}?[\\s,]2");
+        check(p, "1 word word word 2", true);
+        check(p, "1 wor wo w 2", true);
+        check(p, "1 word word 2", true);
+        check(p, "1 word 2", true);
+        check(p, "1 wo w w 2", true);
+        check(p, "1 wo w 2", true);
+        check(p, "1 wor w 2", true);
+
+        p = Pattern.compile("([a-z])+?c");
+        Matcher m = p.matcher("ababcdefdec");
+        check(m, "ababc");
+
+        // Supplementary character test
+        p = Pattern.compile(toSupplementaries("([a-z])+?c"));
+        m = p.matcher(toSupplementaries("ababcdefdec"));
+        check(m, toSupplementaries("ababc"));
+
+        report("Reluctant Repetition");
+    }
+
+    private static void serializeTest() throws Exception {
+        String patternStr = "(b)";
+        String matchStr = "b";
+        Pattern pattern = Pattern.compile(patternStr);
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ObjectOutputStream oos = new ObjectOutputStream(baos);
+        oos.writeObject(pattern);
+        oos.close();
+        ObjectInputStream ois = new ObjectInputStream(
+            new ByteArrayInputStream(baos.toByteArray()));
+        Pattern serializedPattern = (Pattern)ois.readObject();
+        ois.close();
+        Matcher matcher = serializedPattern.matcher(matchStr);
+        if (!matcher.matches())
+            failCount++;
+        if (matcher.groupCount() != 1)
+            failCount++;
+
+        report("Serialization");
+    }
+
+    private static void gTest() {
+        Pattern pattern = Pattern.compile("\\G\\w");
+        Matcher matcher = pattern.matcher("abc#x#x");
+        matcher.find();
+        matcher.find();
+        matcher.find();
+        if (matcher.find())
+            failCount++;
+
+        pattern = Pattern.compile("\\GA*");
+        matcher = pattern.matcher("1A2AA3");
+        matcher.find();
+        if (matcher.find())
+            failCount++;
+
+        pattern = Pattern.compile("\\GA*");
+        matcher = pattern.matcher("1A2AA3");
+        if (!matcher.find(1))
+            failCount++;
+        matcher.find();
+        if (matcher.find())
+            failCount++;
+
+        report("\\G");
+    }
+
+    private static void zTest() {
+        Pattern pattern = Pattern.compile("foo\\Z");
+        // Positives
+        check(pattern, "foo\u0085", true);
+        check(pattern, "foo\u2028", true);
+        check(pattern, "foo\u2029", true);
+        check(pattern, "foo\n", true);
+        check(pattern, "foo\r", true);
+        check(pattern, "foo\r\n", true);
+        // Negatives
+        check(pattern, "fooo", false);
+        check(pattern, "foo\n\r", false);
+
+        pattern = Pattern.compile("foo\\Z", Pattern.UNIX_LINES);
+        // Positives
+        check(pattern, "foo", true);
+        check(pattern, "foo\n", true);
+        // Negatives
+        check(pattern, "foo\r", false);
+        check(pattern, "foo\u0085", false);
+        check(pattern, "foo\u2028", false);
+        check(pattern, "foo\u2029", false);
+
+        report("\\Z");
+    }
+
+    private static void replaceFirstTest() {
+        Pattern pattern = Pattern.compile("(ab)(c*)");
+        Matcher matcher = pattern.matcher("abccczzzabcczzzabccc");
+        if (!matcher.replaceFirst("test").equals("testzzzabcczzzabccc"))
+            failCount++;
+
+        matcher.reset("zzzabccczzzabcczzzabccczzz");
+        if (!matcher.replaceFirst("test").equals("zzztestzzzabcczzzabccczzz"))
+            failCount++;
+
+        matcher.reset("zzzabccczzzabcczzzabccczzz");
+        String result = matcher.replaceFirst("$1");
+        if (!result.equals("zzzabzzzabcczzzabccczzz"))
+            failCount++;
+
+        matcher.reset("zzzabccczzzabcczzzabccczzz");
+        result = matcher.replaceFirst("$2");
+        if (!result.equals("zzzccczzzabcczzzabccczzz"))
+            failCount++;
+
+        pattern = Pattern.compile("a*");
+        matcher = pattern.matcher("aaaaaaaaaa");
+        if (!matcher.replaceFirst("test").equals("test"))
+            failCount++;
+
+        pattern = Pattern.compile("a+");
+        matcher = pattern.matcher("zzzaaaaaaaaaa");
+        if (!matcher.replaceFirst("test").equals("zzztest"))
+            failCount++;
+
+        // Supplementary character test
+        pattern = Pattern.compile(toSupplementaries("(ab)(c*)"));
+        matcher = pattern.matcher(toSupplementaries("abccczzzabcczzzabccc"));
+        if (!matcher.replaceFirst(toSupplementaries("test"))
+                .equals(toSupplementaries("testzzzabcczzzabccc")))
+            failCount++;
+
+        matcher.reset(toSupplementaries("zzzabccczzzabcczzzabccczzz"));
+        if (!matcher.replaceFirst(toSupplementaries("test")).
+            equals(toSupplementaries("zzztestzzzabcczzzabccczzz")))
+            failCount++;
+
+        matcher.reset(toSupplementaries("zzzabccczzzabcczzzabccczzz"));
+        result = matcher.replaceFirst("$1");
+        if (!result.equals(toSupplementaries("zzzabzzzabcczzzabccczzz")))
+            failCount++;
+
+        matcher.reset(toSupplementaries("zzzabccczzzabcczzzabccczzz"));
+        result = matcher.replaceFirst("$2");
+        if (!result.equals(toSupplementaries("zzzccczzzabcczzzabccczzz")))
+            failCount++;
+
+        pattern = Pattern.compile(toSupplementaries("a*"));
+        matcher = pattern.matcher(toSupplementaries("aaaaaaaaaa"));
+        if (!matcher.replaceFirst(toSupplementaries("test")).equals(toSupplementaries("test")))
+            failCount++;
+
+        pattern = Pattern.compile(toSupplementaries("a+"));
+        matcher = pattern.matcher(toSupplementaries("zzzaaaaaaaaaa"));
+        if (!matcher.replaceFirst(toSupplementaries("test")).equals(toSupplementaries("zzztest")))
+            failCount++;
+
+        report("Replace First");
+    }
+
+    private static void unixLinesTest() {
+        Pattern pattern = Pattern.compile(".*");
+        Matcher matcher = pattern.matcher("aa\u2028blah");
+        matcher.find();
+        if (!matcher.group(0).equals("aa"))
+            failCount++;
+
+        pattern = Pattern.compile(".*", Pattern.UNIX_LINES);
+        matcher = pattern.matcher("aa\u2028blah");
+        matcher.find();
+        if (!matcher.group(0).equals("aa\u2028blah"))
+            failCount++;
+
+        pattern = Pattern.compile("[az]$",
+                                  Pattern.MULTILINE | Pattern.UNIX_LINES);
+        matcher = pattern.matcher("aa\u2028zz");
+        check(matcher, "a\u2028", false);
+
+        // Supplementary character test
+        pattern = Pattern.compile(".*");
+        matcher = pattern.matcher(toSupplementaries("aa\u2028blah"));
+        matcher.find();
+        if (!matcher.group(0).equals(toSupplementaries("aa")))
+            failCount++;
+
+        pattern = Pattern.compile(".*", Pattern.UNIX_LINES);
+        matcher = pattern.matcher(toSupplementaries("aa\u2028blah"));
+        matcher.find();
+        if (!matcher.group(0).equals(toSupplementaries("aa\u2028blah")))
+            failCount++;
+
+        pattern = Pattern.compile(toSupplementaries("[az]$"),
+                                  Pattern.MULTILINE | Pattern.UNIX_LINES);
+        matcher = pattern.matcher(toSupplementaries("aa\u2028zz"));
+        check(matcher, toSupplementaries("a\u2028"), false);
+
+        report("Unix Lines");
+    }
+
+    private static void commentsTest() {
+        int flags = Pattern.COMMENTS;
+
+        Pattern pattern = Pattern.compile("aa \\# aa", flags);
+        Matcher matcher = pattern.matcher("aa#aa");
+        if (!matcher.matches())
+            failCount++;
+
+        pattern = Pattern.compile("aa  # blah", flags);
+        matcher = pattern.matcher("aa");
+        if (!matcher.matches())
+            failCount++;
+
+        pattern = Pattern.compile("aa blah", flags);
+        matcher = pattern.matcher("aablah");
+        if (!matcher.matches())
+             failCount++;
+
+        pattern = Pattern.compile("aa  # blah blech  ", flags);
+        matcher = pattern.matcher("aa");
+        if (!matcher.matches())
+            failCount++;
+
+        pattern = Pattern.compile("aa  # blah\n  ", flags);
+        matcher = pattern.matcher("aa");
+        if (!matcher.matches())
+            failCount++;
+
+        pattern = Pattern.compile("aa  # blah\nbc # blech", flags);
+        matcher = pattern.matcher("aabc");
+        if (!matcher.matches())
+             failCount++;
+
+        pattern = Pattern.compile("aa  # blah\nbc# blech", flags);
+        matcher = pattern.matcher("aabc");
+        if (!matcher.matches())
+             failCount++;
+
+        pattern = Pattern.compile("aa  # blah\nbc\\# blech", flags);
+        matcher = pattern.matcher("aabc#blech");
+        if (!matcher.matches())
+             failCount++;
+
+        // Supplementary character test
+        pattern = Pattern.compile(toSupplementaries("aa \\# aa"), flags);
+        matcher = pattern.matcher(toSupplementaries("aa#aa"));
+        if (!matcher.matches())
+            failCount++;
+
+        pattern = Pattern.compile(toSupplementaries("aa  # blah"), flags);
+        matcher = pattern.matcher(toSupplementaries("aa"));
+        if (!matcher.matches())
+            failCount++;
+
+        pattern = Pattern.compile(toSupplementaries("aa blah"), flags);
+        matcher = pattern.matcher(toSupplementaries("aablah"));
+        if (!matcher.matches())
+             failCount++;
+
+        pattern = Pattern.compile(toSupplementaries("aa  # blah blech  "), flags);
+        matcher = pattern.matcher(toSupplementaries("aa"));
+        if (!matcher.matches())
+            failCount++;
+
+        pattern = Pattern.compile(toSupplementaries("aa  # blah\n  "), flags);
+        matcher = pattern.matcher(toSupplementaries("aa"));
+        if (!matcher.matches())
+            failCount++;
+
+        pattern = Pattern.compile(toSupplementaries("aa  # blah\nbc # blech"), flags);
+        matcher = pattern.matcher(toSupplementaries("aabc"));
+        if (!matcher.matches())
+             failCount++;
+
+        pattern = Pattern.compile(toSupplementaries("aa  # blah\nbc# blech"), flags);
+        matcher = pattern.matcher(toSupplementaries("aabc"));
+        if (!matcher.matches())
+             failCount++;
+
+        pattern = Pattern.compile(toSupplementaries("aa  # blah\nbc\\# blech"), flags);
+        matcher = pattern.matcher(toSupplementaries("aabc#blech"));
+        if (!matcher.matches())
+             failCount++;
+
+        report("Comments");
+    }
+
+    private static void caseFoldingTest() { // bug 4504687
+        int flags = Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE;
+        Pattern pattern = Pattern.compile("aa", flags);
+        Matcher matcher = pattern.matcher("ab");
+        if (matcher.matches())
+            failCount++;
+
+        pattern = Pattern.compile("aA", flags);
+        matcher = pattern.matcher("ab");
+        if (matcher.matches())
+            failCount++;
+
+        pattern = Pattern.compile("aa", flags);
+        matcher = pattern.matcher("aB");
+        if (matcher.matches())
+            failCount++;
+        matcher = pattern.matcher("Ab");
+        if (matcher.matches())
+            failCount++;
+
+        // ASCII               "a"
+        // Latin-1 Supplement  "a" + grave
+        // Cyrillic            "a"
+        String[] patterns = new String[] {
+            //single
+            "a", "\u00e0", "\u0430",
+            //slice
+            "ab", "\u00e0\u00e1", "\u0430\u0431",
+            //class single
+            "[a]", "[\u00e0]", "[\u0430]",
+            //class range
+            "[a-b]", "[\u00e0-\u00e5]", "[\u0430-\u0431]",
+            //back reference
+            "(a)\\1", "(\u00e0)\\1", "(\u0430)\\1"
+        };
+
+        String[] texts = new String[] {
+            "A", "\u00c0", "\u0410",
+            "AB", "\u00c0\u00c1", "\u0410\u0411",
+            "A", "\u00c0", "\u0410",
+            "B", "\u00c2", "\u0411",
+            "aA", "\u00e0\u00c0", "\u0430\u0410"
+        };
+
+        boolean[] expected = new boolean[] {
+            true, false, false,
+            true, false, false,
+            true, false, false,
+            true, false, false,
+            true, false, false
+        };
+
+        flags = Pattern.CASE_INSENSITIVE;
+        for (int i = 0; i < patterns.length; i++) {
+            pattern = Pattern.compile(patterns[i], flags);
+            matcher = pattern.matcher(texts[i]);
+            if (matcher.matches() != expected[i]) {
+                System.out.println("<1> Failed at " + i);
+                failCount++;
+            }
+        }
+
+        flags = Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE;
+        for (int i = 0; i < patterns.length; i++) {
+            pattern = Pattern.compile(patterns[i], flags);
+            matcher = pattern.matcher(texts[i]);
+            if (!matcher.matches()) {
+                System.out.println("<2> Failed at " + i);
+                failCount++;
+            }
+        }
+        // flag unicode_case alone should do nothing
+        flags = Pattern.UNICODE_CASE;
+        for (int i = 0; i < patterns.length; i++) {
+            pattern = Pattern.compile(patterns[i], flags);
+            matcher = pattern.matcher(texts[i]);
+            if (matcher.matches()) {
+                System.out.println("<3> Failed at " + i);
+                failCount++;
+            }
+        }
+
+        // Special cases: i, I, u+0131 and u+0130
+        flags = Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE;
+        pattern = Pattern.compile("[h-j]+", flags);
+        if (!pattern.matcher("\u0131\u0130").matches())
+            failCount++;
+        report("Case Folding");
+    }
+
+    private static void appendTest() {
+        Pattern pattern = Pattern.compile("(ab)(cd)");
+        Matcher matcher = pattern.matcher("abcd");
+        String result = matcher.replaceAll("$2$1");
+        if (!result.equals("cdab"))
+            failCount++;
+
+        String  s1 = "Swap all: first = 123, second = 456";
+        String  s2 = "Swap one: first = 123, second = 456";
+        String  r  = "$3$2$1";
+        pattern = Pattern.compile("([a-z]+)( *= *)([0-9]+)");
+        matcher = pattern.matcher(s1);
+
+        result = matcher.replaceAll(r);
+        if (!result.equals("Swap all: 123 = first, 456 = second"))
+            failCount++;
+
+        matcher = pattern.matcher(s2);
+
+        if (matcher.find()) {
+            StringBuffer sb = new StringBuffer();
+            matcher.appendReplacement(sb, r);
+            matcher.appendTail(sb);
+            result = sb.toString();
+            if (!result.equals("Swap one: 123 = first, second = 456"))
+                failCount++;
+        }
+
+        // Supplementary character test
+        pattern = Pattern.compile(toSupplementaries("(ab)(cd)"));
+        matcher = pattern.matcher(toSupplementaries("abcd"));
+        result = matcher.replaceAll("$2$1");
+        if (!result.equals(toSupplementaries("cdab")))
+            failCount++;
+
+        s1 = toSupplementaries("Swap all: first = 123, second = 456");
+        s2 = toSupplementaries("Swap one: first = 123, second = 456");
+        r  = toSupplementaries("$3$2$1");
+        pattern = Pattern.compile(toSupplementaries("([a-z]+)( *= *)([0-9]+)"));
+        matcher = pattern.matcher(s1);
+
+        result = matcher.replaceAll(r);
+        if (!result.equals(toSupplementaries("Swap all: 123 = first, 456 = second")))
+            failCount++;
+
+        matcher = pattern.matcher(s2);
+
+        if (matcher.find()) {
+            StringBuffer sb = new StringBuffer();
+            matcher.appendReplacement(sb, r);
+            matcher.appendTail(sb);
+            result = sb.toString();
+            if (!result.equals(toSupplementaries("Swap one: 123 = first, second = 456")))
+                failCount++;
+        }
+        report("Append");
+    }
+
+    private static void splitTest() {
+        Pattern pattern = Pattern.compile(":");
+        String[] result = pattern.split("foo:and:boo", 2);
+        if (!result[0].equals("foo"))
+            failCount++;
+        if (!result[1].equals("and:boo"))
+            failCount++;
+        // Supplementary character test
+        Pattern patternX = Pattern.compile(toSupplementaries("X"));
+        result = patternX.split(toSupplementaries("fooXandXboo"), 2);
+        if (!result[0].equals(toSupplementaries("foo")))
+            failCount++;
+        if (!result[1].equals(toSupplementaries("andXboo")))
+            failCount++;
+
+        CharBuffer cb = CharBuffer.allocate(100);
+        cb.put("foo:and:boo");
+        cb.flip();
+        result = pattern.split(cb);
+        if (!result[0].equals("foo"))
+            failCount++;
+        if (!result[1].equals("and"))
+            failCount++;
+        if (!result[2].equals("boo"))
+            failCount++;
+
+        // Supplementary character test
+        CharBuffer cbs = CharBuffer.allocate(100);
+        cbs.put(toSupplementaries("fooXandXboo"));
+        cbs.flip();
+        result = patternX.split(cbs);
+        if (!result[0].equals(toSupplementaries("foo")))
+            failCount++;
+        if (!result[1].equals(toSupplementaries("and")))
+            failCount++;
+        if (!result[2].equals(toSupplementaries("boo")))
+            failCount++;
+
+        String source = "0123456789";
+        for (int limit=-2; limit<3; limit++) {
+            for (int x=0; x<10; x++) {
+                result = source.split(Integer.toString(x), limit);
+                int expectedLength = limit < 1 ? 2 : limit;
+
+                if ((limit == 0) && (x == 9)) {
+                    // expected dropping of ""
+                    if (result.length != 1)
+                        failCount++;
+                    if (!result[0].equals("012345678")) {
+                        failCount++;
+                    }
+                } else {
+                    if (result.length != expectedLength) {
+                        failCount++;
+                    }
+                    if (!result[0].equals(source.substring(0,x))) {
+                        if (limit != 1) {
+                            failCount++;
+                        } else {
+                            if (!result[0].equals(source.substring(0,10))) {
+                                failCount++;
+                            }
+                        }
+                    }
+                    if (expectedLength > 1) { // Check segment 2
+                        if (!result[1].equals(source.substring(x+1,10)))
+                            failCount++;
+                    }
+                }
+            }
+        }
+        // Check the case for no match found
+        for (int limit=-2; limit<3; limit++) {
+            result = source.split("e", limit);
+            if (result.length != 1)
+                failCount++;
+            if (!result[0].equals(source))
+                failCount++;
+        }
+        // Check the case for limit == 0, source = "";
+        source = "";
+        result = source.split("e", 0);
+        if (result.length != 1)
+            failCount++;
+        if (!result[0].equals(source))
+            failCount++;
+
+        report("Split");
+    }
+
+    private static void negationTest() {
+        Pattern pattern = Pattern.compile("[\\[@^]+");
+        Matcher matcher = pattern.matcher("@@@@[[[[^^^^");
+        if (!matcher.find())
+            failCount++;
+        if (!matcher.group(0).equals("@@@@[[[[^^^^"))
+            failCount++;
+        pattern = Pattern.compile("[@\\[^]+");
+        matcher = pattern.matcher("@@@@[[[[^^^^");
+        if (!matcher.find())
+            failCount++;
+        if (!matcher.group(0).equals("@@@@[[[[^^^^"))
+            failCount++;
+        pattern = Pattern.compile("[@\\[^@]+");
+        matcher = pattern.matcher("@@@@[[[[^^^^");
+        if (!matcher.find())
+            failCount++;
+        if (!matcher.group(0).equals("@@@@[[[[^^^^"))
+            failCount++;
+
+        pattern = Pattern.compile("\\)");
+        matcher = pattern.matcher("xxx)xxx");
+        if (!matcher.find())
+            failCount++;
+
+        report("Negation");
+    }
+
+    private static void ampersandTest() {
+        Pattern pattern = Pattern.compile("[&@]+");
+        check(pattern, "@@@@&&&&", true);
+
+        pattern = Pattern.compile("[@&]+");
+        check(pattern, "@@@@&&&&", true);
+
+        pattern = Pattern.compile("[@\\&]+");
+        check(pattern, "@@@@&&&&", true);
+
+        report("Ampersand");
+    }
+
+    private static void octalTest() throws Exception {
+        Pattern pattern = Pattern.compile("\\u0007");
+        Matcher matcher = pattern.matcher("\u0007");
+        if (!matcher.matches())
+            failCount++;
+        pattern = Pattern.compile("\\07");
+        matcher = pattern.matcher("\u0007");
+        if (!matcher.matches())
+            failCount++;
+        pattern = Pattern.compile("\\007");
+        matcher = pattern.matcher("\u0007");
+        if (!matcher.matches())
+            failCount++;
+        pattern = Pattern.compile("\\0007");
+        matcher = pattern.matcher("\u0007");
+        if (!matcher.matches())
+            failCount++;
+        pattern = Pattern.compile("\\040");
+        matcher = pattern.matcher("\u0020");
+        if (!matcher.matches())
+            failCount++;
+        pattern = Pattern.compile("\\0403");
+        matcher = pattern.matcher("\u00203");
+        if (!matcher.matches())
+            failCount++;
+        pattern = Pattern.compile("\\0103");
+        matcher = pattern.matcher("\u0043");
+        if (!matcher.matches())
+            failCount++;
+
+        report("Octal");
+    }
+
+    private static void longPatternTest() throws Exception {
+        try {
+            Pattern pattern = Pattern.compile(
+                "a 32-character-long pattern xxxx");
+            pattern = Pattern.compile("a 33-character-long pattern xxxxx");
+            pattern = Pattern.compile("a thirty four character long regex");
+            StringBuffer patternToBe = new StringBuffer(101);
+            for (int i=0; i<100; i++)
+                patternToBe.append((char)(97 + i%26));
+            pattern = Pattern.compile(patternToBe.toString());
+        } catch (PatternSyntaxException e) {
+            failCount++;
+        }
+
+        // Supplementary character test
+        try {
+            Pattern pattern = Pattern.compile(
+                toSupplementaries("a 32-character-long pattern xxxx"));
+            pattern = Pattern.compile(toSupplementaries("a 33-character-long pattern xxxxx"));
+            pattern = Pattern.compile(toSupplementaries("a thirty four character long regex"));
+            StringBuffer patternToBe = new StringBuffer(101*2);
+            for (int i=0; i<100; i++)
+                patternToBe.append(Character.toChars(Character.MIN_SUPPLEMENTARY_CODE_POINT
+                                                     + 97 + i%26));
+            pattern = Pattern.compile(patternToBe.toString());
+        } catch (PatternSyntaxException e) {
+            failCount++;
+        }
+        report("LongPattern");
+    }
+
+    private static void group0Test() throws Exception {
+        Pattern pattern = Pattern.compile("(tes)ting");
+        Matcher matcher = pattern.matcher("testing");
+        check(matcher, "testing");
+
+        matcher.reset("testing");
+        if (matcher.lookingAt()) {
+            if (!matcher.group(0).equals("testing"))
+                failCount++;
+        } else {
+            failCount++;
+        }
+
+        matcher.reset("testing");
+        if (matcher.matches()) {
+            if (!matcher.group(0).equals("testing"))
+                failCount++;
+        } else {
+            failCount++;
+        }
+
+        pattern = Pattern.compile("(tes)ting");
+        matcher = pattern.matcher("testing");
+        if (matcher.lookingAt()) {
+            if (!matcher.group(0).equals("testing"))
+                failCount++;
+        } else {
+            failCount++;
+        }
+
+        pattern = Pattern.compile("^(tes)ting");
+        matcher = pattern.matcher("testing");
+        if (matcher.matches()) {
+            if (!matcher.group(0).equals("testing"))
+                failCount++;
+        } else {
+            failCount++;
+        }
+
+        // Supplementary character test
+        pattern = Pattern.compile(toSupplementaries("(tes)ting"));
+        matcher = pattern.matcher(toSupplementaries("testing"));
+        check(matcher, toSupplementaries("testing"));
+
+        matcher.reset(toSupplementaries("testing"));
+        if (matcher.lookingAt()) {
+            if (!matcher.group(0).equals(toSupplementaries("testing")))
+                failCount++;
+        } else {
+            failCount++;
+        }
+
+        matcher.reset(toSupplementaries("testing"));
+        if (matcher.matches()) {
+            if (!matcher.group(0).equals(toSupplementaries("testing")))
+                failCount++;
+        } else {
+            failCount++;
+        }
+
+        pattern = Pattern.compile(toSupplementaries("(tes)ting"));
+        matcher = pattern.matcher(toSupplementaries("testing"));
+        if (matcher.lookingAt()) {
+            if (!matcher.group(0).equals(toSupplementaries("testing")))
+                failCount++;
+        } else {
+            failCount++;
+        }
+
+        pattern = Pattern.compile(toSupplementaries("^(tes)ting"));
+        matcher = pattern.matcher(toSupplementaries("testing"));
+        if (matcher.matches()) {
+            if (!matcher.group(0).equals(toSupplementaries("testing")))
+                failCount++;
+        } else {
+            failCount++;
+        }
+
+        report("Group0");
+    }
+
+    private static void findIntTest() throws Exception {
+        Pattern p = Pattern.compile("blah");
+        Matcher m = p.matcher("zzzzblahzzzzzblah");
+        boolean result = m.find(2);
+        if (!result)
+            failCount++;
+
+        p = Pattern.compile("$");
+        m = p.matcher("1234567890");
+        result = m.find(10);
+        if (!result)
+            failCount++;
+        try {
+            result = m.find(11);
+            failCount++;
+        } catch (IndexOutOfBoundsException e) {
+            // correct result
+        }
+
+        // Supplementary character test
+        p = Pattern.compile(toSupplementaries("blah"));
+        m = p.matcher(toSupplementaries("zzzzblahzzzzzblah"));
+        result = m.find(2);
+        if (!result)
+            failCount++;
+
+        report("FindInt");
+    }
+
+    private static void emptyPatternTest() throws Exception {
+        Pattern p = Pattern.compile("");
+        Matcher m = p.matcher("foo");
+
+        // Should find empty pattern at beginning of input
+        boolean result = m.find();
+        if (result != true)
+            failCount++;
+        if (m.start() != 0)
+            failCount++;
+
+        // Should not match entire input if input is not empty
+        m.reset();
+        result = m.matches();
+        if (result == true)
+            failCount++;
+
+        try {
+            m.start(0);
+            failCount++;
+        } catch (IllegalStateException e) {
+            // Correct result
+        }
+
+        // Should match entire input if input is empty
+        m.reset("");
+        result = m.matches();
+        if (result != true)
+            failCount++;
+
+        result = Pattern.matches("", "");
+        if (result != true)
+            failCount++;
+
+        result = Pattern.matches("", "foo");
+        if (result == true)
+            failCount++;
+        report("EmptyPattern");
+    }
+
+    private static void charClassTest() throws Exception {
+        Pattern pattern = Pattern.compile("blah[ab]]blech");
+        check(pattern, "blahb]blech", true);
+
+        pattern = Pattern.compile("[abc[def]]");
+        check(pattern, "b", true);
+
+        // Supplementary character tests
+        pattern = Pattern.compile(toSupplementaries("blah[ab]]blech"));
+        check(pattern, toSupplementaries("blahb]blech"), true);
+
+        pattern = Pattern.compile(toSupplementaries("[abc[def]]"));
+        check(pattern, toSupplementaries("b"), true);
+
+        try {
+            // u00ff when UNICODE_CASE
+            pattern = Pattern.compile("[ab\u00ffcd]",
+                                      Pattern.CASE_INSENSITIVE|
+                                      Pattern.UNICODE_CASE);
+            check(pattern, "ab\u00ffcd", true);
+            check(pattern, "Ab\u0178Cd", true);
+
+            // u00b5 when UNICODE_CASE
+            pattern = Pattern.compile("[ab\u00b5cd]",
+                                      Pattern.CASE_INSENSITIVE|
+                                      Pattern.UNICODE_CASE);
+            check(pattern, "ab\u00b5cd", true);
+            check(pattern, "Ab\u039cCd", true);
+        } catch (Exception e) { failCount++; }
+
+        /* Special cases
+           (1)LatinSmallLetterLongS u+017f
+           (2)LatinSmallLetterDotlessI u+0131
+           (3)LatineCapitalLetterIWithDotAbove u+0130
+           (4)KelvinSign u+212a
+           (5)AngstromSign u+212b
+        */
+        int flags = Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE;
+        pattern = Pattern.compile("[sik\u00c5]+", flags);
+        if (!pattern.matcher("\u017f\u0130\u0131\u212a\u212b").matches())
+            failCount++;
+
+        report("CharClass");
+    }
+
+    private static void caretTest() throws Exception {
+        Pattern pattern = Pattern.compile("\\w*");
+        Matcher matcher = pattern.matcher("a#bc#def##g");
+        check(matcher, "a");
+        check(matcher, "");
+        check(matcher, "bc");
+        check(matcher, "");
+        check(matcher, "def");
+        check(matcher, "");
+        check(matcher, "");
+        check(matcher, "g");
+        check(matcher, "");
+        if (matcher.find())
+            failCount++;
+
+        pattern = Pattern.compile("^\\w*");
+        matcher = pattern.matcher("a#bc#def##g");
+        check(matcher, "a");
+        if (matcher.find())
+            failCount++;
+
+        pattern = Pattern.compile("\\w");
+        matcher = pattern.matcher("abc##x");
+        check(matcher, "a");
+        check(matcher, "b");
+        check(matcher, "c");
+        check(matcher, "x");
+        if (matcher.find())
+            failCount++;
+
+        pattern = Pattern.compile("^\\w");
+        matcher = pattern.matcher("abc##x");
+        check(matcher, "a");
+        if (matcher.find())
+            failCount++;
+
+        pattern = Pattern.compile("\\A\\p{Alpha}{3}");
+        matcher = pattern.matcher("abcdef-ghi\njklmno");
+        check(matcher, "abc");
+        if (matcher.find())
+            failCount++;
+
+        pattern = Pattern.compile("^\\p{Alpha}{3}", Pattern.MULTILINE);
+        matcher = pattern.matcher("abcdef-ghi\njklmno");
+        check(matcher, "abc");
+        check(matcher, "jkl");
+        if (matcher.find())
+            failCount++;
+
+        pattern = Pattern.compile("^", Pattern.MULTILINE);
+        matcher = pattern.matcher("this is some text");
+        String result = matcher.replaceAll("X");
+        if (!result.equals("Xthis is some text"))
+            failCount++;
+
+        pattern = Pattern.compile("^");
+        matcher = pattern.matcher("this is some text");
+        result = matcher.replaceAll("X");
+        if (!result.equals("Xthis is some text"))
+            failCount++;
+
+        pattern = Pattern.compile("^", Pattern.MULTILINE | Pattern.UNIX_LINES);
+        matcher = pattern.matcher("this is some text\n");
+        result = matcher.replaceAll("X");
+        if (!result.equals("Xthis is some text\n"))
+            failCount++;
+
+        report("Caret");
+    }
+
+    private static void groupCaptureTest() throws Exception {
+        // Independent group
+        Pattern pattern = Pattern.compile("x+(?>y+)z+");
+        Matcher matcher = pattern.matcher("xxxyyyzzz");
+        matcher.find();
+        try {
+            String blah = matcher.group(1);
+            failCount++;
+        } catch (IndexOutOfBoundsException ioobe) {
+            // Good result
+        }
+        // Pure group
+        pattern = Pattern.compile("x+(?:y+)z+");
+        matcher = pattern.matcher("xxxyyyzzz");
+        matcher.find();
+        try {
+            String blah = matcher.group(1);
+            failCount++;
+        } catch (IndexOutOfBoundsException ioobe) {
+            // Good result
+        }
+
+        // Supplementary character tests
+        // Independent group
+        pattern = Pattern.compile(toSupplementaries("x+(?>y+)z+"));
+        matcher = pattern.matcher(toSupplementaries("xxxyyyzzz"));
+        matcher.find();
+        try {
+            String blah = matcher.group(1);
+            failCount++;
+        } catch (IndexOutOfBoundsException ioobe) {
+            // Good result
+        }
+        // Pure group
+        pattern = Pattern.compile(toSupplementaries("x+(?:y+)z+"));
+        matcher = pattern.matcher(toSupplementaries("xxxyyyzzz"));
+        matcher.find();
+        try {
+            String blah = matcher.group(1);
+            failCount++;
+        } catch (IndexOutOfBoundsException ioobe) {
+            // Good result
+        }
+
+        report("GroupCapture");
+    }
+
+    private static void backRefTest() throws Exception {
+        Pattern pattern = Pattern.compile("(a*)bc\\1");
+        check(pattern, "zzzaabcazzz", true);
+
+        pattern = Pattern.compile("(a*)bc\\1");
+        check(pattern, "zzzaabcaazzz", true);
+
+        pattern = Pattern.compile("(abc)(def)\\1");
+        check(pattern, "abcdefabc", true);
+
+        pattern = Pattern.compile("(abc)(def)\\3");
+        check(pattern, "abcdefabc", false);
+
+        try {
+            for (int i = 1; i < 10; i++) {
+                // Make sure backref 1-9 are always accepted
+                pattern = Pattern.compile("abcdef\\" + i);
+                // and fail to match if the target group does not exit
+                check(pattern, "abcdef", false);
+            }
+        } catch(PatternSyntaxException e) {
+            failCount++;
+        }
+
+        pattern = Pattern.compile("(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)\\11");
+        check(pattern, "abcdefghija", false);
+        check(pattern, "abcdefghija1", true);
+
+        pattern = Pattern.compile("(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\\11");
+        check(pattern, "abcdefghijkk", true);
+
+        pattern = Pattern.compile("(a)bcdefghij\\11");
+        check(pattern, "abcdefghija1", true);
+
+        // Supplementary character tests
+        pattern = Pattern.compile(toSupplementaries("(a*)bc\\1"));
+        check(pattern, toSupplementaries("zzzaabcazzz"), true);
+
+        pattern = Pattern.compile(toSupplementaries("(a*)bc\\1"));
+        check(pattern, toSupplementaries("zzzaabcaazzz"), true);
+
+        pattern = Pattern.compile(toSupplementaries("(abc)(def)\\1"));
+        check(pattern, toSupplementaries("abcdefabc"), true);
+
+        pattern = Pattern.compile(toSupplementaries("(abc)(def)\\3"));
+        check(pattern, toSupplementaries("abcdefabc"), false);
+
+        pattern = Pattern.compile(toSupplementaries("(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)\\11"));
+        check(pattern, toSupplementaries("abcdefghija"), false);
+        check(pattern, toSupplementaries("abcdefghija1"), true);
+
+        pattern = Pattern.compile(toSupplementaries("(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\\11"));
+        check(pattern, toSupplementaries("abcdefghijkk"), true);
+
+        report("BackRef");
+    }
+
+    /**
+     * Unicode Technical Report #18, section 2.6 End of Line
+     * There is no empty line to be matched in the sequence \u000D\u000A
+     * but there is an empty line in the sequence \u000A\u000D.
+     */
+    private static void anchorTest() throws Exception {
+        Pattern p = Pattern.compile("^.*$", Pattern.MULTILINE);
+        Matcher m = p.matcher("blah1\r\nblah2");
+        m.find();
+        m.find();
+        if (!m.group().equals("blah2"))
+            failCount++;
+
+        m.reset("blah1\n\rblah2");
+        m.find();
+        m.find();
+        m.find();
+        if (!m.group().equals("blah2"))
+            failCount++;
+
+        // Test behavior of $ with \r\n at end of input
+        p = Pattern.compile(".+$");
+        m = p.matcher("blah1\r\n");
+        if (!m.find())
+            failCount++;
+       if (!m.group().equals("blah1"))
+            failCount++;
+        if (m.find())
+            failCount++;
+
+        // Test behavior of $ with \r\n at end of input in multiline
+        p = Pattern.compile(".+$", Pattern.MULTILINE);
+        m = p.matcher("blah1\r\n");
+        if (!m.find())
+            failCount++;
+        if (m.find())
+            failCount++;
+
+        // Test for $ recognition of \u0085 for bug 4527731
+        p = Pattern.compile(".+$", Pattern.MULTILINE);
+        m = p.matcher("blah1\u0085");
+        if (!m.find())
+            failCount++;
+
+        // Supplementary character test
+        p = Pattern.compile("^.*$", Pattern.MULTILINE);
+        m = p.matcher(toSupplementaries("blah1\r\nblah2"));
+        m.find();
+        m.find();
+        if (!m.group().equals(toSupplementaries("blah2")))
+            failCount++;
+
+        m.reset(toSupplementaries("blah1\n\rblah2"));
+        m.find();
+        m.find();
+        m.find();
+        if (!m.group().equals(toSupplementaries("blah2")))
+            failCount++;
+
+        // Test behavior of $ with \r\n at end of input
+        p = Pattern.compile(".+$");
+        m = p.matcher(toSupplementaries("blah1\r\n"));
+        if (!m.find())
+            failCount++;
+        if (!m.group().equals(toSupplementaries("blah1")))
+            failCount++;
+        if (m.find())
+            failCount++;
+
+        // Test behavior of $ with \r\n at end of input in multiline
+        p = Pattern.compile(".+$", Pattern.MULTILINE);
+        m = p.matcher(toSupplementaries("blah1\r\n"));
+        if (!m.find())
+            failCount++;
+        if (m.find())
+            failCount++;
+
+        // Test for $ recognition of \u0085 for bug 4527731
+        p = Pattern.compile(".+$", Pattern.MULTILINE);
+        m = p.matcher(toSupplementaries("blah1\u0085"));
+        if (!m.find())
+            failCount++;
+
+        report("Anchors");
+    }
+
+    /**
+     * A basic sanity test of Matcher.lookingAt().
+     */
+    private static void lookingAtTest() throws Exception {
+        Pattern p = Pattern.compile("(ab)(c*)");
+        Matcher m = p.matcher("abccczzzabcczzzabccc");
+
+        if (!m.lookingAt())
+            failCount++;
+
+        if (!m.group().equals(m.group(0)))
+            failCount++;
+
+        m = p.matcher("zzzabccczzzabcczzzabccczzz");
+        if (m.lookingAt())
+            failCount++;
+
+        // Supplementary character test
+        p = Pattern.compile(toSupplementaries("(ab)(c*)"));
+        m = p.matcher(toSupplementaries("abccczzzabcczzzabccc"));
+
+        if (!m.lookingAt())
+            failCount++;
+
+        if (!m.group().equals(m.group(0)))
+            failCount++;
+
+        m = p.matcher(toSupplementaries("zzzabccczzzabcczzzabccczzz"));
+        if (m.lookingAt())
+            failCount++;
+
+        report("Looking At");
+    }
+
+    /**
+     * A basic sanity test of Matcher.matches().
+     */
+    private static void matchesTest() throws Exception {
+        // matches()
+        Pattern p = Pattern.compile("ulb(c*)");
+        Matcher m = p.matcher("ulbcccccc");
+        if (!m.matches())
+            failCount++;
+
+        // find() but not matches()
+        m.reset("zzzulbcccccc");
+        if (m.matches())
+            failCount++;
+
+        // lookingAt() but not matches()
+        m.reset("ulbccccccdef");
+        if (m.matches())
+            failCount++;
+
+        // matches()
+        p = Pattern.compile("a|ad");
+        m = p.matcher("ad");
+        if (!m.matches())
+            failCount++;
+
+        // Supplementary character test
+        // matches()
+        p = Pattern.compile(toSupplementaries("ulb(c*)"));
+        m = p.matcher(toSupplementaries("ulbcccccc"));
+        if (!m.matches())
+            failCount++;
+
+        // find() but not matches()
+        m.reset(toSupplementaries("zzzulbcccccc"));
+        if (m.matches())
+            failCount++;
+
+        // lookingAt() but not matches()
+        m.reset(toSupplementaries("ulbccccccdef"));
+        if (m.matches())
+            failCount++;
+
+        // matches()
+        p = Pattern.compile(toSupplementaries("a|ad"));
+        m = p.matcher(toSupplementaries("ad"));
+        if (!m.matches())
+            failCount++;
+
+        report("Matches");
+    }
+
+    /**
+     * A basic sanity test of Pattern.matches().
+     */
+    private static void patternMatchesTest() throws Exception {
+        // matches()
+        if (!Pattern.matches(toSupplementaries("ulb(c*)"),
+                             toSupplementaries("ulbcccccc")))
+            failCount++;
+
+        // find() but not matches()
+        if (Pattern.matches(toSupplementaries("ulb(c*)"),
+                            toSupplementaries("zzzulbcccccc")))
+            failCount++;
+
+        // lookingAt() but not matches()
+        if (Pattern.matches(toSupplementaries("ulb(c*)"),
+                            toSupplementaries("ulbccccccdef")))
+            failCount++;
+
+        // Supplementary character test
+        // matches()
+        if (!Pattern.matches(toSupplementaries("ulb(c*)"),
+                             toSupplementaries("ulbcccccc")))
+            failCount++;
+
+        // find() but not matches()
+        if (Pattern.matches(toSupplementaries("ulb(c*)"),
+                            toSupplementaries("zzzulbcccccc")))
+            failCount++;
+
+        // lookingAt() but not matches()
+        if (Pattern.matches(toSupplementaries("ulb(c*)"),
+                            toSupplementaries("ulbccccccdef")))
+            failCount++;
+
+        report("Pattern Matches");
+    }
+
+    /**
+     * Canonical equivalence testing. Tests the ability of the engine
+     * to match sequences that are not explicitly specified in the
+     * pattern when they are considered equivalent by the Unicode Standard.
+     */
+    private static void ceTest() throws Exception {
+        // Decomposed char outside char classes
+        Pattern p = Pattern.compile("testa\u030a", Pattern.CANON_EQ);
+        Matcher m = p.matcher("test\u00e5");
+        if (!m.matches())
+            failCount++;
+
+        m.reset("testa\u030a");
+        if (!m.matches())
+            failCount++;
+
+        // Composed char outside char classes
+        p = Pattern.compile("test\u00e5", Pattern.CANON_EQ);
+        m = p.matcher("test\u00e5");
+        if (!m.matches())
+            failCount++;
+
+        m.reset("testa\u030a");
+        if (!m.find())
+            failCount++;
+
+        // Decomposed char inside a char class
+        p = Pattern.compile("test[abca\u030a]", Pattern.CANON_EQ);
+        m = p.matcher("test\u00e5");
+        if (!m.find())
+            failCount++;
+
+        m.reset("testa\u030a");
+        if (!m.find())
+            failCount++;
+
+        // Composed char inside a char class
+        p = Pattern.compile("test[abc\u00e5def\u00e0]", Pattern.CANON_EQ);
+        m = p.matcher("test\u00e5");
+        if (!m.find())
+            failCount++;
+
+        m.reset("testa\u0300");
+        if (!m.find())
+            failCount++;
+
+        m.reset("testa\u030a");
+        if (!m.find())
+            failCount++;
+
+        // Marks that cannot legally change order and be equivalent
+        p = Pattern.compile("testa\u0308\u0300", Pattern.CANON_EQ);
+        check(p, "testa\u0308\u0300", true);
+        check(p, "testa\u0300\u0308", false);
+
+        // Marks that can legally change order and be equivalent
+        p = Pattern.compile("testa\u0308\u0323", Pattern.CANON_EQ);
+        check(p, "testa\u0308\u0323", true);
+        check(p, "testa\u0323\u0308", true);
+
+        // Test all equivalences of the sequence a\u0308\u0323\u0300
+        p = Pattern.compile("testa\u0308\u0323\u0300", Pattern.CANON_EQ);
+        check(p, "testa\u0308\u0323\u0300", true);
+        check(p, "testa\u0323\u0308\u0300", true);
+        check(p, "testa\u0308\u0300\u0323", true);
+        check(p, "test\u00e4\u0323\u0300", true);
+        check(p, "test\u00e4\u0300\u0323", true);
+
+        /*
+         * The following canonical equivalence tests don't work. Bug id: 4916384.
+         *
+        // Decomposed hangul (jamos)
+        p = Pattern.compile("\u1100\u1161", Pattern.CANON_EQ);
+        m = p.matcher("\u1100\u1161");
+        if (!m.matches())
+            failCount++;
+
+        m.reset("\uac00");
+        if (!m.matches())
+            failCount++;
+
+        // Composed hangul
+        p = Pattern.compile("\uac00", Pattern.CANON_EQ);
+        m = p.matcher("\u1100\u1161");
+        if (!m.matches())
+            failCount++;
+
+        m.reset("\uac00");
+        if (!m.matches())
+            failCount++;
+
+        // Decomposed supplementary outside char classes
+        p = Pattern.compile("test\ud834\uddbc\ud834\udd6f", Pattern.CANON_EQ);
+        m = p.matcher("test\ud834\uddc0");
+        if (!m.matches())
+            failCount++;
+
+        m.reset("test\ud834\uddbc\ud834\udd6f");
+        if (!m.matches())
+            failCount++;
+
+        // Composed supplementary outside char classes
+        p = Pattern.compile("test\ud834\uddc0", Pattern.CANON_EQ);
+        m.reset("test\ud834\uddbc\ud834\udd6f");
+        if (!m.matches())
+            failCount++;
+
+        m = p.matcher("test\ud834\uddc0");
+        if (!m.matches())
+            failCount++;
+
+        */
+
+        report("Canonical Equivalence");
+    }
+
+    /**
+     * A basic sanity test of Matcher.replaceAll().
+     */
+    private static void globalSubstitute() throws Exception {
+        // Global substitution with a literal
+        Pattern p = Pattern.compile("(ab)(c*)");
+        Matcher m = p.matcher("abccczzzabcczzzabccc");
+        if (!m.replaceAll("test").equals("testzzztestzzztest"))
+            failCount++;
+
+        m.reset("zzzabccczzzabcczzzabccczzz");
+        if (!m.replaceAll("test").equals("zzztestzzztestzzztestzzz"))
+            failCount++;
+
+        // Global substitution with groups
+        m.reset("zzzabccczzzabcczzzabccczzz");
+        String result = m.replaceAll("$1");
+        if (!result.equals("zzzabzzzabzzzabzzz"))
+            failCount++;
+
+        // Supplementary character test
+        // Global substitution with a literal
+        p = Pattern.compile(toSupplementaries("(ab)(c*)"));
+        m = p.matcher(toSupplementaries("abccczzzabcczzzabccc"));
+        if (!m.replaceAll(toSupplementaries("test")).
+            equals(toSupplementaries("testzzztestzzztest")))
+            failCount++;
+
+        m.reset(toSupplementaries("zzzabccczzzabcczzzabccczzz"));
+        if (!m.replaceAll(toSupplementaries("test")).
+            equals(toSupplementaries("zzztestzzztestzzztestzzz")))
+            failCount++;
+
+        // Global substitution with groups
+        m.reset(toSupplementaries("zzzabccczzzabcczzzabccczzz"));
+        result = m.replaceAll("$1");
+        if (!result.equals(toSupplementaries("zzzabzzzabzzzabzzz")))
+            failCount++;
+
+        report("Global Substitution");
+    }
+
+    /**
+     * Tests the usage of Matcher.appendReplacement() with literal
+     * and group substitutions.
+     */
+    private static void stringbufferSubstitute() throws Exception {
+        // SB substitution with literal
+        String blah = "zzzblahzzz";
+        Pattern p = Pattern.compile("blah");
+        Matcher m = p.matcher(blah);
+        StringBuffer result = new StringBuffer();
+        try {
+            m.appendReplacement(result, "blech");
+            failCount++;
+        } catch (IllegalStateException e) {
+        }
+        m.find();
+        m.appendReplacement(result, "blech");
+        if (!result.toString().equals("zzzblech"))
+            failCount++;
+
+        m.appendTail(result);
+        if (!result.toString().equals("zzzblechzzz"))
+            failCount++;
+
+        // SB substitution with groups
+        blah = "zzzabcdzzz";
+        p = Pattern.compile("(ab)(cd)*");
+        m = p.matcher(blah);
+        result = new StringBuffer();
+        try {
+            m.appendReplacement(result, "$1");
+            failCount++;
+        } catch (IllegalStateException e) {
+        }
+        m.find();
+        m.appendReplacement(result, "$1");
+        if (!result.toString().equals("zzzab"))
+            failCount++;
+
+        m.appendTail(result);
+        if (!result.toString().equals("zzzabzzz"))
+            failCount++;
+
+        // SB substitution with 3 groups
+        blah = "zzzabcdcdefzzz";
+        p = Pattern.compile("(ab)(cd)*(ef)");
+        m = p.matcher(blah);
+        result = new StringBuffer();
+        try {
+            m.appendReplacement(result, "$1w$2w$3");
+            failCount++;
+        } catch (IllegalStateException e) {
+        }
+        m.find();
+        m.appendReplacement(result, "$1w$2w$3");
+        if (!result.toString().equals("zzzabwcdwef"))
+            failCount++;
+
+        m.appendTail(result);
+        if (!result.toString().equals("zzzabwcdwefzzz"))
+            failCount++;
+
+        // SB substitution with groups and three matches
+        // skipping middle match
+        blah = "zzzabcdzzzabcddzzzabcdzzz";
+        p = Pattern.compile("(ab)(cd*)");
+        m = p.matcher(blah);
+        result = new StringBuffer();
+        try {
+            m.appendReplacement(result, "$1");
+            failCount++;
+        } catch (IllegalStateException e) {
+        }
+        m.find();
+        m.appendReplacement(result, "$1");
+        if (!result.toString().equals("zzzab"))
+            failCount++;
+
+        m.find();
+        m.find();
+        m.appendReplacement(result, "$2");
+        if (!result.toString().equals("zzzabzzzabcddzzzcd"))
+            failCount++;
+
+        m.appendTail(result);
+        if (!result.toString().equals("zzzabzzzabcddzzzcdzzz"))
+            failCount++;
+
+        // Check to make sure escaped $ is ignored
+        blah = "zzzabcdcdefzzz";
+        p = Pattern.compile("(ab)(cd)*(ef)");
+        m = p.matcher(blah);
+        result = new StringBuffer();
+        m.find();
+        m.appendReplacement(result, "$1w\\$2w$3");
+        if (!result.toString().equals("zzzabw$2wef"))
+            failCount++;
+
+        m.appendTail(result);
+        if (!result.toString().equals("zzzabw$2wefzzz"))
+            failCount++;
+
+        // Check to make sure a reference to nonexistent group causes error
+        blah = "zzzabcdcdefzzz";
+        p = Pattern.compile("(ab)(cd)*(ef)");
+        m = p.matcher(blah);
+        result = new StringBuffer();
+        m.find();
+        try {
+            m.appendReplacement(result, "$1w$5w$3");
+            failCount++;
+        } catch (IndexOutOfBoundsException ioobe) {
+            // Correct result
+        }
+
+        // Check double digit group references
+        blah = "zzz123456789101112zzz";
+        p = Pattern.compile("(1)(2)(3)(4)(5)(6)(7)(8)(9)(10)(11)");
+        m = p.matcher(blah);
+        result = new StringBuffer();
+        m.find();
+        m.appendReplacement(result, "$1w$11w$3");
+        if (!result.toString().equals("zzz1w11w3"))
+            failCount++;
+
+        // Check to make sure it backs off $15 to $1 if only three groups
+        blah = "zzzabcdcdefzzz";
+        p = Pattern.compile("(ab)(cd)*(ef)");
+        m = p.matcher(blah);
+        result = new StringBuffer();
+        m.find();
+        m.appendReplacement(result, "$1w$15w$3");
+        if (!result.toString().equals("zzzabwab5wef"))
+            failCount++;
+
+
+        // Supplementary character test
+        // SB substitution with literal
+        blah = toSupplementaries("zzzblahzzz");
+        p = Pattern.compile(toSupplementaries("blah"));
+        m = p.matcher(blah);
+        result = new StringBuffer();
+        try {
+            m.appendReplacement(result, toSupplementaries("blech"));
+            failCount++;
+        } catch (IllegalStateException e) {
+        }
+        m.find();
+        m.appendReplacement(result, toSupplementaries("blech"));
+        if (!result.toString().equals(toSupplementaries("zzzblech")))
+            failCount++;
+
+        m.appendTail(result);
+        if (!result.toString().equals(toSupplementaries("zzzblechzzz")))
+            failCount++;
+
+        // SB substitution with groups
+        blah = toSupplementaries("zzzabcdzzz");
+        p = Pattern.compile(toSupplementaries("(ab)(cd)*"));
+        m = p.matcher(blah);
+        result = new StringBuffer();
+        try {
+            m.appendReplacement(result, "$1");
+            failCount++;
+        } catch (IllegalStateException e) {
+        }
+        m.find();
+        m.appendReplacement(result, "$1");
+        if (!result.toString().equals(toSupplementaries("zzzab")))
+            failCount++;
+
+        m.appendTail(result);
+        if (!result.toString().equals(toSupplementaries("zzzabzzz")))
+            failCount++;
+
+        // SB substitution with 3 groups
+        blah = toSupplementaries("zzzabcdcdefzzz");
+        p = Pattern.compile(toSupplementaries("(ab)(cd)*(ef)"));
+        m = p.matcher(blah);
+        result = new StringBuffer();
+        try {
+            m.appendReplacement(result, toSupplementaries("$1w$2w$3"));
+            failCount++;
+        } catch (IllegalStateException e) {
+        }
+        m.find();
+        m.appendReplacement(result, toSupplementaries("$1w$2w$3"));
+        if (!result.toString().equals(toSupplementaries("zzzabwcdwef")))
+            failCount++;
+
+        m.appendTail(result);
+        if (!result.toString().equals(toSupplementaries("zzzabwcdwefzzz")))
+            failCount++;
+
+        // SB substitution with groups and three matches
+        // skipping middle match
+        blah = toSupplementaries("zzzabcdzzzabcddzzzabcdzzz");
+        p = Pattern.compile(toSupplementaries("(ab)(cd*)"));
+        m = p.matcher(blah);
+        result = new StringBuffer();
+        try {
+            m.appendReplacement(result, "$1");
+            failCount++;
+        } catch (IllegalStateException e) {
+        }
+        m.find();
+        m.appendReplacement(result, "$1");
+        if (!result.toString().equals(toSupplementaries("zzzab")))
+            failCount++;
+
+        m.find();
+        m.find();
+        m.appendReplacement(result, "$2");
+        if (!result.toString().equals(toSupplementaries("zzzabzzzabcddzzzcd")))
+            failCount++;
+
+        m.appendTail(result);
+        if (!result.toString().equals(toSupplementaries("zzzabzzzabcddzzzcdzzz")))
+            failCount++;
+
+        // Check to make sure escaped $ is ignored
+        blah = toSupplementaries("zzzabcdcdefzzz");
+        p = Pattern.compile(toSupplementaries("(ab)(cd)*(ef)"));
+        m = p.matcher(blah);
+        result = new StringBuffer();
+        m.find();
+        m.appendReplacement(result, toSupplementaries("$1w\\$2w$3"));
+        if (!result.toString().equals(toSupplementaries("zzzabw$2wef")))
+            failCount++;
+
+        m.appendTail(result);
+        if (!result.toString().equals(toSupplementaries("zzzabw$2wefzzz")))
+            failCount++;
+
+        // Check to make sure a reference to nonexistent group causes error
+        blah = toSupplementaries("zzzabcdcdefzzz");
+        p = Pattern.compile(toSupplementaries("(ab)(cd)*(ef)"));
+        m = p.matcher(blah);
+        result = new StringBuffer();
+        m.find();
+        try {
+            m.appendReplacement(result, toSupplementaries("$1w$5w$3"));
+            failCount++;
+        } catch (IndexOutOfBoundsException ioobe) {
+            // Correct result
+        }
+
+        // Check double digit group references
+        blah = toSupplementaries("zzz123456789101112zzz");
+        p = Pattern.compile("(1)(2)(3)(4)(5)(6)(7)(8)(9)(10)(11)");
+        m = p.matcher(blah);
+        result = new StringBuffer();
+        m.find();
+        m.appendReplacement(result, toSupplementaries("$1w$11w$3"));
+        if (!result.toString().equals(toSupplementaries("zzz1w11w3")))
+            failCount++;
+
+        // Check to make sure it backs off $15 to $1 if only three groups
+        blah = toSupplementaries("zzzabcdcdefzzz");
+        p = Pattern.compile(toSupplementaries("(ab)(cd)*(ef)"));
+        m = p.matcher(blah);
+        result = new StringBuffer();
+        m.find();
+        m.appendReplacement(result, toSupplementaries("$1w$15w$3"));
+        if (!result.toString().equals(toSupplementaries("zzzabwab5wef")))
+            failCount++;
+
+        // Check nothing has been appended into the output buffer if
+        // the replacement string triggers IllegalArgumentException.
+        p = Pattern.compile("(abc)");
+        m = p.matcher("abcd");
+        result = new StringBuffer();
+        m.find();
+        try {
+            m.appendReplacement(result, ("xyz$g"));
+            failCount++;
+        } catch (IllegalArgumentException iae) {
+            if (result.length() != 0)
+                failCount++;
+        }
+
+        report("SB Substitution");
+    }
+
+    /*
+     * 5 groups of characters are created to make a substitution string.
+     * A base string will be created including random lead chars, the
+     * substitution string, and random trailing chars.
+     * A pattern containing the 5 groups is searched for and replaced with:
+     * random group + random string + random group.
+     * The results are checked for correctness.
+     */
+    private static void substitutionBasher() {
+        for (int runs = 0; runs<1000; runs++) {
+            // Create a base string to work in
+            int leadingChars = generator.nextInt(10);
+            StringBuffer baseBuffer = new StringBuffer(100);
+            String leadingString = getRandomAlphaString(leadingChars);
+            baseBuffer.append(leadingString);
+
+            // Create 5 groups of random number of random chars
+            // Create the string to substitute
+            // Create the pattern string to search for
+            StringBuffer bufferToSub = new StringBuffer(25);
+            StringBuffer bufferToPat = new StringBuffer(50);
+            String[] groups = new String[5];
+            for(int i=0; i<5; i++) {
+                int aGroupSize = generator.nextInt(5)+1;
+                groups[i] = getRandomAlphaString(aGroupSize);
+                bufferToSub.append(groups[i]);
+                bufferToPat.append('(');
+                bufferToPat.append(groups[i]);
+                bufferToPat.append(')');
+            }
+            String stringToSub = bufferToSub.toString();
+            String pattern = bufferToPat.toString();
+
+            // Place sub string into working string at random index
+            baseBuffer.append(stringToSub);
+
+            // Append random chars to end
+            int trailingChars = generator.nextInt(10);
+            String trailingString = getRandomAlphaString(trailingChars);
+            baseBuffer.append(trailingString);
+            String baseString = baseBuffer.toString();
+
+            // Create test pattern and matcher
+            Pattern p = Pattern.compile(pattern);
+            Matcher m = p.matcher(baseString);
+
+            // Reject candidate if pattern happens to start early
+            m.find();
+            if (m.start() < leadingChars)
+                continue;
+
+            // Reject candidate if more than one match
+            if (m.find())
+                continue;
+
+            // Construct a replacement string with :
+            // random group + random string + random group
+            StringBuffer bufferToRep = new StringBuffer();
+            int groupIndex1 = generator.nextInt(5);
+            bufferToRep.append("$" + (groupIndex1 + 1));
+            String randomMidString = getRandomAlphaString(5);
+            bufferToRep.append(randomMidString);
+            int groupIndex2 = generator.nextInt(5);
+            bufferToRep.append("$" + (groupIndex2 + 1));
+            String replacement = bufferToRep.toString();
+
+            // Do the replacement
+            String result = m.replaceAll(replacement);
+
+            // Construct expected result
+            StringBuffer bufferToRes = new StringBuffer();
+            bufferToRes.append(leadingString);
+            bufferToRes.append(groups[groupIndex1]);
+            bufferToRes.append(randomMidString);
+            bufferToRes.append(groups[groupIndex2]);
+            bufferToRes.append(trailingString);
+            String expectedResult = bufferToRes.toString();
+
+            // Check results
+            if (!result.equals(expectedResult))
+                failCount++;
+        }
+
+        report("Substitution Basher");
+    }
+
+    /**
+     * Checks the handling of some escape sequences that the Pattern
+     * class should process instead of the java compiler. These are
+     * not in the file because the escapes should be be processed
+     * by the Pattern class when the regex is compiled.
+     */
+    private static void escapes() throws Exception {
+        Pattern p = Pattern.compile("\\043");
+        Matcher m = p.matcher("#");
+        if (!m.find())
+            failCount++;
+
+        p = Pattern.compile("\\x23");
+        m = p.matcher("#");
+        if (!m.find())
+            failCount++;
+
+        p = Pattern.compile("\\u0023");
+        m = p.matcher("#");
+        if (!m.find())
+            failCount++;
+
+        report("Escape sequences");
+    }
+
+    /**
+     * Checks the handling of blank input situations. These
+     * tests are incompatible with my test file format.
+     */
+    private static void blankInput() throws Exception {
+        Pattern p = Pattern.compile("abc", Pattern.CASE_INSENSITIVE);
+        Matcher m = p.matcher("");
+        if (m.find())
+            failCount++;
+
+        p = Pattern.compile("a*", Pattern.CASE_INSENSITIVE);
+        m = p.matcher("");
+        if (!m.find())
+            failCount++;
+
+        p = Pattern.compile("abc");
+        m = p.matcher("");
+        if (m.find())
+            failCount++;
+
+        p = Pattern.compile("a*");
+        m = p.matcher("");
+        if (!m.find())
+            failCount++;
+
+        report("Blank input");
+    }
+
+    /**
+     * Tests the Boyer-Moore pattern matching of a character sequence
+     * on randomly generated patterns.
+     */
+    private static void bm() throws Exception {
+        doBnM('a');
+        report("Boyer Moore (ASCII)");
+
+        doBnM(Character.MIN_SUPPLEMENTARY_CODE_POINT - 10);
+        report("Boyer Moore (Supplementary)");
+    }
+
+    private static void doBnM(int baseCharacter) throws Exception {
+        int achar=0;
+
+        for (int i=0; i<100; i++) {
+            // Create a short pattern to search for
+            int patternLength = generator.nextInt(7) + 4;
+            StringBuffer patternBuffer = new StringBuffer(patternLength);
+            for (int x=0; x<patternLength; x++) {
+                int ch = baseCharacter + generator.nextInt(26);
+                if (Character.isSupplementaryCodePoint(ch)) {
+                    patternBuffer.append(Character.toChars(ch));
+                } else {
+                    patternBuffer.append((char)ch);
+                }
+            }
+            String pattern =  patternBuffer.toString();
+            Pattern p = Pattern.compile(pattern);
+
+            // Create a buffer with random ASCII chars that does
+            // not match the sample
+            String toSearch = null;
+            StringBuffer s = null;
+            Matcher m = p.matcher("");
+            do {
+                s = new StringBuffer(100);
+                for (int x=0; x<100; x++) {
+                    int ch = baseCharacter + generator.nextInt(26);
+                    if (Character.isSupplementaryCodePoint(ch)) {
+                        s.append(Character.toChars(ch));
+                    } else {
+                        s.append((char)ch);
+                    }
+                }
+                toSearch = s.toString();
+                m.reset(toSearch);
+            } while (m.find());
+
+            // Insert the pattern at a random spot
+            int insertIndex = generator.nextInt(99);
+            if (Character.isLowSurrogate(s.charAt(insertIndex)))
+                insertIndex++;
+            s = s.insert(insertIndex, pattern);
+            toSearch = s.toString();
+
+            // Make sure that the pattern is found
+            m.reset(toSearch);
+            if (!m.find())
+                failCount++;
+
+            // Make sure that the match text is the pattern
+            if (!m.group().equals(pattern))
+                failCount++;
+
+            // Make sure match occured at insertion point
+            if (m.start() != insertIndex)
+                failCount++;
+        }
+    }
+
+    /**
+     * Tests the matching of slices on randomly generated patterns.
+     * The Boyer-Moore optimization is not done on these patterns
+     * because it uses unicode case folding.
+     */
+    private static void slice() throws Exception {
+        doSlice(Character.MAX_VALUE);
+        report("Slice");
+
+        doSlice(Character.MAX_CODE_POINT);
+        report("Slice (Supplementary)");
+    }
+
+    private static void doSlice(int maxCharacter) throws Exception {
+        Random generator = new Random();
+        int achar=0;
+
+        for (int i=0; i<100; i++) {
+            // Create a short pattern to search for
+            int patternLength = generator.nextInt(7) + 4;
+            StringBuffer patternBuffer = new StringBuffer(patternLength);
+            for (int x=0; x<patternLength; x++) {
+                int randomChar = 0;
+                while (!Character.isLetterOrDigit(randomChar))
+                    randomChar = generator.nextInt(maxCharacter);
+                if (Character.isSupplementaryCodePoint(randomChar)) {
+                    patternBuffer.append(Character.toChars(randomChar));
+                } else {
+                    patternBuffer.append((char) randomChar);
+                }
+            }
+            String pattern =  patternBuffer.toString();
+            Pattern p = Pattern.compile(pattern, Pattern.UNICODE_CASE);
+
+            // Create a buffer with random chars that does not match the sample
+            String toSearch = null;
+            StringBuffer s = null;
+            Matcher m = p.matcher("");
+            do {
+                s = new StringBuffer(100);
+                for (int x=0; x<100; x++) {
+                    int randomChar = 0;
+                    while (!Character.isLetterOrDigit(randomChar))
+                        randomChar = generator.nextInt(maxCharacter);
+                    if (Character.isSupplementaryCodePoint(randomChar)) {
+                        s.append(Character.toChars(randomChar));
+                    } else {
+                        s.append((char) randomChar);
+                    }
+                }
+                toSearch = s.toString();
+                m.reset(toSearch);
+            } while (m.find());
+
+            // Insert the pattern at a random spot
+            int insertIndex = generator.nextInt(99);
+            if (Character.isLowSurrogate(s.charAt(insertIndex)))
+                insertIndex++;
+            s = s.insert(insertIndex, pattern);
+            toSearch = s.toString();
+
+            // Make sure that the pattern is found
+            m.reset(toSearch);
+            if (!m.find())
+                failCount++;
+
+            // Make sure that the match text is the pattern
+            if (!m.group().equals(pattern))
+                failCount++;
+
+            // Make sure match occured at insertion point
+            if (m.start() != insertIndex)
+                failCount++;
+        }
+    }
+
+    private static void explainFailure(String pattern, String data,
+                                       String expected, String actual) {
+        System.err.println("----------------------------------------");
+        System.err.println("Pattern = "+pattern);
+        System.err.println("Data = "+data);
+        System.err.println("Expected = " + expected);
+        System.err.println("Actual   = " + actual);
+    }
+
+    private static void explainFailure(String pattern, String data,
+                                       Throwable t) {
+        System.err.println("----------------------------------------");
+        System.err.println("Pattern = "+pattern);
+        System.err.println("Data = "+data);
+        t.printStackTrace(System.err);
+    }
+
+    // Testing examples from a file
+
+    /**
+     * Goes through the file "TestCases.txt" and creates many patterns
+     * described in the file, matching the patterns against input lines in
+     * the file, and comparing the results against the correct results
+     * also found in the file. The file format is described in comments
+     * at the head of the file.
+     */
+    private static void processFile(String fileName) throws Exception {
+        File testCases = new File(System.getProperty("test.src", "."),
+                                  fileName);
+        FileInputStream in = new FileInputStream(testCases);
+        BufferedReader r = new BufferedReader(new InputStreamReader(in));
+
+        // Process next test case.
+        String aLine;
+        while((aLine = r.readLine()) != null) {
+            // Read a line for pattern
+            String patternString = grabLine(r);
+            Pattern p = null;
+            try {
+                p = compileTestPattern(patternString);
+            } catch (PatternSyntaxException e) {
+                String dataString = grabLine(r);
+                String expectedResult = grabLine(r);
+                if (expectedResult.startsWith("error"))
+                    continue;
+                explainFailure(patternString, dataString, e);
+                failCount++;
+                continue;
+            }
+
+            // Read a line for input string
+            String dataString = grabLine(r);
+            Matcher m = p.matcher(dataString);
+            StringBuffer result = new StringBuffer();
+
+            // Check for IllegalStateExceptions before a match
+            failCount += preMatchInvariants(m);
+
+            boolean found = m.find();
+
+            if (found)
+                failCount += postTrueMatchInvariants(m);
+            else
+                failCount += postFalseMatchInvariants(m);
+
+            if (found) {
+                result.append("true ");
+                result.append(m.group(0) + " ");
+            } else {
+                result.append("false ");
+            }
+
+            result.append(m.groupCount());
+
+            if (found) {
+                for (int i=1; i<m.groupCount()+1; i++)
+                    if (m.group(i) != null)
+                        result.append(" " +m.group(i));
+            }
+
+            // Read a line for the expected result
+            String expectedResult = grabLine(r);
+
+            if (!result.toString().equals(expectedResult)) {
+                explainFailure(patternString, dataString, expectedResult, result.toString());
+                failCount++;
+            }
+        }
+
+        report(fileName);
+    }
+
+    private static int preMatchInvariants(Matcher m) {
+        int failCount = 0;
+        try {
+            m.start();
+            failCount++;
+        } catch (IllegalStateException ise) {}
+        try {
+            m.end();
+            failCount++;
+        } catch (IllegalStateException ise) {}
+        try {
+            m.group();
+            failCount++;
+        } catch (IllegalStateException ise) {}
+        return failCount;
+    }
+
+    private static int postFalseMatchInvariants(Matcher m) {
+        int failCount = 0;
+        try {
+            m.group();
+            failCount++;
+        } catch (IllegalStateException ise) {}
+        try {
+            m.start();
+            failCount++;
+        } catch (IllegalStateException ise) {}
+        try {
+            m.end();
+            failCount++;
+        } catch (IllegalStateException ise) {}
+        return failCount;
+    }
+
+    private static int postTrueMatchInvariants(Matcher m) {
+        int failCount = 0;
+        //assert(m.start() = m.start(0);
+        if (m.start() != m.start(0))
+            failCount++;
+        //assert(m.end() = m.end(0);
+        if (m.start() != m.start(0))
+            failCount++;
+        //assert(m.group() = m.group(0);
+        if (!m.group().equals(m.group(0)))
+            failCount++;
+        try {
+            m.group(50);
+            failCount++;
+        } catch (IndexOutOfBoundsException ise) {}
+
+        return failCount;
+    }
+
+    private static Pattern compileTestPattern(String patternString) {
+        if (!patternString.startsWith("'")) {
+            return Pattern.compile(patternString);
+        }
+
+        int break1 = patternString.lastIndexOf("'");
+        String flagString = patternString.substring(
+                                          break1+1, patternString.length());
+        patternString = patternString.substring(1, break1);
+
+        if (flagString.equals("i"))
+            return Pattern.compile(patternString, Pattern.CASE_INSENSITIVE);
+
+        if (flagString.equals("m"))
+            return Pattern.compile(patternString, Pattern.MULTILINE);
+
+        return Pattern.compile(patternString);
+    }
+
+    /**
+     * Reads a line from the input file. Keeps reading lines until a non
+     * empty non comment line is read. If the line contains a \n then
+     * these two characters are replaced by a newline char. If a \\uxxxx
+     * sequence is read then the sequence is replaced by the unicode char.
+     */
+    private static String grabLine(BufferedReader r) throws Exception {
+        int index = 0;
+        String line = r.readLine();
+        while (line.startsWith("//") || line.length() < 1)
+            line = r.readLine();
+        while ((index = line.indexOf("\\n")) != -1) {
+            StringBuffer temp = new StringBuffer(line);
+            temp.replace(index, index+2, "\n");
+            line = temp.toString();
+        }
+        while ((index = line.indexOf("\\u")) != -1) {
+            StringBuffer temp = new StringBuffer(line);
+            String value = temp.substring(index+2, index+6);
+            char aChar = (char)Integer.parseInt(value, 16);
+            String unicodeChar = "" + aChar;
+            temp.replace(index, index+6, unicodeChar);
+            line = temp.toString();
+        }
+
+        return line;
+    }
+
+    private static void check(Pattern p, String s, String g, String expected) {
+        Matcher m = p.matcher(s);
+        m.find();
+        if (!m.group(g).equals(expected))
+            failCount++;
+    }
+
+    private static void checkReplaceFirst(String p, String s, String r, String expected)
+    {
+        if (!expected.equals(Pattern.compile(p)
+                                    .matcher(s)
+                                    .replaceFirst(r)))
+            failCount++;
+    }
+
+    private static void checkReplaceAll(String p, String s, String r, String expected)
+    {
+        if (!expected.equals(Pattern.compile(p)
+                                    .matcher(s)
+                                    .replaceAll(r)))
+            failCount++;
+    }
+
+    private static void checkExpectedFail(String p) {
+        try {
+            Pattern.compile(p);
+        } catch (PatternSyntaxException pse) {
+            //pse.printStackTrace();
+            return;
+        }
+        failCount++;
+    }
+
+    private static void checkExpectedFail(Matcher m, String g) {
+        m.find();
+        try {
+            m.group(g);
+        } catch (IllegalArgumentException iae) {
+            //iae.printStackTrace();
+            return;
+        } catch (NullPointerException npe) {
+            return;
+        }
+        failCount++;
+    }
+
+
+    private static void namedGroupCaptureTest() throws Exception {
+        check(Pattern.compile("x+(?<gname>y+)z+"),
+              "xxxyyyzzz",
+              "gname",
+              "yyy");
+
+        //backref
+        Pattern pattern = Pattern.compile("(a*)bc\\1");
+        check(pattern, "zzzaabcazzz", true);  // found "abca"
+
+        check(Pattern.compile("(?<gname>a*)bc\\k<gname>"),
+              "zzzaabcaazzz", true);
+
+        check(Pattern.compile("(?<gname>abc)(def)\\k<gname>"),
+              "abcdefabc", true);
+
+        check(Pattern.compile("(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(?<gname>k)\\k<gname>"),
+              "abcdefghijkk", true);
+
+        // Supplementary character tests
+        check(Pattern.compile("(?<gname>" + toSupplementaries("a*)bc") + "\\k<gname>"),
+              toSupplementaries("zzzaabcazzz"), true);
+
+        check(Pattern.compile("(?<gname>" + toSupplementaries("a*)bc") + "\\k<gname>"),
+              toSupplementaries("zzzaabcaazzz"), true);
+
+        check(Pattern.compile("(?<gname>" + toSupplementaries("abc)(def)") + "\\k<gname>"),
+              toSupplementaries("abcdefabc"), true);
+
+        check(Pattern.compile(toSupplementaries("(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)") +
+                              "(?<gname>" +
+                              toSupplementaries("k)") + "\\k<gname>"),
+              toSupplementaries("abcdefghijkk"), true);
+
+        check(Pattern.compile("x+(?<gname>y+)z+\\k<gname>"),
+              "xxxyyyzzzyyy",
+              "gname",
+              "yyy");
+
+        //replaceFirst/All
+        checkReplaceFirst("(?<gn>ab)(c*)",
+                          "abccczzzabcczzzabccc",
+                          "$<gn>",
+                          "abzzzabcczzzabccc");
+
+        checkReplaceAll("(?<gn>ab)(c*)",
+                        "abccczzzabcczzzabccc",
+                        "$<gn>",
+                        "abzzzabzzzab");
+
+
+        checkReplaceFirst("(?<gn>ab)(c*)",
+                          "zzzabccczzzabcczzzabccczzz",
+                          "$<gn>",
+                          "zzzabzzzabcczzzabccczzz");
+
+        checkReplaceAll("(?<gn>ab)(c*)",
+                        "zzzabccczzzabcczzzabccczzz",
+                        "$<gn>",
+                        "zzzabzzzabzzzabzzz");
+
+        checkReplaceFirst("(?<gn1>ab)(?<gn2>c*)",
+                          "zzzabccczzzabcczzzabccczzz",
+                          "$<gn2>",
+                          "zzzccczzzabcczzzabccczzz");
+
+        checkReplaceAll("(?<gn1>ab)(?<gn2>c*)",
+                        "zzzabccczzzabcczzzabccczzz",
+                        "$<gn2>",
+                        "zzzccczzzcczzzccczzz");
+
+        //toSupplementaries("(ab)(c*)"));
+        checkReplaceFirst("(?<gn1>" + toSupplementaries("ab") +
+                           ")(?<gn2>" + toSupplementaries("c") + "*)",
+                          toSupplementaries("abccczzzabcczzzabccc"),
+                          "$<gn1>",
+                          toSupplementaries("abzzzabcczzzabccc"));
+
+
+        checkReplaceAll("(?<gn1>" + toSupplementaries("ab") +
+                        ")(?<gn2>" + toSupplementaries("c") + "*)",
+                        toSupplementaries("abccczzzabcczzzabccc"),
+                        "$<gn1>",
+                        toSupplementaries("abzzzabzzzab"));
+
+        checkReplaceFirst("(?<gn1>" + toSupplementaries("ab") +
+                           ")(?<gn2>" + toSupplementaries("c") + "*)",
+                          toSupplementaries("abccczzzabcczzzabccc"),
+                          "$<gn2>",
+                          toSupplementaries("ccczzzabcczzzabccc"));
+
+
+        checkReplaceAll("(?<gn1>" + toSupplementaries("ab") +
+                        ")(?<gn2>" + toSupplementaries("c") + "*)",
+                        toSupplementaries("abccczzzabcczzzabccc"),
+                        "$<gn2>",
+                        toSupplementaries("ccczzzcczzzccc"));
+
+        checkReplaceFirst("(?<dog>Dog)AndCat",
+                          "zzzDogAndCatzzzDogAndCatzzz",
+                          "$<dog>",
+                          "zzzDogzzzDogAndCatzzz");
+
+
+        checkReplaceAll("(?<dog>Dog)AndCat",
+                          "zzzDogAndCatzzzDogAndCatzzz",
+                          "$<dog>",
+                          "zzzDogzzzDogzzz");
+
+        // backref in Matcher & String
+        if (!"abcdefghij".replaceFirst("cd(?<gn>ef)gh", "$<gn>").equals("abefij") ||
+            !"abbbcbdbefgh".replaceAll("(?<gn>[a-e])b", "$<gn>").equals("abcdefgh"))
+            failCount++;
+
+        // negative
+        checkExpectedFail("(?<groupnamehasnoascii.in>abc)(def)");
+        checkExpectedFail("(?<groupnamehasnoascii_in>abc)(def)");
+        checkExpectedFail("(?<gname>abc)(def)\\k<gnameX>");
+        checkExpectedFail("(?<gname>abc)(?<gname>def)\\k<gnameX>");
+        checkExpectedFail(Pattern.compile("(?<gname>abc)(def)").matcher("abcdef"),
+                          "gnameX");
+        checkExpectedFail(Pattern.compile("(?<gname>abc)(def)").matcher("abcdef"),
+                          null);
+        report("NamedGroupCapture");
+    }
+}
diff --git a/jdk/test/java/util/regex/SupplementaryTestCases.txt b/jdk/test/java/util/regex/SupplementaryTestCases.txt
new file mode 100644
index 0000000..2f05d4f
--- /dev/null
+++ b/jdk/test/java/util/regex/SupplementaryTestCases.txt
@@ -0,0 +1,1434 @@
+//
+// Copyright 1999-2009 Sun Microsystems, Inc.  All Rights Reserved.
+// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+//
+// This code is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License version 2 only, as
+// published by the Free Software Foundation.
+//
+// This code is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// version 2 for more details (a copy is included in the LICENSE file that
+// accompanied this code).
+//
+// You should have received a copy of the GNU General Public License version
+// 2 along with this work; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+// CA 95054 USA or visit www.sun.com if you need additional information or
+// have any questions.
+//
+// --------------------------------------------------------
+// This file contains test cases with supplementary characters for regular expressions.
+// A test case consists of three lines:
+// The first line is a pattern used in the test
+// The second line is the input to search for the pattern in
+// The third line is a concatentation of the match, the number of groups,
+//     and the contents of the first four subexpressions.
+// Empty lines and lines beginning with comment slashes are ignored.
+
+// Test unsetting of backed off groups
+^(\ud800\udc61)?\ud800\udc61
+\ud800\udc61
+true \ud800\udc61 1
+
+^(\ud800\udc61\ud800)?\ud800\udc61\ud800
+\ud800\udc61\ud800
+true \ud800\udc61\ud800 1
+
+^(\ud800\udc61\ud800\udc61(\ud800\udc62\ud800\udc62)?)+$
+\ud800\udc61\ud800\udc61\ud800\udc62\ud800\udc62\ud800\udc61\ud800\udc61
+true \ud800\udc61\ud800\udc61\ud800\udc62\ud800\udc62\ud800\udc61\ud800\udc61 2 \ud800\udc61\ud800\udc61 \ud800\udc62\ud800\udc62
+
+^(\ud800\udc61\ud800\udc61\ud800(\ud800\udc62\ud800\udc62\ud800)?)+$
+\ud800\udc61\ud800\udc61\ud800\ud800\udc62\ud800\udc62\ud800\ud800\udc61\ud800\udc61\ud800
+true \ud800\udc61\ud800\udc61\ud800\ud800\udc62\ud800\udc62\ud800\ud800\udc61\ud800\udc61\ud800 2 \ud800\udc61\ud800\udc61\ud800 \ud800\udc62\ud800\udc62\ud800
+
+((\ud800\udc61|\ud800\udc62)?\ud800\udc62)+
+\ud800\udc62
+true \ud800\udc62 2 \ud800\udc62
+
+((\ud800|\ud800\udc62)?\ud800\udc62)+
+\ud800\udc62
+true \ud800\udc62 2 \ud800\udc62
+
+(\ud800\udc61\ud800\udc61\ud800\udc61)?\ud800\udc61\ud800\udc61\ud800\udc61
+\ud800\udc61\ud800\udc61\ud800\udc61
+true \ud800\udc61\ud800\udc61\ud800\udc61 1
+
+(\ud800\udc61\ud800\udc61\ud800\ud800\udc61)?\ud800\udc61\ud800\udc61\ud800\ud800\udc61
+\ud800\udc61\ud800\udc61\ud800\ud800\udc61
+true \ud800\udc61\ud800\udc61\ud800\ud800\udc61 1
+
+^(\ud800\udc61\ud800(\ud800\udc62\ud800)?)+$
+\ud800\udc61\ud800\ud800\udc62\ud800\ud800\udc61\ud800
+true \ud800\udc61\ud800\ud800\udc62\ud800\ud800\udc61\ud800 2 \ud800\udc61\ud800 \ud800\udc62\ud800
+
+^(\ud800\udc61(\ud800\udc62)?)+$
+\ud800\udc61\ud800\udc62\ud800\udc61
+true \ud800\udc61\ud800\udc62\ud800\udc61 2 \ud800\udc61 \ud800\udc62
+
+^(\ud800\udc61\ud800(\ud800\udc62\ud800)?)+$
+\ud800\udc61\ud800\ud800\udc62\ud800\ud800\udc61\ud800
+true \ud800\udc61\ud800\ud800\udc62\ud800\ud800\udc61\ud800 2 \ud800\udc61\ud800 \ud800\udc62\ud800
+
+^(\ud800\udc61(\ud800\udc62(\ud800\udc63)?)?)?\ud800\udc61\ud800\udc62\ud800\udc63
+\ud800\udc61\ud800\udc62\ud800\udc63
+true \ud800\udc61\ud800\udc62\ud800\udc63 3
+
+^(\ud800\udc61\ud800(\ud800\udc62(\ud800\udc63)?)?)?\ud800\udc61\ud800\ud800\udc62\ud800\udc63
+\ud800\udc61\ud800\ud800\udc62\ud800\udc63
+true \ud800\udc61\ud800\ud800\udc62\ud800\udc63 3
+
+^(\ud800\udc61(\ud800\udc02(\ud800\udc63))).*
+\ud800\udc61\ud800\udc02\ud800\udc63
+true \ud800\udc61\ud800\udc02\ud800\udc63 3 \ud800\udc61\ud800\udc02\ud800\udc63 \ud800\udc02\ud800\udc63 \ud800\udc63
+
+^(\ud800\udc61(\ud800(\ud800\udc63))).*
+\ud800\udc61\ud800\ud800\udc63
+true \ud800\udc61\ud800\ud800\udc63 3 \ud800\udc61\ud800\ud800\udc63 \ud800\ud800\udc63 \ud800\udc63
+
+// Patterns including no surrogates
+(.)([^a])xyz
+\ud801\ud800\udc00xyz
+true \ud801\ud800\udc00xyz 2 \ud801 \ud800\udc00
+
+[^a-z]..
+\ud801\ud800\udc00xyz
+true \ud801\ud800\udc00x 0
+
+.$
+\ud801\ud800\udc00
+true \ud800\udc00 0
+
+.$
+\ud801\udc01\ud800\udc00
+true \ud800\udc00 0
+
+.$
+\ud801\udc01\ud800\udc00\udcff
+true \udcff 0
+
+[^x-\uffff][^y-\uffff]
+\ud800\udc00pqr
+true \ud800\udc00p 0
+
+[^x-\uffff]+
+\ud800\udc00pqrx
+true \ud800\udc00pqr 0
+
+/// The following test cases fail due to use of Start rather than
+/// StartS. Disabled for now.
+///[a-\uffff]
+///\ud800\udc00x
+///true x 0
+///
+///[a-\uffff]
+///\ud800\udc00
+///false 0
+
+// use of x modifier
+\ud800\udc61bc(?x)bl\ud800\udc61h
+\ud800\udc61bcbl\ud800\udc61h
+true \ud800\udc61bcbl\ud800\udc61h 0
+
+\ud800\udc61bc(?x)  bl\ud800\udc61h
+\ud800\udc61bcbl\ud800\udc61h
+true \ud800\udc61bcbl\ud800\udc61h 0
+
+\ud800\udc61bc(?x)  bl\ud800\udc61h  blech
+\ud800\udc61bcbl\ud800\udc61hblech
+true \ud800\udc61bcbl\ud800\udc61hblech 0
+
+\ud800\udc61bc(?x)  bl\ud800\udc61h # ignore comment
+\ud800\udc61bcbl\ud800\udc61h
+true \ud800\udc61bcbl\ud800\udc61h 0
+
+// Simple alternation
+\ud800\udc61|\ud800\udc62
+\ud800\udc61
+true \ud800\udc61 0
+
+\ud800\udc61|\ud800\udc62|\ud800
+\ud800\udc61
+true \ud800\udc61 0
+
+\ud800\udc61|\ud800
+\ud800\udc62
+false 0
+
+\ud800\udc62|\ud800
+\ud800
+true \ud800 0
+
+\ud800\udc61|\ud802\udc02
+z
+false 0
+
+\ud800\udc61|\ud802\udc02
+\ud802\udc02
+true \ud802\udc02 0
+
+\ud800\udc61|\ud802\udc02|\ud803\udc03\ud804\udc04
+\ud803\udc03\ud804\udc04
+true \ud803\udc03\ud804\udc04 0
+
+\ud800\udc61|\ud800\udc61d
+\ud800\udc61d
+true \ud800\udc61 0
+
+z(\ud800\udc61|\ud800\udc61c)\ud802\udc02
+z\ud800\udc61c\ud802\udc02
+true z\ud800\udc61c\ud802\udc02 1 \ud800\udc61c
+
+z(\ud800\udc61|\ud800\udc61c|\udc61c)\ud802\udc02
+z\udc61c\ud802\udc02
+true z\udc61c\ud802\udc02 1 \udc61c
+
+// Simple codepoint class
+[\ud800\udc61\ud802\udc02c]+
+\ud800\udc61\ud802\udc02\ud800\udc61\ud802\udc02\ud800\udc61\ud802\udc02
+true \ud800\udc61\ud802\udc02\ud800\udc61\ud802\udc02\ud800\udc61\ud802\udc02 0
+
+[\ud800\udc61\ud802\udc02c]+
+\ud800\udc61\ud802\udc02\ud800\udc61\ud802\udc02\ud800\udc61\ud802\udc02
+true \ud800\udc61\ud802\udc02\ud800\udc61\ud802\udc02\ud800\udc61\ud802\udc02 0
+
+[\ud800\udc61\ud802\udc02c\ud800]+
+\ud800\udc61\ud802\udc02\ud800\ud800\udc61\ud802\udc02\ud800\udc61\ud802\udc02
+true \ud800\udc61\ud802\udc02\ud800\ud800\udc61\ud802\udc02\ud800\udc61\ud802\udc02 0
+
+[\ud800\udc61bc]+
+d\ud800\udc62fg
+false 0
+
+[\ud800\udc61bc]+[\ud804\udc04ef]+[\ud807\udc07hi]+
+zzz\ud800\udc61\ud800\udc61\ud804\udc04\ud804\udc04\ud807\udc07\ud807\udc07zzz
+true \ud800\udc61\ud800\udc61\ud804\udc04\ud804\udc04\ud807\udc07\ud807\udc07 0
+
+// Range codepoint class
+[\ud801\udc01-\ud807\udc07]+
+\ud8ff\udcff\ud8ff\udcff\ud8ff\udcff\ud807\udc07\ud807\udc07\ud807\udc07
+true \ud807\udc07\ud807\udc07\ud807\udc07 0
+
+[\ud801\udc01-\ud807\udc07]+
+mmm
+false 0
+
+[\ud800\udc61-]+
+z\ud800\udc61-9z
+true \ud800\udc61- 0
+
+// Negated char class
+[^\ud800\udc61\ud802\udc02c]+
+\ud800\udc61\ud802\udc02\ud800\udc61\ud802\udc02\ud800\udc61\ud802\udc02
+false 0
+
+[^\ud800\udc61\ud802\udc02\ud803\udc03]+
+\ud800\udc61\ud800\udc61\ud800\udc61\ud802\udc02\ud802\udc02\ud802\udc02\ud803\udc03\ud803\udc03\ud803\udc03\ud804\udc04efg
+true \ud804\udc04efg 0
+
+[^\ud800\udc61\ud802\udc02\ud803\udc03\ud800]+
+\ud800\udc61\ud800\udc61\ud800\udc61\ud802\udc02\ud802\udc02\ud802\udc02\ud803\udc03\ud803\udc03\ud803\udc03\ud804\udc04efg
+true \ud804\udc04efg 0
+
+// Making sure a ^ not in first position matches literal ^
+[\ud801\udc01\ud802\udc02\ud803\udc03^\ud802\udc02]
+\ud802\udc02
+true \ud802\udc02 0
+
+[\ud801\udc01\ud802\udc02\ud803\udc03^\ud802\udc02]
+^
+true ^ 0
+
+// Class union and intersection
+[\ud801\udc01\ud802\udc02\ud803\udc03[\ud804\udc04\ud805\udc05\ud806\udc06]]
+\ud802\udc02
+true \ud802\udc02 0
+
+[\ud800\udc61\ud802\udc02\ud803\udc03[\ud804\udc04\ud805\udc05\ud806\udc06]]
+\ud805\udc05
+true \ud805\udc05 0
+
+[\ud801\udc01-\ud804\udc04[0-9][\ud80b\udc0b-\ud80d\udc0d]]
+\ud801\udc01
+true \ud801\udc01 0
+
+[\ud801\udc01-\ud804\udc04[0-9][\ud80b\udc0b-\ud80d\udc0d]]
+\ud80c\udc0c
+true \ud80c\udc0c 0
+
+[\ud801\udc01-\ud804\udc04[0-9][\ud80b\udc0b-\ud80d\udc0d]]
+4
+true 4 0
+
+[\ud801\udc01-\ud804\udc04[0-9][\ud80b\udc0b-\ud80d\udc0d]]
+\ud805\udc05
+false 0
+
+[\ud801\udc01-\ud804\udc04[0-9][\ud80b\udc0b-\ud80d\udc0d]]
+\ud816\udc16
+false 0
+
+[[\ud801\udc01-\ud804\udc04][0-9][\ud80b\udc0b-\ud80d\udc0d]]
+\ud802\udc02
+true \ud802\udc02 0
+
+[[\ud801\udc01-\ud804\udc04][0-9][\ud80b\udc0b-\ud80d\udc0d]]
+\ud81a\udc1a
+false 0
+
+[\ud801\udc01-\ud803\udc03[\ud804\udc04-\ud806\udc06[\ud807\udc07-\ud809\udc09]]]
+\ud801\udc01
+true \ud801\udc01 0
+
+[\ud801\udc01-\ud803\udc03[\ud804\udc04-\ud806\udc06[\ud807\udc07-\ud809\udc09]]]
+\ud805\udc05
+true \ud805\udc05 0
+
+[\ud801\udc01-\ud803\udc03[\ud804\udc04-\ud806\udc06[\ud807\udc07-\ud809\udc09]]]
+\ud808\udc08
+true \ud808\udc08 0
+
+[\ud801\udc01-\ud803\udc03[\ud804\udc04-\ud806\udc06[\ud807\udc07-\ud809\udc09]]]
+\ud80d\udc0d
+false 0
+
+[\ud801\udc01-\ud803\udc03[\ud804\udc04-\ud806\udc06[\ud807\udc07-\ud809\udc09]]\ud80d\udc0d]
+\ud80d\udc0d
+true \ud80d\udc0d 0
+
+[\ud801\udc01\ud802\udc02\ud803\udc03[\ud804\udc04\ud805\udc05\ud806\udc06]\ud807\udc07\ud808\udc08\ud809\udc09]
+\ud801\udc01
+true \ud801\udc01 0
+
+[\ud800\udc61\ud802\udc02\ud803\udc03[\ud804\udc04\ud805\udc05\ud806\udc06]\ud807\udc07\ud808\udc08\ud809\udc09]
+\ud804\udc04
+true \ud804\udc04 0
+
+[\ud800\udc61\ud802\udc02\ud803\udc03[\ud804\udc04\ud805\udc05\ud806\udc06]\ud807\udc07\ud808\udc08\ud809\udc09]
+\ud808\udc08
+true \ud808\udc08 0
+
+[\ud800\udc61\ud802\udc02\ud803\udc03[\ud804\udc04\ud805\udc05\ud806\udc06]\ud807\udc07\ud808\udc08\ud809\udc09]
+\ud816\udc16
+false 0
+
+[\ud801\udc01-\ud803\udc03&&[\ud804\udc04-\ud806\udc06]]
+\ud801\udc01
+false 0
+
+[\ud801\udc01-\ud803\udc03&&[\ud804\udc04-\ud806\udc06]]
+\ud805\udc05
+false 0
+
+[\ud801\udc01-\ud803\udc03&&[\ud804\udc04-\ud806\udc06]]
+\ud81a\udc1a
+false 0
+
+[[\ud801\udc01-\ud803\udc03]&&[\ud804\udc04-\ud806\udc06]]
+\ud801\udc01
+false 0
+
+[[\ud801\udc01-\ud803\udc03]&&[\ud804\udc04-\ud806\udc06]]
+\ud805\udc05
+false 0
+
+[[\ud801\udc01-\ud803\udc03]&&[\ud804\udc04-\ud806\udc06]]
+\ud81a\udc1a
+false 0
+
+[\ud801\udc01-\ud803\udc03&&\ud804\udc04-\ud806\udc06]
+\ud801\udc01
+false 0
+
+[\ud801\udc01-\ud80d\udc0d&&\ud80d\udc0d-\ud81a\udc1a]
+\ud80d\udc0d
+true \ud80d\udc0d 0
+
+[\ud801\udc01-\ud80d\udc0d&&\ud80d\udc0d-\ud81a\udc1a&&\ud801\udc01-\ud803\udc03]
+\ud80d\udc0d
+false 0
+
+[\ud801\udc01-\ud80d\udc0d&&\ud80d\udc0d-\ud81a\udc1a&&\ud801\udc01-\ud81a\udc1a]
+\ud80d\udc0d
+true \ud80d\udc0d 0
+
+[[\ud801\udc01-\ud80d\udc0d]&&[\ud80d\udc0d-\ud81a\udc1a]]
+\ud801\udc01
+false 0
+
+[[\ud801\udc01-\ud80d\udc0d]&&[\ud80d\udc0d-\ud81a\udc1a]]
+\ud80d\udc0d
+true \ud80d\udc0d 0
+
+[[\ud801\udc01-\ud80d\udc0d]&&[\ud80d\udc0d-\ud81a\udc1a]]
+\ud81a\udc1a
+false 0
+
+[[\ud801\udc01-\ud80d\udc0d]&&[^\ud801\udc01-\ud803\udc03]]
+\ud801\udc01
+false 0
+
+[[\ud801\udc01-\ud80d\udc0d]&&[^\ud801\udc01-\ud803\udc03]]
+\ud804\udc04
+true \ud804\udc04 0
+
+[\ud801\udc01-\ud80d\udc0d&&[^\ud801\udc01-\ud803\udc03]]
+\ud801\udc01
+false 0
+
+[\ud801\udc01-\ud80d\udc0d&&[^\ud801\udc01-\ud803\udc03]]
+\ud804\udc04
+true \ud804\udc04 0
+
+[\ud801\udc01-\ud803\udc03\ud804\udc04-\ud806\udc06&&[\ud804\udc04-\ud806\udc06]]
+\ud801\udc01
+false 0
+
+[\ud801\udc01-\ud803\udc03\ud804\udc04-\ud806\udc06&&[\ud804\udc04-\ud806\udc06]]
+\ud805\udc05
+true \ud805\udc05 0
+
+[[\ud801\udc01-\ud803\udc03]&&\ud804\udc04-\ud806\udc06\ud801\udc01-\ud803\udc03]
+\ud801\udc01
+true \ud801\udc01 0
+
+[[\ud801\udc01-\ud803\udc03]&&[\ud804\udc04-\ud806\udc06][\ud801\udc01-\ud803\udc03]]
+\ud801\udc01
+true \ud801\udc01 0
+
+[[\ud801\udc01-\ud803\udc03][\ud804\udc04-\ud806\udc06]&&\ud801\udc01\ud802\udc02\ud803\udc03]
+\ud801\udc01
+true \ud801\udc01 0
+
+[[\ud801\udc01-\ud803\udc03][\ud804\udc04-\ud806\udc06]&&\ud801\udc01\ud802\udc02\ud803\udc03[\ud804\udc04\ud805\udc05\ud806\udc06]]
+\ud805\udc05
+true \ud805\udc05 0
+
+[[\ud801\udc01-\ud803\udc03]&&[\ud802\udc02-\ud804\udc04]&&[\ud803\udc03-\ud805\udc05]]
+\ud801\udc01
+false 0
+
+[[\ud801\udc01-\ud803\udc03]&&[\ud802\udc02-\ud804\udc04]&&[\ud803\udc03-\ud805\udc05]]
+\ud803\udc03
+true \ud803\udc03 0
+
+[[\ud801\udc01-\ud803\udc03]&&[\ud802\udc02-\ud804\udc04][\ud803\udc03-\ud805\udc05]&&[\ud815\udc15-\ud81a\udc1a]]
+\ud803\udc03
+false 0
+
+[\ud801\udc01\ud802\udc02\ud803\udc03[^\ud802\udc02\ud803\udc03\ud804\udc04]]
+\ud801\udc01
+true \ud801\udc01 0
+
+[\ud800\udc61\ud802\udc02\ud803\udc03[^\ud802\udc02\ud803\udc03\ud804\udc04]]
+\ud804\udc04
+false 0
+
+[\ud801\udc01-\ud803\udc03&&\ud801\udc01-\ud804\udc04&&\ud801\udc01-\ud805\udc05\ud807\udc07\ud808\udc08\ud809\udc09]
+\ud802\udc02
+true \ud802\udc02 0
+
+[\ud801\udc01-\ud803\udc03&&\ud801\udc01-\ud804\udc04&&\ud801\udc01-\ud805\udc05\ud807\udc07\ud808\udc08\ud809\udc09]
+\ud807\udc07
+false 0
+
+[[\ud801\udc01[\ud802\udc02]]&&[\ud802\udc02[\ud801\udc01]]]
+\ud801\udc01
+true \ud801\udc01 0
+
+// Unicode isn't supported in clazz()
+[[\ud800\udc61]&&[b][c][\ud800\udc61]&&[^d]]
+\ud800\udc61
+true \ud800\udc61 0
+
+[[\ud800\udc61]&&[\ud802\udc02][\ud800][\ud800\udc61]&&[^\ud804\udc04]]
+\ud800\udc61
+true \ud800\udc61 0
+
+[[\ud800\udc61]&&[b][\ud800][\ud800\udc61]&&[^\ud804\udc04]]
+\ud804\udc04
+false 0
+
+[[\ud800\udc61]&&[b][c][\ud800\udc61]&&[^d]]
+d
+false 0
+
+[[[\ud800\udc01-\ud800\udc04]&&[\ud800\udc03-\ud800\udc06]]]
+\ud800\udc01
+false 0
+
+[[[\ud800\udc01-\ud800\udc04]&&[\ud800\udc03-\ud800\udc06]]]
+\ud800\udc03
+true \ud800\udc03 0
+
+[[[\ud800\udc01-\ud800\udc04]&&[\ud800\udc03-\ud800\udc06]]&&[\ud800\udc03]]
+\ud800\udc03
+true \ud800\udc03 0
+
+[[[\ud800\udc01-\ud800\udc04]&&[\ud800\udc03-\ud800\udc06]]&&[\ud800\udc03]&&\ud800\udc03]
+\ud800\udc03
+true \ud800\udc03 0
+
+[[[\ud800\udc01-\ud800\udc04]&&[\ud800\udc03-\ud800\udc06]]&&[\ud800\udc03]&&\ud800\udc03&&\ud800\udc03]
+\ud800\udc03
+true \ud800\udc03 0
+
+[[[\ud800\udc01-\ud800\udc04]&&[\ud800\udc03-\ud800\udc06]]&&[\ud800\udc03]&&\ud800\udc03&&[\ud800\udc03\ud800\udc04\ud800\udc05]]
+\ud800\udc03
+true \ud800\udc03 0
+
+[z[\ud800\udc61b\ud800\udc03&&b\ud800\udc03\ud800\udc04]]
+\ud800\udc03
+true \ud800\udc03 0
+
+[z[\ud800\udc61b\ud800\udc03&&b\ud800\udc03\ud800\udc04]&&[u-z]]
+z
+true z 0
+
+[x[\ud800\udc61b\ud800\udc03&&b\ud800\udc03\ud800\udc04[z]]&&[u-z]]
+z
+false 0
+
+[x[[wz]\ud800\udc61b\ud800\udc03&&b\ud800\udc03\ud800\udc04[z]]&&[u-z]]
+z
+true z 0
+
+[[\ud800\udc61b\ud800\udc03]&&[\ud800\udc04\ud800\udc05f]\ud800\udc61b\ud800\udc03]
+\ud800\udc61
+true \ud800\udc61 0
+
+[[\ud800\udc61b\ud800\udc03]&&[\ud800\udc04\ud800\udc05f]xyz[\ud800\udc61b\ud800\udc03]]
+\ud800\udc61
+true \ud800\udc61 0
+
+\pL
+\ud800\udc00
+true \ud800\udc00 0
+
+\p{IsASCII}
+\ud800\udc00
+false 0
+
+\pLbc
+\ud800\udc00bc
+true \ud800\udc00bc 0
+
+\ud800\udc61[r\p{InGreek}]c
+\ud800\udc61\u0370c
+true \ud800\udc61\u0370c 0
+
+\ud800\udc61\p{InGreek}
+\ud800\udc61\u0370
+true \ud800\udc61\u0370 0
+
+\ud800\udc61\P{InGreek}
+\ud800\udc61\u0370
+false 0
+
+\ud800\udc61\P{InGreek}
+\ud800\udc61b
+true \ud800\udc61b 0
+
+\ud800\udc61{^InGreek}
+-
+error
+
+\ud800\udc61\p{^InGreek}
+-
+error
+
+\ud800\udc61\P{^InGreek}
+-
+error
+
+\ud800\udc61\p{InGreek}
+\ud800\udc61\u0370
+true \ud800\udc61\u0370 0
+
+\ud800\udc61[\p{InGreek}]c
+\ud800\udc61\u0370c
+true \ud800\udc61\u0370c 0
+
+\ud800\udc61[\P{InGreek}]c
+\ud800\udc61\u0370c
+false 0
+
+\ud800\udc61[\P{InGreek}]c
+\ud800\udc61bc
+true \ud800\udc61bc 0
+
+\ud800\udc61[{^InGreek}]c
+\ud800\udc61nc
+true \ud800\udc61nc 0
+
+\ud800\udc61[{^InGreek}]c
+\ud800\udc61zc
+false 0
+
+\ud800\udc61[\p{^InGreek}]c
+-
+error
+
+\ud800\udc61[\P{^InGreek}]c
+-
+error
+
+\ud800\udc61[\p{InGreek}]
+\ud800\udc61\u0370
+true \ud800\udc61\u0370 0
+
+\ud800\udc61[r\p{InGreek}]c
+\ud800\udc61rc
+true \ud800\udc61rc 0
+
+\ud800\udc61[\p{InGreek}r]c
+\ud800\udc61rc
+true \ud800\udc61rc 0
+
+\ud800\udc61[r\p{InGreek}]c
+\ud800\udc61rc
+true \ud800\udc61rc 0
+
+\ud800\udc61[^\p{InGreek}]c
+\ud800\udc61\u0370c
+false 0
+
+\ud800\udc61[^\P{InGreek}]c
+\ud800\udc61\u0370c
+true \ud800\udc61\u0370c 0
+
+\ud800\udc61[\p{InGreek}&&[^\u0370]]c
+\ud800\udc61\u0370c
+false 0
+
+// Test the dot metacharacter
+\ud800\udc61.c.+
+\ud800\udc61#c%&
+true \ud800\udc61#c%& 0
+
+\ud800\udc61b.
+\ud800\udc61b\n
+false 0
+
+(?s)\ud800\udc61b.
+\ud800\udc61b\n
+true \ud800\udc61b\n 0
+
+\ud800\udc61[\p{L}&&[\P{InGreek}]]c
+\ud800\udc61\u6000c
+true \ud800\udc61\u6000c 0
+
+\ud800\udc61[\p{L}&&[\P{InGreek}]]c
+\ud800\udc61rc
+true \ud800\udc61rc 0
+
+\ud800\udc61[\p{L}&&[\P{InGreek}]]c
+\ud800\udc61\u0370c
+false 0
+
+\ud800\udc61\p{InGreek}c
+\ud800\udc61\u0370c
+true \ud800\udc61\u0370c 0
+
+\ud800\udc61\p{Sc}
+\ud800\udc61$
+true \ud800\udc61$ 0
+
+// Test \p{L}
+\p{L}
+\ud800\udf1e
+true \ud800\udf1e 0
+
+^a\p{L}z$
+a\ud800\udf1ez
+true a\ud800\udf1ez 0
+
+// Test \P{InDeseret}
+
+\ud800\udf00\p{L}{2,3}\P{L}*supp->\ud900\udc00<-\P{InDeseret}
+\ud800\udf00\ud800\udf1e\ud800\udf1esupp->\ud900\udc00<-\ud901\udf00
+true \ud800\udf00\ud800\udf1e\ud800\udf1esupp->\ud900\udc00<-\ud901\udf00 0
+
+\ud800\udf00\p{L}{2,3}\P{L}*supp->\ud900\udc00<-\P{InDeseret}
+\ud800\udf00\ud800\udf1e\ud800\udf1e\ud901\udf00supp->\ud900\udc00<-\ud901\udf00
+true \ud800\udf00\ud800\udf1e\ud800\udf1e\ud901\udf00supp->\ud900\udc00<-\ud901\udf00 0
+
+// Test \p{InDeseret}
+\ud800\udf00\p{L}{2,3}\P{L}*supp->\ud900\udc00<-\p{InDeseret}
+\ud800\udf00\ud800\udf1e\ud800\udf1e\ud901\udf00supp->\ud900\udc00<-\ud801\udc00
+true \ud800\udf00\ud800\udf1e\ud800\udf1e\ud901\udf00supp->\ud900\udc00<-\ud801\udc00 0
+
+// Test the word char escape sequence
+\ud800\udc61b\wc
+\ud800\udc61bcc
+true \ud800\udc61bcc 0
+
+\ud800\udc61bc[\w]
+\ud800\udc61bcd
+true \ud800\udc61bcd 0
+
+\ud800\udc61bc[\sdef]*
+\ud800\udc61bc  def
+true \ud800\udc61bc  def 0
+
+\ud800\udc61bc[\sy-z]*
+\ud800\udc61bc y z
+true \ud800\udc61bc y z 0
+
+\ud800\udc01bc[\ud800\udc01-\ud800\udc04\sm-p]*
+\ud800\udc01bc\ud800\udc01\ud800\udc01 mn  p
+true \ud800\udc01bc\ud800\udc01\ud800\udc01 mn  p 0
+
+// Test the whitespace escape sequence
+\ud800\udc61b\s\ud800\udc03
+\ud800\udc61b \ud800\udc03
+true \ud800\udc61b \ud800\udc03 0
+
+\s\s\s
+bl\ud800\udc61h  err
+false 0
+
+\S\S\s
+bl\ud800\udc61h  err
+true \ud800\udc61h  0
+
+// Test the digit escape sequence
+\ud800\udc61b\d\ud800\udc03
+\ud800\udc61b9\ud800\udc03
+true \ud800\udc61b9\ud800\udc03 0
+
+\d\d\d
+bl\ud800\udc61h45
+false 0
+
+// Test the caret metacharacter
+^\ud800\udc61bc
+\ud800\udc61bcdef
+true \ud800\udc61bc 0
+
+^\ud800\udc61bc
+bcd\ud800\udc61bc
+false 0
+
+// Greedy ? metacharacter
+\ud800\udc61?\ud800\udc02
+\ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc02
+true \ud800\udc61\ud800\udc02 0
+
+\udc61?\ud800\udc02
+\ud800\udc61\udc61\udc61\ud800\udc02
+true \udc61\ud800\udc02 0
+
+\ud800\udc61?\ud800\udc02
+\ud800\udc02
+true \ud800\udc02 0
+
+\ud800?\ud800\udc02
+\ud800\udc02
+true \ud800\udc02 0
+
+\ud800\udc61?\ud800\udc02
+\ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc03\ud800\udc03\ud800\udc03
+false 0
+
+.?\ud800\udc02
+\ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc02
+true \ud800\udc61\ud800\udc02 0
+
+// Reluctant ? metacharacter
+\ud800\udc61??\ud800\udc02
+\ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc02
+true \ud800\udc61\ud800\udc02 0
+
+\ud800??\ud800\udc02
+\ud800\ud800\ud8001\ud800\ud800\udc02
+true \ud800\ud800\udc02 0
+
+\ud800\udc61??\ud800\udc02
+\ud800\udc02
+true \ud800\udc02 0
+
+\ud800??\ud800\udc02
+\ud800\udc02
+true \ud800\udc02 0
+
+\ud800\udc61??\ud800\udc02
+\ud800\udc61\ud800\udc61\ud800\udc61ccc
+false 0
+
+.??\ud800\udc02
+\ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc02
+true \ud800\udc61\ud800\udc02 0
+
+// Possessive ? metacharacter
+\ud800\udc61?+\ud800\udc02
+\ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc02
+true \ud800\udc61\ud800\udc02 0
+
+\ud800\udc61?+\ud800\udc02
+\ud800\udc02
+true \ud800\udc02 0
+
+\ud800\udc61?+\ud800\udc02
+\ud800\udc61\ud800\udc61\ud800\udc61ccc
+false 0
+
+.?+\ud800\udc02
+\ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc02
+true \ud800\udc61\ud800\udc02 0
+
+// Greedy + metacharacter
+\ud800\udc61+\ud800\udc02
+\ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc02
+true \ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc02 0
+
+\udc61+\ud800\udc02
+\ud800\udc61\udc61\udc61\udc61\ud800\udc02
+true \udc61\udc61\udc61\ud800\udc02 0
+
+\ud800\udc61+\ud800\udc02
+\ud800\udc02
+false 0
+
+\ud800+\ud800\udc02
+\ud800\udc02
+false 0
+
+\ud800\udc61+\ud800\udc02
+\ud800\udc61\ud800\udc61\ud800\udc61ccc
+false 0
+
+.+\ud800\udc02
+\ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc02
+true \ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc02 0
+
+.+\ud800\udc02
+\ud800\udc61\udc61\udc61\udc61\ud800\udc02
+true \ud800\udc61\udc61\udc61\udc61\ud800\udc02 0
+
+// Reluctant + metacharacter
+\ud800\udc61+?\ud800\udc02
+\ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc02
+true \ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc02 0
+
+\udc61+?\ud800\udc02
+\udc61\udc61\udc61\udc61\ud800\udc02
+true \udc61\udc61\udc61\udc61\ud800\udc02 0
+
+\ud800\udc61+?\ud800\udc02
+\ud800\udc02
+false 0
+
+\ud800+?\ud800\udc02
+\ud800\udc02
+false 0
+
+\ud800\udc61+?\ud800\udc02
+\ud800\udc61\ud800\udc61\ud800\udc61ccc
+false 0
+
+.+?\ud800\udc02
+\ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc02
+true \ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc02 0
+
+// Possessive + metacharacter
+\ud800\udc61++\ud800\udc02
+\ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc02
+true \ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc02 0
+
+\ud800\udc61++\ud800\udc02
+\ud800\udc02
+false 0
+
+\ud800\udc61++\ud800\udc02
+\ud800\udc61\ud800\udc61\ud800\udc61ccc
+false 0
+
+.++\ud800\udc02
+\ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc02
+false 0
+
+// Greedy Repetition
+\ud800\udc61{2,3}
+\ud800\udc61
+false 0
+
+\ud800\udc61{2,3}
+\ud800\udc61\ud800\udc61
+true \ud800\udc61\ud800\udc61 0
+
+\ud800\udc61{2,3}
+\ud800\udc61\ud800\udc61\ud800\udc61
+true \ud800\udc61\ud800\udc61\ud800\udc61 0
+
+\ud800\udc61{2,3}
+\ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc61
+true \ud800\udc61\ud800\udc61\ud800\udc61 0
+
+\ud800\udc61{3,}
+zzz\ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc61zzz
+true \ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc61 0
+
+\ud800\udc61{3,}
+zzz\ud800\udc61\ud800\udc61zzz
+false 0
+
+// Reluctant Repetition
+\ud800\udc61{2,3}?
+\ud800\udc61
+false 0
+
+\ud800\udc61{2,3}?
+\ud800\udc61\ud800\udc61
+true \ud800\udc61\ud800\udc61 0
+
+\ud800\udc61{2,3}?
+\ud800\udc61\ud800\udc61\ud800\udc61
+true \ud800\udc61\ud800\udc61 0
+
+\ud800\udc61{2,3}?
+\ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc61
+true \ud800\udc61\ud800\udc61 0
+
+// Zero width Positive lookahead
+\ud800\udc61\ud802\udc02\ud803\udc03(?=\ud804\udc04)
+zzz\ud800\udc61\ud802\udc02\ud803\udc03\ud804\udc04
+true \ud800\udc61\ud802\udc02\ud803\udc03 0
+
+\ud800\udc61\ud802\udc02\ud803\udc03(?=\ud804\udc04)
+zzz\ud800\udc61\ud802\udc02\ud803\udc03e\ud804\udc04
+false 0
+
+\ud800\udc61\ud802\udc02\ud803\udc03(?=\udcff\ud804\udc04)
+zzz\ud800\udc61\ud802\udc02\ud803\udc03\udcff\ud804\udc04
+true \ud800\udc61\ud802\udc02\ud803\udc03 0
+
+\ud800\udc61\ud802\udc02\ud803\udc03(?=\udcff\ud804\udc04)
+zzz\ud800\udc61\ud802\udc02\ud803\udc03\ud8ff\udcff\ud804\udc04
+false 0
+
+// Zero width Negative lookahead
+\ud800\udc61\ud802\udc02\ud803\udc03(?!\ud804\udc04)
+zz\ud800\udc61\ud802\udc02\ud803\udc03\ud804\udc04
+false 0
+
+a\ud802\udc02\ud803\udc03(?!\ud804\udc04)
+zza\ud802\udc02\ud803\udc03\udc04\ud804\udc04
+true a\ud802\udc02\ud803\udc03 0
+
+\ud800\udc61\ud802\udc02\ud803\udc03(?!\ud804\udc04\ud8ff)
+zz\ud800\udc61\ud802\udc02\ud803\udc03\ud804\udc04\ud8ffX
+false 0
+
+a\ud802\udc02\ud803\udc03(?!\ud804\udc04\ud8ff)
+zza\ud802\udc02\ud803\udc03e\ud804\udc04\ud8ff\udcff
+true a\ud802\udc02\ud803\udc03 0
+
+// Zero width Positive lookbehind
+(?<=\ud801\udc01\ud802\udc02)\ud803\udc03
+\ud801\udc01\ud802\udc02\ud803\udc03
+true \ud803\udc03 0
+
+// Zero width Negative lookbehind
+(?<!\ud801\udc01)\ud802\udc02\ud803\udc03
+###\ud800\udc00\ud802\udc02\ud803\udc03
+true \ud802\udc02\ud803\udc03 0
+
+(?<![\ud801\udc01\ud802\udc02])\ud803\udc03.
+\ud801\udc01\ud803\udc03x\ud800\udc00\ud803\udc03y
+true \ud803\udc03y 0
+
+(?<!\ud801\udc01)\ud803\udc03
+\ud801\udc01\ud803\udc03
+false 0
+
+// Nondeterministic group
+(\ud800\udc61+\ud802)+
+\ud800\udc61\ud802\ud800\udc61\ud802\ud800\udc61\ud802
+true \ud800\udc61\ud802\ud800\udc61\ud802\ud800\udc61\ud802 1 \ud800\udc61\ud802
+
+(\ud800\udc61|\ud802)+
+\ud800\ud802\udc61\ud803\ud802\udc61
+false 1
+
+// Deterministic group
+(\ud800\udc61\ud802)+
+\ud800\udc61\ud802\ud800\udc61\ud802\ud800\udc61\ud802
+true \ud800\udc61\ud802\ud800\udc61\ud802\ud800\udc61\ud802 1 \ud800\udc61\ud802
+
+(\ud800\udc61\ud802)+
+\ud800\udc61ccccd
+false 1
+
+(\ud800\udc61\ud802)*
+\ud800\udc61\ud802\ud800\udc61\ud802\ud800\udc61\ud802
+true \ud800\udc61\ud802\ud800\udc61\ud802\ud800\udc61\ud802 1 \ud800\udc61\ud802
+
+(\ud800\udc61b)(cd*)
+zzz\ud800\udc61bczzz
+true \ud800\udc61bc 2 \ud800\udc61b c
+
+\ud800\udc61bc(\ud804\udc04)*\ud800\udc61bc
+\ud800\udc61bc\ud804\udc04\ud804\udc04\ud804\udc04\ud804\udc04\ud804\udc04\ud800\udc61bc
+true \ud800\udc61bc\ud804\udc04\ud804\udc04\ud804\udc04\ud804\udc04\ud804\udc04\ud800\udc61bc 1 \ud804\udc04
+
+// Back references
+(\ud800\udc61*)\ud802\udc02c\1
+zzz\ud800\udc61\ud800\udc61\ud802\udc02c\ud800\udc61\ud800\udc61zzz
+true \ud800\udc61\ud800\udc61\ud802\udc02c\ud800\udc61\ud800\udc61 1 \ud800\udc61\ud800\udc61
+
+(\ud800\udc61*)\ud802\udc02c\1
+zzz\ud800\udc61\ud800\udc61\ud802\udc02c\ud800\udc61zzz
+true \ud800\udc61\ud802\udc02c\ud800\udc61 1 \ud800\udc61
+
+(\ud800\udc07\ud800\udc14*)(\ud804\udc04\ud804\udc04e)*(yu)\1\3(vv)
+zzz\ud800\udc07\ud800\udc14\ud800\udc14\ud804\udc04\ud804\udc04e\ud804\udc04\ud804\udc04eyu\ud800\udc07\ud800\udc14\ud800\udc14yuvvzzz
+true \ud800\udc07\ud800\udc14\ud800\udc14\ud804\udc04\ud804\udc04e\ud804\udc04\ud804\udc04eyu\ud800\udc07\ud800\udc14\ud800\udc14yuvv 4 \ud800\udc07\ud800\udc14\ud800\udc14 \ud804\udc04\ud804\udc04e yu vv
+
+// Greedy * metacharacter
+\ud800\udc61*\ud802\udc02
+\ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc61\ud802\udc02
+true \ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc61\ud802\udc02 0
+
+\ud800\udc61*\ud802\udc02
+\ud802\udc02
+true \ud802\udc02 0
+
+\ud800\udc61*\ud802\udc02
+\ud800\udc61\ud800\udc61\ud800\udc61ccc
+false 0
+
+.*\ud802\udc02
+\ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc61\ud802\udc02
+true \ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc61\ud802\udc02 0
+
+// Reluctant * metacharacter
+\ud800\udc61*?\ud802\udc02
+\ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc61\ud802\udc02
+true \ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc61\ud802\udc02 0
+
+\ud800\udc61*?\ud802\udc02
+\ud802\udc02
+true \ud802\udc02 0
+
+\ud800\udc61*?\ud802\udc02
+\ud800\udc61\ud800\udc61\ud800\udc61ccc
+false 0
+
+.*?\ud802\udc02
+\ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc61\ud802\udc02
+true \ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc61\ud802\udc02 0
+
+// Possessive * metacharacter
+\ud800\udc61*+\ud802\udc02
+\ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc61\ud802\udc02
+true \ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc61\ud802\udc02 0
+
+\ud800\udc61*+\ud802\udc02
+\ud802\udc02
+true \ud802\udc02 0
+
+\ud800\udc61*+\ud802\udc02
+\ud800\udc61\ud800\udc61\ud800\udc61ccc
+false 0
+
+.*+\ud802\udc02
+\ud800\udc61\ud800\udc61\ud800\udc61\ud800\udc61\ud802\udc02
+false 0
+
+// Case insensitivity
+(?iu)\ud801\udc00\ud801\udc01\ud801\udc02x
+\ud801\udc28\ud801\udc29\ud801\udc2aX
+true \ud801\udc28\ud801\udc29\ud801\udc2aX 0
+
+\ud801\udc00(?iu)\ud801\udc01\ud801\udc02
+\ud801\udc00\ud801\udc29\ud801\udc2a
+true \ud801\udc00\ud801\udc29\ud801\udc2a 0
+
+\ud801\udc00(?iu)\ud801\udc01\ud801\udc02
+\ud801\udc28\ud801\udc29\ud801\udc2a
+false 0
+
+(?iu)\ud801\udc00[\ud801\udc01\ud801\udc02]+
+\ud801\udc28\ud801\udc29\ud801\udc2a
+true \ud801\udc28\ud801\udc29\ud801\udc2a 0
+
+(?iu)[\ud801\udc00-\ud801\udc02]+
+\ud801\udc28\ud801\udc29\ud801\udc2a
+true \ud801\udc28\ud801\udc29\ud801\udc2a 0
+
+// Disable metacharacters- test both length <=3 and >3
+// So that the BM optimization is part of test
+\Q***\E\ud801\udc01\ud802\udc02\ud800\udc03
+***\ud801\udc01\ud802\udc02\ud800\udc03
+true ***\ud801\udc01\ud802\udc02\ud800\udc03 0
+
+\ud802\udc02l\Q***\E\ud801\udc01\ud802\udc02\ud800\udc03
+\ud802\udc02l***\ud801\udc01\ud802\udc02\ud800\udc03
+true \ud802\udc02l***\ud801\udc01\ud802\udc02\ud800\udc03 0
+
+\Q***\ud801\udc01\ud802\udc02\ud800\udc03
+***\ud801\udc01\ud802\udc02\ud800\udc03
+true ***\ud801\udc01\ud802\udc02\ud800\udc03 0
+
+\ud802\udc02l\ud801\udc01h\Q***\E\ud801\udc01\ud802\udc02\ud800\udc03
+\ud802\udc02l\ud801\udc01h***\ud801\udc01\ud802\udc02\ud800\udc03
+true \ud802\udc02l\ud801\udc01h***\ud801\udc01\ud802\udc02\ud800\udc03 0
+
+\Q***\ud801\udc01\ud802\udc02\ud800\udc03
+***\ud801\udc01\ud802\udc02\ud800\udc03
+true ***\ud801\udc01\ud802\udc02\ud800\udc03 0
+
+\Q*\ud801\udc01\ud802\udc02
+*\ud801\udc01\ud802\udc02
+true *\ud801\udc01\ud802\udc02 0
+
+\ud802\udc02l\ud801\udc01h\Q***\ud801\udc01\ud802\udc02\ud800\udc03
+\ud802\udc02l\ud801\udc01h***\ud801\udc01\ud802\udc02\ud800\udc03
+true \ud802\udc02l\ud801\udc01h***\ud801\udc01\ud802\udc02\ud800\udc03 0
+
+\ud802\udc02l\ud801\udc01\Q***\ud801\udc01\ud802\udc02\ud800\udc03
+\ud802\udc02l\ud801\udc01***\ud801\udc01\ud802\udc02\ud800\udc03
+true \ud802\udc02l\ud801\udc01***\ud801\udc01\ud802\udc02\ud800\udc03 0
+
+//Test cases below copied from i18n QE's RegexSupplementaryTests.txt
+\uD800\uDFFF\uD801\uDFF1\uDB00\uDC00
+\uD800\uDFFF\uD801\uDFF1\uDB00\uDC00
+true \uD800\uDFFF\uD801\uDFF1\uDB00\uDC00 0
+
+\uD800\uDFFF\uD801\uDFF1\uDB00\uDC00
+\u1000\uD801\uDFF1\uDB00\uDC00
+false 0
+
+\uD800\uDFFF\uD801\uDFF1\uDB00\uDC00
+\uD800\uDFFF\uFFFF\uDB00\uDC00
+false 0
+
+\uD800\uDFFF\uD801\uDFF1\uDB00\uDC00
+\uD800\uDFFF\uD801\uDFF1\uFFFF
+false 0
+
+\u1000.\uFFFF
+\u1000\uD800\uDFFF\uFFFF
+true \u1000\uD800\uDFFF\uFFFF 0
+
+//=======
+// Ranges
+//=======
+[a-\uD800\uDFFF]
+\uDFFF
+true \uDFFF 0
+
+[a-\uD800\uDFFF]
+\uD800
+true \uD800 0
+
+[a-\uD800\uDFFF]
+\uD800\uDFFF
+true \uD800\uDFFF 0
+
+[\uD800\uDC00-\uDBFF\uDFFF]
+\uDBFF
+false 0
+
+[\uD800\uDC00-\uDBFF\uDFFF]
+\uDC00
+false 0
+
+[\uD800-\uDFFF]
+\uD800\uDFFF
+false 0
+
+[\uD800-\uDFFF]
+\uDFFF\uD800
+true \uDFFF 0
+
+foo[^\uD800-\uDFFF]
+foo\uD800\uDFFF
+true foo\uD800\uDFFF 0
+
+foo[^\uD800-\uDFFF]
+foo\uDFFF\uD800
+false 0
+
+//fo\uD800[\uDC00-\uDFFF]
+
+//==================
+// Character Classes
+//==================
+// Simple class
+[ab\uD800\uDFFFcd]at
+\uD800at
+false 0
+
+[ab\uD800\uDFFFcd]at
+\uD800\uDFFFat
+true \uD800\uDFFFat 0
+
+// Negation
+[^\uD800\uDFFFcd]at
+\uD800at
+true \uD800at 0
+
+[^\uD800\uDFFFcd]at
+\uDFFFat
+true \uDFFFat 0
+
+// Inclusive range
+[\u0000-\uD800\uDFFF-\uFFFF]
+\uD800\uDFFF
+true \uD800\uDFFF 0
+
+// Unions
+[\u0000-\uD800[\uDFFF-\uFFFF]]
+\uD800\uDFFF
+false 0
+
+
+// Intersection
+[\u0000-\uFFFF&&[\uD800\uDFFF]]
+\uD800\uDFFF
+false 0
+
+[\u0000-\uFFFF&&[\uD800\uDFFF]]
+\uD800
+false 0
+
+[\u0000-\uFFFF&&[\uDFFF\uD800]]
+\uD800
+true \uD800 0
+
+[\u0000-\uFFFF&&[\uDFFF\uD800\uDC00]]
+\uDC00
+false 0
+
+[\u0000-\uDFFF&&[\uD800-\uFFFF]]
+\uD800\uDFFF
+false 0
+
+[\u0000-\uDFFF&&[\uD800-\uFFFF]]
+\uDFFF\uD800
+true \uDFFF 0
+
+// Subtraction
+[\u0000-\uD800\uDFFF&&[^\uD800\uDC00]]
+\uD800
+true \uD800 0
+
+[\u0000-\uD800\uDFFF&&[^\uD800\uDC00]]
+\uDC00
+true \uDC00 0
+
+[\u0000-\uD800\uDFFF&&[^\uD800\uDC00]]
+\uD800\uDFFF
+true \uD800\uDFFF 0
+
+[\u0000-\uD800\uDFFF&&[^\uD800\uDBFF\uDC00]]
+\uD800
+false 0
+
+[\u0000-\uD800\uDFFF&&[^\uDC00\uD800\uDBFF]]
+\uD800\uDC00
+true \uD800\uDC00 0
+
+// Quantifiers
+a\uD800\uDFFF?
+a\uD800
+true a 0
+
+a\uD800\uDFFF?
+a\uDFFF
+true a 0
+
+a\uD800\uDFFF?
+a\uD800\uDFFF
+true a\uD800\uDFFF 0
+
+a\uDFFF\uD800?
+a\uDFFF
+true a\uDFFF 0
+
+a\uDFFF\uD800?
+a\uD800
+false 0
+
+\uD800\uDFFF\uDC00?
+\uD800
+false 0
+
+\uD800\uDFFF\uDC00?
+\uD800\uDFFF
+true \uD800\uDFFF 0
+
+a\uD800\uDFFF??
+a\uDFFF
+true a 0
+
+a\uD800\uDFFF*
+a
+true a 0
+
+a\uD800\uDFFF*
+a\uD800
+true a 0
+
+\uD800\uDFFF*
+\uD800\uDFFF\uD800\uDFFF\uD800\uDFFF\uD800\uDFFF
+true \uD800\uDFFF\uD800\uDFFF\uD800\uDFFF\uD800\uDFFF 0
+
+\uD800\uDFFF*
+\uD800\uDFFF\uDFFF\uDFFF\uDFFF
+true \uD800\uDFFF 0
+
+\uD800*\uDFFF
+\uD800\uDFFF
+false 0
+
+a\uD800\uDFFF*
+a\uD800
+true a 0
+
+\uDFFF\uD800*
+\uDFFF
+true \uDFFF 0
+
+\uDFFF\uD800*
+\uDFFF\uD800\uD800\uD800
+true \uDFFF\uD800\uD800\uD800 0
+
+\uD800\uDFFF+
+\uD800\uDFFF\uDFFF\uDFFF
+true \uD800\uDFFF 0
+
+\uD800\uDFFF+
+\uD800
+false 0
+
+\uD800\uDFFF+
+\uD800\uDFFF
+true \uD800\uDFFF 0
+
+\uD800\uDFFF+
+\uD800\uDFFF\uD800\uDFFF\uD800\uDFFF
+true \uD800\uDFFF\uD800\uDFFF\uD800\uDFFF 0
+
+\uDFFF\uD800+
+\uDFFF\uD800\uDFFF\uD800
+false 0
+
+\uD800+\uDFFF
+\uD800\uDFFF
+false 0
+
+\uD800+\uDFFF
+\uD800
+false 0
+
+\uDFFF+\uD800
+\uD800
+false 0
+
+\uDFFF+\uD800
+\uDFFF\uD800
+true \uDFFF\uD800 0
+
+\uD800\uDFFF{3}
+\uD800\uDFFF\uDFFF\uDFFF
+false 0
+
+\uD800\uDFFF{3}
+\uD800\uDFFF\uD800\uDFFF\uD800\uDFFF
+true \uD800\uDFFF\uD800\uDFFF\uD800\uDFFF 0
+
+\uDFFF\uD800{3}
+\uDFFF\uD800\uDFFF\uD800\uDFFF\uD800
+false 0
+
+\uDFFF\uD800{3}
+\uDFFF\uD800\uD800\uD800
+true \uDFFF\uD800\uD800\uD800 0
+
+\uD800\uDFFF{2,}
+\uD800\uDFFF
+false 0
+
+\uD800\uDFFF{2,}
+\uD800\uDFFF\uDFFF
+false 0
+
+\uD800\uDFFF{2,}
+\uD800\uDFFF\uD800\uDFFF
+true \uD800\uDFFF\uD800\uDFFF 0
+
+\uDFFF\uD800{2,}
+\uDFFF\uD800\uDFFF\uD800
+false 0
+
+\uDFFF\uD800{2,}
+\uDFFF\uD800\uD800\uD800
+true \uDFFF\uD800\uD800\uD800 0
+
+\uD800\uDFFF{3,4}
+\uD800\uDFFF\uD800\uDFFF\uD800\uDFFF\uD800\uDFFF
+true \uD800\uDFFF\uD800\uDFFF\uD800\uDFFF\uD800\uDFFF 0
+
+\uD800\uDFFF{3,4}
+\uD800\uDFFF\uD800\uDFFF\uD800\uDFFF\uD800
+true \uD800\uDFFF\uD800\uDFFF\uD800\uDFFF 0
+
+\uD800\uDFFF{3,4}
+\uD800\uDFFF\uD800\uD800\uDFFF\uD800\uDFFF
+false 0
+
+\uDFFF\uD800{3,5}
+\uDFFF\uD800\uD800\uD800\uD800\uD800\uD800\uD800
+true \uDFFF\uD800\uD800\uD800\uD800\uD800 0
+
+\uD800\uDFFF{3,5}
+\uD800\uDFFF\uDFFF\uDFFF
+false 0
+
+\uD800\uDFFF{3,5}
+\uD800\uDFFF\uD800\uD800\uDFFF\uD800\uDFFF\uD800\uDFFF
+true \uD800\uDFFF\uD800\uDFFF\uD800\uDFFF 0
+
+// Groupings
+(\uD800(\uDFFF))
+\uD800\uDFFF
+false 2
+
+(\uD800(\uDC00)(\uDFFF))
+\uD800\uDC00\uDFFF
+false 3
+
+((\uD800)(\uDFFF))
+\uD800\uDFFF
+false 3
+
+(\uD800(\uDFFF)\uDFFF)
+\uD800\uDFFF
+false 2
+
+(\uDFFF(\uD800)(\uDBFF))
+\uDFFF\uD800\uDBFF
+true \uDFFF\uD800\uDBFF 3 \uDFFF\uD800\uDBFF \uD800 \uDBFF
+
+(\uDFFF(\uD800)(\uDC00))
+\uDFFF\uD800\uDC00
+false 3
+
+(\uDFFF\uD800(\uDC00\uDBFF))
+\uDFFF\uD800\uDC00\uDBFF
+false 2
+
+(\uD800\uDFFF(\uDBFF)(\uDC00))
+\uD800\uDFFF\uDBFF\uDC00
+false 3
+
+(\uD800\uDFFF(\uDBFF\uDC00))
+\uD800\uDFFF\uDBFF\uDC00
+true \uD800\uDFFF\uDBFF\uDC00 2 \uD800\uDFFF\uDBFF\uDC00 \uDBFF\uDC00
diff --git a/jdk/test/java/util/regex/TestCases.txt b/jdk/test/java/util/regex/TestCases.txt
new file mode 100644
index 0000000..fd41df33
--- /dev/null
+++ b/jdk/test/java/util/regex/TestCases.txt
@@ -0,0 +1,1092 @@
+//
+// Copyright 1999-2009 Sun Microsystems, Inc.  All Rights Reserved.
+// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+//
+// This code is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License version 2 only, as
+// published by the Free Software Foundation.
+//
+// This code is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// version 2 for more details (a copy is included in the LICENSE file that
+// accompanied this code).
+//
+// You should have received a copy of the GNU General Public License version
+// 2 along with this work; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+// CA 95054 USA or visit www.sun.com if you need additional information or
+// have any questions.
+//
+//
+// This file contains test cases for regular expressions.
+// A test case consists of three lines:
+// The first line is a pattern used in the test
+// The second line is the input to search for the pattern in
+// The third line is a concatentation of the match, the number of groups,
+//     and the contents of the first four subexpressions.
+// Empty lines and lines beginning with comment slashes are ignored.
+//
+// Test unsetting of backed off groups
+^(a)?a
+a
+true a 1
+
+^(aa(bb)?)+$
+aabbaa
+true aabbaa 2 aa bb
+
+((a|b)?b)+
+b
+true b 2 b
+
+(aaa)?aaa
+aaa
+true aaa 1
+
+^(a(b)?)+$
+aba
+true aba 2 a b
+
+^(a(b(c)?)?)?abc
+abc
+true abc 3
+
+^(a(b(c))).*
+abc
+true abc 3 abc bc c
+
+// use of x modifier
+abc(?x)blah
+abcblah
+true abcblah 0
+
+abc(?x)  blah
+abcblah
+true abcblah 0
+
+abc(?x)  blah  blech
+abcblahblech
+true abcblahblech 0
+
+abc(?x)  blah # ignore comment
+abcblah
+true abcblah 0
+
+// Simple alternation
+a|b
+a
+true a 0
+
+a|b
+z
+false 0
+
+a|b
+b
+true b 0
+
+a|b|cd
+cd
+true cd 0
+
+a|ad
+ad
+true a 0
+
+z(a|ac)b
+zacb
+true zacb 1 ac
+
+// Simple char class
+[abc]+
+ababab
+true ababab 0
+
+[abc]+
+defg
+false 0
+
+[abc]+[def]+[ghi]+
+zzzaaddggzzz
+true aaddgg 0
+
+// Range char class
+[a-g]+
+zzzggg
+true ggg 0
+
+[a-g]+
+mmm
+false 0
+
+[a-]+
+za-9z
+true a- 0
+
+[a-\\u4444]+
+za-9z
+true za 0
+
+// Negated char class
+[^abc]+
+ababab
+false 0
+
+[^abc]+
+aaabbbcccdefg
+true defg 0
+
+// Making sure a ^ not in first position matches literal ^
+[abc^b]
+b
+true b 0
+
+[abc^b]
+^
+true ^ 0
+
+// Class union and intersection
+[abc[def]]
+b
+true b 0
+
+[abc[def]]
+e
+true e 0
+
+[a-d[0-9][m-p]]
+a
+true a 0
+
+[a-d[0-9][m-p]]
+o
+true o 0
+
+[a-d[0-9][m-p]]
+4
+true 4 0
+
+[a-d[0-9][m-p]]
+e
+false 0
+
+[a-d[0-9][m-p]]
+u
+false 0
+
+[[a-d][0-9][m-p]]
+b
+true b 0
+
+[[a-d][0-9][m-p]]
+z
+false 0
+
+[a-c[d-f[g-i]]]
+a
+true a 0
+
+[a-c[d-f[g-i]]]
+e
+true e 0
+
+[a-c[d-f[g-i]]]
+h
+true h 0
+
+[a-c[d-f[g-i]]]
+m
+false 0
+
+[a-c[d-f[g-i]]m]
+m
+true m 0
+
+[abc[def]ghi]
+a
+true a 0
+
+[abc[def]ghi]
+d
+true d 0
+
+[abc[def]ghi]
+h
+true h 0
+
+[abc[def]ghi]
+w
+false 0
+
+[a-c&&[d-f]]
+a
+false 0
+
+[a-c&&[d-f]]
+e
+false 0
+
+[a-c&&[d-f]]
+z
+false 0
+
+[[a-c]&&[d-f]]
+a
+false 0
+
+[[a-c]&&[d-f]]
+e
+false 0
+
+[[a-c]&&[d-f]]
+z
+false 0
+
+[a-c&&d-f]
+a
+false 0
+
+[a-m&&m-z]
+m
+true m 0
+
+[a-m&&m-z&&a-c]
+m
+false 0
+
+[a-m&&m-z&&a-z]
+m
+true m 0
+
+[[a-m]&&[m-z]]
+a
+false 0
+
+[[a-m]&&[m-z]]
+m
+true m 0
+
+[[a-m]&&[m-z]]
+z
+false 0
+
+[[a-m]&&[^a-c]]
+a
+false 0
+
+[[a-m]&&[^a-c]]
+d
+true d 0
+
+[a-m&&[^a-c]]
+a
+false 0
+
+[a-m&&[^a-c]]
+d
+true d 0
+
+[a-cd-f&&[d-f]]
+a
+false 0
+
+[a-cd-f&&[d-f]]
+e
+true e 0
+
+[[a-c]&&d-fa-c]
+a
+true a 0
+
+[[a-c]&&[d-f][a-c]]
+a
+true a 0
+
+[[a-c][d-f]&&abc]
+a
+true a 0
+
+[[a-c][d-f]&&abc[def]]
+e
+true e 0
+
+[[a-c]&&[b-d]&&[c-e]]
+a
+false 0
+
+[[a-c]&&[b-d]&&[c-e]]
+c
+true c 0
+
+[[a-c]&&[b-d][c-e]&&[u-z]]
+c
+false 0
+
+[abc[^bcd]]
+a
+true a 0
+
+[abc[^bcd]]
+d
+false 0
+
+[a-c&&a-d&&a-eghi]
+b
+true b 0
+
+[a-c&&a-d&&a-eghi]
+g
+false 0
+
+[[a[b]]&&[b[a]]]
+a
+true a 0
+
+[[a]&&[b][c][a]&&[^d]]
+a
+true a 0
+
+[[a]&&[b][c][a]&&[^d]]
+d
+false 0
+
+[[[a-d]&&[c-f]]]
+a
+false 0
+
+[[[a-d]&&[c-f]]]
+c
+true c 0
+
+[[[a-d]&&[c-f]]&&[c]]
+c
+true c 0
+
+[[[a-d]&&[c-f]]&&[c]&&c]
+c
+true c 0
+
+[[[a-d]&&[c-f]]&&[c]&&c&&c]
+c
+true c 0
+
+[[[a-d]&&[c-f]]&&[c]&&c&&[cde]]
+c
+true c 0
+
+[z[abc&&bcd]]
+c
+true c 0
+
+[z[abc&&bcd]&&[u-z]]
+z
+true z 0
+
+[x[abc&&bcd[z]]&&[u-z]]
+z
+false 0
+
+[x[[wz]abc&&bcd[z]]&&[u-z]]
+z
+true z 0
+
+[[abc]&&[def]abc]
+a
+true a 0
+
+[[abc]&&[def]xyz[abc]]
+a
+true a 0
+
+\pL
+a
+true a 0
+
+\pL
+7
+false 0
+
+\p{L}
+a
+true a 0
+
+\p{LC}
+a
+true a 0
+
+\p{LC}
+A
+true A 0
+
+\p{IsL}
+a
+true a 0
+
+\p{IsLC}
+a
+true a 0
+
+\p{IsLC}
+A
+true A 0
+
+\p{IsLC}
+9
+false 0
+
+\P{IsLC}
+9
+true 9 0
+
+// Guillemet left is initial quote punctuation
+\p{Pi}
+\u00ab
+true \u00ab 0
+
+\P{Pi}
+\u00ac
+true \u00ac 0
+
+// Guillemet right is final quote punctuation
+\p{IsPf}
+\u00bb
+true \u00bb 0
+
+\p{P}
+\u00bb
+true \u00bb 0
+
+\p{P}+
+\u00bb
+true \u00bb 0
+
+\P{IsPf}
+\u00bc
+true \u00bc 0
+
+\P{IsP}
+\u00bc
+true \u00bc 0
+
+\p{L1}
+\u00bc
+true \u00bc 0
+
+\p{L1}+
+\u00bc
+true \u00bc 0
+
+\p{L1}
+\u02bc
+false 0
+
+\p{ASCII}
+a
+true a 0
+
+\p{IsASCII}
+a
+true a 0
+
+\p{IsASCII}
+\u0370
+false 0
+
+\pLbc
+abc
+true abc 0
+
+a[r\p{InGreek}]c
+a\u0370c
+true a\u0370c 0
+
+a\p{InGreek}
+a\u0370
+true a\u0370 0
+
+a\P{InGreek}
+a\u0370
+false 0
+
+a\P{InGreek}
+ab
+true ab 0
+
+a{^InGreek}
+-
+error
+
+a\p{^InGreek}
+-
+error
+
+a\P{^InGreek}
+-
+error
+
+a\p{InGreek}
+a\u0370
+true a\u0370 0
+
+a[\p{InGreek}]c
+a\u0370c
+true a\u0370c 0
+
+a[\P{InGreek}]c
+a\u0370c
+false 0
+
+a[\P{InGreek}]c
+abc
+true abc 0
+
+a[{^InGreek}]c
+anc
+true anc 0
+
+a[{^InGreek}]c
+azc
+false 0
+
+a[\p{^InGreek}]c
+-
+error
+
+a[\P{^InGreek}]c
+-
+error
+
+a[\p{InGreek}]
+a\u0370
+true a\u0370 0
+
+a[r\p{InGreek}]c
+arc
+true arc 0
+
+a[\p{InGreek}r]c
+arc
+true arc 0
+
+a[r\p{InGreek}]c
+arc
+true arc 0
+
+a[^\p{InGreek}]c
+a\u0370c
+false 0
+
+a[^\P{InGreek}]c
+a\u0370c
+true a\u0370c 0
+
+a[\p{InGreek}&&[^\u0370]]c
+a\u0370c
+false 0
+
+// Test the dot metacharacter
+a.c.+
+a#c%&
+true a#c%& 0
+
+ab.
+ab\n
+false 0
+
+(?s)ab.
+ab\n
+true ab\n 0
+
+a[\p{L}&&[\P{InGreek}]]c
+a\u6000c
+true a\u6000c 0
+
+a[\p{L}&&[\P{InGreek}]]c
+arc
+true arc 0
+
+a[\p{L}&&[\P{InGreek}]]c
+a\u0370c
+false 0
+
+a\p{InGreek}c
+a\u0370c
+true a\u0370c 0
+
+a\p{Sc}
+a$
+true a$ 0
+
+// Test the word char escape sequence
+ab\wc
+abcc
+true abcc 0
+
+\W\w\W
+#r#
+true #r# 0
+
+\W\w\W
+rrrr#ggg
+false 0
+
+abc[\w]
+abcd
+true abcd 0
+
+abc[\sdef]*
+abc  def
+true abc  def 0
+
+abc[\sy-z]*
+abc y z
+true abc y z 0
+
+abc[a-d\sm-p]*
+abcaa mn  p
+true abcaa mn  p 0
+
+// Test the whitespace escape sequence
+ab\sc
+ab c
+true ab c 0
+
+\s\s\s
+blah  err
+false 0
+
+\S\S\s
+blah  err
+true ah  0
+
+// Test the digit escape sequence
+ab\dc
+ab9c
+true ab9c 0
+
+\d\d\d
+blah45
+false 0
+
+// Test the caret metacharacter
+^abc
+abcdef
+true abc 0
+
+^abc
+bcdabc
+false 0
+
+// Greedy ? metacharacter
+a?b
+aaaab
+true ab 0
+
+a?b
+b
+true b 0
+
+a?b
+aaaccc
+false 0
+
+.?b
+aaaab
+true ab 0
+
+// Reluctant ? metacharacter
+a??b
+aaaab
+true ab 0
+
+a??b
+b
+true b 0
+
+a??b
+aaaccc
+false 0
+
+.??b
+aaaab
+true ab 0
+
+// Possessive ? metacharacter
+a?+b
+aaaab
+true ab 0
+
+a?+b
+b
+true b 0
+
+a?+b
+aaaccc
+false 0
+
+.?+b
+aaaab
+true ab 0
+
+// Greedy + metacharacter
+a+b
+aaaab
+true aaaab 0
+
+a+b
+b
+false 0
+
+a+b
+aaaccc
+false 0
+
+.+b
+aaaab
+true aaaab 0
+
+// Reluctant + metacharacter
+a+?b
+aaaab
+true aaaab 0
+
+a+?b
+b
+false 0
+
+a+?b
+aaaccc
+false 0
+
+.+?b
+aaaab
+true aaaab 0
+
+// Possessive + metacharacter
+a++b
+aaaab
+true aaaab 0
+
+a++b
+b
+false 0
+
+a++b
+aaaccc
+false 0
+
+.++b
+aaaab
+false 0
+
+// Greedy Repetition
+a{2,3}
+a
+false 0
+
+a{2,3}
+aa
+true aa 0
+
+a{2,3}
+aaa
+true aaa 0
+
+a{2,3}
+aaaa
+true aaa 0
+
+a{3,}
+zzzaaaazzz
+true aaaa 0
+
+a{3,}
+zzzaazzz
+false 0
+
+// Reluctant Repetition
+a{2,3}?
+a
+false 0
+
+a{2,3}?
+aa
+true aa 0
+
+a{2,3}?
+aaa
+true aa 0
+
+a{2,3}?
+aaaa
+true aa 0
+
+// Zero width Positive lookahead
+abc(?=d)
+zzzabcd
+true abc 0
+
+abc(?=d)
+zzzabced
+false 0
+
+// Zero width Negative lookahead
+abc(?!d)
+zzabcd
+false 0
+
+abc(?!d)
+zzabced
+true abc 0
+
+// Zero width Positive lookbehind
+\w(?<=a)
+###abc###
+true a 0
+
+\w(?<=a)
+###ert###
+false 0
+
+// Zero width Negative lookbehind
+(?<!a)\w
+###abc###
+true a 0
+
+(?<!a)c
+bc
+true c 0
+
+(?<!a)c
+ac
+false 0
+
+// Nondeterministic group
+(a+b)+
+ababab
+true ababab 1 ab
+
+(a|b)+
+ccccd
+false 1
+
+// Deterministic group
+(ab)+
+ababab
+true ababab 1 ab
+
+(ab)+
+accccd
+false 1
+
+(ab)*
+ababab
+true ababab 1 ab
+
+(ab)(cd*)
+zzzabczzz
+true abc 2 ab c
+
+abc(d)*abc
+abcdddddabc
+true abcdddddabc 1 d
+
+// Escaped metacharacter
+\*
+*
+true * 0
+
+\\
+\
+true \ 0
+
+\\
+\\\\
+true \ 0
+
+// Back references
+(a*)bc\1
+zzzaabcaazzz
+true aabcaa 1 aa
+
+(a*)bc\1
+zzzaabcazzz
+true abca 1 a
+
+(gt*)(dde)*(yu)\1\3(vv)
+zzzgttddeddeyugttyuvvzzz
+true gttddeddeyugttyuvv 4 gtt dde yu vv
+
+// Greedy * metacharacter
+a*b
+aaaab
+true aaaab 0
+
+a*b
+b
+true b 0
+
+a*b
+aaaccc
+false 0
+
+.*b
+aaaab
+true aaaab 0
+
+// Reluctant * metacharacter
+a*?b
+aaaab
+true aaaab 0
+
+a*?b
+b
+true b 0
+
+a*?b
+aaaccc
+false 0
+
+.*?b
+aaaab
+true aaaab 0
+
+// Possessive * metacharacter
+a*+b
+aaaab
+true aaaab 0
+
+a*+b
+b
+true b 0
+
+a*+b
+aaaccc
+false 0
+
+.*+b
+aaaab
+false 0
+
+// Case insensitivity
+(?i)foobar
+fOobAr
+true fOobAr 0
+
+f(?i)oobar
+fOobAr
+true fOobAr 0
+
+foo(?i)bar
+fOobAr
+false 0
+
+(?i)foo[bar]+
+foObAr
+true foObAr 0
+
+(?i)foo[a-r]+
+foObAr
+true foObAr 0
+
+// Disable metacharacters- test both length <=3 and >3
+// So that the BM optimization is part of test
+\Q***\Eabc
+***abc
+true ***abc 0
+
+bl\Q***\Eabc
+bl***abc
+true bl***abc 0
+
+\Q***abc
+***abc
+true ***abc 0
+
+blah\Q***\Eabc
+blah***abc
+true blah***abc 0
+
+\Q***abc
+***abc
+true ***abc 0
+
+\Q*ab
+*ab
+true *ab 0
+
+blah\Q***abc
+blah***abc
+true blah***abc 0
+
+bla\Q***abc
+bla***abc
+true bla***abc 0
+
+// Escapes in char classes
+[ab\Qdef\E]
+d
+true d 0
+
+[ab\Q[\E]
+[
+true [ 0
+
+[\Q]\E]
+]
+true ] 0
+
+[\Q\\E]
+\
+true \ 0
+
+[\Q(\E]
+(
+true ( 0
+
+[\n-#]
+!
+true ! 0
+
+[\n-#]
+-
+false 0
+
+[\w-#]
+!
+false 0
+
+[\w-#]
+a
+true a 0
+
+[\w-#]
+-
+true - 0
+
+[\w-#]
+#
+true # 0
+
+[\043]+
+blahblah#blech
+true # 0
+
+[\042-\044]+
+blahblah#blech
+true # 0
+
+[\u1234-\u1236]
+blahblah\u1235blech
+true \u1235 0
+
+[^\043]*
+blahblah#blech
+true blahblah 0
+
+(|f)?+
+foo
+true  1 
diff --git a/jdk/test/java/util/zip/ZipFile/LargeZipFile.java b/jdk/test/java/util/zip/ZipFile/LargeZipFile.java
new file mode 100644
index 0000000..e4f986e
--- /dev/null
+++ b/jdk/test/java/util/zip/ZipFile/LargeZipFile.java
@@ -0,0 +1,138 @@
+import java.io.*;
+import java.nio.*;
+import java.util.*;
+import java.util.zip.*;
+
+public class LargeZipFile {
+    // If true, don't delete large ZIP file created for test.
+    static final boolean debug = System.getProperty("debug") != null;
+
+    static final int DATA_LEN = 1024 * 1024;
+    static final int DATA_SIZE = 8;
+
+    static long fileSize = 3L * 1024L * 1024L * 1024L; // 3GB
+
+    static boolean userFile = false;
+
+    static byte[] data;
+    static File largeFile;
+    static String lastEntryName;
+
+    /* args can be empty, in which case check a 3 GB file which is created for
+     * this test (and then deleted).  Or it can be a number, in which case
+     * that designates the size of the file that's created for this test (and
+     * then deleted).  Or it can be the name of a file to use for the test, in
+     * which case it is *not* deleted.  Note that in this last case, the data
+     * comparison might fail.
+     */
+    static void realMain (String[] args) throws Throwable {
+        if (args.length > 0) {
+            try {
+                fileSize = Long.parseLong(args[0]);
+                System.out.println("Testing with file of size " + fileSize);
+            } catch (NumberFormatException ex) {
+                largeFile = new File(args[0]);
+                if (!largeFile.exists()) {
+                    throw new Exception("Specified file " + args[0] + " does not exist");
+                }
+                userFile = true;
+                System.out.println("Testing with user-provided file " + largeFile);
+            }
+        }
+        File testDir = null;
+        if (largeFile == null) {
+            testDir = new File(System.getProperty("test.scratch", "."),
+                                    "LargeZip");
+            if (testDir.exists()) {
+                if (!testDir.delete()) {
+                    throw new Exception("Cannot delete already-existing test directory");
+                }
+            }
+            check(!testDir.exists() && testDir.mkdirs());
+            largeFile = new File(testDir, "largezip.zip");
+            createLargeZip();
+        }
+
+        readLargeZip();
+
+        if (!userFile && !debug) {
+            check(largeFile.delete());
+            check(testDir.delete());
+        }
+    }
+
+    static void createLargeZip() throws Throwable {
+        int iterations = DATA_LEN / DATA_SIZE;
+        ByteBuffer bb = ByteBuffer.allocate(DATA_SIZE);
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        for (int i = 0; i < iterations; i++) {
+            bb.putDouble(0, Math.random());
+            baos.write(bb.array(), 0, DATA_SIZE);
+        }
+        data = baos.toByteArray();
+
+        ZipOutputStream zos = new ZipOutputStream(
+            new BufferedOutputStream(new FileOutputStream(largeFile)));
+        long length = 0;
+        while (length < fileSize) {
+            ZipEntry ze = new ZipEntry("entry-" + length);
+            lastEntryName = ze.getName();
+            zos.putNextEntry(ze);
+            zos.write(data, 0, data.length);
+            zos.closeEntry();
+            length = largeFile.length();
+        }
+        System.out.println("Last entry written is " + lastEntryName);
+        zos.close();
+    }
+
+    static void readLargeZip() throws Throwable {
+        ZipFile zipFile = new ZipFile(largeFile);
+        ZipEntry entry = null;
+        String entryName = null;
+        int count = 0;
+        Enumeration<? extends ZipEntry> entries = zipFile.entries();
+        while (entries.hasMoreElements()) {
+            entry = entries.nextElement();
+            entryName = entry.getName();
+            count++;
+        }
+        System.out.println("Number of entries read: " + count);
+        System.out.println("Last entry read is " + entryName);
+        check(!entry.isDirectory());
+        if (check(entryName.equals(lastEntryName))) {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            InputStream is = zipFile.getInputStream(entry);
+            byte buf[] = new byte[4096];
+            int len;
+            while ((len = is.read(buf)) >= 0) {
+                baos.write(buf, 0, len);
+            }
+            baos.close();
+            is.close();
+            check(Arrays.equals(data, baos.toByteArray()));
+        }
+        try {
+          zipFile.close();
+        } catch (IOException ioe) {/* what can you do */ }
+    }
+
+    //--------------------- Infrastructure ---------------------------
+    static volatile int passed = 0, failed = 0;
+    static void pass() {passed++;}
+    static void pass(String msg) {System.out.println(msg); passed++;}
+    static void fail() {failed++; Thread.dumpStack();}
+    static void fail(String msg) {System.out.println(msg); fail();}
+    static void unexpected(Throwable t) {failed++; t.printStackTrace();}
+    static void unexpected(Throwable t, String msg) {
+        System.out.println(msg); failed++; t.printStackTrace();}
+    static boolean check(boolean cond) {if (cond) pass(); else fail(); return cond;}
+    static void equal(Object x, Object y) {
+        if (x == null ? y == null : x.equals(y)) pass();
+        else fail(x + " not equal to " + y);}
+    public static void main(String[] args) throws Throwable {
+        try {realMain(args);} catch (Throwable t) {unexpected(t);}
+        System.out.println("\nPassed = " + passed + " failed = " + failed);
+        if (failed > 0) throw new AssertionError("Some tests failed");}
+}
+
diff --git a/jdk/test/sun/security/krb5/ParseCAPaths.java b/jdk/test/sun/security/krb5/ParseCAPaths.java
new file mode 100644
index 0000000..9f6772d
--- /dev/null
+++ b/jdk/test/sun/security/krb5/ParseCAPaths.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+/*
+ * @test
+ * @bug 6789935
+ * @summary cross-realm capath search error
+ */
+
+import java.util.Arrays;
+import sun.security.krb5.Realm;
+
+public class ParseCAPaths {
+    static boolean failed = false;
+    public static void main(String[] args) throws Exception {
+        System.setProperty("java.security.krb5.conf", System.getProperty("test.src", ".") +"/krb5-capaths.conf");
+        //System.setProperty("sun.security.krb5.debug", "true");
+
+        // Standard example
+        check("ANL.GOV", "TEST.ANL.GOV", "ANL.GOV");
+        check("ANL.GOV", "ES.NET", "ANL.GOV");
+        check("ANL.GOV", "PNL.GOV", "ANL.GOV", "ES.NET");
+        check("ANL.GOV", "NERSC.GOV", "ANL.GOV", "ES.NET");
+        // Hierachical
+        check("N1.N.COM", "N2.N.COM", "N1.N.COM", "N.COM");     // 2 common
+        check("N1.N.COM", "N2.N3.COM", "N1.N.COM", "N.COM",     // 1 common
+                "COM", "N3.COM");
+        check("N1.COM", "N2.COM", "N1.COM", "COM");             // 1 common
+        check("N1", "N2", "N1");                                // 0 common
+        // Extra garbages
+        check("A1.COM", "A4.COM", "A1.COM", "A2.COM");
+        check("B1.COM", "B3.COM", "B1.COM", "B2.COM");
+        // Missing is "."
+        check("C1.COM", "C3.COM", "C1.COM", "C2.COM");
+        // Multiple path
+        check("D1.COM", "D4.COM", "D1.COM", "D2.COM");
+        check("E1.COM", "E4.COM", "E1.COM", "E2.COM");
+        check("F1.COM", "F4.COM", "F1.COM", "F9.COM");
+        // Infinite loop
+        check("G1.COM", "G3.COM", "G1.COM", "COM");
+        check("H1.COM", "H3.COM", "H1.COM");
+        check("I1.COM", "I4.COM", "I1.COM", "I5.COM");
+
+        if (failed) {
+            throw new Exception("Failed somewhere.");
+        }
+    }
+
+    static void check(String from, String to, String... paths) {
+        try {
+            check2(from, to, paths);
+        } catch (Exception e) {
+            failed = true;
+            e.printStackTrace();
+        }
+    }
+    static void check2(String from, String to, String... paths)
+            throws Exception {
+        System.out.println(from + " -> " + to);
+        System.out.println("    expected: " + Arrays.toString(paths));
+        String[] result = Realm.getRealmsList(from, to);
+        System.out.println("    result:   " + Arrays.toString(result));
+        if (result == null) {
+            if (paths.length == 0) {
+                // OK
+            } else {
+                throw new Exception("Shouldn't have a valid path.");
+            }
+        } else if(result.length != paths.length) {
+            throw new Exception("Length of path not correct");
+        } else {
+            for (int i=0; i<result.length; i++) {
+                if (!result[i].equals(paths[i])) {
+                    throw new Exception("Path not same");
+                }
+            }
+        }
+    }
+}
diff --git a/jdk/test/sun/security/krb5/krb5-capaths.conf b/jdk/test/sun/security/krb5/krb5-capaths.conf
new file mode 100644
index 0000000..db67282
--- /dev/null
+++ b/jdk/test/sun/security/krb5/krb5-capaths.conf
@@ -0,0 +1,87 @@
+[capaths]
+
+# Standard
+
+ANL.GOV = {
+    TEST.ANL.GOV = .
+    PNL.GOV = ES.NET
+    NERSC.GOV = ES.NET
+    ES.NET = .
+}
+TEST.ANL.GOV = {
+    ANL.GOV = .
+}
+PNL.GOV = {
+    ANL.GOV = ES.NET
+}
+NERSC.GOV = {
+    ANL.GOV = ES.NET
+}
+ES.NET = {
+    ANL.GOV = .
+}
+
+# Extra garbages
+
+A1.COM = {
+    A2.COM = .
+    A4.COM = A2.COM
+    A3.COM = A4.COM
+    A3.COM = A2.COM
+}
+
+B1.COM = {
+    B2.COM = .
+    B3.COM = B2.COM
+    B3.COM = B4.COM
+}
+
+# Missing is "."
+
+C1.COM = {
+    C3.COM = C2.COM
+}
+
+# Multiple paths
+
+D1.COM = {
+    D2.COM = .
+    D3.COM = .
+    D4.COM = D2.COM
+    D4.COM = D3.COM
+}
+
+E1.COM = {
+    E2.COM = .
+    E3.COM = .
+    E4.COM = E2.COM   E3.COM   E2.COM
+}
+
+# Shortest or First?
+
+F1.COM = {
+    F2.COM = .
+    F3.COM = F2.COM
+    F4.COM = F9.COM
+    F4.COM = F3.COM
+    F4.COM = F2.COM
+}
+
+# Infinite loop
+
+G1.COM = {
+    G2.COM = G3.COM
+    G3.COM = G2.COM
+}
+
+H1.COM = {
+    H2.COM = H3.COM
+    H3.COM = H2.COM
+    H3.COM = .
+}
+
+I1.COM = {
+    I2.COM = I3.COM
+    I3.COM = I2.COM
+    I4.COM = I2.COM I5.COM
+}
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/AppInputStream/ReadZeroBytes.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/AppInputStream/ReadZeroBytes.java
new file mode 100644
index 0000000..56134e0
--- /dev/null
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/AppInputStream/ReadZeroBytes.java
@@ -0,0 +1,254 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6697270
+ * @summary Inputstream dosent behave correct
+ */
+
+import java.io.*;
+import java.net.*;
+import javax.net.ssl.*;
+
+public class ReadZeroBytes {
+
+    /*
+     * =============================================================
+     * Set the various variables needed for the tests, then
+     * specify what tests to run on each side.
+     */
+
+    /*
+     * Should we run the client or server in a separate thread?
+     * Both sides can throw exceptions, but do you have a preference
+     * as to which side should be the main thread.
+     */
+    static boolean separateServerThread = false;
+
+    /*
+     * Where do we find the keystores?
+     */
+    static String pathToStores = "../../../../../../../etc";
+    static String keyStoreFile = "keystore";
+    static String trustStoreFile = "truststore";
+    static String passwd = "passphrase";
+
+    /*
+     * Is the server ready to serve?
+     */
+    volatile static boolean serverReady = false;
+
+    /*
+     * Turn on SSL debugging?
+     */
+    static boolean debug = false;
+
+    /*
+     * Define the server side of the test.
+     */
+    void doServerSide() throws Exception {
+        SSLServerSocketFactory sslssf =
+            (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
+        SSLServerSocket sslServerSocket =
+            (SSLServerSocket) sslssf.createServerSocket(serverPort);
+
+        serverPort = sslServerSocket.getLocalPort();
+
+        /*
+         * Signal Client, we're ready for his connect.
+         */
+        serverReady = true;
+
+        SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
+        InputStream sslIS = sslSocket.getInputStream();
+        OutputStream sslOS = sslSocket.getOutputStream();
+
+        // no read, no write.
+        SSLSession sess = sslSocket.getSession();
+        if (!sess.isValid()) {
+            throw new Exception("Error occurs during the initial handshake");
+        }
+
+        sslIS.close();
+        sslOS.close();
+        sslSocket.close();
+    }
+
+    /*
+     * Define the client side of the test.
+     */
+    void doClientSide() throws Exception {
+
+        /*
+         * Wait for server to get started.
+         */
+        while (!serverReady) {
+            Thread.sleep(50);
+        }
+
+        SSLSocketFactory sslsf =
+            (SSLSocketFactory) SSLSocketFactory.getDefault();
+        SSLSocket sslSocket = (SSLSocket)
+            sslsf.createSocket("localhost", serverPort);
+
+        InputStream sslIS = sslSocket.getInputStream();
+        OutputStream sslOS = sslSocket.getOutputStream();
+
+        // read zero byte, write zero byte.
+        sslIS.read(new byte[0], 0, 0);
+        sslOS.write(new byte[0], 0, 0);
+
+        // if byte array length matters.
+        sslIS.read(new byte[1], 0, 0);
+        sslOS.write(new byte[1], 0, 0);
+
+        // note that the above read/write should not kickoff handshaking.
+        SSLSession sess = sslSocket.getSession();
+        if (!sess.isValid()) {
+            throw new Exception("Error occurs during the initial handshake");
+        }
+
+        sslIS.close();
+        sslOS.close();
+        sslSocket.close();
+    }
+
+    /*
+     * =============================================================
+     * The remainder is just support stuff
+     */
+
+    // use any free port by default
+    volatile int serverPort = 0;
+
+    volatile Exception serverException = null;
+    volatile Exception clientException = null;
+
+    public static void main(String[] args) throws Exception {
+        String keyFilename =
+            System.getProperty("test.src", "./") + "/" + pathToStores +
+                "/" + keyStoreFile;
+        String trustFilename =
+            System.getProperty("test.src", "./") + "/" + pathToStores +
+                "/" + trustStoreFile;
+
+        System.setProperty("javax.net.ssl.keyStore", keyFilename);
+        System.setProperty("javax.net.ssl.keyStorePassword", passwd);
+        System.setProperty("javax.net.ssl.trustStore", trustFilename);
+        System.setProperty("javax.net.ssl.trustStorePassword", passwd);
+
+        if (debug)
+            System.setProperty("javax.net.debug", "all");
+
+        /*
+         * Start the tests.
+         */
+        new ReadZeroBytes();
+    }
+
+    Thread clientThread = null;
+    Thread serverThread = null;
+
+    /*
+     * Primary constructor, used to drive remainder of the test.
+     *
+     * Fork off the other side, then do your work.
+     */
+    ReadZeroBytes () throws Exception {
+        if (separateServerThread) {
+            startServer(true);
+            startClient(false);
+        } else {
+            startClient(true);
+            startServer(false);
+        }
+
+        /*
+         * Wait for other side to close down.
+         */
+        if (separateServerThread) {
+            serverThread.join();
+        } else {
+            clientThread.join();
+        }
+
+        /*
+         * When we get here, the test is pretty much over.
+         *
+         * If the main thread excepted, that propagates back
+         * immediately.  If the other thread threw an exception, we
+         * should report back.
+         */
+        if (serverException != null)
+            throw serverException;
+        if (clientException != null)
+            throw clientException;
+    }
+
+    void startServer(boolean newThread) throws Exception {
+        if (newThread) {
+            serverThread = new Thread() {
+                public void run() {
+                    try {
+                        doServerSide();
+                    } catch (Exception e) {
+                        /*
+                         * Our server thread just died.
+                         *
+                         * Release the client, if not already active...
+                         */
+                        System.out.println("Server died...");
+                        serverReady = true;
+                        serverException = e;
+                    }
+                }
+            };
+            serverThread.start();
+        } else {
+            doServerSide();
+        }
+    }
+
+    void startClient(boolean newThread) throws Exception {
+        if (newThread) {
+            clientThread = new Thread() {
+                public void run() {
+                    try {
+                        doClientSide();
+                    } catch (Exception e) {
+                        /*
+                         * Our client thread just died.
+                         */
+                        System.out.println("Client died...");
+                        clientException = e;
+                    }
+                }
+            };
+            clientThread.start();
+        } else {
+            doClientSide();
+        }
+    }
+}
+
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/LoopbackSSLSocket.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/LoopbackSSLSocket.java
new file mode 100644
index 0000000..d97f20d
--- /dev/null
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/LoopbackSSLSocket.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 5067458
+ * @summary Loopback SSLSocketImpl createSocket is throwing an exception.
+ * @author Xuelei Fan
+ */
+
+import java.io.*;
+import java.net.*;
+
+import javax.net.ssl.*;
+
+public class LoopbackSSLSocket {
+
+    public static void main(String[] args) throws Exception {
+        SSLSocketFactory sf = (SSLSocketFactory)SSLSocketFactory.getDefault();
+        // we won't expect a IllegalArgumentException: hostname can't be null.
+        try {
+            SSLSocket s = (SSLSocket)sf.createSocket((String)null, 0);
+            s.close();
+        } catch (IOException ioe) {
+            // would catch a IOException because there is no listener on
+            // that socket.
+        }
+    }
+
+}
diff --git a/jdk/test/sun/security/tools/keytool/KeyToolTest.java b/jdk/test/sun/security/tools/keytool/KeyToolTest.java
index e25c376..e1edebe 100644
--- a/jdk/test/sun/security/tools/keytool/KeyToolTest.java
+++ b/jdk/test/sun/security/tools/keytool/KeyToolTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2005-2009 Sun Microsystems, Inc.  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
@@ -56,11 +56,14 @@
  */
 
 import java.security.KeyStore;
-import java.util.Locale;
-import java.util.MissingResourceException;
 import sun.security.tools.KeyTool;
 import sun.security.x509.*;
 import java.io.*;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import java.util.*;
+import java.security.cert.X509Certificate;
+import sun.security.util.ObjectIdentifier;
 
 public class KeyToolTest {
 
@@ -118,7 +121,7 @@
         lastInput = input;
         lastCommand = cmd;
 
-        // "X" is appened so that we can precisely test how input is consumed
+        // "X" is appended so that we can precisely test how input is consumed
         HumanInputStream in = new HumanInputStream(input+"X");
         test(in, cmd);
         // make sure the input string is no more no less
@@ -264,12 +267,21 @@
     }
 
     void assertTrue(boolean bool, String msg) {
+        if (debug) {
+            System.err.println("If not " + bool + ", " + msg);
+        } else {
+            System.err.print("v");
+        }
         if(!bool) {
             afterFail(lastInput, lastCommand, "TRUE");
+                System.err.println(msg);
             throw new RuntimeException(msg);
         }
     }
 
+    void assertTrue(boolean bool) {
+        assertTrue(bool, "well...");
+    }
     /**
      * Helper method, load a keystore
      * @param file file for keystore, null or "NONE" for PKCS11
@@ -827,32 +839,363 @@
         remove("mykey.cert");
     }
 
+    void v3extTest(String keyAlg) throws Exception {
+        KeyStore ks;
+        remove("x.jks");
+        String simple = "-keystore x.jks -storepass changeit -keypass changeit -noprompt -keyalg " + keyAlg + " ";
+        String pre = simple + "-genkeypair -dname CN=Olala -alias ";
+
+        // Version and SKID
+        testOK("", pre + "o1");
+
+        ks = loadStore("x.jks", "changeit", "JKS");
+        assertTrue(((X509Certificate)ks.getCertificate("o1")).getVersion() == 3);
+        assertTrue(((X509CertImpl)ks.getCertificate("o1")).getSubjectKeyIdentifierExtension() != null);
+
+        // BC
+        testOK("", pre + "b1 -ext BC:critical");
+        testOK("", pre + "b2 -ext BC");
+        testOK("", pre + "b3 -ext bc");
+        testOK("", pre + "b4 -ext BasicConstraints");
+        testOK("", pre + "b5 -ext basicconstraints");
+        testOK("", pre + "b6 -ext BC=ca:true,pathlen:12");
+        testOK("", pre + "b7 -ext BC=ca:false");
+        testOK("", pre + "b8 -ext BC:critical=ca:false");
+        testOK("", pre + "b9 -ext BC=12");
+
+        ks = loadStore("x.jks", "changeit", "JKS");
+        assertTrue(((X509CertImpl)ks.getCertificate("b1")).getBasicConstraintsExtension().isCritical());
+        assertTrue(!((X509CertImpl)ks.getCertificate("b2")).getBasicConstraintsExtension().isCritical());
+        assertTrue(((X509CertImpl)ks.getCertificate("b8")).getBasicConstraintsExtension().isCritical());
+        assertTrue(((X509Certificate)ks.getCertificate("b1")).getBasicConstraints() == Integer.MAX_VALUE);
+        assertTrue(((X509Certificate)ks.getCertificate("b2")).getBasicConstraints() == Integer.MAX_VALUE);
+        assertTrue(((X509Certificate)ks.getCertificate("b3")).getBasicConstraints() == Integer.MAX_VALUE);
+        assertTrue(((X509Certificate)ks.getCertificate("b4")).getBasicConstraints() == Integer.MAX_VALUE);
+        assertTrue(((X509Certificate)ks.getCertificate("b5")).getBasicConstraints() == Integer.MAX_VALUE);
+        assertTrue(((X509Certificate)ks.getCertificate("b6")).getBasicConstraints() == 12);
+        assertTrue(((X509Certificate)ks.getCertificate("b7")).getBasicConstraints() == -1);
+        assertTrue(((X509Certificate)ks.getCertificate("b9")).getBasicConstraints() == 12);
+
+        // KU
+        testOK("", pre + "ku1 -ext KeyUsage:critical=digitalsignature");
+        testOK("", pre + "ku2 -ext KU=digitalSignature");
+        testOK("", pre + "ku3 -ext KU=ds");
+        testOK("", pre + "ku4 -ext KU=dig");
+        testFail("", pre + "ku5 -ext KU=d");    // ambigous value
+        testFail("", pre + "ku6 -ext KU=cs");   // cRLSign cannot be cs
+        testOK("", pre + "ku11 -ext KU=nr");
+        testFail("", pre + "ku12 -ext KU=ke");  // ke also means keyAgreement
+        testOK("", pre + "ku12 -ext KU=keyE");
+        testFail("", pre + "ku13 -ext KU=de");  // de also means decipherOnly
+        testOK("", pre + "ku13 -ext KU=dataE");
+        testOK("", pre + "ku14 -ext KU=ka");
+        testOK("", pre + "ku15 -ext KU=kcs");
+        testOK("", pre + "ku16 -ext KU=crls");
+        testOK("", pre + "ku17 -ext KU=eo");
+        testOK("", pre + "ku18 -ext KU=do");
+        testOK("", pre + "ku19 -ext KU=cc");
+
+        testOK("", pre + "ku017 -ext KU=ds,cc,eo");
+        testOK("", pre + "ku135 -ext KU=nr,dataEncipherment,keyCertSign");
+        testOK("", pre + "ku246 -ext KU=keyEnc,cRL,keyA");
+        testOK("", pre + "ku1234 -ext KU=ka,da,keyE,nonR");
+
+        ks = loadStore("x.jks", "changeit", "JKS");
+        class CheckKU {
+            void check(KeyStore ks, String alias, int... pos) throws Exception {
+                System.err.print("x");
+                boolean[] bs = ((X509Certificate)ks.getCertificate(alias)).getKeyUsage();
+                bs = Arrays.copyOf(bs, 9);
+                for (int i=0; i<bs.length; i++) {
+                    boolean found = false;
+                    for (int p: pos) {
+                        if (p == i) found = true;
+                    }
+                    if (!found ^ bs[i]) {
+                        // OK
+                    } else {
+                        throw new RuntimeException("KU not match at " + i +
+                                ": " + found + " vs " + bs[i]);
+                    }
+                }
+            }
+        }
+        CheckKU c = new CheckKU();
+        assertTrue(((X509CertImpl)ks.getCertificate("ku1")).getExtension(PKIXExtensions.KeyUsage_Id).isCritical());
+        assertTrue(!((X509CertImpl)ks.getCertificate("ku2")).getExtension(PKIXExtensions.KeyUsage_Id).isCritical());
+        c.check(ks, "ku1", 0);
+        c.check(ks, "ku2", 0);
+        c.check(ks, "ku3", 0);
+        c.check(ks, "ku4", 0);
+        c.check(ks, "ku11", 1);
+        c.check(ks, "ku12", 2);
+        c.check(ks, "ku13", 3);
+        c.check(ks, "ku14", 4);
+        c.check(ks, "ku15", 5);
+        c.check(ks, "ku16", 6);
+        c.check(ks, "ku17", 7);
+        c.check(ks, "ku18", 8);
+        c.check(ks, "ku19", 1);
+        c.check(ks, "ku11", 1);
+        c.check(ks, "ku11", 1);
+        c.check(ks, "ku11", 1);
+        c.check(ks, "ku017", 0, 1, 7);
+        c.check(ks, "ku135", 1, 3, 5);
+        c.check(ks, "ku246", 6, 2, 4);
+        c.check(ks, "ku1234", 1, 2, 3, 4);
+
+        // EKU
+        testOK("", pre + "eku1 -ext EKU:critical=sa");
+        testOK("", pre + "eku2 -ext ExtendedKeyUsage=ca");
+        testOK("", pre + "eku3 -ext EKU=cs");
+        testOK("", pre + "eku4 -ext EKU=ep");
+        testOK("", pre + "eku8 -ext EKU=ts");
+        testFail("", pre + "eku9 -ext EKU=os");
+        testOK("", pre + "eku9 -ext EKU=ocsps");
+        testOK("", pre + "eku10 -ext EKU=any");
+        testOK("", pre + "eku11 -ext EKU=1.2.3.4,1.3.5.7,ep");
+        testFail("", pre + "eku12 -ext EKU=c");
+        testFail("", pre + "eku12 -ext EKU=nothing");
+
+        ks = loadStore("x.jks", "changeit", "JKS");
+        class CheckEKU {
+            void check(KeyStore ks, String alias, String... pos) throws Exception {
+                System.err.print("x");
+                List<String> bs = ((X509Certificate)ks.getCertificate(alias)).getExtendedKeyUsage();
+                int found = 0;
+                for (String p: pos) {
+                    if (bs.contains(p)) {
+                        found++;
+                    } else {
+                        throw new RuntimeException("EKU: not included " + p);
+                    }
+                }
+                if (found != bs.size()) {
+                    throw new RuntimeException("EKU: more items than expected");
+                }
+            }
+        }
+        CheckEKU cx = new CheckEKU();
+        assertTrue(((X509CertImpl)ks.getCertificate("eku1")).getExtension(PKIXExtensions.ExtendedKeyUsage_Id).isCritical());
+        assertTrue(!((X509CertImpl)ks.getCertificate("eku2")).getExtension(PKIXExtensions.ExtendedKeyUsage_Id).isCritical());
+        cx.check(ks, "eku1", "1.3.6.1.5.5.7.3.1");
+        cx.check(ks, "eku2", "1.3.6.1.5.5.7.3.2");
+        cx.check(ks, "eku3", "1.3.6.1.5.5.7.3.3");
+        cx.check(ks, "eku4", "1.3.6.1.5.5.7.3.4");
+        cx.check(ks, "eku8", "1.3.6.1.5.5.7.3.8");
+        cx.check(ks, "eku9", "1.3.6.1.5.5.7.3.9");
+        cx.check(ks, "eku10", "2.5.29.37.0");
+        cx.check(ks, "eku11", "1.3.6.1.5.5.7.3.4", "1.2.3.4", "1.3.5.7");
+
+        // SAN
+        testOK("", pre+"san1 -ext san:critical=email:me@me.org");
+        testOK("", pre+"san2 -ext san=uri:http://me.org");
+        testOK("", pre+"san3 -ext san=dns:me.org");
+        testOK("", pre+"san4 -ext san=ip:192.168.0.1");
+        testOK("", pre+"san5 -ext san=oid:1.2.3.4");
+        testOK("", pre+"san235 -ext san=uri:http://me.org,dns:me.org,oid:1.2.3.4");
+
+        ks = loadStore("x.jks", "changeit", "JKS");
+        class CheckSAN {
+            // Please sort items with name type
+            void check(KeyStore ks, String alias, int type, Object... items) throws Exception {
+                int pos = 0;
+                System.err.print("x");
+                Object[] names = null;
+                if (type == 0) names = ((X509Certificate)ks.getCertificate(alias)).getSubjectAlternativeNames().toArray();
+                else names = ((X509Certificate)ks.getCertificate(alias)).getIssuerAlternativeNames().toArray();
+                Arrays.sort(names, new Comparator() {
+                    public int compare(Object o1, Object o2) {
+                        int i1 = (Integer)((List)o1).get(0);
+                        int i2 = (Integer)((List)o2).get(0);
+                        return i1 - i2;
+                    }
+                });
+                for (Object o: names) {
+                    List l = (List)o;
+                    for (Object o2: l) {
+                        if (!items[pos++].equals(o2)) {
+                            throw new RuntimeException("Not equals at " + pos
+                                    + ": " + items[pos-1] + " vs " + o2);
+                        }
+                    }
+                }
+                if (pos != items.length) {
+                    throw new RuntimeException("Extra items, pos is " + pos);
+                }
+            }
+        }
+        CheckSAN csan = new CheckSAN();
+        assertTrue(((X509CertImpl)ks.getCertificate("san1")).getSubjectAlternativeNameExtension().isCritical());
+        assertTrue(!((X509CertImpl)ks.getCertificate("san2")).getSubjectAlternativeNameExtension().isCritical());
+        csan.check(ks, "san1", 0, 1, "me@me.org");
+        csan.check(ks, "san2", 0, 6, "http://me.org");
+        csan.check(ks, "san3", 0, 2, "me.org");
+        csan.check(ks, "san4", 0, 7, "192.168.0.1");
+        csan.check(ks, "san5", 0, 8, "1.2.3.4");
+        csan.check(ks, "san235", 0, 2, "me.org", 6, "http://me.org", 8, "1.2.3.4");
+
+        // IAN
+        testOK("", pre+"ian1 -ext ian:critical=email:me@me.org");
+        testOK("", pre+"ian2 -ext ian=uri:http://me.org");
+        testOK("", pre+"ian3 -ext ian=dns:me.org");
+        testOK("", pre+"ian4 -ext ian=ip:192.168.0.1");
+        testOK("", pre+"ian5 -ext ian=oid:1.2.3.4");
+        testOK("", pre+"ian235 -ext ian=uri:http://me.org,dns:me.org,oid:1.2.3.4");
+
+        ks = loadStore("x.jks", "changeit", "JKS");
+        assertTrue(((X509CertImpl)ks.getCertificate("ian1")).getIssuerAlternativeNameExtension().isCritical());
+        assertTrue(!((X509CertImpl)ks.getCertificate("ian2")).getIssuerAlternativeNameExtension().isCritical());
+        csan.check(ks, "ian1", 1, 1, "me@me.org");
+        csan.check(ks, "ian2", 1, 6, "http://me.org");
+        csan.check(ks, "ian3", 1, 2, "me.org");
+        csan.check(ks, "ian4", 1, 7, "192.168.0.1");
+        csan.check(ks, "ian5", 1, 8, "1.2.3.4");
+        csan.check(ks, "ian235", 1, 2, "me.org", 6, "http://me.org", 8, "1.2.3.4");
+
+        // SIA
+        testOK("", pre+"sia1 -ext sia=care:uri:ldap://ca.com/cn=CA");
+        testOK("", pre+"sia2 -ext sia=ts:email:ts@ca.com");
+        testFail("SIA never critical", pre+"sia3 -ext sia:critical=ts:email:ts@ca.com");
+
+        ks = loadStore("x.jks", "changeit", "JKS");
+        class CheckSia {
+            void check(KeyStore ks, String alias, int type, Object... items) throws Exception {
+                int pos = 0;
+                System.err.print("x");
+                AccessDescription[] ads = null;
+                if (type == 0) {
+                    SubjectInfoAccessExtension siae = (SubjectInfoAccessExtension)((X509CertImpl)ks.getCertificate(alias)).getExtension(PKIXExtensions.SubjectInfoAccess_Id);
+                    ads = siae.getAccessDescriptions().toArray(new AccessDescription[0]);
+                } else {
+                    AuthorityInfoAccessExtension aiae = (AuthorityInfoAccessExtension)((X509CertImpl)ks.getCertificate(alias)).getExtension(PKIXExtensions.AuthInfoAccess_Id);
+                    ads = aiae.getAccessDescriptions().toArray(new AccessDescription[0]);
+                }
+                Arrays.sort(ads, new Comparator<AccessDescription>() {
+                    @Override
+                    public int compare(AccessDescription o1, AccessDescription o2) {
+                        return o1.getAccessMethod().toString().compareTo(o2.getAccessMethod().toString());
+                    }
+                });
+                for (AccessDescription ad: ads) {
+                    if (!ad.getAccessMethod().equals(items[pos++]) ||
+                            !new Integer(ad.getAccessLocation().getType()).equals(items[pos++])) {
+                        throw new RuntimeException("Not same type at " + pos);
+                    }
+                    String name = null;
+                    switch (ad.getAccessLocation().getType()) {
+                        case 1:
+                            name = ((RFC822Name)ad.getAccessLocation().getName()).getName();
+                            break;
+                        case 6:
+                            name = ((URIName)ad.getAccessLocation().getName()).getURI().toString();
+                            break;
+                        default:
+                            throw new RuntimeException("Not implemented: " + ad);
+                    }
+                    if (!name.equals(items[pos++])) {
+                        throw new Exception("Name not same for " + ad + " at pos " + pos);
+                    }
+                }
+            }
+        }
+        CheckSia csia = new CheckSia();
+        assertTrue(!((X509CertImpl)ks.getCertificate("sia1")).getExtension(PKIXExtensions.SubjectInfoAccess_Id).isCritical());
+        csia.check(ks, "sia1", 0, AccessDescription.Ad_CAREPOSITORY_Id, 6, "ldap://ca.com/cn=CA");
+        csia.check(ks, "sia2", 0, AccessDescription.Ad_TIMESTAMPING_Id, 1, "ts@ca.com");
+
+        // AIA
+        testOK("", pre+"aia1 -ext aia=cai:uri:ldap://ca.com/cn=CA");
+        testOK("", pre+"aia2 -ext aia=ocsp:email:ocsp@ca.com");
+        testFail("AIA never critical", pre+"aia3 -ext aia:critical=ts:email:ts@ca.com");
+
+        ks = loadStore("x.jks", "changeit", "JKS");
+        assertTrue(!((X509CertImpl)ks.getCertificate("aia1")).getExtension(PKIXExtensions.AuthInfoAccess_Id).isCritical());
+        csia.check(ks, "aia1", 1, AccessDescription.Ad_CAISSUERS_Id, 6, "ldap://ca.com/cn=CA");
+        csia.check(ks, "aia2", 1, AccessDescription.Ad_OCSP_Id, 1, "ocsp@ca.com");
+
+        // OID
+        testOK("", pre+"oid1 -ext 1.2.3:critical=0102");
+        testOK("", pre+"oid2 -ext 1.2.3");
+        testOK("", pre+"oid12 -ext 1.2.3 -ext 1.2.4=01:02:03");
+
+        ks = loadStore("x.jks", "changeit", "JKS");
+        class CheckOid {
+            void check(KeyStore ks, String alias, String oid, byte[] value) throws Exception {
+                int pos = 0;
+                System.err.print("x");
+                Extension ex = ((X509CertImpl)ks.getCertificate(alias)).getExtension(new ObjectIdentifier(oid));
+                if (!Arrays.equals(value, ex.getValue())) {
+                    throw new RuntimeException("Not same content in " + alias + " for " + oid);
+                }
+            }
+        }
+        CheckOid coid = new CheckOid();
+        assertTrue(((X509CertImpl)ks.getCertificate("oid1")).getExtension(new ObjectIdentifier("1.2.3")).isCritical());
+        assertTrue(!((X509CertImpl)ks.getCertificate("oid2")).getExtension(new ObjectIdentifier("1.2.3")).isCritical());
+        coid.check(ks, "oid1", "1.2.3", new byte[]{1,2});
+        coid.check(ks, "oid2", "1.2.3", new byte[]{});
+        coid.check(ks, "oid12", "1.2.3", new byte[]{});
+        coid.check(ks, "oid12", "1.2.4", new byte[]{1,2,3});
+
+        // honored
+        testOK("", pre+"ca");
+        testOK("", pre+"a");
+        // request: BC,KU,1.2.3,1.2.4,1.2.5
+        testOK("", simple+"-alias a -certreq " +
+                "-ext BC=1 -ext KU=crl " +
+                "-ext 1.2.3=01 -ext 1.2.4:critical=0102 -ext 1.2.5=010203 " +
+                "-rfc -file test.req");
+        // printcertreq
+        testOK("", "-printcertreq -file test.req");
+        // issue: deny KU, change criticality of 1.2.3 and 1.2.4, change content of BC, add 2.3.4
+        testOK("", simple+"-gencert -alias ca -infile test.req -ext " +
+                "honored=all,-KU,1.2.3:critical,1.2.4:non-critical " +
+                "-ext BC=2 -ext 2.3.4=01020304 " +
+                "-debug -rfc -outfile test.cert");
+        testOK("", simple+"-importcert -file test.cert -alias a");
+        ks = loadStore("x.jks", "changeit", "JKS");
+        X509CertImpl a = (X509CertImpl)ks.getCertificate("a");
+        assertTrue(a.getAuthorityKeyIdentifierExtension() != null);
+        assertTrue(a.getSubjectKeyIdentifierExtension() != null);
+        assertTrue(a.getKeyUsage() == null);
+        assertTrue(a.getExtension(new ObjectIdentifier("1.2.3")).isCritical());
+        assertTrue(!a.getExtension(new ObjectIdentifier("1.2.4")).isCritical());
+        assertTrue(!a.getExtension(new ObjectIdentifier("1.2.5")).isCritical());
+        assertTrue(a.getExtensionValue("1.2.3").length == 3);
+        assertTrue(a.getExtensionValue("1.2.4").length == 4);
+        assertTrue(a.getExtensionValue("1.2.5").length == 5);
+        assertTrue(a.getBasicConstraints() == 2);
+        assertTrue(!a.getExtension(new ObjectIdentifier("2.3.4")).isCritical());
+        assertTrue(a.getExtensionValue("2.3.4").length == 6);
+
+        remove("x.jks");
+        remove("test.req");
+        remove("test.cert");
+    }
+
     void i18nTest() throws Exception {
         //   1.  keytool -help
         remove("x.jks");
-        try {
-            test("", "-help");
-            assertTrue(false, "Cannot come here");
-        } catch(RuntimeException e) {
-            assertTrue(e.getMessage().indexOf("NO ERROR, SORRY") != -1, "No error");
-        }
+        testOK("", "-help");
+
         //   2. keytool -genkey -v -keysize 512 Enter "a" for the keystore password. Check error (password too short). Enter "password" for the keystore password. Hit 'return' for "first and last name", "organizational unit", "City", "State", and "Country Code". Type "yes" when they ask you if everything is correct. Type 'return' for new key password.
         testOK("a\npassword\npassword\nMe\nHere\nNow\nPlace\nPlace\nUS\nyes\n\n", "-genkey -v -keysize 512 -keystore x.jks");
         //   3. keytool -list -v -storepass password
         testOK("", "-list -v -storepass password -keystore x.jks");
         //   4. keytool -list -v Type "a" for the keystore password. Check error (wrong keystore password).
         testFail("a\n", "-list -v -keystore x.jks");
-        assertTrue(ex.indexOf("password was incorrect") != -1, "");
+        assertTrue(ex.indexOf("password was incorrect") != -1);
         //   5. keytool -genkey -v -keysize 512 Enter "password" as the password. Check error (alias 'mykey' already exists).
         testFail("password\n", "-genkey -v -keysize 512 -keystore x.jks");
-        assertTrue(ex.indexOf("alias <mykey> already exists") != -1, "");
+        assertTrue(ex.indexOf("alias <mykey> already exists") != -1);
         //   6. keytool -genkey -v -keysize 512 -alias mykey2 -storepass password Hit 'return' for "first and last name", "organizational unit", "City", "State", and "Country Code". Type "yes" when they ask you if everything is correct. Type 'return' for new key password.
         testOK("\n\n\n\n\n\nyes\n\n", "-genkey -v -keysize 512 -alias mykey2 -storepass password -keystore x.jks");
         //   7. keytool -list -v Type 'password' for the store password.
         testOK("password\n", "-list -v -keystore x.jks");
         //   8. keytool -keypasswd -v -alias mykey2 -storepass password Type "a" for the new key password. Type "aaaaaa" for the new key password. Type "bbbbbb" when re-entering the new key password. Type "a" for the new key password. Check Error (too many failures).
         testFail("a\naaaaaa\nbbbbbb\na\n", "-keypasswd -v -alias mykey2 -storepass password -keystore x.jks");
-        assertTrue(ex.indexOf("Too many failures - try later") != -1, "");
+        assertTrue(ex.indexOf("Too many failures - try later") != -1);
         //   9. keytool -keypasswd -v -alias mykey2 -storepass password Type "aaaaaa" for the new key password. Type "aaaaaa" when re-entering the new key password.
         testOK("aaaaaa\naaaaaa\n", "-keypasswd -v -alias mykey2 -storepass password -keystore x.jks");
         //  10. keytool -selfcert -v -alias mykey -storepass password
@@ -864,7 +1207,7 @@
         testOK("", "-export -v -alias mykey -file cert -storepass password -keystore x.jks");
         //  13. keytool -import -v -file cert -storepass password Check error (Certificate reply and cert are the same)
         testFail("", "-import -v -file cert -storepass password -keystore x.jks");
-        assertTrue(ex.indexOf("Certificate reply and certificate in keystore are identical") != -1, "");
+        assertTrue(ex.indexOf("Certificate reply and certificate in keystore are identical") != -1);
         //  14. keytool -printcert -file cert
         testOK("", "-printcert -file cert -keystore x.jks");
         remove("cert");
@@ -875,26 +1218,26 @@
 
         //   1. keytool -storepasswd -storepass password -new abc Check error (password too short)
         testFail("", "-storepasswd -storepass password -new abc");
-        assertTrue(ex.indexOf("New password must be at least 6 characters") != -1, "");
+        assertTrue(ex.indexOf("New password must be at least 6 characters") != -1);
         // Changed, no NONE needed now
         //   2. keytool -list -storetype PKCS11 Check error (-keystore must be NONE)
         //testFail("", "-list -storetype PKCS11");
-        //assertTrue(err.indexOf("keystore must be NONE") != -1, "");
+        //assertTrue(err.indexOf("keystore must be NONE") != -1);
         //   3. keytool -storepasswd -storetype PKCS11 -keystore NONE Check error (unsupported operation)
         testFail("", "-storepasswd -storetype PKCS11 -keystore NONE");
-        assertTrue(ex.indexOf("UnsupportedOperationException") != -1, "");
+        assertTrue(ex.indexOf("UnsupportedOperationException") != -1);
         //   4. keytool -keypasswd -storetype PKCS11 -keystore NONE Check error (unsupported operation)
         testFail("", "-keypasswd -storetype PKCS11 -keystore NONE");
-        assertTrue(ex.indexOf("UnsupportedOperationException") != -1, "");
+        assertTrue(ex.indexOf("UnsupportedOperationException") != -1);
         //   5. keytool -list -protected -storepass password Check error (password can not be specified with -protected)
         testFail("", "-list -protected -storepass password -keystore x.jks");
-        assertTrue(ex.indexOf("if -protected is specified, then") != -1, "");
+        assertTrue(ex.indexOf("if -protected is specified, then") != -1);
         //   6. keytool -keypasswd -protected -keypass password Check error (password can not be specified with -protected)
         testFail("", "-keypasswd -protected -keypass password -keystore x.jks");
-        assertTrue(ex.indexOf("if -protected is specified, then") != -1, "");
+        assertTrue(ex.indexOf("if -protected is specified, then") != -1);
         //   7. keytool -keypasswd -protected -new password Check error (password can not be specified with -protected)
         testFail("", "-keypasswd -protected -new password -keystore x.jks");
-        assertTrue(ex.indexOf("if -protected is specified, then") != -1, "");
+        assertTrue(ex.indexOf("if -protected is specified, then") != -1);
         remove("x.jks");
     }
 
@@ -911,11 +1254,11 @@
         testOK("", "-printcert -file genkey.cert");
         testOK("", p11Arg + "-storepass test12 -selfcert -alias genkey -dname cn=selfCert");
         testOK("", p11Arg + "-storepass test12 -list -alias genkey -v");
-        assertTrue(out.indexOf("Owner: CN=selfCert") != -1, "");
+        assertTrue(out.indexOf("Owner: CN=selfCert") != -1);
         //(check that cert subject DN is [cn=selfCert])
         testOK("", p11Arg + "-storepass test12 -delete -alias genkey");
         testOK("", p11Arg + "-storepass test12 -list");
-        assertTrue(out.indexOf("Your keystore contains 0 entries") != -1, "");
+        assertTrue(out.indexOf("Your keystore contains 0 entries") != -1);
         //(check for empty database listing)
         //Runtime.getRuntime().exec("/usr/ccs/bin/sccs unedit cert8.db key3.db");
         remove("genkey.cert");
@@ -943,6 +1286,15 @@
             t.sqeTest();
             t.testAll();
             t.i18nTest();
+            t.v3extTest("RSA");
+            t.v3extTest("DSA");
+            boolean testEC = true;
+            try {
+                KeyPairGenerator.getInstance("EC");
+            } catch (NoSuchAlgorithmException nae) {
+                testEC = false;
+            }
+            if (testEC) t.v3extTest("EC");
         }
 
         if (System.getProperty("nss") != null) {
diff --git a/jdk/test/sun/security/tools/keytool/autotest.sh b/jdk/test/sun/security/tools/keytool/autotest.sh
index 04c00c1..e343183 100644
--- a/jdk/test/sun/security/tools/keytool/autotest.sh
+++ b/jdk/test/sun/security/tools/keytool/autotest.sh
@@ -1,5 +1,5 @@
 #
-# Copyright 2006-2008 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2006-2009 Sun Microsystems, Inc.  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
@@ -25,6 +25,8 @@
 # @summary (almost) all keytool behaviors
 # @author Weijun Wang
 #
+# This test is only executed on several platforms
+#
 # set a few environment variables so that the shell-script can run stand-alone
 # in the source directory
 if [ "${TESTSRC}" = "" ] ; then
@@ -88,7 +90,7 @@
 chmod u+w key3.db
 chmod u+w cert8.db
 
-echo | ${TESTJAVA}${FS}bin${FS}java -Dfile -Dnss \
+echo | ${TESTJAVA}${FS}bin${FS}java -Dnss \
    -Dnss.lib=${NSS}${FS}lib${FS}${PF}${FS}${LIBNAME} \
    KeyToolTest
 status=$?
@@ -99,8 +101,8 @@
 rm -f secmod.db
 
 rm HumanInputStream*.class
-rm KeyToolTest.class
-rm TestException.class 
+rm KeyToolTest*.class
+rm TestException.class
 
 exit $status
 
diff --git a/jdk/test/sun/security/tools/keytool/standard.sh b/jdk/test/sun/security/tools/keytool/standard.sh
new file mode 100644
index 0000000..fe4a0a8
--- /dev/null
+++ b/jdk/test/sun/security/tools/keytool/standard.sh
@@ -0,0 +1,64 @@
+#
+# Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
+# @test
+# @summary (almost) all keytool behaviors
+# @author Weijun Wang
+#
+# This test is always excecuted.
+#
+# set a few environment variables so that the shell-script can run stand-alone
+# in the source directory
+if [ "${TESTSRC}" = "" ] ; then
+  TESTSRC="."
+fi
+if [ "${TESTCLASSES}" = "" ] ; then
+  TESTCLASSES="."
+fi
+if [ "${TESTJAVA}" = "" ] ; then
+  JAVAC_CMD=`which javac`
+  TESTJAVA=`dirname $JAVAC_CMD`/..
+fi
+
+# set platform-dependent variables
+OS=`uname -s`
+case "$OS" in
+  Windows_* )
+    FS="\\"
+    ;;
+  * )
+    FS="/"
+    ;;
+esac
+
+${TESTJAVA}${FS}bin${FS}javac -d . ${TESTSRC}${FS}KeyToolTest.java || exit 10
+
+echo | ${TESTJAVA}${FS}bin${FS}java -Dfile KeyToolTest
+status=$?
+
+rm HumanInputStream*.class
+rm KeyToolTest*.class
+rm TestException.class
+
+exit $status
+
diff --git a/jdk/test/sun/security/util/DerValue/EmptyValue.java b/jdk/test/sun/security/util/DerValue/EmptyValue.java
new file mode 100644
index 0000000..b280380
--- /dev/null
+++ b/jdk/test/sun/security/util/DerValue/EmptyValue.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6804045
+ * @summary DerValue does not accept empty OCTET STRING
+ */
+
+import sun.security.util.DerValue;
+
+public class EmptyValue {
+
+    public static void main(String[] args) throws Exception {
+        DerValue v = new DerValue(new byte[]{4,0});
+        if (v.getOctetString().length != 0) {
+            throw new Exception("Get octet string error");
+        }
+        v = new DerValue(new byte[]{0x30,0});
+        if (v.data.available() != 0) {
+            throw new Exception("Get sequence error");
+        }
+    }
+}
diff --git a/jdk/test/sun/security/x509/Extensions/BCNull.java b/jdk/test/sun/security/x509/Extensions/BCNull.java
new file mode 100644
index 0000000..e906f57
--- /dev/null
+++ b/jdk/test/sun/security/x509/Extensions/BCNull.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary BasicConstraintsExtension does not encode when (ca==false && pathLen<0)
+ * @bug 6803376
+ */
+
+import sun.security.x509.BasicConstraintsExtension;
+import java.io.ByteArrayOutputStream;
+
+public class BCNull {
+    public static void main(String [] args) throws Exception {
+        new BasicConstraintsExtension(false, -1).encode(new ByteArrayOutputStream());
+    }
+}
diff --git a/langtools/.hgtags b/langtools/.hgtags
index e2051a0..6e74f307 100644
--- a/langtools/.hgtags
+++ b/langtools/.hgtags
@@ -23,3 +23,4 @@
 be546a6c08e3c31fba2edcae1de43ae3515d2e59 jdk7-b46
 2b8f6bab23926aa32b9cf7e4c540b9d1ce74b7d5 jdk7-b47
 c53007f34195f69223bdd4125ec6c0740f7d6736 jdk7-b48
+d17d927ad9bdfafae32451645d182acb7bed7be6 jdk7-b49
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java
index 8a668cd..352eeb7 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java
@@ -245,6 +245,29 @@
     }
 
     /**
+     * Check whether there are any tags to be printed.
+     *
+     * @param doc the Doc object to check for tags.
+     * @return true if there are tags to be printed else return false.
+     */
+    protected boolean hasTagsToPrint(Doc doc) {
+        if (doc instanceof MethodDoc) {
+            ClassDoc[] intfacs = ((MethodDoc)doc).containingClass().interfaces();
+            MethodDoc overriddenMethod = ((MethodDoc)doc).overriddenMethod();
+            if ((intfacs.length > 0 &&
+                new ImplementedMethods((MethodDoc)doc, this.configuration).build().length > 0) ||
+                overriddenMethod != null) {
+                return true;
+            }
+        }
+        TagletOutputImpl output = new TagletOutputImpl("");
+        TagletWriter.genTagOuput(configuration.tagletManager, doc,
+            configuration.tagletManager.getCustomTags(doc),
+                getTagletWriterInstance(false), output);
+        return (output.toString().trim().isEmpty());
+    }
+
+    /**
      * Returns a TagletWriter that knows how to write HTML.
      *
      * @return a TagletWriter that knows how to write HTML.
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlSerialFieldWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlSerialFieldWriter.java
index 5b77065..3e84b00 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlSerialFieldWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlSerialFieldWriter.java
@@ -164,4 +164,20 @@
     public void writeMemberFooter(FieldDoc member) {
         writer.dlEnd();
     }
+
+    /**
+     * Check to see if member details should be printed. If
+     * nocomment option set or if there is no text to be printed
+     * for deprecation info, inline comment, no serial tag or inline tags,
+     * do not print member details.
+     */
+    public boolean shouldPrintMemberDetails(FieldDoc field) {
+        if (!configuration().nocomment)
+            if((field.inlineTags().length > 0) ||
+                (field.tags("serial").length > 0) || (writer.hasTagsToPrint(field)))
+                return true;
+        if (!Util.isDeprecated(field))
+            return true;
+        return false;
+    }
 }
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/TagletOutputImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/TagletOutputImpl.java
index af85324..9ecb4d6 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/TagletOutputImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/TagletOutputImpl.java
@@ -67,4 +67,10 @@
         return output.toString();
     }
 
+    /**
+     * Check whether the taglet output is empty.
+     */
+    public boolean isEmpty() {
+        return (toString().trim().isEmpty());
+    }
 }
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/SerializedFormWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/SerializedFormWriter.java
index 06fbb61..d1de4df 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/SerializedFormWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/SerializedFormWriter.java
@@ -152,6 +152,17 @@
          * @param member the member to write the header for.
          */
         public void writeMemberFooter(FieldDoc member);
+
+        /**
+         * Check to see if member details should be printed. If
+         * nocomment option set or if there is no text to be printed
+         * for deprecation info, inline comment, no serial tag or inline tags,
+         * do not print member details.
+         *
+         * @param member the member to check details for.
+         * @return true if details need to be printed
+         */
+        public boolean shouldPrintMemberDetails(FieldDoc member);
     }
 
     /**
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/SerializedFormBuilder.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/SerializedFormBuilder.java
index 636db90..1434bc0 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/SerializedFormBuilder.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/SerializedFormBuilder.java
@@ -403,16 +403,17 @@
         if (classDoc.definesSerializableFields()) {
             FieldDoc serialPersistentField =
                 Util.asList(classDoc.serializableFields()).get(0);
-            String comment = serialPersistentField.commentText();
-            if (comment.length() > 0) {
+            // Check to see if there are inline comments, tags or deprecation
+            // information to be printed.
+            if (fieldWriter.shouldPrintMemberDetails(serialPersistentField)) {
                 fieldWriter.writeHeader(
                     configuration.getText("doclet.Serialized_Form_class"));
+                fieldWriter.writeMemberDeprecatedInfo(serialPersistentField);
                 if (!configuration.nocomment) {
-                    fieldWriter.writeMemberDeprecatedInfo(serialPersistentField);
                     fieldWriter.writeMemberDescription(serialPersistentField);
                     fieldWriter.writeMemberTags(serialPersistentField);
-                    fieldWriter.writeMemberFooter(serialPersistentField);
                 }
+                fieldWriter.writeMemberFooter(serialPersistentField);
             }
         }
     }
@@ -429,6 +430,16 @@
     }
 
     /**
+     * Build the field deprecation information.
+     */
+    public void buildFieldDeprecationInfo() {
+        if (!currentClass.definesSerializableFields()) {
+            FieldDoc field = (FieldDoc)currentMember;
+            fieldWriter.writeMemberDeprecatedInfo(field);
+        }
+    }
+
+    /**
      * Build the field information.
      */
     public void buildFieldInfo() {
@@ -459,7 +470,6 @@
                         "doclet.MissingSerialTag", cd.qualifiedName(),
                         field.name());
             }
-            fieldWriter.writeMemberDeprecatedInfo(field);
             fieldWriter.writeMemberDescription(field);
             fieldWriter.writeMemberTags(field);
         }
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclet.xml b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclet.xml
index 2ecd836..8eaa2d7 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclet.xml
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclet.xml
@@ -1,30 +1,30 @@
 <?xml version='1.0' encoding='utf-8'?>
-
-<!--
- Copyright 2003 Sun Microsystems, Inc.  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.  Sun designates this
- particular file as subject to the "Classpath" exception as provided
- by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- CA 95054 USA or visit www.sun.com if you need additional information or
- have any questions.
--->
-
+
+<!--
+ Copyright 2003 Sun Microsystems, Inc.  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.  Sun designates this
+ particular file as subject to the "Classpath" exception as provided
+ by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ CA 95054 USA or visit www.sun.com if you need additional information or
+ have any questions.
+-->
+
 
 <Doclet>
 
@@ -183,8 +183,8 @@
                     <MethodHeader/>
                     <SerializableMethods>
                         <MethodSubHeader/>
+                        <DeprecatedMethodInfo/>
                         <MethodInfo>
-                            <DeprecatedMethodInfo/>
                             <MethodDescription/>
                             <MethodTags/>
                         </MethodInfo>
@@ -193,6 +193,7 @@
                     <FieldHeader/>
                     <SerializableFields>
                         <FieldSubHeader/>
+                        <FieldDeprecationInfo/>
                         <FieldInfo/>
                         <FieldFooter/>
                     </SerializableFields>                  
diff --git a/langtools/src/share/classes/com/sun/tools/javac/api/DiagnosticFormatter.java b/langtools/src/share/classes/com/sun/tools/javac/api/DiagnosticFormatter.java
index 6fd51b1..1c035fb 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/api/DiagnosticFormatter.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/api/DiagnosticFormatter.java
@@ -25,16 +25,18 @@
 package com.sun.tools.javac.api;
 
 import java.util.Locale;
+import java.util.Set;
 import javax.tools.Diagnostic;
+import com.sun.tools.javac.api.DiagnosticFormatter.*;
 
 /**
- * Provides simple functionalities for javac diagnostic formatting
+ * Provides simple functionalities for javac diagnostic formatting.
  * @param <D> type of diagnostic handled by this formatter
  */
 public interface DiagnosticFormatter<D extends Diagnostic<?>> {
 
     /**
-     * Whether the source code output for this diagnostic is to be displayed
+     * Whether the source code output for this diagnostic is to be displayed.
      *
      * @param diag diagnostic to be formatted
      * @return true if the source line this diagnostic refers to is to be displayed
@@ -42,7 +44,7 @@
     boolean displaySource(D diag);
 
     /**
-     * Format the contents of a diagnostics
+     * Format the contents of a diagnostics.
      *
      * @param diag the diagnostic to be formatted
      * @param l locale object to be used for i18n
@@ -115,4 +117,97 @@
          */
         OFFSET
     }
+
+    /**
+     * Get a list of all the enabled verbosity options.
+     * @return verbosity options
+     */
+    public Configuration getConfiguration();
+    //where
+
+    /**
+     * This interface provides functionalities for tuning the output of a
+     * diagnostic formatter in multiple ways.
+     */
+    interface Configuration {
+        /**
+         * Configure the set of diagnostic parts that should be displayed
+         * by the formatter.
+         * @param options options to set
+         */
+        public void setVisible(Set<DiagnosticPart> visibleParts);
+
+        /**
+         * Retrieve the set of diagnostic parts that should be displayed
+         * by the formatter.
+         * @return verbosity options
+         */
+        public Set<DiagnosticPart> getVisible();
+
+        //where
+        /**
+         * A given diagnostic message can be divided into sub-parts each of which
+         * might/might not be displayed by the formatter, according to the
+         * current configuration settings.
+         */
+        public enum DiagnosticPart {
+            /**
+             * Short description of the diagnostic - usually one line long.
+             */
+            SUMMARY,
+            /**
+             * Longer description that provides additional details w.r.t. the ones
+             * in the diagnostic's description.
+             */
+            DETAILS,
+            /**
+             * Source line the diagnostic refers to (if applicable).
+             */
+            SOURCE,
+            /**
+             * Subdiagnostics attached to a given multiline diagnostic.
+             */
+            SUBDIAGNOSTICS,
+            /**
+             * JLS paragraph this diagnostic might refer to (if applicable).
+             */
+            JLS;
+        }
+
+        /**
+         * Set a limit for multiline diagnostics.
+         * Note: Setting a limit has no effect if multiline diagnostics are either
+         * fully enabled or disabled.
+         *
+         * @param limit the kind of limit to be set
+         * @param value the limit value
+         */
+        public void setMultilineLimit(MultilineLimit limit, int value);
+
+        /**
+         * Get a multiline diagnostic limit.
+         *
+         * @param limit the kind of limit to be retrieved
+         * @return limit value or -1 if no limit is set
+         */
+        public int getMultilineLimit(MultilineLimit limit);
+        //where
+        /**
+         * A multiline limit control the verbosity of multiline diagnostics
+         * either by setting a maximum depth of nested multidiagnostics,
+         * or by limiting the amount of subdiagnostics attached to a given
+         * diagnostic (or both).
+         */
+        public enum MultilineLimit {
+            /**
+             * Controls the maximum depth of nested multiline diagnostics.
+             */
+            DEPTH,
+            /**
+             * Controls the maximum amount of subdiagnostics that are part of a
+             * given multiline diagnostic.
+             */
+            LENGTH;
+        }
+    }
 }
diff --git a/langtools/src/share/classes/com/sun/tools/javac/api/Messages.java b/langtools/src/share/classes/com/sun/tools/javac/api/Messages.java
index 7b67fe6..bc38794 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/api/Messages.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/api/Messages.java
@@ -44,7 +44,7 @@
     void add(String bundleName) throws MissingResourceException;
 
     /**
-     * Get a localized formatted string
+     * Get a localized formatted string.
      * @param l locale in which the text is to be localized
      * @param key locale-independent message key
      * @param args misc message arguments
diff --git a/langtools/src/share/classes/com/sun/tools/javac/main/OptionName.java b/langtools/src/share/classes/com/sun/tools/javac/main/OptionName.java
index 3ffbccd..61a2d1b 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/main/OptionName.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/OptionName.java
@@ -40,6 +40,7 @@
     G_CUSTOM("-g:"),
     XLINT("-Xlint"),
     XLINT_CUSTOM("-Xlint:"),
+    DIAGS("-XDdiags="),
     NOWARN("-nowarn"),
     VERBOSE("-verbose"),
     DEPRECATION("-deprecation"),
diff --git a/langtools/src/share/classes/com/sun/tools/javac/main/RecognizedOptions.java b/langtools/src/share/classes/com/sun/tools/javac/main/RecognizedOptions.java
index 980d677..f69f0c1 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/main/RecognizedOptions.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/RecognizedOptions.java
@@ -145,6 +145,7 @@
         TARGET,
         VERSION,
         FULLVERSION,
+        DIAGS,
         HELP,
         A,
         X,
@@ -372,6 +373,21 @@
                 return super.process(options, option);
             }
         },
+        new HiddenOption(DIAGS) {
+            @Override
+            public boolean process(Options options, String option) {
+                Option xd = getOptions(helper, EnumSet.of(XD))[0];
+                option = option.substring(option.indexOf('=') + 1);
+                String diagsOption = option.contains("%") ?
+                    "-XDdiagsFormat=" :
+                    "-XDdiags=";
+                diagsOption += option;
+                if (xd.matches(diagsOption))
+                    return xd.process(options, diagsOption);
+                else
+                    return false;
+            }
+        },
         new Option(HELP,                                        "opt.help") {
             @Override
             public boolean process(Options options, String option) {
diff --git a/langtools/src/share/classes/com/sun/tools/javac/processing/PrintingProcessor.java b/langtools/src/share/classes/com/sun/tools/javac/processing/PrintingProcessor.java
index a943358..2c26697 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/processing/PrintingProcessor.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/processing/PrintingProcessor.java
@@ -125,7 +125,7 @@
                     return this;
 
                 defaultAction(e, true);
-                printFormalTypeParameters(e);
+                printFormalTypeParameters(e, true);
 
                 switch(kind) {
                     case CONSTRUCTOR:
@@ -207,7 +207,7 @@
                 writer.print(" ");
                 writer.print(e.getSimpleName());
 
-                printFormalTypeParameters(e);
+                printFormalTypeParameters(e, false);
 
                 // Print superclass information if informative
                 if (kind == CLASS) {
@@ -364,16 +364,9 @@
             }
         }
 
-        private void printFormalTypeParameters(ExecutableElement executable) {
-            printFormalTypeParameters(executable.getTypeParameters(), true);
-        }
-
-        private void printFormalTypeParameters(TypeElement type) {
-            printFormalTypeParameters(type.getTypeParameters(), false);
-        }
-
-        private void printFormalTypeParameters(List<? extends TypeParameterElement> typeParams,
+        private void printFormalTypeParameters(Parameterizable e,
                                                boolean pad) {
+            List<? extends TypeParameterElement> typeParams = e.getTypeParameters();
             if (typeParams.size() > 0) {
                 writer.print("<");
 
diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties
index a7e75fa..d892db0 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties
@@ -907,16 +907,16 @@
 
 compiler.err.prob.found.req=\
 {0}\n\
-found   : {1}\n\
-required: {2}
+required: {2}\n\
+found:    {1}
 compiler.warn.prob.found.req=\
 {0}\n\
-found   : {1}\n\
-required: {2}
+required: {2}\n\
+found:    {1}
 compiler.err.prob.found.req.1=\
 {0} {3}\n\
-found   : {1}\n\
-required: {2}
+required: {2}\n\
+found:    {1}
 
 ## The following are all possible strings for the first argument ({0}) of the
 ## above strings.
@@ -951,8 +951,8 @@
 
 compiler.err.type.found.req=\
 unexpected type\n\
-found   : {0}\n\
-required: {1}
+required: {1}\n\
+found:    {0}
 
 ## The following are all possible strings for the first argument ({0}) of the
 ## above string.
@@ -1003,7 +1003,7 @@
 compiler.err.unexpected.type=\
 unexpected type\n\
 required: {0}\n\
-found   : {1}
+found:    {1}
 
 ## The first argument {0} is a "kindname" (e.g. 'constructor', 'field', etc.)
 ## The second argument {1} is the non-resolved symbol
@@ -1026,17 +1026,17 @@
 ## The sixth argument {5} is the location type
 compiler.err.cant.resolve.location=\
     cannot find symbol\n\
-    symbol  : {0} {1}\n\
+    symbol:   {0} {1}\n\
     location: {4} {5}
 
 compiler.err.cant.resolve.location.args=\
     cannot find symbol\n\
-    symbol  : {0} {1}({3})\n\
+    symbol:   {0} {1}({3})\n\
     location: {4} {5}
 
 compiler.err.cant.resolve.location.args.params=\
     cannot find symbol\n\
-    symbol  : {0} <{2}>{1}({3})\n\
+    symbol:   {0} <{2}>{1}({3})\n\
     location: {4} {5}
 
 ## The following are all possible string for "kindname".
diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java b/langtools/src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java
index e930c75..179e284 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java
@@ -24,16 +24,23 @@
  */
 package com.sun.tools.javac.util;
 
+import java.util.Arrays;
 import java.util.Collection;
+import java.util.EnumSet;
+import java.util.HashMap;
 import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
 import javax.tools.JavaFileObject;
 
 import com.sun.tools.javac.api.DiagnosticFormatter;
-import com.sun.tools.javac.api.Formattable;
+import com.sun.tools.javac.api.DiagnosticFormatter.Configuration.DiagnosticPart;
+import com.sun.tools.javac.api.DiagnosticFormatter.Configuration.MultilineLimit;
 import com.sun.tools.javac.api.DiagnosticFormatter.PositionKind;
+import com.sun.tools.javac.api.Formattable;
 import com.sun.tools.javac.file.JavacFileManager;
+
 import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticType.*;
-import static com.sun.tools.javac.util.LayoutCharacters.*;
 
 /**
  * This abstract class provides a basic implementation of the functionalities that should be provided
@@ -50,35 +57,19 @@
 public abstract class AbstractDiagnosticFormatter implements DiagnosticFormatter<JCDiagnostic> {
 
     /**
-     * JavacMessages object used by this formatter for i18n
+     * JavacMessages object used by this formatter for i18n.
      */
     protected JavacMessages messages;
-    protected boolean showSource;
+    private SimpleConfiguration config;
+    protected int depth = 0;
 
     /**
-     * Initialize an AbstractDiagnosticFormatter by setting its JavacMessages object
+     * Initialize an AbstractDiagnosticFormatter by setting its JavacMessages object.
      * @param messages
      */
-    protected AbstractDiagnosticFormatter(JavacMessages messages, Options options, boolean showSource) {
+    protected AbstractDiagnosticFormatter(JavacMessages messages, SimpleConfiguration config) {
         this.messages = messages;
-        this.showSource = options.get("showSource") == null ? showSource :
-                          options.get("showSource").equals("true");
-    }
-
-    protected AbstractDiagnosticFormatter(JavacMessages messages, boolean showSource) {
-        this.messages = messages;
-        this.showSource = showSource;
-    }
-
-    public String formatMessage(JCDiagnostic d, Locale l) {
-        //this code should rely on the locale settings but it's not! See RFE 6443132
-        StringBuilder buf = new StringBuilder();
-        Collection<String> args = formatArguments(d, l);
-        buf.append(localize(l, d.getCode(), args.toArray()));
-        if (d.isMultiline()) {
-            buf.append(formatSubdiagnostics(d, l));
-        }
-        return buf.toString();
+        this.config = config;
     }
 
     public String formatKind(JCDiagnostic d, Locale l) {
@@ -96,8 +87,8 @@
         assert (d.getPosition() != Position.NOPOS);
         return String.valueOf(getPosition(d, pk));
     }
-    //WHERE
-    public long getPosition(JCDiagnostic d, PositionKind pk) {
+    //where
+    private long getPosition(JCDiagnostic d, PositionKind pk) {
         switch (pk) {
             case START: return d.getIntStartPosition();
             case END: return d.getIntEndPosition();
@@ -138,8 +129,17 @@
      * @return string representation of the diagnostic argument
      */
     protected String formatArgument(JCDiagnostic d, Object arg, Locale l) {
-        if (arg instanceof JCDiagnostic)
-            return format((JCDiagnostic)arg, l);
+        if (arg instanceof JCDiagnostic) {
+            String s = null;
+            depth++;
+            try {
+                s = formatMessage((JCDiagnostic)arg, l);
+            }
+            finally {
+                depth--;
+            }
+            return s;
+        }
         else if (arg instanceof Iterable<?>) {
             return formatIterable(d, (Iterable<?>)arg, l);
         }
@@ -171,45 +171,74 @@
     }
 
     /**
-     * Format all the subdiagnostics attached to a given diagnostic
+     * Format all the subdiagnostics attached to a given diagnostic.
      *
      * @param d diagnostic whose subdiagnostics are to be formatted
      * @param l locale object to be used for i18n
+     * @return list of all string representations of the subdiagnostics
+     */
+    protected List<String> formatSubdiagnostics(JCDiagnostic d, Locale l) {
+        List<String> subdiagnostics = List.nil();
+        int maxDepth = config.getMultilineLimit(MultilineLimit.DEPTH);
+        if (maxDepth == -1 || depth < maxDepth) {
+            depth++;
+            try {
+                int maxCount = config.getMultilineLimit(MultilineLimit.LENGTH);
+                int count = 0;
+                for (JCDiagnostic d2 : d.getSubdiagnostics()) {
+                    if (maxCount == -1 || count < maxCount) {
+                        subdiagnostics = subdiagnostics.append(formatSubdiagnostic(d, d2, l));
+                        count++;
+                    }
+                    else
+                        break;
+                }
+            }
+            finally {
+                depth--;
+            }
+        }
+        return subdiagnostics;
+    }
+
+    /**
+     * Format a subdiagnostics attached to a given diagnostic.
+     *
+     * @param parent multiline diagnostic whose subdiagnostics is to be formatted
+     * @param sub subdiagnostic to be formatted
+     * @param l locale object to be used for i18n
      * @return string representation of the subdiagnostics
      */
-    protected String formatSubdiagnostics(JCDiagnostic d, Locale l) {
-        StringBuilder buf = new StringBuilder();
-        for (JCDiagnostic d2 : d.getSubdiagnostics()) {
-            buf.append('\n');
-            String subdiagMsg = format(d2, l);
-            buf.append(indent(subdiagMsg, DiagInc));
-        }
-        return buf.toString();
+    protected String formatSubdiagnostic(JCDiagnostic parent, JCDiagnostic sub, Locale l) {
+        return formatMessage(sub, l);
     }
 
     /** Format the faulty source code line and point to the error.
      *  @param d The diagnostic for which the error line should be printed
      */
-    protected String formatSourceLine(JCDiagnostic d) {
+    protected String formatSourceLine(JCDiagnostic d, int nSpaces) {
         StringBuilder buf = new StringBuilder();
         DiagnosticSource source = d.getDiagnosticSource();
         int pos = d.getIntPosition();
-        if (d.getIntPosition() != Position.NOPOS) {
-            String line = (source == null ? null : source.getLine(pos));
-            if (line == null)
-                return "";
-            buf.append(line+"\n");
-            int col = source.getColumnNumber(pos, false);
+        if (d.getIntPosition() == Position.NOPOS)
+            throw new AssertionError();
+        String line = (source == null ? null : source.getLine(pos));
+        if (line == null)
+            return "";
+        buf.append(indent(line, nSpaces));
+        int col = source.getColumnNumber(pos, false);
+        if (config.isCaretEnabled()) {
+            buf.append("\n");
             for (int i = 0; i < col - 1; i++)  {
                 buf.append((line.charAt(i) == '\t') ? "\t" : " ");
             }
-            buf.append("^");
-         }
-         return buf.toString();
+            buf.append(indent("^", nSpaces));
+        }
+        return buf.toString();
     }
 
     /**
-     * Converts a String into a locale-dependent representation accordingly to a given locale
+     * Converts a String into a locale-dependent representation accordingly to a given locale.
      *
      * @param l locale object to be used for i18n
      * @param key locale-independent key used for looking up in a resource file
@@ -221,7 +250,9 @@
     }
 
     public boolean displaySource(JCDiagnostic d) {
-        return showSource && d.getType() != FRAGMENT;
+        return config.getVisible().contains(DiagnosticPart.SOURCE) &&
+                d.getType() != FRAGMENT &&
+                d.getIntPosition() != Position.NOPOS;
     }
 
     /**
@@ -245,7 +276,7 @@
 
     /**
      * Indent a string by prepending a given amount of empty spaces to each line
-     * of the string
+     * of the string.
      *
      * @param s the string to be indented
      * @param nSpaces the amount of spaces that should be prepended to each line
@@ -263,4 +294,114 @@
         }
         return buf.toString();
     }
+
+    public SimpleConfiguration getConfiguration() {
+        return config;
+    }
+
+    static public class SimpleConfiguration implements Configuration {
+
+        protected Map<MultilineLimit, Integer> multilineLimits;
+        protected EnumSet<DiagnosticPart> visibleParts;
+        protected boolean caretEnabled;
+
+        public SimpleConfiguration(Set<DiagnosticPart> parts) {
+            multilineLimits = new HashMap<MultilineLimit, Integer>();
+            setVisible(parts);
+            setMultilineLimit(MultilineLimit.DEPTH, -1);
+            setMultilineLimit(MultilineLimit.LENGTH, -1);
+            setCaretEnabled(true);
+        }
+
+        @SuppressWarnings("fallthrough")
+        public SimpleConfiguration(Options options, Set<DiagnosticPart> parts) {
+            this(parts);
+            String showSource = null;
+            if ((showSource = options.get("showSource")) != null) {
+                if (showSource.equals("true"))
+                    visibleParts.add(DiagnosticPart.SOURCE);
+                else if (showSource.equals("false"))
+                    visibleParts.remove(DiagnosticPart.SOURCE);
+            }
+            String diagOpts = options.get("diags");
+            if (diagOpts != null) {//override -XDshowSource
+                Collection<String> args = Arrays.asList(diagOpts.split(","));
+                if (args.contains("short")) {
+                    visibleParts.remove(DiagnosticPart.DETAILS);
+                    visibleParts.remove(DiagnosticPart.SUBDIAGNOSTICS);
+                }
+                if (args.contains("source"))
+                    visibleParts.add(DiagnosticPart.SOURCE);
+                if (args.contains("-source"))
+                    visibleParts.remove(DiagnosticPart.SOURCE);
+            }
+            String multiPolicy = null;
+            if ((multiPolicy = options.get("multilinePolicy")) != null) {
+                if (multiPolicy.equals("disabled"))
+                    visibleParts.remove(DiagnosticPart.SUBDIAGNOSTICS);
+                else if (multiPolicy.startsWith("limit:")) {
+                    String limitString = multiPolicy.substring("limit:".length());
+                    String[] limits = limitString.split(":");
+                    try {
+                        switch (limits.length) {
+                            case 2: {
+                                if (!limits[1].equals("*"))
+                                    setMultilineLimit(MultilineLimit.DEPTH, Integer.parseInt(limits[1]));
+                            }
+                            case 1: {
+                                if (!limits[0].equals("*"))
+                                    setMultilineLimit(MultilineLimit.LENGTH, Integer.parseInt(limits[0]));
+                            }
+                        }
+                    }
+                    catch(NumberFormatException ex) {
+                        setMultilineLimit(MultilineLimit.DEPTH, -1);
+                        setMultilineLimit(MultilineLimit.LENGTH, -1);
+                    }
+                }
+            }
+            String showCaret = null;
+            if (((showCaret = options.get("showCaret")) != null) &&
+                showCaret.equals("false"))
+                    setCaretEnabled(false);
+            else
+                setCaretEnabled(true);
+        }
+
+        public int getMultilineLimit(MultilineLimit limit) {
+            return multilineLimits.get(limit);
+        }
+
+        public EnumSet<DiagnosticPart> getVisible() {
+            return EnumSet.copyOf(visibleParts);
+        }
+
+        public void setMultilineLimit(MultilineLimit limit, int value) {
+            multilineLimits.put(limit, value < -1 ? -1 : value);
+        }
+
+
+        public void setVisible(Set<DiagnosticPart> diagParts) {
+            visibleParts = EnumSet.copyOf(diagParts);
+        }
+
+        /**
+         * Shows a '^' sign under the source line displayed by the formatter
+         * (if applicable).
+         *
+         * @param caretEnabled if true enables caret
+         */
+        public void setCaretEnabled(boolean caretEnabled) {
+            this.caretEnabled = caretEnabled;
+        }
+
+        /**
+         * Tells whether the caret display is active or not.
+         *
+         * @param caretEnabled if true the caret is enabled
+         */
+        public boolean isCaretEnabled() {
+            return caretEnabled;
+        }
+    }
 }
diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java b/langtools/src/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java
index 0210245..e3cc45c 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java
@@ -25,13 +25,20 @@
 
 package com.sun.tools.javac.util;
 
+import java.util.Collection;
+import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.Locale;
 import java.util.Map;
+import java.util.regex.Matcher;
 import javax.tools.JavaFileObject;
 
-import static com.sun.tools.javac.util.BasicDiagnosticFormatter.BasicFormatKind.*;
+import com.sun.tools.javac.util.AbstractDiagnosticFormatter.SimpleConfiguration;
+import com.sun.tools.javac.util.BasicDiagnosticFormatter.BasicConfiguration;
+
 import static com.sun.tools.javac.api.DiagnosticFormatter.PositionKind.*;
+import static com.sun.tools.javac.util.BasicDiagnosticFormatter.BasicConfiguration.*;
+import static com.sun.tools.javac.util.LayoutCharacters.*;
 
 /**
  * A basic formatter for diagnostic messages.
@@ -53,7 +60,7 @@
  */
 public class BasicDiagnosticFormatter extends AbstractDiagnosticFormatter {
 
-    protected Map<BasicFormatKind, String> availableFormats;
+    protected int currentIndentation = 0;
 
     /**
      * Create a basic formatter based on the supplied options.
@@ -62,21 +69,8 @@
      * @param msgs JavacMessages object used for i18n
      */
     @SuppressWarnings("fallthrough")
-    BasicDiagnosticFormatter(Options opts, JavacMessages msgs) {
-        super(msgs, opts, true);
-        initAvailableFormats();
-        String fmt = opts.get("diags");
-        if (fmt != null) {
-            String[] formats = fmt.split("\\|");
-            switch (formats.length) {
-                case 3:
-                    availableFormats.put(DEFAULT_CLASS_FORMAT, formats[2]);
-                case 2:
-                    availableFormats.put(DEFAULT_NO_POS_FORMAT, formats[1]);
-                default:
-                    availableFormats.put(DEFAULT_POS_FORMAT, formats[0]);
-            }
-        }
+    public BasicDiagnosticFormatter(Options options, JavacMessages msgs) {
+        super(msgs, new BasicConfiguration(options));
     }
 
     /**
@@ -85,15 +79,7 @@
      * @param msgs JavacMessages object used for i18n
      */
     public BasicDiagnosticFormatter(JavacMessages msgs) {
-        super(msgs, true);
-        initAvailableFormats();
-    }
-
-    public void initAvailableFormats() {
-        availableFormats = new HashMap<BasicFormatKind, String>();
-        availableFormats.put(DEFAULT_POS_FORMAT, "%f:%l:%_%t%m");
-        availableFormats.put(DEFAULT_NO_POS_FORMAT, "%p%m");
-        availableFormats.put(DEFAULT_CLASS_FORMAT, "%f:%_%t%m");
+        super(msgs, new BasicConfiguration());
     }
 
     public String format(JCDiagnostic d, Locale l) {
@@ -110,10 +96,55 @@
             }
             buf.append(meta ? formatMeta(c, d, l) : String.valueOf(c));
         }
-        if (displaySource(d)) {
-            buf.append("\n" + formatSourceLine(d));
+        if (depth == 0)
+            return addSourceLineIfNeeded(d, buf.toString());
+        else
+            return buf.toString();
+    }
+
+    public String formatMessage(JCDiagnostic d, Locale l) {
+        int prevIndentation = currentIndentation;
+        try {
+            StringBuilder buf = new StringBuilder();
+            Collection<String> args = formatArguments(d, l);
+            String msg = localize(l, d.getCode(), args.toArray());
+            String[] lines = msg.split("\n");
+            if (getConfiguration().getVisible().contains(DiagnosticPart.SUMMARY)) {
+                currentIndentation += getConfiguration().getIndentation(DiagnosticPart.SUMMARY);
+                buf.append(indent(lines[0], currentIndentation)); //summary
+            }
+            if (lines.length > 1 && getConfiguration().getVisible().contains(DiagnosticPart.DETAILS)) {
+                currentIndentation += getConfiguration().getIndentation(DiagnosticPart.DETAILS);
+                for (int i = 1;i < lines.length; i++) {
+                    buf.append("\n" + indent(lines[i], currentIndentation));
+                }
+            }
+            if (d.isMultiline() && getConfiguration().getVisible().contains(DiagnosticPart.SUBDIAGNOSTICS)) {
+                currentIndentation += getConfiguration().getIndentation(DiagnosticPart.SUBDIAGNOSTICS);
+                for (String sub : formatSubdiagnostics(d, l)) {
+                    buf.append("\n" + sub);
+                }
+            }
+            return buf.toString();
         }
-        return buf.toString();
+        finally {
+            currentIndentation = prevIndentation;
+        }
+    }
+
+    protected String addSourceLineIfNeeded(JCDiagnostic d, String msg) {
+        if (!displaySource(d))
+            return msg;
+        else {
+            BasicConfiguration conf = getConfiguration();
+            int indentSource = conf.getIndentation(DiagnosticPart.SOURCE);
+            String sourceLine = "\n" + formatSourceLine(d, indentSource);
+            boolean singleLine = msg.indexOf("\n") == -1;
+            if (singleLine || getConfiguration().getSourcePosition() == SourcePosition.BOTTOM)
+                return msg + sourceLine;
+            else
+                return msg.replaceFirst("\n", Matcher.quoteReplacement(sourceLine) + "\n");
+        }
     }
 
     protected String formatMeta(char c, JCDiagnostic d, Locale l) {
@@ -164,34 +195,199 @@
 
     private String selectFormat(JCDiagnostic d) {
         DiagnosticSource source = d.getDiagnosticSource();
-        String format = availableFormats.get(DEFAULT_NO_POS_FORMAT);
+        String format = getConfiguration().getFormat(BasicFormatKind.DEFAULT_NO_POS_FORMAT);
         if (source != null) {
             if (d.getIntPosition() != Position.NOPOS) {
-                format = availableFormats.get(DEFAULT_POS_FORMAT);
+                format = getConfiguration().getFormat(BasicFormatKind.DEFAULT_POS_FORMAT);
             } else if (source.getFile() != null &&
                        source.getFile().getKind() == JavaFileObject.Kind.CLASS) {
-                format = availableFormats.get(DEFAULT_CLASS_FORMAT);
+                format = getConfiguration().getFormat(BasicFormatKind.DEFAULT_CLASS_FORMAT);
             }
         }
         return format;
     }
 
-    /**
-     * This enum contains all the kinds of formatting patterns supported
-     * by a basic diagnostic formatter.
-     */
-    public enum BasicFormatKind {
+    @Override
+    public BasicConfiguration getConfiguration() {
+        return (BasicConfiguration)super.getConfiguration();
+    }
+
+    static public class BasicConfiguration extends SimpleConfiguration {
+
+        protected Map<DiagnosticPart, Integer> indentationLevels;
+        protected Map<BasicFormatKind, String> availableFormats;
+        protected SourcePosition sourcePosition;
+
+        @SuppressWarnings("fallthrough")
+        public BasicConfiguration(Options options) {
+            super(options, EnumSet.of(DiagnosticPart.SUMMARY,
+                            DiagnosticPart.DETAILS,
+                            DiagnosticPart.SUBDIAGNOSTICS,
+                            DiagnosticPart.SOURCE));
+            initFormat();
+            initIndentation();
+            String fmt = options.get("diagsFormat");
+            if (fmt != null) {
+                String[] formats = fmt.split("\\|");
+                switch (formats.length) {
+                    case 3:
+                        setFormat(BasicFormatKind.DEFAULT_CLASS_FORMAT, formats[2]);
+                    case 2:
+                        setFormat(BasicFormatKind.DEFAULT_NO_POS_FORMAT, formats[1]);
+                    default:
+                        setFormat(BasicFormatKind.DEFAULT_POS_FORMAT, formats[0]);
+                }
+            }
+            String sourcePosition = null;
+            if ((((sourcePosition = options.get("sourcePosition")) != null)) &&
+                    sourcePosition.equals("bottom"))
+                    setSourcePosition(SourcePosition.BOTTOM);
+            else
+                setSourcePosition(SourcePosition.AFTER_SUMMARY);
+            String indent = options.get("diagsIndentation");
+            if (indent != null) {
+                String[] levels = indent.split("\\|");
+                try {
+                    switch (levels.length) {
+                        case 5:
+                            setIndentation(DiagnosticPart.JLS,
+                                    Integer.parseInt(levels[4]));
+                        case 4:
+                            setIndentation(DiagnosticPart.SUBDIAGNOSTICS,
+                                    Integer.parseInt(levels[3]));
+                        case 3:
+                            setIndentation(DiagnosticPart.SOURCE,
+                                    Integer.parseInt(levels[2]));
+                        case 2:
+                            setIndentation(DiagnosticPart.DETAILS,
+                                    Integer.parseInt(levels[1]));
+                        default:
+                            setIndentation(DiagnosticPart.SUMMARY,
+                                    Integer.parseInt(levels[0]));
+                    }
+                }
+                catch (NumberFormatException ex) {
+                    initIndentation();
+                }
+            }
+        }
+
+        public BasicConfiguration() {
+            super(EnumSet.of(DiagnosticPart.SUMMARY,
+                  DiagnosticPart.DETAILS,
+                  DiagnosticPart.SUBDIAGNOSTICS,
+                  DiagnosticPart.SOURCE));
+            initFormat();
+            initIndentation();
+        }
+        //where
+        private void initFormat() {
+            availableFormats = new HashMap<BasicFormatKind, String>();
+            setFormat(BasicFormatKind.DEFAULT_POS_FORMAT, "%f:%l:%_%t%m");
+            setFormat(BasicFormatKind.DEFAULT_NO_POS_FORMAT, "%p%m");
+            setFormat(BasicFormatKind.DEFAULT_CLASS_FORMAT, "%f:%_%t%m");
+        }
+        //where
+        private void initIndentation() {
+            indentationLevels = new HashMap<DiagnosticPart, Integer>();
+            setIndentation(DiagnosticPart.SUMMARY, 0);
+            setIndentation(DiagnosticPart.DETAILS, DetailsInc);
+            setIndentation(DiagnosticPart.SUBDIAGNOSTICS, DiagInc);
+            setIndentation(DiagnosticPart.SOURCE, 0);
+        }
+
         /**
-        * A format string to be used for diagnostics with a given position.
-        */
-        DEFAULT_POS_FORMAT,
+         * Get the amount of spaces for a given indentation kind
+         * @param diagPart the diagnostic part for which the indentation is
+         * to be retrieved
+         * @return the amount of spaces used for the specified indentation kind
+         */
+        public int getIndentation(DiagnosticPart diagPart) {
+            return indentationLevels.get(diagPart);
+        }
+
         /**
-        * A format string to be used for diagnostics without a given position.
-        */
-        DEFAULT_NO_POS_FORMAT,
+         * Set the indentation level for various element of a given diagnostic -
+         * this might lead to more readable diagnostics
+         *
+         * @param indentationKind kind of indentation to be set
+         * @param nSpaces amount of spaces for the specified diagnostic part
+         */
+        public void setIndentation(DiagnosticPart diagPart, int nSpaces) {
+            indentationLevels.put(diagPart, nSpaces);
+        }
+
         /**
-        * A format string to be used for diagnostics regarding classfiles
-        */
-        DEFAULT_CLASS_FORMAT;
+         * Set the source line positioning used by this formatter
+         *
+         * @param sourcePos a positioning value for source line
+         */
+        public void setSourcePosition(SourcePosition sourcePos) {
+            sourcePosition = sourcePos;
+        }
+
+        /**
+         * Get the source line positioning used by this formatter
+         *
+         * @return the positioning value used by this formatter
+         */
+        public SourcePosition getSourcePosition() {
+            return sourcePosition;
+        }
+        //where
+        /**
+         * A source positioning value controls the position (within a given
+         * diagnostic message) in which the source line the diagnostic refers to
+         * should be displayed (if applicable)
+         */
+        public enum SourcePosition {
+            /**
+             * Source line is displayed after the diagnostic message
+             */
+            BOTTOM,
+            /**
+             * Source line is displayed after the first line of the diagnostic
+             * message
+             */
+            AFTER_SUMMARY;
+        }
+
+        /**
+         * Set a metachar string for a specific format
+         *
+         * @param kind the format kind to be set
+         * @param s the metachar string specifying the format
+         */
+        public void setFormat(BasicFormatKind kind, String s) {
+            availableFormats.put(kind, s);
+        }
+
+        /**
+         * Get a metachar string for a specific format
+         *
+         * @param sourcePos a positioning value for source line
+         */
+        public String getFormat(BasicFormatKind kind) {
+            return availableFormats.get(kind);
+        }
+        //where
+        /**
+         * This enum contains all the kinds of formatting patterns supported
+         * by a basic diagnostic formatter.
+         */
+        public enum BasicFormatKind {
+            /**
+            * A format string to be used for diagnostics with a given position.
+            */
+            DEFAULT_POS_FORMAT,
+            /**
+            * A format string to be used for diagnostics without a given position.
+            */
+            DEFAULT_NO_POS_FORMAT,
+            /**
+            * A format string to be used for diagnostics regarding classfiles
+            */
+            DEFAULT_CLASS_FORMAT;
+        }
     }
 }
diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/LayoutCharacters.java b/langtools/src/share/classes/com/sun/tools/javac/util/LayoutCharacters.java
index 7e332eb..b6f275f 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/util/LayoutCharacters.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/LayoutCharacters.java
@@ -39,9 +39,13 @@
      */
     final static int TabInc = 8;
 
-    /** Diagnostic standard indentation
+    /** Standard indentation for subdiagnostics
      */
-    final static int DiagInc = 2;
+    final static int DiagInc = 4;
+
+    /** Standard indentation for additional diagnostic lines
+     */
+    final static int DetailsInc = 2;
 
     /** Tabulator character.
      */
diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/Log.java b/langtools/src/share/classes/com/sun/tools/javac/util/Log.java
index e7359a3..e22f615 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/util/Log.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/Log.java
@@ -93,17 +93,17 @@
     protected DiagnosticListener<? super JavaFileObject> diagListener;
 
     /**
-     * Formatter for diagnostics
+     * Formatter for diagnostics.
      */
     private DiagnosticFormatter<JCDiagnostic> diagFormatter;
 
     /**
-     * Keys for expected diagnostics
+     * Keys for expected diagnostics.
      */
     public Set<String> expectDiagKeys;
 
     /**
-     * JavacMessages object used for localization
+     * JavacMessages object used for localization.
      */
     private JavacMessages messages;
 
@@ -206,6 +206,18 @@
         return source == null ? null : source.getFile();
     }
 
+    /** Get the current diagnostic formatter.
+     */
+    public DiagnosticFormatter<JCDiagnostic> getDiagnosticFormatter() {
+        return diagFormatter;
+    }
+
+    /** Set the current diagnostic formatter.
+     */
+    public void setDiagnosticFormatter(DiagnosticFormatter<JCDiagnostic> diagFormatter) {
+        this.diagFormatter = diagFormatter;
+    }
+
     /** Flush the logs
      */
     public void flush() {
diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/RawDiagnosticFormatter.java b/langtools/src/share/classes/com/sun/tools/javac/util/RawDiagnosticFormatter.java
index 4337797..db05a73 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/util/RawDiagnosticFormatter.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/RawDiagnosticFormatter.java
@@ -24,9 +24,14 @@
  */
 package com.sun.tools.javac.util;
 
+import java.util.Collection;
+import java.util.EnumSet;
 import java.util.Locale;
 
+import com.sun.tools.javac.api.DiagnosticFormatter.Configuration.*;
 import com.sun.tools.javac.api.Formattable;
+import com.sun.tools.javac.util.AbstractDiagnosticFormatter.SimpleConfiguration;
+
 import static com.sun.tools.javac.api.DiagnosticFormatter.PositionKind.*;
 
 /**
@@ -35,14 +40,17 @@
  * or not the source name and position are set. This formatter provides a standardized, localize-independent
  * implementation of a diagnostic formatter; as such, this formatter is best suited for testing purposes.
  */
-public class RawDiagnosticFormatter extends AbstractDiagnosticFormatter {
+public final class RawDiagnosticFormatter extends AbstractDiagnosticFormatter {
 
     /**
      * Create a formatter based on the supplied options.
      * @param msgs
      */
-    public RawDiagnosticFormatter(Options opts) {
-        super(null, opts, false);
+    public RawDiagnosticFormatter(Options options) {
+        super(null, new SimpleConfiguration(options,
+                EnumSet.of(DiagnosticPart.SUMMARY,
+                        DiagnosticPart.DETAILS,
+                        DiagnosticPart.SUBDIAGNOSTICS)));
     }
 
     //provide common default formats
@@ -62,7 +70,7 @@
             buf.append(' ');
             buf.append(formatMessage(d, null));
             if (displaySource(d))
-                buf.append("\n" + formatSourceLine(d));
+                buf.append("\n" + formatSourceLine(d, 0));
             return buf.toString();
         }
         catch (Exception e) {
@@ -71,6 +79,32 @@
         }
     }
 
+    public String formatMessage(JCDiagnostic d, Locale l) {
+        StringBuilder buf = new StringBuilder();
+        Collection<String> args = formatArguments(d, l);
+        buf.append(d.getCode());
+        String sep = ": ";
+        for (Object o : args) {
+            buf.append(sep);
+            buf.append(o);
+            sep = ", ";
+        }
+        if (d.isMultiline() && getConfiguration().getVisible().contains(DiagnosticPart.SUBDIAGNOSTICS)) {
+            List<String> subDiags = formatSubdiagnostics(d, null);
+            if (subDiags.nonEmpty()) {
+                sep = "";
+                buf.append(",{");
+                for (String sub : formatSubdiagnostics(d, null)) {
+                    buf.append(sep);
+                    buf.append("(" + sub + ")");
+                    sep = ",";
+                }
+                buf.append('}');
+            }
+        }
+        return buf.toString();
+    }
+
     @Override
     protected String formatArgument(JCDiagnostic diag, Object arg, Locale l) {
         String s;
@@ -83,31 +117,4 @@
         else
             return s;
     }
-
-    @Override
-    protected String formatSubdiagnostics(JCDiagnostic d, Locale l) {
-        StringBuilder buf = new StringBuilder();
-        String sep = "";
-        buf.append(",{");
-        for (JCDiagnostic d2 : d.getSubdiagnostics()) {
-            buf.append(sep);
-            buf.append("(" + format(d2, l) + ")");
-            sep = ",";
-        }
-        buf.append('}');
-        return buf.toString();
-    }
-
-    @Override
-    protected String localize(Locale l, String s, Object... args) {
-        StringBuffer buf = new StringBuffer();
-        buf.append(s);
-        String sep = ": ";
-        for (Object o : args) {
-            buf.append(sep);
-            buf.append(o);
-            sep = ", ";
-        }
-        return buf.toString();
-    }
 }
diff --git a/langtools/src/share/classes/javax/lang/model/element/ExecutableElement.java b/langtools/src/share/classes/javax/lang/model/element/ExecutableElement.java
index 180f23b..427373f 100644
--- a/langtools/src/share/classes/javax/lang/model/element/ExecutableElement.java
+++ b/langtools/src/share/classes/javax/lang/model/element/ExecutableElement.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2005-2009 Sun Microsystems, Inc.  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,7 +40,7 @@
  * @see ExecutableType
  * @since 1.6
  */
-public interface ExecutableElement extends Element {
+public interface ExecutableElement extends Element, Parameterizable {
     /**
      * Returns the formal type parameters of this executable
      * in declaration order.
diff --git a/langtools/src/share/classes/javax/lang/model/element/PackageElement.java b/langtools/src/share/classes/javax/lang/model/element/PackageElement.java
index 56df80a..e6b74e2 100644
--- a/langtools/src/share/classes/javax/lang/model/element/PackageElement.java
+++ b/langtools/src/share/classes/javax/lang/model/element/PackageElement.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2005-2009 Sun Microsystems, Inc.  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
@@ -25,7 +25,6 @@
 
 package javax.lang.model.element;
 
-
 /**
  * Represents a package program element.  Provides access to information
  * about the package and its members.
@@ -36,8 +35,7 @@
  * @see javax.lang.model.util.Elements#getPackageOf
  * @since 1.6
  */
-
-public interface PackageElement extends Element {
+public interface PackageElement extends Element, QualifiedNameable {
 
     /**
      * Returns the fully qualified name of this package.
diff --git a/langtools/src/share/classes/javax/lang/model/element/Parameterizable.java b/langtools/src/share/classes/javax/lang/model/element/Parameterizable.java
new file mode 100644
index 0000000..cc428b2
--- /dev/null
+++ b/langtools/src/share/classes/javax/lang/model/element/Parameterizable.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package javax.lang.model.element;
+
+import java.util.List;
+
+/**
+ * A mixin interface for an element that has type parameters.
+ *
+ * @author Joseph D. Darcy
+ * @since 1.7
+ */
+public interface Parameterizable extends Element {
+    /**
+     * Returns the formal type parameters of the type element in
+     * declaration order.
+     *
+     * @return the formal type parameters, or an empty list
+     * if there are none
+     */
+    List<? extends TypeParameterElement> getTypeParameters();
+}
diff --git a/langtools/src/share/classes/javax/lang/model/element/QualifiedNameable.java b/langtools/src/share/classes/javax/lang/model/element/QualifiedNameable.java
new file mode 100644
index 0000000..a6096bf
--- /dev/null
+++ b/langtools/src/share/classes/javax/lang/model/element/QualifiedNameable.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package javax.lang.model.element;
+
+/**
+ * A mixin interface for an element that has a qualified name.
+ *
+ * @author Joseph D. Darcy
+ * @since 1.7
+ */
+public interface QualifiedNameable extends Element {
+    /**
+     * Returns the fully qualified name of an element.
+     *
+     * @return the fully qualified name of an element
+     */
+    Name getQualifiedName();
+}
diff --git a/langtools/src/share/classes/javax/lang/model/element/TypeElement.java b/langtools/src/share/classes/javax/lang/model/element/TypeElement.java
index 235a252..808ac77 100644
--- a/langtools/src/share/classes/javax/lang/model/element/TypeElement.java
+++ b/langtools/src/share/classes/javax/lang/model/element/TypeElement.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2005-2009 Sun Microsystems, Inc.  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
@@ -59,7 +59,7 @@
  * @see DeclaredType
  * @since 1.6
  */
-public interface TypeElement extends Element {
+public interface TypeElement extends Element, Parameterizable, QualifiedNameable {
 
     /**
      * Returns the <i>nesting kind</i> of this type element.
diff --git a/langtools/test/com/sun/javadoc/testSerializedFormDeprecationInfo/TestSerializedFormDeprecationInfo.java b/langtools/test/com/sun/javadoc/testSerializedFormDeprecationInfo/TestSerializedFormDeprecationInfo.java
new file mode 100644
index 0000000..d4f5294
--- /dev/null
+++ b/langtools/test/com/sun/javadoc/testSerializedFormDeprecationInfo/TestSerializedFormDeprecationInfo.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6802694
+ * @summary This test verifies deprecation info in serialized-form.html.
+ * @author Bhavesh Patel
+ * @library ../lib/
+ * @build JavadocTester
+ * @build TestSerializedFormDeprecationInfo
+ * @run main TestSerializedFormDeprecationInfo
+ */
+
+public class TestSerializedFormDeprecationInfo extends JavadocTester {
+
+    private static final String BUG_ID = "6802694";
+
+    // Test for normal run of javadoc. The serialized-form.html should
+    // display the inline comments, tags and deprecation information if any.
+    private static final String[][] TEST_CMNT_DEPR = {
+        {BUG_ID + FS + "serialized-form.html", "<DL>" + NL + "<DD><DL>" + NL + NL +
+                 "<DT><STRONG>Throws:</STRONG>" + NL + "<DD><CODE>" +
+                 "java.io.IOException</CODE><DT><STRONG>See Also:</STRONG>" +
+                 "<DD><A HREF=\"pkg1/C1.html#setUndecorated(boolean)\">" +
+                 "<CODE>C1.setUndecorated(boolean)</CODE></A></DD>" + NL +
+                 "</DL>" + NL + "</DL>"},
+        {BUG_ID + FS + "serialized-form.html", "<DL>" + NL +
+                 "<DD><STRONG>Deprecated.</STRONG>&nbsp;<I>As of JDK version" +
+                 " 1.5, replaced by" + NL +
+                 " <A HREF=\"pkg1/C1.html#setUndecorated(boolean)\">" +
+                 "<CODE>setUndecorated(boolean)</CODE></A>.</I>" +
+                 "<DD>This field indicates whether the C1 is undecorated." + NL +
+                 "<P>" + NL + "<DT><DD>&nbsp;<DL>" + NL +
+                 "<DT><STRONG>Since:</STRONG></DT>" + NL +
+                 "  <DD>1.4</DD>" + NL + "<DT><STRONG>See Also:</STRONG>" +
+                 "<DD><A HREF=\"pkg1/C1.html#setUndecorated(boolean)\">" +
+                 "<CODE>C1.setUndecorated(boolean)</CODE></A></DL>" + NL +
+                 "</DL>"},
+        {BUG_ID + FS + "serialized-form.html", "<DL>" + NL +
+                 "<DD><STRONG>Deprecated.</STRONG>&nbsp;<I>As of JDK version" +
+                 " 1.5, replaced by" + NL +
+                 " <A HREF=\"pkg1/C1.html#setUndecorated(boolean)\">" +
+                 "<CODE>setUndecorated(boolean)</CODE></A>.</I>" + NL + "<P>" + NL +
+                 "<DD>Reads the object stream." + NL + "<P>" + NL +
+                 "<DD><DL>" + NL + NL + "<DT><STRONG>Throws:" +
+                 "</STRONG>" + NL + "<DD><CODE><code>" +
+                 "IOException</code></CODE>" + NL +
+                 "<DD><CODE>java.io.IOException</CODE></DD>" + NL +
+                 "</DL>" + NL + "</DL>"},
+        {BUG_ID + FS + "serialized-form.html", "<DL>" + NL +
+                 "<DD><STRONG>Deprecated.</STRONG>&nbsp;<DD>" +
+                 "The name for this class." + NL + "<P>" + NL +
+                 "<DT><DD>&nbsp;<DL>" + NL + "</DL>" + NL + "</DL>"}};
+
+    // Test with -nocomment option. The serialized-form.html should
+    // not display the inline comments and tags but should display deprecation
+    // information if any.
+    private static final String[][] TEST_NOCMNT = {
+        {BUG_ID + FS + "serialized-form.html", "<PRE>" + NL + "boolean <STRONG>" +
+                 "undecorated</STRONG></PRE>" + NL + "<DL>" + NL + "<DD><STRONG>" +
+                 "Deprecated.</STRONG>&nbsp;<I>As of JDK version 1.5, replaced by" + NL +
+                 " <A HREF=\"pkg1/C1.html#setUndecorated(boolean)\"><CODE>" +
+                 "setUndecorated(boolean)</CODE></A>.</I></DL>"},
+        {BUG_ID + FS + "serialized-form.html", "<DL>" + NL + "<DD><STRONG>" +
+                 "Deprecated.</STRONG>&nbsp;<I>As of JDK version" +
+                 " 1.5, replaced by" + NL +
+                 " <A HREF=\"pkg1/C1.html#setUndecorated(boolean)\">" +
+                 "<CODE>setUndecorated(boolean)</CODE></A>.</I>" + NL + "<P>" + NL +
+                 "</DL>"},
+        {BUG_ID + FS + "serialized-form.html", "<PRE>" + NL + "int <STRONG>" +
+                 "publicKey</STRONG></PRE>" + NL + "<DL>" + NL + "<DD><STRONG>" +
+                 "Deprecated.</STRONG>&nbsp;</DL>"}};
+
+    // Test with -nodeprecated option. The serialized-form.html should
+    // ignore the -nodeprecated tag and display the deprecation info. This
+    // test is similar to the normal run of javadoc in which inline comment, tags
+    // and deprecation information will be displayed.
+    private static final String[][] TEST_NODEPR = TEST_CMNT_DEPR;
+
+    // Test with -nodeprecated and -nocomment options. The serialized-form.html should
+    // ignore the -nodeprecated tag and display the deprecation info but should not
+    // display the inline comments and tags. This test is similar to the test with
+    // -nocomment option.
+    private static final String[][] TEST_NOCMNT_NODEPR = TEST_NOCMNT;
+
+    private static final String[] ARGS1 =
+        new String[] {
+            "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg1"};
+
+    private static final String[] ARGS2 =
+        new String[] {
+            "-d", BUG_ID, "-nocomment", "-sourcepath", SRC_DIR, "pkg1"};
+
+    private static final String[] ARGS3 =
+        new String[] {
+            "-d", BUG_ID, "-nodeprecated", "-sourcepath", SRC_DIR, "pkg1"};
+
+    private static final String[] ARGS4 =
+        new String[] {
+            "-d", BUG_ID, "-nocomment", "-nodeprecated", "-sourcepath", SRC_DIR, "pkg1"};
+
+    /**
+     * The entry point of the test.
+     * @param args the array of command line arguments.
+     */
+    public static void main(String[] args) {
+        TestSerializedFormDeprecationInfo tester = new TestSerializedFormDeprecationInfo();
+        run(tester, ARGS1, TEST_CMNT_DEPR, TEST_NOCMNT);
+        run(tester, ARGS2, TEST_NOCMNT, TEST_CMNT_DEPR);
+        run(tester, ARGS3, TEST_NODEPR, TEST_NOCMNT_NODEPR);
+        run(tester, ARGS4, TEST_NOCMNT_NODEPR, TEST_NODEPR);
+        tester.printSummary();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getBugId() {
+        return BUG_ID;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getBugName() {
+        return getClass().getName();
+    }
+}
diff --git a/langtools/test/com/sun/javadoc/testSerializedFormDeprecationInfo/pkg1/C1.java b/langtools/test/com/sun/javadoc/testSerializedFormDeprecationInfo/pkg1/C1.java
new file mode 100644
index 0000000..a3dbc13
--- /dev/null
+++ b/langtools/test/com/sun/javadoc/testSerializedFormDeprecationInfo/pkg1/C1.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package pkg1;
+
+import java.io.IOException;
+import java.io.Serializable;
+
+/**
+ * A class comment for testing.
+ *
+ * @author      Bhavesh Patel
+ * @see C2
+ * @since       JDK1.0
+ */
+
+public class C1 implements Serializable {
+
+    /**
+     * This field indicates whether the C1 is undecorated.
+     *
+     * @see #setUndecorated(boolean)
+     * @since 1.4
+     * @serial
+     * @deprecated As of JDK version 1.5, replaced by
+     * {@link C1#setUndecorated(boolean) setUndecorated(boolean)}.
+     */
+     @Deprecated
+    public boolean undecorated = false;
+
+    private String title;
+
+    /**
+     * This enum specifies the possible modal exclusion types.
+     *
+     * @since 1.6
+     */
+    public static enum ModalExclusionType {
+        /**
+         * No modal exclusion.
+         */
+        NO_EXCLUDE,
+        /**
+         * <code>APPLICATION_EXCLUDE</code> indicates that a top-level window
+         * won't be blocked by any application-modal dialogs. Also, it isn't
+         * blocked by document-modal dialogs from outside of its child hierarchy.
+         */
+        APPLICATION_EXCLUDE
+    };
+
+    /**
+     * Constructor.
+     *
+     * @param title the title
+     * @param test boolean value
+     * @exception IllegalArgumentException if the <code>owner</code>'s
+     *     <code>GraphicsConfiguration</code> is not from a screen device
+     * @exception HeadlessException
+     */
+     public C1(String title, boolean test) {
+
+     }
+
+     public C1(String title) {
+
+     }
+
+    /**
+     * Method comments.
+     * @param  undecorated <code>true</code> if no decorations are
+     *         to be enabled;
+     *         <code>false</code> if decorations are to be enabled.
+     * @see    #readObject()
+     * @since 1.4
+     */
+    public void setUndecorated(boolean undecorated) {
+        /* Make sure we don't run in the middle of peer creation.*/
+    }
+
+    /**
+     * @see #setUndecorated(boolean)
+     */
+    public void readObject() throws IOException {
+
+    }
+}
diff --git a/langtools/test/com/sun/javadoc/testSerializedFormDeprecationInfo/pkg1/C2.java b/langtools/test/com/sun/javadoc/testSerializedFormDeprecationInfo/pkg1/C2.java
new file mode 100644
index 0000000..b0e098d
--- /dev/null
+++ b/langtools/test/com/sun/javadoc/testSerializedFormDeprecationInfo/pkg1/C2.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package pkg1;
+
+import java.io.ObjectInputStream;
+import java.io.IOException;
+import java.io.Serializable;
+
+/**
+ * A class comment for testing.
+ *
+ * @author      Bhavesh Patel
+ * @see C1
+ * @since       JDK1.0
+ */
+
+public class C2 implements Serializable {
+
+    /**
+     * This field indicates title.
+     */
+    String title;
+
+    public static enum ModalType {
+        NO_EXCLUDE
+    };
+
+    /**
+     * Constructor.
+     *
+     */
+     public C2() {
+
+     }
+
+     public C2(String title) {
+
+     }
+
+     /**
+     * Set visible.
+     *
+     * @param set boolean
+     * @since 1.4
+     * @deprecated As of JDK version 1.5, replaced by
+     * {@link C1#setUndecorated(boolean) setUndecorated(boolean)}.
+     */
+     @Deprecated
+     public void setVisible(boolean set) {
+     }
+
+     /**
+     * Reads the object stream.
+     *
+     * @param s ObjectInputStream
+     * @throws <code>IOException</code>
+     * @deprecated As of JDK version 1.5, replaced by
+     * {@link C1#setUndecorated(boolean) setUndecorated(boolean)}.
+     */
+     @Deprecated
+     public void readObject(ObjectInputStream s) throws IOException {
+     }
+}
diff --git a/langtools/test/com/sun/javadoc/testSerializedFormDeprecationInfo/pkg1/C3.java b/langtools/test/com/sun/javadoc/testSerializedFormDeprecationInfo/pkg1/C3.java
new file mode 100644
index 0000000..918a674
--- /dev/null
+++ b/langtools/test/com/sun/javadoc/testSerializedFormDeprecationInfo/pkg1/C3.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package pkg1;
+
+import java.io.Serializable;
+
+/**
+ * Test for Serializable
+ *
+ * @author Bhavesh Patel
+ * @deprecated This class is no longer used.
+ */
+@Deprecated
+public abstract class C3 implements Serializable {
+
+    /**
+     * The name for this class.
+     *
+     * @serial
+     */
+    private String name;
+
+    /**
+     * @serial
+     */
+    private int publicKey;
+
+    /**
+     * Constructor for serialization only.
+     */
+    protected C3() {
+
+    }
+
+    /**
+     * Prints general information.
+     *
+     */
+    public void printInfo() {
+
+    }
+}
diff --git a/langtools/test/tools/javac/6304921/T6304921.out b/langtools/test/tools/javac/6304921/T6304921.out
index d69e1bd..7a18b05 100644
--- a/langtools/test/tools/javac/6304921/T6304921.out
+++ b/langtools/test/tools/javac/6304921/T6304921.out
@@ -1,18 +1,18 @@
 T6304921.java:671/671/680: warning: [rawtypes] found raw type: java.util.ArrayList
-missing type parameters for generic class java.util.ArrayList<E>
         List<Integer> list = new ArrayList();
                                  ^
+  missing type parameters for generic class java.util.ArrayList<E>
 T6304921.java:667/667/682: warning: [unchecked] unchecked conversion
-found   : java.util.ArrayList
-required: java.util.List<java.lang.Integer>
         List<Integer> list = new ArrayList();
                              ^
+  required: java.util.List<java.lang.Integer>
+  found:    java.util.ArrayList
 error: warnings found and -Werror specified
 T6304921.java:727/733/737: cannot find symbol
-symbol  : variable orr
-location: class java.lang.System
         System.orr.println("abc"); // name not found
               ^
+  symbol:   variable orr
+  location: class java.lang.System
 T6304921.java:812/816/822: operator + cannot be applied to int,boolean
         return 123 + true; // bad binary expression
                    ^
diff --git a/langtools/test/tools/javac/6668794/badClass/Test.java b/langtools/test/tools/javac/6668794/badClass/Test.java
index 40e514f..e78ce5f 100644
--- a/langtools/test/tools/javac/6668794/badClass/Test.java
+++ b/langtools/test/tools/javac/6668794/badClass/Test.java
@@ -54,8 +54,8 @@
             throw new Error("no diagnostics generated");
 
         String expected = "B.java:6:6: compiler.err.cant.access: p.A, " +
-            "(- compiler.misc.bad.class.file.header: A.class, " +
-            "(- compiler.misc.class.file.wrong.class: q.A))";
+            "(compiler.misc.bad.class.file.header: A.class, " +
+            "(compiler.misc.class.file.wrong.class: q.A))";
 
         if (!out[0].equals(expected)) {
             System.err.println("expected: " + expected);
diff --git a/langtools/test/tools/javac/6668794/badSource/Test.out b/langtools/test/tools/javac/6668794/badSource/Test.out
index e9fbdf9..94e1416 100644
--- a/langtools/test/tools/javac/6668794/badSource/Test.out
+++ b/langtools/test/tools/javac/6668794/badSource/Test.out
@@ -1 +1 @@
-Test.java:10:6: compiler.err.cant.access: p.A, (- compiler.misc.bad.source.file.header: A.java, (- compiler.misc.file.doesnt.contain.class: p.A))
+Test.java:10:6: compiler.err.cant.access: p.A, (compiler.misc.bad.source.file.header: A.java, (compiler.misc.file.doesnt.contain.class: p.A))
diff --git a/langtools/test/tools/javac/6758789/T6758789b.out b/langtools/test/tools/javac/6758789/T6758789b.out
index eae65eb..af29552 100644
--- a/langtools/test/tools/javac/6758789/T6758789b.out
+++ b/langtools/test/tools/javac/6758789/T6758789b.out
@@ -1,4 +1,4 @@
-T6758789b.java:39:11: compiler.warn.prob.found.req: (- compiler.misc.unchecked.assign), T6758789a.Foo, T6758789a.Foo<X>
+T6758789b.java:39:11: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T6758789a.Foo, T6758789a.Foo<X>
 T6758789b.java:39:10: compiler.warn.unchecked.meth.invocation.applied: kindname.method, m, T6758789a.Foo<X>, T6758789a.Foo, kindname.class, T6758789a
 - compiler.err.warnings.and.werror
 1 error
diff --git a/langtools/test/tools/javac/Diagnostics/6769027/T6769027.java b/langtools/test/tools/javac/Diagnostics/6769027/T6769027.java
new file mode 100644
index 0000000..6ede4dc
--- /dev/null
+++ b/langtools/test/tools/javac/Diagnostics/6769027/T6769027.java
@@ -0,0 +1,499 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug     6769027
+ * @summary Source line should be displayed immediately after the first diagnostic line
+ * @author  Maurizio Cimadamore
+ * @run main/othervm T6769027
+ */
+import java.net.URI;
+import java.util.regex.Matcher;
+import javax.tools.*;
+import com.sun.tools.javac.util.*;
+
+public class T6769027 {
+
+    enum OutputKind {
+        RAW("rawDiagnostics","rawDiagnostics"),
+        BASIC("","");
+
+        String key;
+        String value;
+
+        void init(Options opts) {
+            opts.put(key, value);
+        }
+
+        OutputKind(String key, String value) {
+            this.key = key;
+            this.value = value;
+        }
+    }
+
+    enum CaretKind {
+        DEFAULT("", ""),
+        SHOW("showCaret","true"),
+        HIDE("showCaret","false");
+
+        String key;
+        String value;
+
+        void init(Options opts) {
+            opts.put(key, value);
+        }
+
+        CaretKind(String key, String value) {
+            this.key = key;
+            this.value = value;
+        }
+
+        boolean isEnabled() {
+            return this == DEFAULT || this == SHOW;
+        }
+    }
+
+    enum SourceLineKind {
+        DEFAULT("", ""),
+        AFTER_SUMMARY("sourcePosition", "top"),
+        BOTTOM("sourcePosition", "bottom");
+
+        String key;
+        String value;
+
+        void init(Options opts) {
+            opts.put(key, value);
+        }
+
+        SourceLineKind(String key, String value) {
+            this.key = key;
+            this.value = value;
+        }
+
+        boolean isAfterSummary() {
+            return this == DEFAULT || this == AFTER_SUMMARY;
+        }
+    }
+
+    enum XDiagsSource {
+        DEFAULT(""),
+        SOURCE("source"),
+        NO_SOURCE("-source");
+
+        String flag;
+
+        void init(Options opts) {
+            if (this != DEFAULT) {
+                String flags = opts.get("diags");
+                flags = flags == null ? flag : flags + "," + flag;
+                opts.put("diags", flags);
+            }
+        }
+
+        XDiagsSource(String flag) {
+            this.flag = flag;
+        }
+
+        String getOutput(CaretKind caretKind, IndentKind indent, OutputKind outKind) {
+            String spaces = (outKind == OutputKind.BASIC) ? indent.string : "";
+            return "\n" + spaces + "This is a source line" +
+                   (caretKind.isEnabled() ? "\n" + spaces + "     ^" : "");
+        }
+    }
+
+    enum XDiagsCompact {
+        DEFAULT(""),
+        COMPACT("short"),
+        NO_COMPACT("-short");
+
+        String flag;
+
+        void init(Options opts) {
+            if (this != DEFAULT) {
+                String flags = opts.get("diags");
+                flags = flags == null ? flag : flags + "," + flag;
+                opts.put("diags", flags);
+            }
+        }
+
+        XDiagsCompact(String flag) {
+            this.flag = flag;
+        }
+    }
+
+    enum ErrorKind {
+        SINGLE("single",
+            "compiler.err.single: Hello!",
+            "KXThis is a test error message Hello!"),
+        DOUBLE("double",
+            "compiler.err.double: Hello!",
+            "KXThis is a test error message.\n" +
+            "KXYThis is another line of the above error message Hello!");
+
+        String key;
+        String rawOutput;
+        String nonRawOutput;
+
+        String key() {
+            return key;
+        }
+
+        ErrorKind(String key, String rawOutput, String nonRawOutput) {
+            this.key = key;
+            this.rawOutput = rawOutput;
+            this.nonRawOutput = nonRawOutput;
+        }
+
+        String getOutput(OutputKind outKind, IndentKind summaryIndent, IndentKind detailsIndent) {
+            return outKind == OutputKind.RAW ?
+                rawOutput :
+                nonRawOutput.replace("X", summaryIndent.string).replace("Y", detailsIndent.string).replace("K", "");
+        }
+
+        String getOutput(OutputKind outKind, IndentKind summaryIndent, IndentKind detailsIndent, String indent) {
+            return outKind == OutputKind.RAW ?
+                rawOutput :
+                nonRawOutput.replace("X", summaryIndent.string).replace("Y", detailsIndent.string).replace("K", indent);
+        }
+    }
+
+    enum MultilineKind {
+        NONE(0),
+        DOUBLE(1),
+        NESTED(2),
+        DOUBLE_NESTED(3);
+
+        static String[][] rawTemplates = {
+            {"", ",{(E),(E)}", ",{(E,{(E)})}", ",{(E,{(E)}),(E,{(E)})}"}, //ENABLED
+            {"", "", "", "",""}, //DISABLED
+            {"", ",{(E)}", ",{(E,{(E)})}", ",{(E,{(E)})}"}, //LIMIT_LENGTH
+            {"", ",{(E),(E)}", ",{(E)}", ",{(E),(E)}"}, //LIMIT_DEPTH
+            {"", ",{(E)}", ",{(E)}", ",{(E)}"}}; //LIMIT_BOTH
+
+        static String[][] basicTemplates = {
+            {"", "\nE\nE", "\nE\nQ", "\nE\nQ\nE\nQ"}, //ENABLED
+            {"", "", "", "",""}, //DISABLED
+            {"", "\nE", "\nE\nQ", "\nE\nQ"}, //LIMIT_LENGTH
+            {"", "\nE\nE", "\nE", "\nE\nE"}, //LIMIT_DEPTH
+            {"", "\nE", "\nE", "\nE"}}; //LIMIT_BOTH
+
+
+        int index;
+
+        MultilineKind (int index) {
+            this.index = index;
+        }
+
+        boolean isDouble() {
+            return this == DOUBLE || this == DOUBLE_NESTED;
+        }
+
+        boolean isNested() {
+            return this == NESTED || this == DOUBLE_NESTED;
+        }
+
+        String getOutput(OutputKind outKind, ErrorKind errKind, MultilinePolicy policy,
+                IndentKind summaryIndent, IndentKind detailsIndent, IndentKind multiIndent) {
+            String constIndent = (errKind == ErrorKind.DOUBLE) ?
+                summaryIndent.string + detailsIndent.string :
+                summaryIndent.string;
+            constIndent += multiIndent.string;
+
+            String errMsg1 = errKind.getOutput(outKind, summaryIndent, detailsIndent, constIndent);
+            String errMsg2 = errKind.getOutput(outKind, summaryIndent, detailsIndent, constIndent + constIndent);
+
+            errMsg1 = errMsg1.replaceAll("compiler.err", "compiler.misc");
+            errMsg1 = errMsg1.replaceAll("error message", "subdiagnostic");
+            errMsg2 = errMsg2.replaceAll("compiler.err", "compiler.misc");
+            errMsg2 = errMsg2.replaceAll("error message", "subdiagnostic");
+
+            String template = outKind == OutputKind.RAW ?
+                rawTemplates[policy.index][index] :
+                basicTemplates[policy.index][index];
+
+            template = template.replaceAll("E", errMsg1);
+            return template.replaceAll("Q", errMsg2);
+        }
+    }
+
+    enum MultilinePolicy {
+        ENABLED(0, "multilinePolicy", "enabled"),
+        DISABLED(1, "multilinePolicy", "disabled"),
+        LIMIT_LENGTH(2, "multilinePolicy", "limit:1:*"),
+        LIMIT_DEPTH(3, "multilinePolicy", "limit:*:1"),
+        LIMIT_BOTH(4, "multilinePolicy", "limit:1:1");
+
+        String name;
+        String value;
+        int index;
+
+        MultilinePolicy(int index, String name, String value) {
+            this.name = name;
+            this.value = value;
+            this.index = index;
+        }
+
+        void init(Options options) {
+            options.put(name, value);
+        }
+    }
+
+    enum PositionKind {
+        NOPOS(Position.NOPOS, "- ", "error: "),
+        POS(5, "/Test.java:1:6: ", "myfo:/Test.java:1: ");
+
+        int pos;
+        String rawOutput;
+        String nonRawOutput;
+
+        PositionKind(int pos, String rawOutput, String nonRawOutput) {
+            this.pos = pos;
+            this.rawOutput = rawOutput;
+            this.nonRawOutput = nonRawOutput;
+        }
+
+        JCDiagnostic.DiagnosticPosition pos() {
+            return new JCDiagnostic.SimpleDiagnosticPosition(pos);
+        }
+
+        String getOutput(OutputKind outputKind) {
+            return outputKind == OutputKind.RAW ?
+                rawOutput :
+                nonRawOutput;
+        }
+    }
+
+    static class MyFileObject extends SimpleJavaFileObject {
+        private String text;
+        public MyFileObject(String text) {
+            super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
+            this.text = text;
+        }
+        @Override
+        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+            return text;
+        }
+    }
+
+    enum IndentKind {
+        NONE(""),
+        CUSTOM("   ");
+
+        String string;
+
+        IndentKind(String indent) {
+            string = indent;
+        }
+    }
+
+    class MyLog extends Log {
+        MyLog(Context ctx) {
+            super(ctx);
+        }
+
+        @Override
+        protected java.io.PrintWriter getWriterForDiagnosticType(JCDiagnostic.DiagnosticType dt) {
+            return new java.io.PrintWriter(System.out);
+        }
+
+        @Override
+        protected boolean shouldReport(JavaFileObject jfo, int pos) {
+            return true;
+        }
+    }
+
+    int nerrors = 0;
+
+    void exec(OutputKind outputKind, ErrorKind errorKind, MultilineKind multiKind,
+            MultilinePolicy multiPolicy, PositionKind posKind, XDiagsSource xdiagsSource,
+            XDiagsCompact xdiagsCompact, CaretKind caretKind, SourceLineKind sourceLineKind,
+            IndentKind summaryIndent, IndentKind detailsIndent, IndentKind sourceIndent,
+            IndentKind subdiagsIndent) {
+        Context ctx = new Context();
+        Options options = Options.instance(ctx);
+        outputKind.init(options);
+        multiPolicy.init(options);
+        xdiagsSource.init(options);
+        xdiagsCompact.init(options);
+        caretKind.init(options);
+        sourceLineKind.init(options);
+        String indentString = "";
+        indentString = (summaryIndent == IndentKind.CUSTOM) ? "3" : "0";
+        indentString += (detailsIndent == IndentKind.CUSTOM) ? "|3" : "|0";
+        indentString += (sourceIndent == IndentKind.CUSTOM) ? "|3" : "|0";
+        indentString += (subdiagsIndent == IndentKind.CUSTOM) ? "|3" : "|0";
+        options.put("diagsIndentation", indentString);
+        MyLog log = new MyLog(ctx);
+        JavacMessages messages = JavacMessages.instance(ctx);
+        messages.add("tester");
+        JCDiagnostic.Factory diags = JCDiagnostic.Factory.instance(ctx);
+        log.useSource(new MyFileObject("This is a source line"));
+        JCDiagnostic d = diags.error(log.currentSource(),
+            posKind.pos(),
+            errorKind.key(), "Hello!");
+        if (multiKind != MultilineKind.NONE) {
+            JCDiagnostic sub = diags.fragment(errorKind.key(), "Hello!");
+            if (multiKind.isNested())
+                sub = new JCDiagnostic.MultilineDiagnostic(sub, List.of(sub));
+            List<JCDiagnostic> subdiags = multiKind.isDouble() ?
+                List.of(sub, sub) :
+                List.of(sub);
+            d = new JCDiagnostic.MultilineDiagnostic(d, subdiags);
+        }
+        String diag = log.getDiagnosticFormatter().format(d, messages.getCurrentLocale());
+        checkOutput(diag,
+                outputKind,
+                errorKind,
+                multiKind,
+                multiPolicy,
+                posKind,
+                xdiagsSource,
+                xdiagsCompact,
+                caretKind,
+                sourceLineKind,
+                summaryIndent,
+                detailsIndent,
+                sourceIndent,
+                subdiagsIndent);
+    }
+
+    void test() {
+        for (OutputKind outputKind : OutputKind.values()) {
+            for (ErrorKind errKind : ErrorKind.values()) {
+                for (MultilineKind multiKind : MultilineKind.values()) {
+                    for (MultilinePolicy multiPolicy : MultilinePolicy.values()) {
+                        for (PositionKind posKind : PositionKind.values()) {
+                            for (XDiagsSource xdiagsSource : XDiagsSource.values()) {
+                                for (XDiagsCompact xdiagsCompact : XDiagsCompact.values()) {
+                                    for (CaretKind caretKind : CaretKind.values()) {
+                                        for (SourceLineKind sourceLineKind : SourceLineKind.values()) {
+                                            for (IndentKind summaryIndent : IndentKind.values()) {
+                                                for (IndentKind detailsIndent : IndentKind.values()) {
+                                                    for (IndentKind sourceIndent : IndentKind.values()) {
+                                                        for (IndentKind subdiagsIndent : IndentKind.values()) {
+                                                            exec(outputKind,
+                                                                errKind,
+                                                                multiKind,
+                                                                multiPolicy,
+                                                                posKind,
+                                                                xdiagsSource,
+                                                                xdiagsCompact,
+                                                                caretKind,
+                                                                sourceLineKind,
+                                                                summaryIndent,
+                                                                detailsIndent,
+                                                                sourceIndent,
+                                                                subdiagsIndent);
+                                                        }
+                                                    }
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        if (nerrors != 0)
+            throw new AssertionError(nerrors + " errors found");
+    }
+
+    void printInfo(String msg, OutputKind outputKind, ErrorKind errorKind, MultilineKind multiKind,
+            MultilinePolicy multiPolicy, PositionKind posKind, XDiagsSource xdiagsSource,
+            XDiagsCompact xdiagsCompact, CaretKind caretKind, SourceLineKind sourceLineKind,
+            IndentKind summaryIndent, IndentKind detailsIndent, IndentKind sourceIndent,
+            IndentKind subdiagsIndent, String errorLine) {
+        String sep = "*********************************************************";
+        String desc = "raw=" + outputKind + " pos=" + posKind + " key=" + errorKind.key() +
+                " multiline=" + multiKind +" multiPolicy=" + multiPolicy.value +
+                " diags= " + java.util.Arrays.asList(xdiagsSource.flag, xdiagsCompact.flag) +
+                " caret=" + caretKind + " sourcePosition=" + sourceLineKind +
+                " summaryIndent=" + summaryIndent + " detailsIndent=" + detailsIndent +
+                " sourceIndent=" + sourceIndent + " subdiagsIndent=" + subdiagsIndent;
+        System.out.println(sep);
+        System.out.println(desc);
+        System.out.println(sep);
+        System.out.println(msg);
+        System.out.println("Diagnostic formatting problem - expected diagnostic...\n" + errorLine);
+    }
+
+    void checkOutput(String msg, OutputKind outputKind, ErrorKind errorKind, MultilineKind multiKind,
+            MultilinePolicy multiPolicy, PositionKind posKind, XDiagsSource xdiagsSource,
+            XDiagsCompact xdiagsCompact, CaretKind caretKind, SourceLineKind sourceLineKind,
+            IndentKind summaryIndent, IndentKind detailsIndent, IndentKind sourceIndent,
+            IndentKind subdiagsIndent) {
+        boolean shouldPrintSource = posKind == PositionKind.POS &&
+                xdiagsSource != XDiagsSource.NO_SOURCE &&
+                (xdiagsSource == XDiagsSource.SOURCE ||
+                outputKind == OutputKind.BASIC);
+        String errorLine = posKind.getOutput(outputKind) +
+                errorKind.getOutput(outputKind, summaryIndent, detailsIndent);
+        if (xdiagsCompact != XDiagsCompact.COMPACT)
+            errorLine += multiKind.getOutput(outputKind, errorKind, multiPolicy, summaryIndent, detailsIndent, subdiagsIndent);
+        String[] lines = errorLine.split("\n");
+        if (xdiagsCompact == XDiagsCompact.COMPACT) {
+            errorLine = lines[0];
+            lines = new String[] {errorLine};
+        }
+        if (shouldPrintSource) {
+            if (sourceLineKind.isAfterSummary()) {
+                String sep = "\n";
+                if (lines.length == 1) {
+                    errorLine += "\n";
+                    sep = "";
+                }
+                errorLine = errorLine.replaceFirst("\n",
+                        Matcher.quoteReplacement(xdiagsSource.getOutput(caretKind, sourceIndent, outputKind) + sep));
+            }
+            else
+                errorLine += xdiagsSource.getOutput(caretKind, sourceIndent, outputKind);
+        }
+
+        if (!msg.equals(errorLine)) {
+            printInfo(msg,
+                    outputKind,
+                    errorKind,
+                    multiKind,
+                    multiPolicy,
+                    posKind,
+                    xdiagsSource,
+                    xdiagsCompact,
+                    caretKind,
+                    sourceLineKind,
+                    summaryIndent,
+                    detailsIndent,
+                    sourceIndent,
+                    subdiagsIndent,
+                    errorLine);
+            nerrors++;
+        }
+    }
+
+    public static void main(String... args) throws Exception {
+        new T6769027().test();
+    }
+}
diff --git a/langtools/test/tools/javac/Diagnostics/6769027/tester.properties b/langtools/test/tools/javac/Diagnostics/6769027/tester.properties
new file mode 100644
index 0000000..666a52e
--- /dev/null
+++ b/langtools/test/tools/javac/Diagnostics/6769027/tester.properties
@@ -0,0 +1,13 @@
+compiler.err.single=\
+    This is a test error message {0}
+
+compiler.err.double=\
+    This is a test error message.\n\
+	This is another line of the above error message {0}
+
+compiler.misc.single=\
+    This is a test subdiagnostic {0}
+
+compiler.misc.double=\
+    This is a test subdiagnostic.\n\
+	This is another line of the above subdiagnostic {0}
diff --git a/langtools/test/tools/javac/ExtendArray.out b/langtools/test/tools/javac/ExtendArray.out
index 8687843..ad5d887 100644
--- a/langtools/test/tools/javac/ExtendArray.out
+++ b/langtools/test/tools/javac/ExtendArray.out
@@ -1,6 +1,6 @@
 ExtendArray.java:11: unexpected type
-found   : java.lang.Object[]
-required: class
 public class ExtendArray extends Object[] {}
                                        ^
+  required: class
+  found:    java.lang.Object[]
 1 error
diff --git a/langtools/test/tools/javac/T5048776b.out b/langtools/test/tools/javac/T5048776b.out
index 5eb9b79..ab9688e 100644
--- a/langtools/test/tools/javac/T5048776b.out
+++ b/langtools/test/tools/javac/T5048776b.out
@@ -1,3 +1,3 @@
-T5048776.java:12:10: compiler.warn.override.varargs.missing: (- compiler.misc.varargs.override: foo(java.lang.Object...), A1a, foo(java.lang.Object[]), A1)
-T5048776.java:20:10: compiler.warn.override.varargs.extra: (- compiler.misc.varargs.override: foo(java.lang.Object[]), A2a, foo(java.lang.Object...), A2)
+T5048776.java:12:10: compiler.warn.override.varargs.missing: (compiler.misc.varargs.override: foo(java.lang.Object...), A1a, foo(java.lang.Object[]), A1)
+T5048776.java:20:10: compiler.warn.override.varargs.extra: (compiler.misc.varargs.override: foo(java.lang.Object[]), A2a, foo(java.lang.Object...), A2)
 2 warnings
diff --git a/langtools/test/tools/javac/T6214885a.out b/langtools/test/tools/javac/T6214885a.out
index f09fff6..8ca1aac 100644
--- a/langtools/test/tools/javac/T6214885a.out
+++ b/langtools/test/tools/javac/T6214885a.out
@@ -1,6 +1,6 @@
 T6214885.java:11 cannot find symbol
-symbol  : variable x
-location: class T6214885
         x = 1;
         ^
+  symbol:   variable x
+  location: class T6214885
 1 error
diff --git a/langtools/test/tools/javac/T6214885b.out b/langtools/test/tools/javac/T6214885b.out
index 1ee8636..4dc3019 100644
--- a/langtools/test/tools/javac/T6214885b.out
+++ b/langtools/test/tools/javac/T6214885b.out
@@ -1,6 +1,6 @@
 T6214885.java:11:9 cannot find symbol
-symbol  : variable x
-location: class T6214885
         x = 1;
         ^
+  symbol:   variable x
+  location: class T6214885
 1 error
diff --git a/langtools/test/tools/javac/T6230128.out b/langtools/test/tools/javac/T6230128.out
index d6a08595..3286353 100644
--- a/langtools/test/tools/javac/T6230128.out
+++ b/langtools/test/tools/javac/T6230128.out
@@ -1,2 +1,2 @@
-T6230128.java:11:10: compiler.err.override.weaker.access: (- compiler.misc.cant.override: foo(java.lang.Object...), A1a, foo(java.lang.Object[]), A1), public
+T6230128.java:11:10: compiler.err.override.weaker.access: (compiler.misc.cant.override: foo(java.lang.Object...), A1a, foo(java.lang.Object[]), A1), public
 1 error
diff --git a/langtools/test/tools/javac/annotations/6365854/test1.out b/langtools/test/tools/javac/annotations/6365854/test1.out
index ed81b94..00eaf21 100644
--- a/langtools/test/tools/javac/annotations/6365854/test1.out
+++ b/langtools/test/tools/javac/annotations/6365854/test1.out
@@ -1,2 +1,2 @@
-- compiler.warn.annotation.method.not.found.reason: test.annotation.TestAnnotation, test, (- compiler.misc.class.file.not.found: test.annotation.TestAnnotation)
+- compiler.warn.annotation.method.not.found.reason: test.annotation.TestAnnotation, test, (compiler.misc.class.file.not.found: test.annotation.TestAnnotation)
 1 warning
diff --git a/langtools/test/tools/javac/cast/6557182/T6557182.out b/langtools/test/tools/javac/cast/6557182/T6557182.out
index 9ebe10e..5f25497 100644
--- a/langtools/test/tools/javac/cast/6557182/T6557182.out
+++ b/langtools/test/tools/javac/cast/6557182/T6557182.out
@@ -1,4 +1,4 @@
-T6557182.java:35:56: compiler.err.prob.found.req: (- compiler.misc.inconvertible.types), T, java.lang.Comparable<java.lang.Integer>
-T6557182.java:39:56: compiler.warn.prob.found.req: (- compiler.misc.unchecked.cast.to.type), T, java.lang.Comparable<java.lang.Integer>
+T6557182.java:35:56: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T, java.lang.Comparable<java.lang.Integer>
+T6557182.java:39:56: compiler.warn.prob.found.req: (compiler.misc.unchecked.cast.to.type), T, java.lang.Comparable<java.lang.Integer>
 1 error
 1 warning
diff --git a/langtools/test/tools/javac/cast/6665356/T6665356.out b/langtools/test/tools/javac/cast/6665356/T6665356.out
index 029c664..1db10c6 100644
--- a/langtools/test/tools/javac/cast/6665356/T6665356.out
+++ b/langtools/test/tools/javac/cast/6665356/T6665356.out
@@ -1,8 +1,8 @@
-T6665356.java:54:55: compiler.err.prob.found.req: (- compiler.misc.inconvertible.types), T6665356.Outer<java.lang.Integer>.Inner<java.lang.Long>, T6665356.Outer<? super java.lang.Number>.Inner<java.lang.Long>
-T6665356.java:58:58: compiler.err.prob.found.req: (- compiler.misc.inconvertible.types), T6665356.Outer<java.lang.Integer>.Inner<java.lang.Long>, T6665356.Outer<java.lang.Integer>.Inner<? super java.lang.Number>
-T6665356.java:62:65: compiler.err.prob.found.req: (- compiler.misc.inconvertible.types), T6665356.Outer<java.lang.Integer>.Inner<java.lang.Long>, T6665356.Outer<? super java.lang.Number>.Inner<? super java.lang.Number>
-T6665356.java:66:57: compiler.err.prob.found.req: (- compiler.misc.inconvertible.types), T6665356.Outer<java.lang.Integer>.Inner<java.lang.Long>, T6665356.Outer<? extends java.lang.String>.Inner<java.lang.Long>
-T6665356.java:70:60: compiler.err.prob.found.req: (- compiler.misc.inconvertible.types), T6665356.Outer<java.lang.Integer>.Inner<java.lang.Long>, T6665356.Outer<java.lang.Integer>.Inner<? extends java.lang.String>
-T6665356.java:74:55: compiler.err.prob.found.req: (- compiler.misc.inconvertible.types), T6665356.Outer<java.lang.Integer>.Inner<java.lang.Long>, T6665356.Outer<? super java.lang.String>.Inner<java.lang.Long>
-T6665356.java:78:58: compiler.err.prob.found.req: (- compiler.misc.inconvertible.types), T6665356.Outer<java.lang.Integer>.Inner<java.lang.Long>, T6665356.Outer<java.lang.Integer>.Inner<? super java.lang.String>
+T6665356.java:54:55: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6665356.Outer<java.lang.Integer>.Inner<java.lang.Long>, T6665356.Outer<? super java.lang.Number>.Inner<java.lang.Long>
+T6665356.java:58:58: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6665356.Outer<java.lang.Integer>.Inner<java.lang.Long>, T6665356.Outer<java.lang.Integer>.Inner<? super java.lang.Number>
+T6665356.java:62:65: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6665356.Outer<java.lang.Integer>.Inner<java.lang.Long>, T6665356.Outer<? super java.lang.Number>.Inner<? super java.lang.Number>
+T6665356.java:66:57: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6665356.Outer<java.lang.Integer>.Inner<java.lang.Long>, T6665356.Outer<? extends java.lang.String>.Inner<java.lang.Long>
+T6665356.java:70:60: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6665356.Outer<java.lang.Integer>.Inner<java.lang.Long>, T6665356.Outer<java.lang.Integer>.Inner<? extends java.lang.String>
+T6665356.java:74:55: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6665356.Outer<java.lang.Integer>.Inner<java.lang.Long>, T6665356.Outer<? super java.lang.String>.Inner<java.lang.Long>
+T6665356.java:78:58: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6665356.Outer<java.lang.Integer>.Inner<java.lang.Long>, T6665356.Outer<java.lang.Integer>.Inner<? super java.lang.String>
 7 errors
\ No newline at end of file
diff --git a/langtools/test/tools/javac/cast/6795580/T6795580.out b/langtools/test/tools/javac/cast/6795580/T6795580.out
index f754e1d..a5d7040 100644
--- a/langtools/test/tools/javac/cast/6795580/T6795580.out
+++ b/langtools/test/tools/javac/cast/6795580/T6795580.out
@@ -1,8 +1,8 @@
-T6795580.java:54:57: compiler.err.prob.found.req: (- compiler.misc.inconvertible.types), T6795580.Outer<java.lang.Integer>.Inner<java.lang.Long>[], T6795580.Outer<? super java.lang.Number>.Inner<java.lang.Long>[]
-T6795580.java:58:60: compiler.err.prob.found.req: (- compiler.misc.inconvertible.types), T6795580.Outer<java.lang.Integer>.Inner<java.lang.Long>[], T6795580.Outer<java.lang.Integer>.Inner<? super java.lang.Number>[]
-T6795580.java:62:67: compiler.err.prob.found.req: (- compiler.misc.inconvertible.types), T6795580.Outer<java.lang.Integer>.Inner<java.lang.Long>[], T6795580.Outer<? super java.lang.Number>.Inner<? super java.lang.Number>[]
-T6795580.java:66:59: compiler.err.prob.found.req: (- compiler.misc.inconvertible.types), T6795580.Outer<java.lang.Integer>.Inner<java.lang.Long>[], T6795580.Outer<? extends java.lang.String>.Inner<java.lang.Long>[]
-T6795580.java:70:62: compiler.err.prob.found.req: (- compiler.misc.inconvertible.types), T6795580.Outer<java.lang.Integer>.Inner<java.lang.Long>[], T6795580.Outer<java.lang.Integer>.Inner<? extends java.lang.String>[]
-T6795580.java:74:57: compiler.err.prob.found.req: (- compiler.misc.inconvertible.types), T6795580.Outer<java.lang.Integer>.Inner<java.lang.Long>[], T6795580.Outer<? super java.lang.String>.Inner<java.lang.Long>[]
-T6795580.java:78:60: compiler.err.prob.found.req: (- compiler.misc.inconvertible.types), T6795580.Outer<java.lang.Integer>.Inner<java.lang.Long>[], T6795580.Outer<java.lang.Integer>.Inner<? super java.lang.String>[]
+T6795580.java:54:57: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6795580.Outer<java.lang.Integer>.Inner<java.lang.Long>[], T6795580.Outer<? super java.lang.Number>.Inner<java.lang.Long>[]
+T6795580.java:58:60: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6795580.Outer<java.lang.Integer>.Inner<java.lang.Long>[], T6795580.Outer<java.lang.Integer>.Inner<? super java.lang.Number>[]
+T6795580.java:62:67: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6795580.Outer<java.lang.Integer>.Inner<java.lang.Long>[], T6795580.Outer<? super java.lang.Number>.Inner<? super java.lang.Number>[]
+T6795580.java:66:59: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6795580.Outer<java.lang.Integer>.Inner<java.lang.Long>[], T6795580.Outer<? extends java.lang.String>.Inner<java.lang.Long>[]
+T6795580.java:70:62: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6795580.Outer<java.lang.Integer>.Inner<java.lang.Long>[], T6795580.Outer<java.lang.Integer>.Inner<? extends java.lang.String>[]
+T6795580.java:74:57: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6795580.Outer<java.lang.Integer>.Inner<java.lang.Long>[], T6795580.Outer<? super java.lang.String>.Inner<java.lang.Long>[]
+T6795580.java:78:60: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6795580.Outer<java.lang.Integer>.Inner<java.lang.Long>[], T6795580.Outer<java.lang.Integer>.Inner<? super java.lang.String>[]
 7 errors
diff --git a/langtools/test/tools/javac/generics/6207386/T6207386.out b/langtools/test/tools/javac/generics/6207386/T6207386.out
index bd98d31..768c5c2 100644
--- a/langtools/test/tools/javac/generics/6207386/T6207386.out
+++ b/langtools/test/tools/javac/generics/6207386/T6207386.out
@@ -1,2 +1,2 @@
-T6207386.java:13:30: compiler.err.prob.found.req: (- compiler.misc.incompatible.types), X, T6207386.F<? super X>
+T6207386.java:13:30: compiler.err.prob.found.req: (compiler.misc.incompatible.types), X, T6207386.F<? super X>
 1 error
diff --git a/langtools/test/tools/javac/generics/inference/6315770/T6315770.out b/langtools/test/tools/javac/generics/inference/6315770/T6315770.out
index 8dc60f9..dd1fdb9 100644
--- a/langtools/test/tools/javac/generics/inference/6315770/T6315770.out
+++ b/langtools/test/tools/javac/generics/inference/6315770/T6315770.out
@@ -1,3 +1,3 @@
-T6315770.java:39:42: compiler.err.undetermined.type.1: <T>T6315770<T>, (- compiler.misc.no.unique.maximal.instance.exists: T, java.lang.String,java.lang.Integer,java.lang.Runnable)
-T6315770.java:40:40: compiler.err.prob.found.req: (- compiler.misc.incompatible.types.1: (- compiler.misc.no.conforming.instance.exists: T, T6315770<T>, T6315770<? super java.lang.String>)), <T>T6315770<T>, T6315770<? super java.lang.String>
+T6315770.java:39:42: compiler.err.undetermined.type.1: <T>T6315770<T>, (compiler.misc.no.unique.maximal.instance.exists: T, java.lang.String,java.lang.Integer,java.lang.Runnable)
+T6315770.java:40:40: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.no.conforming.instance.exists: T, T6315770<T>, T6315770<? super java.lang.String>)), <T>T6315770<T>, T6315770<? super java.lang.String>
 2 errors
diff --git a/langtools/test/tools/javac/generics/inference/6718364/T6718364.out b/langtools/test/tools/javac/generics/inference/6718364/T6718364.out
index e049269..1b5ed9a 100644
--- a/langtools/test/tools/javac/generics/inference/6718364/T6718364.out
+++ b/langtools/test/tools/javac/generics/inference/6718364/T6718364.out
@@ -1,3 +1,3 @@
-T6718364.java:36:32: compiler.warn.prob.found.req: (- compiler.misc.unchecked.assign), T6718364.X, T6718364.X<java.lang.Integer>
+T6718364.java:36:32: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T6718364.X, T6718364.X<java.lang.Integer>
 T6718364.java:36:10: compiler.warn.unchecked.meth.invocation.applied: kindname.method, m, T6718364.X<T>,T, T6718364.X<T6718364.X<java.lang.Integer>>,T6718364.X, kindname.class, T6718364
 2 warnings
\ No newline at end of file
diff --git a/langtools/test/tools/javac/generics/typevars/6680106/T6680106.out b/langtools/test/tools/javac/generics/typevars/6680106/T6680106.out
index 06f1eaf..f26d2a4 100644
--- a/langtools/test/tools/javac/generics/typevars/6680106/T6680106.out
+++ b/langtools/test/tools/javac/generics/typevars/6680106/T6680106.out
@@ -1,13 +1,13 @@
-T6680106.java:34:25: compiler.err.type.found.req: T[], (- compiler.misc.type.req.class)
-T6680106.java:35:25: compiler.err.type.found.req: S[], (- compiler.misc.type.req.class)
-T6680106.java:35:40: compiler.err.type.found.req: T[], (- compiler.misc.type.req.class)
-T6680106.java:36:25: compiler.err.type.found.req: S[], (- compiler.misc.type.req.class)
-T6680106.java:36:40: compiler.err.type.found.req: U[], (- compiler.misc.type.req.class)
-T6680106.java:36:55: compiler.err.type.found.req: T[], (- compiler.misc.type.req.class)
-T6680106.java:37:30: compiler.err.type.found.req: T[], (- compiler.misc.type.req.class)
-T6680106.java:38:30: compiler.err.type.found.req: S[], (- compiler.misc.type.req.class)
-T6680106.java:38:50: compiler.err.type.found.req: T[], (- compiler.misc.type.req.class)
-T6680106.java:39:30: compiler.err.type.found.req: S[], (- compiler.misc.type.req.class)
-T6680106.java:39:50: compiler.err.type.found.req: U[], (- compiler.misc.type.req.class)
-T6680106.java:39:70: compiler.err.type.found.req: T[], (- compiler.misc.type.req.class)
+T6680106.java:34:25: compiler.err.type.found.req: T[], (compiler.misc.type.req.class)
+T6680106.java:35:25: compiler.err.type.found.req: S[], (compiler.misc.type.req.class)
+T6680106.java:35:40: compiler.err.type.found.req: T[], (compiler.misc.type.req.class)
+T6680106.java:36:25: compiler.err.type.found.req: S[], (compiler.misc.type.req.class)
+T6680106.java:36:40: compiler.err.type.found.req: U[], (compiler.misc.type.req.class)
+T6680106.java:36:55: compiler.err.type.found.req: T[], (compiler.misc.type.req.class)
+T6680106.java:37:30: compiler.err.type.found.req: T[], (compiler.misc.type.req.class)
+T6680106.java:38:30: compiler.err.type.found.req: S[], (compiler.misc.type.req.class)
+T6680106.java:38:50: compiler.err.type.found.req: T[], (compiler.misc.type.req.class)
+T6680106.java:39:30: compiler.err.type.found.req: S[], (compiler.misc.type.req.class)
+T6680106.java:39:50: compiler.err.type.found.req: U[], (compiler.misc.type.req.class)
+T6680106.java:39:70: compiler.err.type.found.req: T[], (compiler.misc.type.req.class)
 12 errors
\ No newline at end of file
diff --git a/langtools/test/tools/javac/missingSuperRecovery/MissingSuperRecovery.out b/langtools/test/tools/javac/missingSuperRecovery/MissingSuperRecovery.out
index 94a21c0..b049ccd 100644
--- a/langtools/test/tools/javac/missingSuperRecovery/MissingSuperRecovery.out
+++ b/langtools/test/tools/javac/missingSuperRecovery/MissingSuperRecovery.out
@@ -1,5 +1,5 @@
 MissingSuperRecovery.java:15: cannot access base
-class file for base not found
 public class MissingSuperRecovery extends impl {
        ^
+  class file for base not found
 1 error
diff --git a/langtools/test/tools/javac/unicode/UnicodeNewline.out b/langtools/test/tools/javac/unicode/UnicodeNewline.out
index 366d8c6..5b71702 100644
--- a/langtools/test/tools/javac/unicode/UnicodeNewline.out
+++ b/langtools/test/tools/javac/unicode/UnicodeNewline.out
@@ -1,6 +1,6 @@
 UnicodeNewline.java:11: cannot find symbol
-symbol  : class xyzzy
-location: class UnicodeNewline
     xyzzy plugh; // error should be HERE
     ^
+  symbol:   class xyzzy
+  location: class UnicodeNewline
 1 error
