changeset 4309:e142148d8b54

Merge
author asaha
date Tue, 12 Apr 2011 14:23:03 -0700
parents 557bd9b5d92f 9128eace50f5
children 76e0e562b617 f8eddc85cc02
files src/share/classes/sun/security/ssl/DefaultSSLContextImpl.java
diffstat 231 files changed, 7382 insertions(+), 1819 deletions(-) [+]
line wrap: on
line diff
--- a/make/com/sun/java/pack/Makefile	Fri Apr 08 10:31:14 2011 -0700
+++ b/make/com/sun/java/pack/Makefile	Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -56,10 +56,6 @@
 
 vpath %.cpp $(SHARE_SRC)/native/$(PKGDIR)
 
-
-
-
-
 ifeq ($(STANDALONE),true)
   ZIPOBJDIR = $(OUTPUTDIR)/tmp/sun/java.util.zip/zip/$(OBJDIRNAME)
 
@@ -131,8 +127,9 @@
 pack200-tool:
 	$(call make-launcher, pack200, com.sun.java.util.jar.pack.Driver, , --pack)
 
+# ignore mapfile for non-product binary 
 unpacker:
-	$(MAKE) $(UNPACK_EXE) STANDALONE=true LDMAPFLAGS_OPT= LDMAPFLAGS_DBG=
+	$(MAKE) $(UNPACK_EXE) STANDALONE=true LDMAPFLAGS_DBG=
 
 ifeq ($(PLATFORM), windows)
 IMVERSIONVALUE=$(JDK_MINOR_VERSION).$(JDK_MICRO_VERSION).$(JDK_UPDATE_VER).$(COOKED_BUILD_NUMBER)
@@ -147,8 +144,14 @@
 	$(ECHO) "Resource files not required for Unix"
 endif
 
+# Mapfile-vers.gmk, does not copy over the mapfile-vers-unpack200, when
+# the make utiliy is re-invoked, as in this case. In order to workaround
+# this special case, the mapfile required for the unpack200 command, is
+# explicitly copied over to the expected location.
 $(UNPACK_EXE): $(UNPACK_EXE_FILES_o) updatefiles winres
 	$(prep-target)
+	$(RM) $(TEMPDIR)/mapfile-vers
+	$(CP) mapfile-vers-unpack200 $(TEMPDIR)/mapfile-vers
 	$(LINKER)  $(LDDFLAGS) $(UNPACK_EXE_FILES_o) $(RES) $(LIBCXX) $(LDOUTPUT)$(TEMPDIR)/unpack200$(EXE_SUFFIX)
 ifdef MT
 	$(MT) /manifest $(OBJDIR)/unpack200$(EXE_SUFFIX).manifest /outputresource:$(TEMPDIR)/unpack200$(EXE_SUFFIX);#1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/com/sun/java/pack/mapfile-vers-unpack200	Tue Apr 12 14:23:03 2011 -0700
@@ -0,0 +1,31 @@
+#
+# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+# Define library interface.
+
+SUNWprivate_1.1 {
+	local:
+	    *;
+};
--- a/make/common/Mapfile-vers.gmk	Fri Apr 08 10:31:14 2011 -0700
+++ b/make/common/Mapfile-vers.gmk	Tue Apr 12 14:23:03 2011 -0700
@@ -52,8 +52,8 @@
   endif
   
   # If we are re-ordering functions in this solaris library, we need to make
-  #   sure that -xF is added to the compile lines. This option is critical and
-  #   enables the functions to be reordered.
+  # sure that -xF is added to the compile lines. This option is critical and
+  # enables the functions to be reordered.
   ifdef FILES_reorder
     CFLAGS_OPT   += -xF
     CXXFLAGS_OPT += -xF
@@ -76,7 +76,6 @@
 
 endif # PLATFORM
 
-
 ifeq ($(PLATFORM), linux)
 
 ifeq ($(VARIANT), OPT)
--- a/make/common/Program.gmk	Fri Apr 08 10:31:14 2011 -0700
+++ b/make/common/Program.gmk	Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -55,6 +55,11 @@
 
 program: $(ACTUAL_PROGRAM)
 
+# reuse the mapfiles in the launcher's directory, the same should
+# be applicable to the tool launchers as well.
+FILES_m = $(BUILDDIR)/java/main/java/mapfile-$(ARCH)
+include $(BUILDDIR)/common/Mapfile-vers.gmk
+
 include $(JDK_TOPDIR)/make/common/Rules.gmk
 
 ifdef NEVER_ACT_AS_SERVER_CLASS_MACHINE
--- a/make/java/java/Makefile	Fri Apr 08 10:31:14 2011 -0700
+++ b/make/java/java/Makefile	Tue Apr 12 14:23:03 2011 -0700
@@ -198,10 +198,12 @@
 
 #
 # What to link?
+# On Windows, shell32 is not normally required and so it is delay loaded.
 #
 ifeq ($(PLATFORM),windows)
 OTHER_LDLIBS += $(JVMLIB) -libpath:$(OBJDIR)/../../../fdlibm/$(OBJDIRNAME) fdlibm.lib \
-		       -libpath:$(OBJDIR)/../../../verify/$(OBJDIRNAME) verify.lib
+		       -libpath:$(OBJDIR)/../../../verify/$(OBJDIRNAME) verify.lib \
+		       shell32.lib delayimp.lib /DELAYLOAD:shell32.dll
 else
 OTHER_LDLIBS += $(JVMLIB) -lverify $(LIBSOCKET) $(LIBNSL) -ldl \
 		-L$(OBJDIR)/../../../fdlibm/$(OBJDIRNAME) -lfdlibm.$(ARCH)
--- a/make/java/main/java/Makefile	Fri Apr 08 10:31:14 2011 -0700
+++ b/make/java/main/java/Makefile	Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -61,5 +61,4 @@
 
 ifeq ($(PLATFORM), solaris)
 LDFLAGS += -R$(OPENWIN_LIB)
-LDFLAGS += -M mapfile-$(ARCH)
 endif
--- a/make/java/main/java/mapfile-amd64	Fri Apr 08 10:31:14 2011 -0700
+++ b/make/java/main/java/mapfile-amd64	Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,7 @@
 # interested in declaring a version, simply scoping the file is sufficient.
 #
 
-{
+SUNWprivate_1.1 {
 	global:
 		main;		# Provides basic adb symbol offsets
 		environ;	# Public symbols and required by Java run time
--- a/make/java/main/java/mapfile-i586	Fri Apr 08 10:31:14 2011 -0700
+++ b/make/java/main/java/mapfile-i586	Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,7 @@
 # interested in declaring a version, simply scoping the file is sufficient.
 #
 
-{
+SUNWprivate_1.1 {
 	global:
 		main;		# Provides basic adb symbol offsets
 		environ;	# Public symbols and required by Java run time
--- a/make/java/main/java/mapfile-sparc	Fri Apr 08 10:31:14 2011 -0700
+++ b/make/java/main/java/mapfile-sparc	Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,7 @@
 # interested in declaring a version, simply scoping the file is sufficient.
 #
 
-{
+SUNWprivate_1.1 {
 	global:
 		main;		# Provides basic adb symbol offsets
 		environ;	# Public symbols and required by Java run time
--- a/make/java/main/java/mapfile-sparcv9	Fri Apr 08 10:31:14 2011 -0700
+++ b/make/java/main/java/mapfile-sparcv9	Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -28,7 +28,7 @@
 # interested in declaring a version, simply scoping the file is sufficient.
 #
 
-{
+SUNWprivate_1.1 {
 	global:
 		main;		# Provides basic adb symbol offsets
 		environ;	# Public symbols and required by Java run time
--- a/make/java/management/Makefile	Fri Apr 08 10:31:14 2011 -0700
+++ b/make/java/management/Makefile	Tue Apr 12 14:23:03 2011 -0700
@@ -86,7 +86,8 @@
   -I$(SHARE_SRC)/native/sun/management 
 
 ifeq ($(PLATFORM),windows)
-  OTHER_LDLIBS += $(JVMLIB)
+  # Need process status helper API (psapi) on Windows
+  OTHER_LDLIBS += $(JVMLIB) psapi.lib
 endif
 
 #
--- a/make/mksample/Makefile	Fri Apr 08 10:31:14 2011 -0700
+++ b/make/mksample/Makefile	Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -38,7 +38,7 @@
 endif
 
 SUBDIRS =
-SUBDIRS_misc = nio scripting nbproject
+SUBDIRS_misc = nio scripting nbproject forkjoin
 SUBDIRS_enterprise = $(WEBSERVICES_SUBDIR)
 SUBDIRS_management = jmx
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/mksample/forkjoin/Makefile	Tue Apr 12 14:23:03 2011 -0700
@@ -0,0 +1,41 @@
+#
+# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+#
+# Makefile for building all the samples under the forkjoin subdirectory.
+#
+
+BUILDDIR = ../..
+PRODUCT = java
+include $(BUILDDIR)/common/Defs.gmk
+
+SUBDIRS = mergesort
+include $(BUILDDIR)/common/Subdirs.gmk
+
+all build clean clobber::
+	$(SUBDIRS-loop)
+
+clobber clean ::
+	$(RM) -r $(SAMPLEDIR)/forkjoin
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/mksample/forkjoin/mergesort/Makefile	Tue Apr 12 14:23:03 2011 -0700
@@ -0,0 +1,51 @@
+#
+# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+#
+# Makefile for the forkjoin/mergesort sample code
+#
+
+BUILDDIR = ../../..
+
+PRODUCT = java
+
+include $(BUILDDIR)/common/Defs.gmk
+
+SAMPLE_SRC_DIR = $(SHARE_SRC)/sample/forkjoin/mergesort
+SAMPLE_DST_DIR = $(SAMPLEDIR)/forkjoin/mergesort
+
+SAMPLE_FILES =							\
+	$(SAMPLE_DST_DIR)/MergeDemo.java			\
+	$(SAMPLE_DST_DIR)/MergeSort.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
--- a/make/mksample/nio/Makefile	Fri Apr 08 10:31:14 2011 -0700
+++ b/make/mksample/nio/Makefile	Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -31,7 +31,7 @@
 PRODUCT = java
 include $(BUILDDIR)/common/Defs.gmk
 
-SUBDIRS = file multicast server
+SUBDIRS = chatserver file multicast server
 include $(BUILDDIR)/common/Subdirs.gmk
 
 all build clean clobber::
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/mksample/nio/chatserver/Makefile	Tue Apr 12 14:23:03 2011 -0700
@@ -0,0 +1,56 @@
+#
+# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+#
+# Makefile for the nio/chatserver sample code
+#
+
+BUILDDIR = ../../..
+
+PRODUCT = java
+
+include $(BUILDDIR)/common/Defs.gmk
+
+SAMPLE_SRC_DIR = $(SHARE_SRC)/sample/nio/chatserver
+SAMPLE_DST_DIR = $(SAMPLEDIR)/nio/chatserver
+
+SAMPLE_FILES =							\
+	$(SAMPLE_DST_DIR)/ChatServer.java			\
+	$(SAMPLE_DST_DIR)/Client.java				\
+	$(SAMPLE_DST_DIR)/ClientReader.java			\
+	$(SAMPLE_DST_DIR)/DataReader.java			\
+	$(SAMPLE_DST_DIR)/MessageReader.java			\
+	$(SAMPLE_DST_DIR)/NameReader.java			\
+	$(SAMPLE_DST_DIR)/README.txt
+
+all build: $(SAMPLE_FILES)
+
+$(SAMPLE_DST_DIR)/%: $(SAMPLE_SRC_DIR)/%
+	$(install-file)
+
+clean clobber:
+	$(RM) -r $(SAMPLE_DST_DIR)
+
+.PHONY: all build clean clobber
--- a/src/share/bin/jli_util.h	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/bin/jli_util.h	Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -35,7 +35,6 @@
 void  JLI_MemFree(void *ptr);
 int   JLI_StrCCmp(const char *s1, const char* s2);
 
-
 #define JLI_StrLen(p1)          strlen((p1))
 #define JLI_StrChr(p1, p2)      strchr((p1), (p2))
 #define JLI_StrRChr(p1, p2)     strrchr((p1), (p2))
@@ -48,6 +47,7 @@
 #define JLI_StrSpn(p1, p2)      strspn((p1), (p2))
 #define JLI_StrCSpn(p1, p2)     strcspn((p1), (p2))
 #define JLI_StrPBrk(p1, p2)     strpbrk((p1), (p2))
+#define JLI_StrTok(p1, p2)      strtok((p1), (p2))
 
 /* On Windows lseek() is in io.h rather than the location dictated by POSIX. */
 #ifdef _WIN32
--- a/src/share/classes/java/lang/Character.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/lang/Character.java	Tue Apr 12 14:23:03 2011 -0700
@@ -4184,9 +4184,11 @@
             aliases.put("AVST", AVESTAN);
             aliases.put("BALI", BALINESE);
             aliases.put("BAMU", BAMUM);
+            aliases.put("BATK", BATAK);
             aliases.put("BENG", BENGALI);
             aliases.put("BOPO", BOPOMOFO);
             aliases.put("BRAI", BRAILLE);
+            aliases.put("BRAH", BRAHMI);
             aliases.put("BUGI", BUGINESE);
             aliases.put("BUHD", BUHID);
             aliases.put("CANS", CANADIAN_ABORIGINAL);
@@ -4230,6 +4232,7 @@
             aliases.put("LISU", LISU);
             aliases.put("LYCI", LYCIAN);
             aliases.put("LYDI", LYDIAN);
+            aliases.put("MAND", MANDAIC);
             aliases.put("MLYM", MALAYALAM);
             aliases.put("MONG", MONGOLIAN);
             aliases.put("MTEI", MEETEI_MAYEK);
--- a/src/share/classes/java/lang/reflect/AccessibleObject.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/lang/reflect/AccessibleObject.java	Tue Apr 12 14:23:03 2011 -0700
@@ -26,6 +26,7 @@
 package java.lang.reflect;
 
 import java.security.AccessController;
+import sun.reflect.Reflection;
 import sun.reflect.ReflectionFactory;
 import java.lang.annotation.Annotation;
 
@@ -201,4 +202,73 @@
     public Annotation[] getDeclaredAnnotations()  {
         throw new AssertionError("All subclasses should override this method");
     }
+
+
+    // Shared access checking logic.
+
+    // For non-public members or members in package-private classes,
+    // it is necessary to perform somewhat expensive security checks.
+    // If the security check succeeds for a given class, it will
+    // always succeed (it is not affected by the granting or revoking
+    // of permissions); we speed up the check in the common case by
+    // remembering the last Class for which the check succeeded.
+    //
+    // The simple security check for Constructor is to see if
+    // the caller has already been seen, verified, and cached.
+    // (See also Class.newInstance(), which uses a similar method.)
+    //
+    // A more complicated security check cache is needed for Method and Field
+    // The cache can be either null (empty cache), a 2-array of {caller,target},
+    // or a caller (with target implicitly equal to this.clazz).
+    // In the 2-array case, the target is always different from the clazz.
+    volatile Object securityCheckCache;
+
+    void checkAccess(Class<?> caller, Class<?> clazz, Object obj, int modifiers)
+        throws IllegalAccessException
+    {
+        if (caller == clazz) {  // quick check
+            return;             // ACCESS IS OK
+        }
+        Object cache = securityCheckCache;  // read volatile
+        Class<?> targetClass = clazz;
+        if (obj != null
+            && Modifier.isProtected(modifiers)
+            && ((targetClass = obj.getClass()) != clazz)) {
+            // Must match a 2-list of { caller, targetClass }.
+            if (cache instanceof Class[]) {
+                Class<?>[] cache2 = (Class<?>[]) cache;
+                if (cache2[1] == targetClass &&
+                    cache2[0] == caller) {
+                    return;     // ACCESS IS OK
+                }
+                // (Test cache[1] first since range check for [1]
+                // subsumes range check for [0].)
+            }
+        } else if (cache == caller) {
+            // Non-protected case (or obj.class == this.clazz).
+            return;             // ACCESS IS OK
+        }
+
+        // If no return, fall through to the slow path.
+        slowCheckMemberAccess(caller, clazz, obj, modifiers, targetClass);
+    }
+
+    // Keep all this slow stuff out of line:
+    void slowCheckMemberAccess(Class<?> caller, Class<?> clazz, Object obj, int modifiers,
+                               Class<?> targetClass)
+        throws IllegalAccessException
+    {
+        Reflection.ensureMemberAccess(caller, clazz, obj, modifiers);
+
+        // Success: Update the cache.
+        Object cache = ((targetClass == clazz)
+                        ? caller
+                        : new Class<?>[] { caller, targetClass });
+
+        // Note:  The two cache elements are not volatile,
+        // but they are effectively final.  The Java memory model
+        // guarantees that the initializing stores for the cache
+        // elements will occur before the volatile write.
+        securityCheckCache = cache;         // write volatile
+    }
 }
--- a/src/share/classes/java/lang/reflect/Constructor.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/lang/reflect/Constructor.java	Tue Apr 12 14:23:03 2011 -0700
@@ -74,14 +74,6 @@
     private byte[]              annotations;
     private byte[]              parameterAnnotations;
 
-    // For non-public members or members in package-private classes,
-    // it is necessary to perform somewhat expensive security checks.
-    // If the security check succeeds for a given class, it will
-    // always succeed (it is not affected by the granting or revoking
-    // of permissions); we speed up the check in the common case by
-    // remembering the last Class for which the check succeeded.
-    private volatile Class<?> securityCheckCache;
-
     // Generics infrastructure
     // Accessor for factory
     private GenericsFactory getFactory() {
@@ -495,7 +487,7 @@
      * this object represents
      *
      * @exception IllegalAccessException    if this {@code Constructor} object
-     *              enforces Java language access control and the underlying
+     *              is enforcing Java language access control and the underlying
      *              constructor is inaccessible.
      * @exception IllegalArgumentException  if the number of actual
      *              and formal parameters differ; if an unwrapping
@@ -518,16 +510,17 @@
         if (!override) {
             if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
                 Class<?> caller = Reflection.getCallerClass(2);
-                if (securityCheckCache != caller) {
-                    Reflection.ensureMemberAccess(caller, clazz, null, modifiers);
-                    securityCheckCache = caller;
-                }
+
+                checkAccess(caller, clazz, null, modifiers);
             }
         }
         if ((clazz.getModifiers() & Modifier.ENUM) != 0)
             throw new IllegalArgumentException("Cannot reflectively create enum objects");
-        if (constructorAccessor == null) acquireConstructorAccessor();
-        return (T) constructorAccessor.newInstance(initargs);
+        ConstructorAccessor ca = constructorAccessor;   // read volatile
+        if (ca == null) {
+            ca = acquireConstructorAccessor();
+        }
+        return (T) ca.newInstance(initargs);
     }
 
     /**
@@ -560,18 +553,20 @@
     // ConstructorAccessor for a given Constructor. However, avoiding
     // synchronization will probably make the implementation more
     // scalable.
-    private void acquireConstructorAccessor() {
+    private ConstructorAccessor acquireConstructorAccessor() {
         // First check to see if one has been created yet, and take it
         // if so.
         ConstructorAccessor tmp = null;
         if (root != null) tmp = root.getConstructorAccessor();
         if (tmp != null) {
             constructorAccessor = tmp;
-            return;
+        } else {
+            // Otherwise fabricate one and propagate it up to the root
+            tmp = reflectionFactory.newConstructorAccessor(this);
+            setConstructorAccessor(tmp);
         }
-        // Otherwise fabricate one and propagate it up to the root
-        tmp = reflectionFactory.newConstructorAccessor(this);
-        setConstructorAccessor(tmp);
+
+        return tmp;
     }
 
     // Returns ConstructorAccessor for this Constructor object, not
--- a/src/share/classes/java/lang/reflect/Field.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/lang/reflect/Field.java	Tue Apr 12 14:23:03 2011 -0700
@@ -79,11 +79,6 @@
     // potentially many Field objects pointing to it.)
     private Field               root;
 
-    // More complicated security check cache needed here than for
-    // Class.newInstance() and Constructor.newInstance()
-    private Class<?> securityCheckCache;
-    private Class<?> securityCheckTargetClassCache;
-
     // Generics infrastructure
 
     private String getGenericSignature() {return signature;}
@@ -340,7 +335,7 @@
      * instance of the class or interface declaring the underlying
      * field, the method throws an {@code IllegalArgumentException}.
      *
-     * <p>If this {@code Field} object enforces Java language access control, and
+     * <p>If this {@code Field} object is enforcing Java language access control, and
      * the underlying field is inaccessible, the method throws an
      * {@code IllegalAccessException}.
      * If the underlying field is static, the class that declared the
@@ -360,8 +355,9 @@
      * {@code obj}; primitive values are wrapped in an appropriate
      * object before being returned
      *
-     * @exception IllegalAccessException    if the underlying field
-     *              is inaccessible.
+     * @exception IllegalAccessException    if this {@code Field} object
+     *              is enforcing Java language access control and the underlying
+     *              field is inaccessible.
      * @exception IllegalArgumentException  if the specified object is not an
      *              instance of the class or interface declaring the underlying
      *              field (or a subclass or implementor thereof).
@@ -383,8 +379,9 @@
      * from
      * @return the value of the {@code boolean} field
      *
-     * @exception IllegalAccessException    if the underlying field
-     *              is inaccessible.
+     * @exception IllegalAccessException    if this {@code Field} object
+     *              is enforcing Java language access control and the underlying
+     *              field is inaccessible.
      * @exception IllegalArgumentException  if the specified object is not
      *              an instance of the class or interface declaring the
      *              underlying field (or a subclass or implementor
@@ -410,8 +407,9 @@
      * from
      * @return the value of the {@code byte} field
      *
-     * @exception IllegalAccessException    if the underlying field
-     *              is inaccessible.
+     * @exception IllegalAccessException    if this {@code Field} object
+     *              is enforcing Java language access control and the underlying
+     *              field is inaccessible.
      * @exception IllegalArgumentException  if the specified object is not
      *              an instance of the class or interface declaring the
      *              underlying field (or a subclass or implementor
@@ -439,8 +437,9 @@
      * from
      * @return the value of the field converted to type {@code char}
      *
-     * @exception IllegalAccessException    if the underlying field
-     *              is inaccessible.
+     * @exception IllegalAccessException    if this {@code Field} object
+     *              is enforcing Java language access control and the underlying
+     *              field is inaccessible.
      * @exception IllegalArgumentException  if the specified object is not
      *              an instance of the class or interface declaring the
      *              underlying field (or a subclass or implementor
@@ -468,8 +467,9 @@
      * from
      * @return the value of the field converted to type {@code short}
      *
-     * @exception IllegalAccessException    if the underlying field
-     *              is inaccessible.
+     * @exception IllegalAccessException    if this {@code Field} object
+     *              is enforcing Java language access control and the underlying
+     *              field is inaccessible.
      * @exception IllegalArgumentException  if the specified object is not
      *              an instance of the class or interface declaring the
      *              underlying field (or a subclass or implementor
@@ -497,8 +497,9 @@
      * from
      * @return the value of the field converted to type {@code int}
      *
-     * @exception IllegalAccessException    if the underlying field
-     *              is inaccessible.
+     * @exception IllegalAccessException    if this {@code Field} object
+     *              is enforcing Java language access control and the underlying
+     *              field is inaccessible.
      * @exception IllegalArgumentException  if the specified object is not
      *              an instance of the class or interface declaring the
      *              underlying field (or a subclass or implementor
@@ -526,8 +527,9 @@
      * from
      * @return the value of the field converted to type {@code long}
      *
-     * @exception IllegalAccessException    if the underlying field
-     *              is inaccessible.
+     * @exception IllegalAccessException    if this {@code Field} object
+     *              is enforcing Java language access control and the underlying
+     *              field is inaccessible.
      * @exception IllegalArgumentException  if the specified object is not
      *              an instance of the class or interface declaring the
      *              underlying field (or a subclass or implementor
@@ -555,8 +557,9 @@
      * from
      * @return the value of the field converted to type {@code float}
      *
-     * @exception IllegalAccessException    if the underlying field
-     *              is inaccessible.
+     * @exception IllegalAccessException    if this {@code Field} object
+     *              is enforcing Java language access control and the underlying
+     *              field is inaccessible.
      * @exception IllegalArgumentException  if the specified object is not
      *              an instance of the class or interface declaring the
      *              underlying field (or a subclass or implementor
@@ -584,8 +587,9 @@
      * from
      * @return the value of the field converted to type {@code double}
      *
-     * @exception IllegalAccessException    if the underlying field
-     *              is inaccessible.
+     * @exception IllegalAccessException    if this {@code Field} object
+     *              is enforcing Java language access control and the underlying
+     *              field is inaccessible.
      * @exception IllegalArgumentException  if the specified object is not
      *              an instance of the class or interface declaring the
      *              underlying field (or a subclass or implementor
@@ -621,14 +625,14 @@
      * an instance of the class or interface declaring the underlying
      * field, the method throws an {@code IllegalArgumentException}.
      *
-     * <p>If this {@code Field} object enforces Java language access control, and
+     * <p>If this {@code Field} object is enforcing Java language access control, and
      * the underlying field is inaccessible, the method throws an
      * {@code IllegalAccessException}.
      *
      * <p>If the underlying field is final, the method throws an
-     * {@code IllegalAccessException} unless
-     * {@code setAccessible(true)} has succeeded for this field
-     * and this field is non-static. Setting a final field in this way
+     * {@code IllegalAccessException} unless {@code setAccessible(true)}
+     * has succeeded for this {@code Field} object
+     * and the field is non-static. Setting a final field in this way
      * is meaningful only during deserialization or reconstruction of
      * instances of classes with blank final fields, before they are
      * made available for access by other parts of a program. Use in
@@ -658,8 +662,9 @@
      * @param value the new value for the field of {@code obj}
      * being modified
      *
-     * @exception IllegalAccessException    if the underlying field
-     *              is inaccessible.
+     * @exception IllegalAccessException    if this {@code Field} object
+     *              is enforcing Java language access control and the underlying
+     *              field is either inaccessible or final.
      * @exception IllegalArgumentException  if the specified object is not an
      *              instance of the class or interface declaring the underlying
      *              field (or a subclass or implementor thereof),
@@ -686,8 +691,9 @@
      * @param z   the new value for the field of {@code obj}
      * being modified
      *
-     * @exception IllegalAccessException    if the underlying field
-     *              is inaccessible.
+     * @exception IllegalAccessException    if this {@code Field} object
+     *              is enforcing Java language access control and the underlying
+     *              field is either inaccessible or final.
      * @exception IllegalArgumentException  if the specified object is not an
      *              instance of the class or interface declaring the underlying
      *              field (or a subclass or implementor thereof),
@@ -715,8 +721,9 @@
      * @param b   the new value for the field of {@code obj}
      * being modified
      *
-     * @exception IllegalAccessException    if the underlying field
-     *              is inaccessible.
+     * @exception IllegalAccessException    if this {@code Field} object
+     *              is enforcing Java language access control and the underlying
+     *              field is either inaccessible or final.
      * @exception IllegalArgumentException  if the specified object is not an
      *              instance of the class or interface declaring the underlying
      *              field (or a subclass or implementor thereof),
@@ -744,8 +751,9 @@
      * @param c   the new value for the field of {@code obj}
      * being modified
      *
-     * @exception IllegalAccessException    if the underlying field
-     *              is inaccessible.
+     * @exception IllegalAccessException    if this {@code Field} object
+     *              is enforcing Java language access control and the underlying
+     *              field is either inaccessible or final.
      * @exception IllegalArgumentException  if the specified object is not an
      *              instance of the class or interface declaring the underlying
      *              field (or a subclass or implementor thereof),
@@ -773,8 +781,9 @@
      * @param s   the new value for the field of {@code obj}
      * being modified
      *
-     * @exception IllegalAccessException    if the underlying field
-     *              is inaccessible.
+     * @exception IllegalAccessException    if this {@code Field} object
+     *              is enforcing Java language access control and the underlying
+     *              field is either inaccessible or final.
      * @exception IllegalArgumentException  if the specified object is not an
      *              instance of the class or interface declaring the underlying
      *              field (or a subclass or implementor thereof),
@@ -802,8 +811,9 @@
      * @param i   the new value for the field of {@code obj}
      * being modified
      *
-     * @exception IllegalAccessException    if the underlying field
-     *              is inaccessible.
+     * @exception IllegalAccessException    if this {@code Field} object
+     *              is enforcing Java language access control and the underlying
+     *              field is either inaccessible or final.
      * @exception IllegalArgumentException  if the specified object is not an
      *              instance of the class or interface declaring the underlying
      *              field (or a subclass or implementor thereof),
@@ -831,8 +841,9 @@
      * @param l   the new value for the field of {@code obj}
      * being modified
      *
-     * @exception IllegalAccessException    if the underlying field
-     *              is inaccessible.
+     * @exception IllegalAccessException    if this {@code Field} object
+     *              is enforcing Java language access control and the underlying
+     *              field is either inaccessible or final.
      * @exception IllegalArgumentException  if the specified object is not an
      *              instance of the class or interface declaring the underlying
      *              field (or a subclass or implementor thereof),
@@ -860,8 +871,9 @@
      * @param f   the new value for the field of {@code obj}
      * being modified
      *
-     * @exception IllegalAccessException    if the underlying field
-     *              is inaccessible.
+     * @exception IllegalAccessException    if this {@code Field} object
+     *              is enforcing Java language access control and the underlying
+     *              field is either inaccessible or final.
      * @exception IllegalArgumentException  if the specified object is not an
      *              instance of the class or interface declaring the underlying
      *              field (or a subclass or implementor thereof),
@@ -889,8 +901,9 @@
      * @param d   the new value for the field of {@code obj}
      * being modified
      *
-     * @exception IllegalAccessException    if the underlying field
-     *              is inaccessible.
+     * @exception IllegalAccessException    if this {@code Field} object
+     *              is enforcing Java language access control and the underlying
+     *              field is either inaccessible or final.
      * @exception IllegalArgumentException  if the specified object is not an
      *              instance of the class or interface declaring the underlying
      *              field (or a subclass or implementor thereof),
@@ -936,6 +949,7 @@
             tmp = reflectionFactory.newFieldAccessor(this, overrideFinalCheck);
             setFieldAccessor(tmp, overrideFinalCheck);
         }
+
         return tmp;
     }
 
@@ -965,21 +979,8 @@
         if (!override) {
             if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
                 Class<?> caller = Reflection.getCallerClass(4);
-                Class<?> targetClass = ((obj == null || !Modifier.isProtected(modifiers))
-                                        ? clazz
-                                        : obj.getClass());
 
-                synchronized (this) {
-                    if ((securityCheckCache == caller)
-                            && (securityCheckTargetClassCache == targetClass)) {
-                        return;
-                    }
-                }
-                Reflection.ensureMemberAccess(caller, clazz, obj, modifiers);
-                synchronized (this) {
-                    securityCheckCache = caller;
-                    securityCheckTargetClassCache = targetClass;
-                }
+                checkAccess(caller, clazz, obj, modifiers);
             }
         }
     }
--- a/src/share/classes/java/lang/reflect/Method.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/lang/reflect/Method.java	Tue Apr 12 14:23:03 2011 -0700
@@ -83,11 +83,6 @@
     // potentially many Method objects pointing to it.)
     private Method              root;
 
-    // More complicated security check cache needed here than for
-    // Class.newInstance() and Constructor.newInstance()
-    private Class<?> securityCheckCache;
-    private Class<?> securityCheckTargetClassCache;
-
    // Generics infrastructure
 
     private String getGenericSignature() {return signature;}
@@ -402,28 +397,28 @@
      */
     public String toString() {
         try {
-            StringBuffer sb = new StringBuffer();
+            StringBuilder sb = new StringBuilder();
             int mod = getModifiers() & Modifier.methodModifiers();
             if (mod != 0) {
-                sb.append(Modifier.toString(mod) + " ");
+                sb.append(Modifier.toString(mod)).append(' ');
             }
-            sb.append(Field.getTypeName(getReturnType()) + " ");
-            sb.append(Field.getTypeName(getDeclaringClass()) + ".");
-            sb.append(getName() + "(");
+            sb.append(Field.getTypeName(getReturnType())).append(' ');
+            sb.append(Field.getTypeName(getDeclaringClass())).append('.');
+            sb.append(getName()).append('(');
             Class<?>[] params = parameterTypes; // avoid clone
             for (int j = 0; j < params.length; j++) {
                 sb.append(Field.getTypeName(params[j]));
                 if (j < (params.length - 1))
-                    sb.append(",");
+                    sb.append(',');
             }
-            sb.append(")");
+            sb.append(')');
             Class<?>[] exceptions = exceptionTypes; // avoid clone
             if (exceptions.length > 0) {
                 sb.append(" throws ");
                 for (int k = 0; k < exceptions.length; k++) {
                     sb.append(exceptions[k].getName());
                     if (k < (exceptions.length - 1))
-                        sb.append(",");
+                        sb.append(',');
                 }
             }
             return sb.toString();
@@ -475,15 +470,15 @@
             StringBuilder sb = new StringBuilder();
             int mod = getModifiers() & Modifier.methodModifiers();
             if (mod != 0) {
-                sb.append(Modifier.toString(mod) + " ");
+                sb.append(Modifier.toString(mod)).append(' ');
             }
             TypeVariable<?>[] typeparms = getTypeParameters();
             if (typeparms.length > 0) {
                 boolean first = true;
-                sb.append("<");
+                sb.append('<');
                 for(TypeVariable<?> typeparm: typeparms) {
                     if (!first)
-                        sb.append(",");
+                        sb.append(',');
                     // Class objects can't occur here; no need to test
                     // and call Class.getName().
                     sb.append(typeparm.toString());
@@ -494,10 +489,11 @@
 
             Type genRetType = getGenericReturnType();
             sb.append( ((genRetType instanceof Class<?>)?
-                        Field.getTypeName((Class<?>)genRetType):genRetType.toString())  + " ");
+                        Field.getTypeName((Class<?>)genRetType):genRetType.toString()))
+                    .append(' ');
 
-            sb.append(Field.getTypeName(getDeclaringClass()) + ".");
-            sb.append(getName() + "(");
+            sb.append(Field.getTypeName(getDeclaringClass())).append('.');
+            sb.append(getName()).append('(');
             Type[] params = getGenericParameterTypes();
             for (int j = 0; j < params.length; j++) {
                 String param = (params[j] instanceof Class)?
@@ -507,9 +503,9 @@
                     param = param.replaceFirst("\\[\\]$", "...");
                 sb.append(param);
                 if (j < (params.length - 1))
-                    sb.append(",");
+                    sb.append(',');
             }
-            sb.append(")");
+            sb.append(')');
             Type[] exceptions = getGenericExceptionTypes();
             if (exceptions.length > 0) {
                 sb.append(" throws ");
@@ -518,7 +514,7 @@
                               ((Class)exceptions[k]).getName():
                               exceptions[k].toString());
                     if (k < (exceptions.length - 1))
-                        sb.append(",");
+                        sb.append(',');
                 }
             }
             return sb.toString();
@@ -565,7 +561,7 @@
      * {@code args}
      *
      * @exception IllegalAccessException    if this {@code Method} object
-     *              enforces Java language access control and the underlying
+     *              is enforcing Java language access control and the underlying
      *              method is inaccessible.
      * @exception IllegalArgumentException  if the method is an
      *              instance method and the specified object argument
@@ -591,26 +587,15 @@
         if (!override) {
             if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
                 Class<?> caller = Reflection.getCallerClass(1);
-                Class<?> targetClass = ((obj == null || !Modifier.isProtected(modifiers))
-                                        ? clazz
-                                        : obj.getClass());
 
-                boolean cached;
-                synchronized (this) {
-                    cached = (securityCheckCache == caller)
-                            && (securityCheckTargetClassCache == targetClass);
-                }
-                if (!cached) {
-                    Reflection.ensureMemberAccess(caller, clazz, obj, modifiers);
-                    synchronized (this) {
-                        securityCheckCache = caller;
-                        securityCheckTargetClassCache = targetClass;
-                    }
-                }
+                checkAccess(caller, clazz, obj, modifiers);
             }
         }
-        if (methodAccessor == null) acquireMethodAccessor();
-        return methodAccessor.invoke(obj, args);
+        MethodAccessor ma = methodAccessor;             // read volatile
+        if (ma == null) {
+            ma = acquireMethodAccessor();
+        }
+        return ma.invoke(obj, args);
     }
 
     /**
@@ -654,18 +639,20 @@
     // (though not efficient) to generate more than one MethodAccessor
     // for a given Method. However, avoiding synchronization will
     // probably make the implementation more scalable.
-    private void acquireMethodAccessor() {
+    private MethodAccessor acquireMethodAccessor() {
         // First check to see if one has been created yet, and take it
         // if so
         MethodAccessor tmp = null;
         if (root != null) tmp = root.getMethodAccessor();
         if (tmp != null) {
             methodAccessor = tmp;
-            return;
+        } else {
+            // Otherwise fabricate one and propagate it up to the root
+            tmp = reflectionFactory.newMethodAccessor(this);
+            setMethodAccessor(tmp);
         }
-        // Otherwise fabricate one and propagate it up to the root
-        tmp = reflectionFactory.newMethodAccessor(this);
-        setMethodAccessor(tmp);
+
+        return tmp;
     }
 
     // Returns MethodAccessor for this Method object, not looking up
--- a/src/share/classes/java/nio/file/Files.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/nio/file/Files.java	Tue Apr 12 14:23:03 2011 -0700
@@ -2067,7 +2067,7 @@
      *
      * @return  {@code true} if the file is a symbolic link; {@code false} if
      *          the file does not exist, is not a symbolic link, or it cannot
-     *          be determined if the file is symbolic link or not.
+     *          be determined if the file is a symbolic link or not.
      *
      * @throws  SecurityException
      *          In the case of the default provider, and a security manager is
@@ -2106,7 +2106,7 @@
      *
      * @return  {@code true} if the file is a directory; {@code false} if
      *          the file does not exist, is not a directory, or it cannot
-     *          be determined if the file is directory or not.
+     *          be determined if the file is a directory or not.
      *
      * @throws  SecurityException
      *          In the case of the default provider, and a security manager is
@@ -2142,8 +2142,8 @@
      *          options indicating how symbolic links are handled
      *
      * @return  {@code true} if the file is a regular file; {@code false} if
-     *          the file does not exist, is not a direcregular filetory, or it
-     *          cannot be determined if the file is regular file or not.
+     *          the file does not exist, is not a regular file, or it
+     *          cannot be determined if the file is a regular file or not.
      *
      * @throws  SecurityException
      *          In the case of the default provider, and a security manager is
--- a/src/share/classes/java/nio/file/Path.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/nio/file/Path.java	Tue Apr 12 14:23:03 2011 -0700
@@ -550,18 +550,21 @@
      * <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.
+     * <p> The {@code options} array may be used to indicate how symbolic links
+     * are handled. By default, symbolic links are resolved to their final
+     * target. If the option {@link LinkOption#NOFOLLOW_LINKS NOFOLLOW_LINKS} is
+     * present 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 cause 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.
+     *
+     * @param   options
+     *          options indicating how symbolic links are handled
      *
      * @return  an absolute path represent the <em>real</em> path of the file
      *          located by this object
@@ -576,7 +579,7 @@
      *          checkPropertyAccess} method is invoked to check access to the
      *          system property {@code user.dir}
      */
-    Path toRealPath(boolean resolveLinks) throws IOException;
+    Path toRealPath(LinkOption... options) throws IOException;
 
     /**
      * Returns a {@link File} object representing this path. Where this {@code
--- a/src/share/classes/java/sql/DriverManager.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/sql/DriverManager.java	Tue Apr 12 14:23:03 2011 -0700
@@ -80,7 +80,7 @@
 
 
     // List of registered JDBC drivers
-    private final static CopyOnWriteArrayList<Driver> registeredDrivers = new CopyOnWriteArrayList<Driver>();
+    private final static CopyOnWriteArrayList<DriverInfo> registeredDrivers = new CopyOnWriteArrayList<DriverInfo>();
     private static volatile int loginTimeout = 0;
     private static volatile java.io.PrintWriter logWriter = null;
     private static volatile java.io.PrintStream logStream = null;
@@ -265,22 +265,22 @@
 
         // Walk through the loaded registeredDrivers attempting to locate someone
         // who understands the given URL.
-        for (Driver aDriver : registeredDrivers) {
+        for (DriverInfo aDriver : registeredDrivers) {
             // If the caller does not have permission to load the driver then
             // skip it.
-            if(isDriverAllowed(aDriver, callerCL)) {
+            if(isDriverAllowed(aDriver.driver, callerCL)) {
                 try {
-                    if(aDriver.acceptsURL(url)) {
+                    if(aDriver.driver.acceptsURL(url)) {
                         // Success!
-                        println("getDriver returning " + aDriver.getClass().getName());
-                    return (aDriver);
+                        println("getDriver returning " + aDriver.driver.getClass().getName());
+                    return (aDriver.driver);
                     }
 
                 } catch(SQLException sqe) {
                     // Drop through and try the next driver.
                 }
             } else {
-                println("    skipping: " + aDriver.getClass().getName());
+                println("    skipping: " + aDriver.driver.getClass().getName());
             }
 
         }
@@ -305,7 +305,7 @@
 
         /* Register the driver if it has not already been added to our list */
         if(driver != null) {
-            registeredDrivers.addIfAbsent(driver);
+            registeredDrivers.addIfAbsent(new DriverInfo(driver));
         } else {
             // This is for compatibility with the original DriverManager
             throw new NullPointerException();
@@ -333,9 +333,10 @@
         ClassLoader callerCL = DriverManager.getCallerClassLoader();
         println("DriverManager.deregisterDriver: " + driver);
 
-        if(registeredDrivers.contains(driver)) {
+        DriverInfo aDriver = new DriverInfo(driver);
+        if(registeredDrivers.contains(aDriver)) {
             if (isDriverAllowed(driver, callerCL)) {
-                 registeredDrivers.remove(driver);
+                 registeredDrivers.remove(aDriver);
             } else {
                 // If the caller does not have permission to load the driver then
                 // throw a SecurityException.
@@ -363,11 +364,11 @@
         ClassLoader callerCL = DriverManager.getCallerClassLoader();
 
         // Walk through the loaded registeredDrivers.
-        for(Driver aDriver : registeredDrivers) {
+        for(DriverInfo aDriver : registeredDrivers) {
             // If the caller does not have permission to load the driver then
             // skip it.
-            if(isDriverAllowed(aDriver, callerCL)) {
-                result.addElement(aDriver);
+            if(isDriverAllowed(aDriver.driver, callerCL)) {
+                result.addElement(aDriver.driver);
             } else {
                 println("    skipping: " + aDriver.getClass().getName());
             }
@@ -482,8 +483,8 @@
     private static void loadInitialDrivers() {
         String drivers;
         try {
-            drivers = (String)  AccessController.doPrivileged(new PrivilegedAction() {
-                public Object run() {
+            drivers = AccessController.doPrivileged(new PrivilegedAction<String>() {
+                public String run() {
                     return System.getProperty("jdbc.drivers");
                 }
             });
@@ -495,8 +496,8 @@
         // exposed as a java.sql.Driver.class service.
         // ServiceLoader.load() replaces the sun.misc.Providers()
 
-        AccessController.doPrivileged(new PrivilegedAction() {
-            public Object run() {
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+            public Void run() {
 
                 ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class);
                 Iterator driversIterator = loadedDrivers.iterator();
@@ -569,16 +570,16 @@
         // Remember the first exception that gets raised so we can reraise it.
         SQLException reason = null;
 
-        for(Driver aDriver : registeredDrivers) {
+        for(DriverInfo aDriver : registeredDrivers) {
             // If the caller does not have permission to load the driver then
             // skip it.
-            if(isDriverAllowed(aDriver, callerCL)) {
+            if(isDriverAllowed(aDriver.driver, callerCL)) {
                 try {
-                    println("    trying " + aDriver.getClass().getName());
-                    Connection con = aDriver.connect(url, info);
+                    println("    trying " + aDriver.driver.getClass().getName());
+                    Connection con = aDriver.driver.connect(url, info);
                     if (con != null) {
                         // Success!
-                        println("getConnection returning " + aDriver.getClass().getName());
+                        println("getConnection returning " + aDriver.driver.getClass().getName());
                         return (con);
                     }
                 } catch (SQLException ex) {
@@ -607,3 +608,29 @@
     private static native ClassLoader getCallerClassLoader();
 
 }
+
+/*
+ * Wrapper class for registered Drivers in order to not expose Driver.equals()
+ * to avoid the capture of the Driver it being compared to as it might not
+ * normally have access.
+ */
+class DriverInfo {
+
+    final Driver driver;
+    DriverInfo(Driver driver) {
+        this.driver = driver;
+    }
+
+    public boolean equals(Object other) {
+        return (other instanceof DriverInfo)
+                && this.driver == ((DriverInfo) other).driver;
+    }
+
+    public int hashCode() {
+        return driver.hashCode();
+    }
+
+    public String toString() {
+        return ("driver[className="  + driver + "]");
+    }
+}
--- a/src/share/classes/java/util/AbstractQueue.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/AbstractQueue.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util;
--- a/src/share/classes/java/util/ArrayDeque.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/ArrayDeque.java	Tue Apr 12 14:23:03 2011 -0700
@@ -29,7 +29,7 @@
  * file:
  *
  * Written by Josh Bloch of Google Inc. and released to the public domain,
- * as explained at http://creativecommons.org/licenses/publicdomain.
+ * as explained at http://creativecommons.org/publicdomain/zero/1.0/.
  */
 
 package java.util;
--- a/src/share/classes/java/util/Deque.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/Deque.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea and Josh Bloch with assistance from members of
  * JCP JSR-166 Expert Group and released to the public domain, as explained
- * at http://creativecommons.org/licenses/publicdomain
+ * at http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util;
--- a/src/share/classes/java/util/EnumMap.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/EnumMap.java	Tue Apr 12 14:23:03 2011 -0700
@@ -106,7 +106,7 @@
     /**
      * Distinguished non-null value for representing null values.
      */
-    private static final Object NULL = new Object();
+    private static final Object NULL = new Integer(0);
 
     private Object maskNull(Object value) {
         return (value == null ? NULL : value);
@@ -116,7 +116,7 @@
         return (V) (value == NULL ? null : value);
     }
 
-    private static Enum[] ZERO_LENGTH_ENUM_ARRAY = new Enum[0];
+    private static final Enum[] ZERO_LENGTH_ENUM_ARRAY = new Enum[0];
 
     /**
      * Creates an empty enum map with the specified key type.
@@ -464,6 +464,7 @@
         public Iterator<Map.Entry<K,V>> iterator() {
             return new EntryIterator();
         }
+
         public boolean contains(Object o) {
             if (!(o instanceof Map.Entry))
                 return false;
@@ -552,70 +553,82 @@
         }
     }
 
-    /**
-     * Since we don't use Entry objects, we use the Iterator itself as entry.
-     */
-    private class EntryIterator extends EnumMapIterator<Map.Entry<K,V>>
-        implements Map.Entry<K,V>
-    {
+    private class EntryIterator extends EnumMapIterator<Map.Entry<K,V>> {
+        private Entry lastReturnedEntry = null;
+
         public Map.Entry<K,V> next() {
             if (!hasNext())
                 throw new NoSuchElementException();
-            lastReturnedIndex = index++;
-            return this;
+            lastReturnedEntry = new Entry(index++);
+            return lastReturnedEntry;
         }
 
-        public K getKey() {
-            checkLastReturnedIndexForEntryUse();
-            return keyUniverse[lastReturnedIndex];
+        public void remove() {
+            lastReturnedIndex =
+                ((null == lastReturnedEntry) ? -1 : lastReturnedEntry.index);
+            super.remove();
+            lastReturnedEntry.index = lastReturnedIndex;
+            lastReturnedEntry = null;
         }
 
-        public V getValue() {
-            checkLastReturnedIndexForEntryUse();
-            return unmaskNull(vals[lastReturnedIndex]);
-        }
+        private class Entry implements Map.Entry<K,V> {
+            private int index;
 
-        public V setValue(V value) {
-            checkLastReturnedIndexForEntryUse();
-            V oldValue = unmaskNull(vals[lastReturnedIndex]);
-            vals[lastReturnedIndex] = maskNull(value);
-            return oldValue;
-        }
+            private Entry(int index) {
+                this.index = index;
+            }
 
-        public boolean equals(Object o) {
-            if (lastReturnedIndex < 0)
-                return o == this;
+            public K getKey() {
+                checkIndexForEntryUse();
+                return keyUniverse[index];
+            }
 
-            if (!(o instanceof Map.Entry))
-                return false;
-            Map.Entry e = (Map.Entry)o;
-            V ourValue = unmaskNull(vals[lastReturnedIndex]);
-            Object hisValue = e.getValue();
-            return e.getKey() == keyUniverse[lastReturnedIndex] &&
-                (ourValue == hisValue ||
-                 (ourValue != null && ourValue.equals(hisValue)));
-        }
+            public V getValue() {
+                checkIndexForEntryUse();
+                return unmaskNull(vals[index]);
+            }
 
-        public int hashCode() {
-            if (lastReturnedIndex < 0)
-                return super.hashCode();
+            public V setValue(V value) {
+                checkIndexForEntryUse();
+                V oldValue = unmaskNull(vals[index]);
+                vals[index] = maskNull(value);
+                return oldValue;
+            }
 
-            Object value = vals[lastReturnedIndex];
-            return keyUniverse[lastReturnedIndex].hashCode()
-                ^ (value == NULL ? 0 : value.hashCode());
-        }
+            public boolean equals(Object o) {
+                if (index < 0)
+                    return o == this;
 
-        public String toString() {
-            if (lastReturnedIndex < 0)
-                return super.toString();
+                if (!(o instanceof Map.Entry))
+                    return false;
 
-            return keyUniverse[lastReturnedIndex] + "="
-                + unmaskNull(vals[lastReturnedIndex]);
-        }
+                Map.Entry e = (Map.Entry)o;
+                V ourValue = unmaskNull(vals[index]);
+                Object hisValue = e.getValue();
+                return (e.getKey() == keyUniverse[index] &&
+                        (ourValue == hisValue ||
+                         (ourValue != null && ourValue.equals(hisValue))));
+            }
 
-        private void checkLastReturnedIndexForEntryUse() {
-            if (lastReturnedIndex < 0)
-                throw new IllegalStateException("Entry was removed");
+            public int hashCode() {
+                if (index < 0)
+                    return super.hashCode();
+
+                return entryHashCode(index);
+            }
+
+            public String toString() {
+                if (index < 0)
+                    return super.toString();
+
+                return keyUniverse[index] + "="
+                    + unmaskNull(vals[index]);
+            }
+
+            private void checkIndexForEntryUse() {
+                if (index < 0)
+                    throw new IllegalStateException("Entry was removed");
+            }
         }
     }
 
@@ -631,10 +644,35 @@
      * @return <tt>true</tt> if the specified object is equal to this map
      */
     public boolean equals(Object o) {
-        if (!(o instanceof EnumMap))
-            return super.equals(o);
+        if (this == o)
+            return true;
+        if (o instanceof EnumMap)
+            return equals((EnumMap)o);
+        if (!(o instanceof Map))
+            return false;
 
-        EnumMap em = (EnumMap)o;
+        Map<K,V> m = (Map<K,V>)o;
+        if (size != m.size())
+            return false;
+
+        for (int i = 0; i < keyUniverse.length; i++) {
+            if (null != vals[i]) {
+                K key = keyUniverse[i];
+                V value = unmaskNull(vals[i]);
+                if (null == value) {
+                    if (!((null == m.get(key)) && m.containsKey(key)))
+                       return false;
+                } else {
+                   if (!value.equals(m.get(key)))
+                      return false;
+                }
+            }
+        }
+
+        return true;
+    }
+
+    private boolean equals(EnumMap em) {
         if (em.keyType != keyType)
             return size == 0 && em.size == 0;
 
@@ -650,6 +688,26 @@
     }
 
     /**
+     * Returns the hash code value for this map.  The hash code of a map is
+     * defined to be the sum of the hash codes of each entry in the map.
+     */
+    public int hashCode() {
+        int h = 0;
+
+        for (int i = 0; i < keyUniverse.length; i++) {
+            if (null != vals[i]) {
+                h += entryHashCode(i);
+            }
+        }
+
+        return h;
+    }
+
+    private int entryHashCode(int index) {
+        return (keyUniverse[index].hashCode() ^ vals[index].hashCode());
+    }
+
+    /**
      * Returns a shallow copy of this enum map.  (The values themselves
      * are not cloned.
      *
@@ -705,9 +763,13 @@
         s.writeInt(size);
 
         // Write out keys and values (alternating)
-        for (Map.Entry<K,V> e :  entrySet()) {
-            s.writeObject(e.getKey());
-            s.writeObject(e.getValue());
+        int entriesToBeWritten = size;
+        for (int i = 0; entriesToBeWritten > 0; i++) {
+            if (null != vals[i]) {
+                s.writeObject(keyUniverse[i]);
+                s.writeObject(unmaskNull(vals[i]));
+                entriesToBeWritten--;
+            }
         }
     }
 
--- a/src/share/classes/java/util/IdentityHashMap.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/IdentityHashMap.java	Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -829,71 +829,82 @@
         }
     }
 
-    /**
-     * Since we don't use Entry objects, we use the Iterator
-     * itself as an entry.
-     */
     private class EntryIterator
         extends IdentityHashMapIterator<Map.Entry<K,V>>
-        implements Map.Entry<K,V>
     {
+        private Entry lastReturnedEntry = null;
+
         public Map.Entry<K,V> next() {
-            nextIndex();
-            return this;
+            lastReturnedEntry = new Entry(nextIndex());
+            return lastReturnedEntry;
         }
 
-        public K getKey() {
-            // Provide a better exception than out of bounds index
-            if (lastReturnedIndex < 0)
-                throw new IllegalStateException("Entry was removed");
-
-            return (K) unmaskNull(traversalTable[lastReturnedIndex]);
+        public void remove() {
+            lastReturnedIndex =
+                ((null == lastReturnedEntry) ? -1 : lastReturnedEntry.index);
+            super.remove();
+            lastReturnedEntry.index = lastReturnedIndex;
+            lastReturnedEntry = null;
         }
 
-        public V getValue() {
-            // Provide a better exception than out of bounds index
-            if (lastReturnedIndex < 0)
-                throw new IllegalStateException("Entry was removed");
+        private class Entry implements Map.Entry<K,V> {
+            private int index;
 
-            return (V) traversalTable[lastReturnedIndex+1];
-        }
+            private Entry(int index) {
+                this.index = index;
+            }
 
-        public V setValue(V value) {
-            // It would be mean-spirited to proceed here if remove() called
-            if (lastReturnedIndex < 0)
-                throw new IllegalStateException("Entry was removed");
-            V oldValue = (V) traversalTable[lastReturnedIndex+1];
-            traversalTable[lastReturnedIndex+1] = value;
-            // if shadowing, force into main table
-            if (traversalTable != IdentityHashMap.this.table)
-                put((K) traversalTable[lastReturnedIndex], value);
-            return oldValue;
-        }
+            public K getKey() {
+                checkIndexForEntryUse();
+                return (K) unmaskNull(traversalTable[index]);
+            }
 
-        public boolean equals(Object o) {
-            if (lastReturnedIndex < 0)
-                return super.equals(o);
+            public V getValue() {
+                checkIndexForEntryUse();
+                return (V) traversalTable[index+1];
+            }
 
-            if (!(o instanceof Map.Entry))
-                return false;
-            Map.Entry e = (Map.Entry)o;
-            return e.getKey()   == getKey() &&
-                   e.getValue() == getValue();
-        }
+            public V setValue(V value) {
+                checkIndexForEntryUse();
+                V oldValue = (V) traversalTable[index+1];
+                traversalTable[index+1] = value;
+                // if shadowing, force into main table
+                if (traversalTable != IdentityHashMap.this.table)
+                    put((K) traversalTable[index], value);
+                return oldValue;
+            }
 
-        public int hashCode() {
-            if (lastReturnedIndex < 0)
-                return super.hashCode();
+            public boolean equals(Object o) {
+                if (index < 0)
+                    return super.equals(o);
 
-            return System.identityHashCode(getKey()) ^
-                   System.identityHashCode(getValue());
-        }
+                if (!(o instanceof Map.Entry))
+                    return false;
+                Map.Entry e = (Map.Entry)o;
+                return (e.getKey() == unmaskNull(traversalTable[index]) &&
+                       e.getValue() == traversalTable[index+1]);
+            }
 
-        public String toString() {
-            if (lastReturnedIndex < 0)
-                return super.toString();
+            public int hashCode() {
+                if (lastReturnedIndex < 0)
+                    return super.hashCode();
 
-            return getKey() + "=" + getValue();
+                return (System.identityHashCode(unmaskNull(traversalTable[index])) ^
+                       System.identityHashCode(traversalTable[index+1]));
+            }
+
+            public String toString() {
+                if (index < 0)
+                    return super.toString();
+
+                return (unmaskNull(traversalTable[index]) + "="
+                        + traversalTable[index+1]);
+            }
+
+            private void checkIndexForEntryUse() {
+                if (index < 0)
+                    throw new IllegalStateException("Entry was removed");
+            }
         }
     }
 
--- a/src/share/classes/java/util/NavigableMap.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/NavigableMap.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea and Josh Bloch with assistance from members of JCP
  * JSR-166 Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util;
--- a/src/share/classes/java/util/NavigableSet.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/NavigableSet.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea and Josh Bloch with assistance from members of JCP
  * JSR-166 Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util;
--- a/src/share/classes/java/util/Queue.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/Queue.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util;
--- a/src/share/classes/java/util/concurrent/AbstractExecutorService.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/AbstractExecutorService.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/ArrayBlockingQueue.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/ArrayBlockingQueue.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/BlockingDeque.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/BlockingDeque.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/BlockingQueue.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/BlockingQueue.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/BrokenBarrierException.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/BrokenBarrierException.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/Callable.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/Callable.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/CancellationException.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/CancellationException.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/CompletionService.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/CompletionService.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/ConcurrentHashMap.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/ConcurrentHashMap.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea and Martin Buchholz with assistance from members of
  * JCP JSR-166 Expert Group and released to the public domain, as explained
- * at http://creativecommons.org/licenses/publicdomain
+ * at http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea and Martin Buchholz with assistance from members of
  * JCP JSR-166 Expert Group and released to the public domain, as explained
- * at http://creativecommons.org/licenses/publicdomain
+ * at http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/ConcurrentMap.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/ConcurrentMap.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/ConcurrentNavigableMap.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/ConcurrentNavigableMap.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/ConcurrentSkipListMap.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/ConcurrentSkipListMap.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/ConcurrentSkipListSet.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/ConcurrentSkipListSet.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/CopyOnWriteArraySet.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/CopyOnWriteArraySet.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/CountDownLatch.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/CountDownLatch.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/CyclicBarrier.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/CyclicBarrier.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/DelayQueue.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/DelayQueue.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 
--- a/src/share/classes/java/util/concurrent/Delayed.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/Delayed.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/Exchanger.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/Exchanger.java	Tue Apr 12 14:23:03 2011 -0700
@@ -31,7 +31,7 @@
  * Written by Doug Lea, Bill Scherer, and Michael Scott with
  * assistance from members of JCP JSR-166 Expert Group and released to
  * the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/ExecutionException.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/ExecutionException.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/Executor.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/Executor.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/ExecutorCompletionService.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/ExecutorCompletionService.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/ExecutorService.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/ExecutorService.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/Executors.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/Executors.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/ForkJoinPool.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/ForkJoinPool.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
@@ -791,18 +791,19 @@
 
     /**
      * Tries to enqueue worker w in wait queue and await change in
-     * worker's eventCount.  If the pool is quiescent, possibly
-     * terminates worker upon exit.  Otherwise, before blocking,
-     * rescans queues to avoid missed signals.  Upon finding work,
-     * releases at least one worker (which may be the current
-     * worker). Rescans restart upon detected staleness or failure to
-     * release due to contention. Note the unusual conventions about
-     * Thread.interrupt here and elsewhere: Because interrupts are
-     * used solely to alert threads to check termination, which is
-     * checked here anyway, we clear status (using Thread.interrupted)
-     * before any call to park, so that park does not immediately
-     * return due to status being set via some other unrelated call to
-     * interrupt in user code.
+     * worker's eventCount.  If the pool is quiescent and there is
+     * more than one worker, possibly terminates worker upon exit.
+     * Otherwise, before blocking, rescans queues to avoid missed
+     * signals.  Upon finding work, releases at least one worker
+     * (which may be the current worker). Rescans restart upon
+     * detected staleness or failure to release due to
+     * contention. Note the unusual conventions about Thread.interrupt
+     * here and elsewhere: Because interrupts are used solely to alert
+     * threads to check termination, which is checked here anyway, we
+     * clear status (using Thread.interrupted) before any call to
+     * park, so that park does not immediately return due to status
+     * being set via some other unrelated call to interrupt in user
+     * code.
      *
      * @param w the calling worker
      * @param c the ctl value on entry
@@ -823,7 +824,7 @@
             else if (w.eventCount != v)
                 return true;                      // update next time
         }
-        if (parallelism + (int)(nc >> AC_SHIFT) == 0 &&
+        if ((int)c != 0 && parallelism + (int)(nc >> AC_SHIFT) == 0 &&
             blockedCount == 0 && quiescerCount == 0)
             idleAwaitWork(w, nc, c, v);           // quiescent
         for (boolean rescanned = false;;) {
@@ -893,7 +894,8 @@
                 w.parked = false;
                 if (w.eventCount != v)
                     break;
-                else if (System.nanoTime() - startTime < SHRINK_RATE)
+                else if (System.nanoTime() - startTime <
+                         SHRINK_RATE - (SHRINK_RATE / 10)) // timing slop
                     Thread.interrupted();          // spurious wakeup
                 else if (UNSAFE.compareAndSwapLong(this, ctlOffset,
                                                    currentCtl, prevCtl)) {
@@ -1175,7 +1177,7 @@
                         ws[k] = w;
                         nextWorkerIndex = k + 1;
                         int m = g & SMASK;
-                        g = k >= m? ((m << 1) + 1) & SMASK : g + (SG_UNIT<<1);
+                        g = k > m? ((m << 1) + 1) & SMASK : g + (SG_UNIT<<1);
                     }
                 } finally {
                     scanGuard = g;
--- a/src/share/classes/java/util/concurrent/ForkJoinTask.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/ForkJoinTask.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/ForkJoinWorkerThread.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/ForkJoinWorkerThread.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/Future.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/Future.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/FutureTask.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/FutureTask.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/LinkedBlockingDeque.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/LinkedBlockingDeque.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/LinkedBlockingQueue.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/LinkedBlockingQueue.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/LinkedTransferQueue.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/LinkedTransferQueue.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/Phaser.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/Phaser.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/PriorityBlockingQueue.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/PriorityBlockingQueue.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/RecursiveAction.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/RecursiveAction.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/RecursiveTask.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/RecursiveTask.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/RejectedExecutionException.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/RejectedExecutionException.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/RejectedExecutionHandler.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/RejectedExecutionHandler.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/RunnableFuture.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/RunnableFuture.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/RunnableScheduledFuture.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/RunnableScheduledFuture.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/ScheduledExecutorService.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/ScheduledExecutorService.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/ScheduledFuture.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/ScheduledFuture.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/Semaphore.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/Semaphore.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/SynchronousQueue.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/SynchronousQueue.java	Tue Apr 12 14:23:03 2011 -0700
@@ -31,7 +31,7 @@
  * Written by Doug Lea, Bill Scherer, and Michael Scott with
  * assistance from members of JCP JSR-166 Expert Group and released to
  * the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/ThreadFactory.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/ThreadFactory.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/ThreadLocalRandom.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/ThreadLocalRandom.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/TimeUnit.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/TimeUnit.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/TimeoutException.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/TimeoutException.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/TransferQueue.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/TransferQueue.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent;
--- a/src/share/classes/java/util/concurrent/atomic/AtomicBoolean.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/atomic/AtomicBoolean.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent.atomic;
--- a/src/share/classes/java/util/concurrent/atomic/AtomicInteger.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/atomic/AtomicInteger.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent.atomic;
--- a/src/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent.atomic;
--- a/src/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent.atomic;
--- a/src/share/classes/java/util/concurrent/atomic/AtomicLong.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/atomic/AtomicLong.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent.atomic;
--- a/src/share/classes/java/util/concurrent/atomic/AtomicLongArray.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/atomic/AtomicLongArray.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent.atomic;
--- a/src/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent.atomic;
--- a/src/share/classes/java/util/concurrent/atomic/AtomicMarkableReference.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/atomic/AtomicMarkableReference.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent.atomic;
--- a/src/share/classes/java/util/concurrent/atomic/AtomicReference.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/atomic/AtomicReference.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent.atomic;
--- a/src/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent.atomic;
--- a/src/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent.atomic;
--- a/src/share/classes/java/util/concurrent/atomic/AtomicStampedReference.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/atomic/AtomicStampedReference.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent.atomic;
--- a/src/share/classes/java/util/concurrent/atomic/package-info.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/atomic/package-info.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 /**
--- a/src/share/classes/java/util/concurrent/locks/AbstractOwnableSynchronizer.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/locks/AbstractOwnableSynchronizer.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent.locks;
--- a/src/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent.locks;
--- a/src/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent.locks;
--- a/src/share/classes/java/util/concurrent/locks/Condition.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/locks/Condition.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent.locks;
--- a/src/share/classes/java/util/concurrent/locks/Lock.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/locks/Lock.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent.locks;
--- a/src/share/classes/java/util/concurrent/locks/LockSupport.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/locks/LockSupport.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent.locks;
--- a/src/share/classes/java/util/concurrent/locks/ReadWriteLock.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/locks/ReadWriteLock.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent.locks;
--- a/src/share/classes/java/util/concurrent/locks/ReentrantLock.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/locks/ReentrantLock.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent.locks;
--- a/src/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 package java.util.concurrent.locks;
--- a/src/share/classes/java/util/concurrent/locks/package-info.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/locks/package-info.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 /**
--- a/src/share/classes/java/util/concurrent/package-info.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/concurrent/package-info.java	Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 /**
--- a/src/share/classes/java/util/jar/JarFile.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/jar/JarFile.java	Tue Apr 12 14:23:03 2011 -0700
@@ -37,6 +37,7 @@
 import sun.security.action.GetPropertyAction;
 import sun.security.util.ManifestEntryVerifier;
 import sun.misc.SharedSecrets;
+import sun.security.util.SignatureFileVerifier;
 
 /**
  * The <code>JarFile</code> class is used to read the contents of a jar file
@@ -178,7 +179,7 @@
                     byte[] b = getBytes(manEntry);
                     man = new Manifest(new ByteArrayInputStream(b));
                     if (!jvInitialized) {
-                        jv = new JarVerifier(b);
+                        jv = new JarVerifier(b, man);
                     }
                 } else {
                     man = new Manifest(super.getInputStream(manEntry));
@@ -297,10 +298,7 @@
             if (names != null) {
                 for (int i = 0; i < names.length; i++) {
                     String name = names[i].toUpperCase(Locale.ENGLISH);
-                    if (name.endsWith(".DSA") ||
-                        name.endsWith(".RSA") ||
-                        name.endsWith(".EC") ||
-                        name.endsWith(".SF")) {
+                    if (SignatureFileVerifier.isBlockOrSF(name)) {
                         // Assume since we found a signature-related file
                         // that the jar is signed and that we therefore
                         // need a JarVerifier and Manifest
@@ -329,17 +327,17 @@
             if (names != null) {
                 for (int i = 0; i < names.length; i++) {
                     JarEntry e = getJarEntry(names[i]);
-                    if (!e.isDirectory()) {
+                    if (!e.isDirectory() &&
+                            SignatureFileVerifier.isBlock(names[i])) {
                         if (mev == null) {
                             mev = new ManifestEntryVerifier
                                 (getManifestFromReference());
                         }
-                        byte[] b = getBytes(e);
-                        if (b != null && b.length > 0) {
-                            jv.beginEntry(e, mev);
-                            jv.update(b.length, b, 0, b.length, mev);
-                            jv.update(-1, null, 0, 0, mev);
-                        }
+                        String key = names[i].substring(
+                                0, names[i].lastIndexOf("."));
+                        jv.verifyBlock(names[i],
+                                getBytes(e),
+                                super.getInputStream(getJarEntry(key + ".SF")));
                     }
                 }
             }
--- a/src/share/classes/java/util/jar/JarInputStream.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/jar/JarInputStream.java	Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -95,7 +95,7 @@
             man.read(new ByteArrayInputStream(bytes));
             closeEntry();
             if (doVerify) {
-                jv = new JarVerifier(bytes);
+                jv = new JarVerifier(bytes, man);
                 mev = new ManifestEntryVerifier(man);
             }
             return (JarEntry)super.getNextEntry();
--- a/src/share/classes/java/util/jar/JarVerifier.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/jar/JarVerifier.java	Tue Apr 12 14:23:03 2011 -0700
@@ -48,35 +48,18 @@
 
     /* a table mapping names to code signers, for jar entries that have
        had their actual hashes verified */
-    private Hashtable verifiedSigners;
+    private Map verifiedSigners;
 
     /* a table mapping names to code signers, for jar entries that have
        passed the .SF/.DSA/.EC -> MANIFEST check */
-    private Hashtable sigFileSigners;
-
-    /* a hash table to hold .SF bytes */
-    private Hashtable sigFileData;
-
-    /** "queue" of pending PKCS7 blocks that we couldn't parse
-     *  until we parsed the .SF file */
-    private ArrayList pendingBlocks;
+    private Map sigFileSigners;
 
     /* cache of CodeSigner objects */
     private ArrayList signerCache;
 
-    /* Are we parsing a block? */
-    private boolean parsingBlockOrSF = false;
-
-    /* Are we done parsing META-INF entries? */
-    private boolean parsingMeta = true;
-
     /* Are there are files to verify? */
     private boolean anyToVerify = true;
 
-    /* The output stream to use when keeping track of files we are interested
-       in */
-    private ByteArrayOutputStream baos;
-
     /** The ManifestDigester object */
     private volatile ManifestDigester manDig;
 
@@ -92,20 +75,20 @@
     /** collect -DIGEST-MANIFEST values for blacklist */
     private List manifestDigests;
 
-    public JarVerifier(byte rawBytes[]) {
+    /** The manifest object */
+    Manifest man = null;
+
+    public JarVerifier(byte rawBytes[], Manifest man) {
+        this.man = man;
         manifestRawBytes = rawBytes;
-        sigFileSigners = new Hashtable();
-        verifiedSigners = new Hashtable();
-        sigFileData = new Hashtable(11);
-        pendingBlocks = new ArrayList();
-        baos = new ByteArrayOutputStream();
+        sigFileSigners = new HashMap();
+        verifiedSigners = new HashMap();
         manifestDigests = new ArrayList();
     }
 
     /**
-     * This method scans to see which entry we're parsing and
-     * keeps various state information depending on what type of
-     * file is being parsed.
+     * This method scans to see which entry we're parsing and keeps
+     * various state information depending on the file being parsed.
      */
     public void beginEntry(JarEntry je, ManifestEntryVerifier mev)
         throws IOException
@@ -129,30 +112,6 @@
          *    b. digest mismatch between the actual jar entry and the manifest
          */
 
-        if (parsingMeta) {
-            String uname = name.toUpperCase(Locale.ENGLISH);
-            if ((uname.startsWith("META-INF/") ||
-                 uname.startsWith("/META-INF/"))) {
-
-                if (je.isDirectory()) {
-                    mev.setEntry(null, je);
-                    return;
-                }
-
-                if (SignatureFileVerifier.isBlockOrSF(uname)) {
-                    /* We parse only DSA, RSA or EC PKCS7 blocks. */
-                    parsingBlockOrSF = true;
-                    baos.reset();
-                    mev.setEntry(null, je);
-                }
-                return;
-            }
-        }
-
-        if (parsingMeta) {
-            doneWithMeta();
-        }
-
         if (je.isDirectory()) {
             mev.setEntry(null, je);
             return;
@@ -188,11 +147,7 @@
         throws IOException
     {
         if (b != -1) {
-            if (parsingBlockOrSF) {
-                baos.write(b);
-            } else {
-                mev.update((byte)b);
-            }
+            mev.update((byte)b);
         } else {
             processEntry(mev);
         }
@@ -207,11 +162,7 @@
         throws IOException
     {
         if (n != -1) {
-            if (parsingBlockOrSF) {
-                baos.write(b, off, n);
-            } else {
-                mev.update(b, off, n);
-            }
+            mev.update(b, off, n);
         } else {
             processEntry(mev);
         }
@@ -223,101 +174,10 @@
     private void processEntry(ManifestEntryVerifier mev)
         throws IOException
     {
-        if (!parsingBlockOrSF) {
-            JarEntry je = mev.getEntry();
-            if ((je != null) && (je.signers == null)) {
-                je.signers = mev.verify(verifiedSigners, sigFileSigners);
-                je.certs = mapSignersToCertArray(je.signers);
-            }
-        } else {
-
-            try {
-                parsingBlockOrSF = false;
-
-                if (debug != null) {
-                    debug.println("processEntry: processing block");
-                }
-
-                String uname = mev.getEntry().getName()
-                                             .toUpperCase(Locale.ENGLISH);
-
-                if (uname.endsWith(".SF")) {
-                    String key = uname.substring(0, uname.length()-3);
-                    byte bytes[] = baos.toByteArray();
-                    // add to sigFileData in case future blocks need it
-                    sigFileData.put(key, bytes);
-                    // check pending blocks, we can now process
-                    // anyone waiting for this .SF file
-                    Iterator it = pendingBlocks.iterator();
-                    while (it.hasNext()) {
-                        SignatureFileVerifier sfv =
-                            (SignatureFileVerifier) it.next();
-                        if (sfv.needSignatureFile(key)) {
-                            if (debug != null) {
-                                debug.println(
-                                 "processEntry: processing pending block");
-                            }
-
-                            sfv.setSignatureFile(bytes);
-                            sfv.process(sigFileSigners, manifestDigests);
-                        }
-                    }
-                    return;
-                }
-
-                // now we are parsing a signature block file
-
-                String key = uname.substring(0, uname.lastIndexOf("."));
-
-                if (signerCache == null)
-                    signerCache = new ArrayList();
-
-                if (manDig == null) {
-                    synchronized(manifestRawBytes) {
-                        if (manDig == null) {
-                            manDig = new ManifestDigester(manifestRawBytes);
-                            manifestRawBytes = null;
-                        }
-                    }
-                }
-
-                SignatureFileVerifier sfv =
-                  new SignatureFileVerifier(signerCache,
-                                            manDig, uname, baos.toByteArray());
-
-                if (sfv.needSignatureFileBytes()) {
-                    // see if we have already parsed an external .SF file
-                    byte[] bytes = (byte[]) sigFileData.get(key);
-
-                    if (bytes == null) {
-                        // put this block on queue for later processing
-                        // since we don't have the .SF bytes yet
-                        // (uname, block);
-                        if (debug != null) {
-                            debug.println("adding pending block");
-                        }
-                        pendingBlocks.add(sfv);
-                        return;
-                    } else {
-                        sfv.setSignatureFile(bytes);
-                    }
-                }
-                sfv.process(sigFileSigners, manifestDigests);
-
-            } catch (IOException ioe) {
-                // e.g. sun.security.pkcs.ParsingException
-                if (debug != null) debug.println("processEntry caught: "+ioe);
-                // ignore and treat as unsigned
-            } catch (SignatureException se) {
-                if (debug != null) debug.println("processEntry caught: "+se);
-                // ignore and treat as unsigned
-            } catch (NoSuchAlgorithmException nsae) {
-                if (debug != null) debug.println("processEntry caught: "+nsae);
-                // ignore and treat as unsigned
-            } catch (CertificateException ce) {
-                if (debug != null) debug.println("processEntry caught: "+ce);
-                // ignore and treat as unsigned
-            }
+        JarEntry je = mev.getEntry();
+        if ((je != null) && (je.signers == null)) {
+            je.signers = mev.verify(verifiedSigners, sigFileSigners);
+            je.certs = mapSignersToCertArray(je.signers);
         }
     }
 
@@ -354,15 +214,15 @@
              * Force a read of the entry data to generate the
              * verification hash.
              */
-            try {
-                InputStream s = jar.getInputStream(entry);
+            try (InputStream s = jar.getInputStream(entry)) {
                 byte[] buffer = new byte[1024];
                 int n = buffer.length;
                 while (n != -1) {
                     n = s.read(buffer, 0, buffer.length);
                 }
-                s.close();
             } catch (IOException e) {
+                // Ignore. When an exception is thrown, code signer
+                // will not be assigned.
             }
         }
         return getCodeSigners(name);
@@ -408,11 +268,7 @@
      */
     void doneWithMeta()
     {
-        parsingMeta = false;
         anyToVerify = !sigFileSigners.isEmpty();
-        baos = null;
-        sigFileData = null;
-        pendingBlocks = null;
         signerCache = null;
         manDig = null;
         // MANIFEST.MF is always treated as signed and verified,
@@ -423,6 +279,41 @@
         }
     }
 
+    /**
+     * Verifies a PKCS7 SignedData block
+     * @param key name of block
+     * @param block the pkcs7 file
+     * @param ins the clear data
+     */
+    void verifyBlock(String key, byte[] block, InputStream ins) {
+        try {
+            if (signerCache == null)
+                signerCache = new ArrayList();
+
+            if (manDig == null) {
+                synchronized(manifestRawBytes) {
+                    if (manDig == null) {
+                        manDig = new ManifestDigester(manifestRawBytes);
+                        manifestRawBytes = null;
+                    }
+                }
+            }
+            SignatureFileVerifier sfv =
+                    new SignatureFileVerifier(signerCache, man,
+                                        manDig, key, block);
+
+            if (sfv.needSignatureFile()) {
+                // see if we have already parsed an external .SF file
+                sfv.setSignatureFile(ins);
+            }
+            sfv.process(sigFileSigners, manifestDigests);
+        } catch (Exception e) {
+            if (debug != null) {
+                e.printStackTrace();
+            }
+        }
+    }
+
     static class VerifierStream extends java.io.InputStream {
 
         private InputStream is;
@@ -553,10 +444,7 @@
          * but this handles a CodeSource of any type, just in case.
          */
         CodeSource[] sources = mapSignersToCodeSources(cs.getLocation(), getJarCodeSigners(), true);
-        List sourceList = new ArrayList();
-        for (int i = 0; i < sources.length; i++) {
-            sourceList.add(sources[i]);
-        }
+        List sourceList = Arrays.asList(sources);
         int j = sourceList.indexOf(cs);
         if (j != -1) {
             CodeSigner[] match;
--- a/src/share/classes/java/util/zip/DeflaterOutputStream.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/java/util/zip/DeflaterOutputStream.java	Tue Apr 12 14:23:03 2011 -0700
@@ -206,14 +206,9 @@
             return;
         }
         if (!def.finished()) {
-            // Deflate no more than stride bytes at a time.  This avoids
-            // excess copying in deflateBytes (see Deflater.c)
-            int stride = buf.length;
-            for (int i = 0; i < len; i+= stride) {
-                def.setInput(b, off + i, Math.min(stride, len - i));
-                while (!def.needsInput()) {
-                    deflate();
-                }
+            def.setInput(b, off, len);
+            while (!def.needsInput()) {
+                deflate();
             }
         }
     }
--- a/src/share/classes/javax/swing/plaf/LayerUI.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/javax/swing/plaf/LayerUI.java	Tue Apr 12 14:23:03 2011 -0700
@@ -710,8 +710,8 @@
      *
      * @param x  the x value of the region to be painted
      * @param y  the y value of the region to be painted
-     * @param w  the width of the region to be painted
-     * @param h  the height of the region to be painted
+     * @param width  the width of the region to be painted
+     * @param height  the height of the region to be painted
      *
      * @see JComponent#paintImmediately(int, int, int, int)
      */
--- a/src/share/classes/sun/nio/ch/DatagramChannelImpl.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/sun/nio/ch/DatagramChannelImpl.java	Tue Apr 12 14:23:03 2011 -0700
@@ -388,9 +388,8 @@
         // we must instead use a nonempty buffer, otherwise the call
         // will not block waiting for a datagram on some platforms.
         int newSize = Math.max(rem, 1);
-        ByteBuffer bb = null;
+        ByteBuffer bb = Util.getTemporaryDirectBuffer(newSize);
         try {
-            bb = Util.getTemporaryDirectBuffer(newSize);
             int n = receiveIntoNativeBuffer(fd, bb, newSize, 0);
             bb.flip();
             if (n > 0 && rem > 0)
@@ -482,9 +481,8 @@
         assert (pos <= lim);
         int rem = (pos <= lim ? lim - pos : 0);
 
-        ByteBuffer bb = null;
+        ByteBuffer bb = Util.getTemporaryDirectBuffer(rem);
         try {
-            bb = Util.getTemporaryDirectBuffer(rem);
             bb.put(src);
             bb.flip();
             // Do not update src until we see how many bytes were written
@@ -766,10 +764,10 @@
         // check multicast address is compatible with this socket
         if (group instanceof Inet4Address) {
             if (family == StandardProtocolFamily.INET6 && !Net.canIPv6SocketJoinIPv4Group())
-                throw new IllegalArgumentException("Group is not IPv4 multicast address");
+                throw new IllegalArgumentException("IPv6 socket cannot join IPv4 multicast group");
         } else if (group instanceof Inet6Address) {
             if (family != StandardProtocolFamily.INET6)
-                throw new IllegalArgumentException("Group is not IPv6 multicast address");
+                throw new IllegalArgumentException("Only IPv6 sockets can join IPv6 multicast group");
         } else {
             throw new IllegalArgumentException("Address type not supported");
         }
--- a/src/share/classes/sun/nio/ch/IOUtil.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/sun/nio/ch/IOUtil.java	Tue Apr 12 14:23:03 2011 -0700
@@ -50,9 +50,8 @@
         int lim = src.limit();
         assert (pos <= lim);
         int rem = (pos <= lim ? lim - pos : 0);
-        ByteBuffer bb = null;
+        ByteBuffer bb = Util.getTemporaryDirectBuffer(rem);
         try {
-            bb = Util.getTemporaryDirectBuffer(rem);
             bb.put(src);
             bb.flip();
             // Do not update src until we see how many bytes were written
@@ -187,9 +186,8 @@
             return readIntoNativeBuffer(fd, dst, position, nd, lock);
 
         // Substitute a native buffer
-        ByteBuffer bb = null;
+        ByteBuffer bb = Util.getTemporaryDirectBuffer(dst.remaining());
         try {
-            bb = Util.getTemporaryDirectBuffer(dst.remaining());
             int n = readIntoNativeBuffer(fd, bb, position, nd, lock);
             bb.flip();
             if (n > 0)
--- a/src/share/classes/sun/nio/fs/Util.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/sun/nio/fs/Util.java	Tue Apr 12 14:23:03 2011 -0700
@@ -26,6 +26,7 @@
 package sun.nio.fs;
 
 import java.util.*;
+import java.nio.file.*;
 
 /**
  * Utility methods
@@ -80,4 +81,21 @@
         }
         return set;
     }
+
+    /**
+     * Returns {@code true} if symbolic links should be followed
+     */
+    static boolean followLinks(LinkOption... options) {
+        boolean followLinks = true;
+        for (LinkOption option: options) {
+            if (option == LinkOption.NOFOLLOW_LINKS) {
+                followLinks = false;
+            } else if (option == null) {
+                throw new NullPointerException();
+            } else {
+                throw new AssertionError("Should not get here");
+            }
+        }
+        return followLinks;
+    }
 }
--- a/src/share/classes/sun/security/jgss/krb5/InitSecContextToken.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/sun/security/jgss/krb5/InitSecContextToken.java	Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -127,8 +127,8 @@
             //System.out.println("Sub-Session Key Missing in Authenticator.\n");
         }
 
-        OverloadedChecksum gssChecksum =
-            new OverloadedChecksum(context, apReq.getChecksum(), sessionKey);
+        OverloadedChecksum gssChecksum = new OverloadedChecksum(
+                context, apReq.getChecksum(), sessionKey, subKey);
         gssChecksum.setContextFlags(context);
         Credentials delegCred = gssChecksum.getDelegatedCreds();
         if (delegCred != null) {
--- a/src/share/classes/sun/security/jgss/krb5/InitialToken.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/sun/security/jgss/krb5/InitialToken.java	Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -210,8 +210,8 @@
         // be passed in if this checksum type denotes a
         // raw_checksum. In that case, make Checksum class krb5
         // internal.
-        public OverloadedChecksum(Krb5Context context,
-                                  Checksum checksum, EncryptionKey key)
+        public OverloadedChecksum(Krb5Context context, Checksum checksum,
+                                  EncryptionKey key, EncryptionKey subKey)
             throws GSSException, KrbException, IOException {
 
             int pos = 0;
@@ -283,9 +283,17 @@
                         new KrbCred(credBytes, EncryptionKey.NULL_KEY).
                         getDelegatedCreds()[0];
                 } else {
-                    delegCreds =
-                        new KrbCred(credBytes, key).
-                        getDelegatedCreds()[0];
+                    KrbCred cred;
+                    try {
+                        cred = new KrbCred(credBytes, key);
+                    } catch (KrbException e) {
+                        if (subKey != null) {
+                            cred = new KrbCred(credBytes, subKey);
+                        } else {
+                            throw e;
+                        }
+                    }
+                    delegCreds = cred.getDelegatedCreds()[0];
                 }
             }
         }
--- a/src/share/classes/sun/security/krb5/KrbApReq.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/sun/security/krb5/KrbApReq.java	Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,6 +37,7 @@
 import java.net.InetAddress;
 import sun.security.util.*;
 import java.io.IOException;
+import java.util.Arrays;
 
 /**
  * This class encapsulates a KRB-AP-REQ that a client sends to a
@@ -54,9 +55,6 @@
     private static CacheTable table = new CacheTable();
     private static boolean DEBUG = Krb5.DEBUG;
 
-    // default is address-less tickets
-    private boolean KDC_EMPTY_ADDRESSES_ALLOWED = true;
-
     /**
      * Contructs a AP-REQ message to send to the peer.
      * @param tgsCred the <code>Credentials</code> to be used to construct the
@@ -312,23 +310,19 @@
             table.put(client, time, currTime.getTime());
         }
 
-        // check to use addresses in tickets
-        if (Config.getInstance().useAddresses()) {
-            KDC_EMPTY_ADDRESSES_ALLOWED = false;
-        }
-
-        // sender host address
-        HostAddress sender = null;
         if (initiator != null) {
-            sender = new HostAddress(initiator);
-        }
-
-        if (sender != null || !KDC_EMPTY_ADDRESSES_ALLOWED) {
-            if (enc_ticketPart.caddr != null) {
-                if (sender == null)
-                    throw new KrbApErrException(Krb5.KRB_AP_ERR_BADADDR);
-                if (!enc_ticketPart.caddr.inList(sender))
-                    throw new KrbApErrException(Krb5.KRB_AP_ERR_BADADDR);
+            // sender host address
+            HostAddress sender = new HostAddress(initiator);
+            if (enc_ticketPart.caddr != null
+                    && !enc_ticketPart.caddr.inList(sender)) {
+                if (DEBUG) {
+                    System.out.println(">>> KrbApReq: initiator is "
+                            + sender.getInetAddress()
+                            + ", but caddr is "
+                            + Arrays.toString(
+                                enc_ticketPart.caddr.getInetAddresses()));
+                }
+                throw new KrbApErrException(Krb5.KRB_AP_ERR_BADADDR);
             }
         }
 
--- a/src/share/classes/sun/security/pkcs/PKCS7.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/sun/security/pkcs/PKCS7.java	Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -38,6 +38,7 @@
 import sun.security.util.*;
 import sun.security.x509.AlgorithmId;
 import sun.security.x509.CertificateIssuerName;
+import sun.security.x509.KeyUsageExtension;
 import sun.security.x509.X509CertImpl;
 import sun.security.x509.X509CertInfo;
 import sun.security.x509.X509CRLImpl;
@@ -492,7 +493,7 @@
         // CRLs (optional)
         if (crls != null && crls.length != 0) {
             // cast to X509CRLImpl[] since X509CRLImpl implements DerEncoder
-            Set<X509CRLImpl> implCRLs = new HashSet<X509CRLImpl>(crls.length);
+            Set<X509CRLImpl> implCRLs = new HashSet<>(crls.length);
             for (X509CRL crl: crls) {
                 if (crl instanceof X509CRLImpl)
                     implCRLs.add((X509CRLImpl) crl);
@@ -530,6 +531,168 @@
     }
 
     /**
+     * Verifying signed data using an external chunked data source.
+     */
+    public static class PKCS7Verifier {
+
+        private final SignerInfo si;          // Signer to verify
+        private final MessageDigest md;       // MessageDigest object for chunks
+        private final Signature sig;          // Signature object for chunks
+
+        private PKCS7Verifier(SignerInfo si, MessageDigest md, Signature sig) {
+            this.si = si;
+            this.md = md;
+            this.sig = sig;
+        }
+
+        public static PKCS7Verifier from(PKCS7 block, SignerInfo si) throws
+                SignatureException, NoSuchAlgorithmException {
+
+            try {
+                MessageDigest md = null;
+                Signature sig;
+
+                ContentInfo content = block.getContentInfo();
+                String digestAlgname = si.getDigestAlgorithmId().getName();
+
+                // if there are authenticate attributes, feed data chunks to
+                // the message digest. In this case, pv.md is not null
+                if (si.authenticatedAttributes != null) {
+                    // first, check content type
+                    ObjectIdentifier contentType = (ObjectIdentifier)
+                           si.authenticatedAttributes.getAttributeValue(
+                             PKCS9Attribute.CONTENT_TYPE_OID);
+                    if (contentType == null ||
+                        !contentType.equals(content.contentType))
+                        return null;  // contentType does not match, bad SignerInfo
+
+                    // now, check message digest
+                    byte[] messageDigest = (byte[])
+                        si.authenticatedAttributes.getAttributeValue(
+                             PKCS9Attribute.MESSAGE_DIGEST_OID);
+
+                    if (messageDigest == null) // fail if there is no message digest
+                        return null;
+
+                    md = MessageDigest.getInstance(digestAlgname);
+                }
+
+                // put together digest algorithm and encryption algorithm
+                // to form signing algorithm
+                String encryptionAlgname =
+                    si.getDigestEncryptionAlgorithmId().getName();
+
+                // Workaround: sometimes the encryptionAlgname is actually
+                // a signature name
+                String tmp = AlgorithmId.getEncAlgFromSigAlg(encryptionAlgname);
+                if (tmp != null) encryptionAlgname = tmp;
+                String algname = AlgorithmId.makeSigAlg(
+                        digestAlgname, encryptionAlgname);
+
+                sig = Signature.getInstance(algname);
+                X509Certificate cert = si.getCertificate(block);
+
+                if (cert == null) {
+                    return null;
+                }
+                if (cert.hasUnsupportedCriticalExtension()) {
+                    throw new SignatureException("Certificate has unsupported "
+                                                 + "critical extension(s)");
+                }
+
+                // Make sure that if the usage of the key in the certificate is
+                // restricted, it can be used for digital signatures.
+                // XXX We may want to check for additional extensions in the
+                // future.
+                boolean[] keyUsageBits = cert.getKeyUsage();
+                if (keyUsageBits != null) {
+                    KeyUsageExtension keyUsage;
+                    try {
+                        // We don't care whether or not this extension was marked
+                        // critical in the certificate.
+                        // We're interested only in its value (i.e., the bits set)
+                        // and treat the extension as critical.
+                        keyUsage = new KeyUsageExtension(keyUsageBits);
+                    } catch (IOException ioe) {
+                        throw new SignatureException("Failed to parse keyUsage "
+                                                     + "extension");
+                    }
+
+                    boolean digSigAllowed = ((Boolean)keyUsage.get(
+                            KeyUsageExtension.DIGITAL_SIGNATURE)).booleanValue();
+
+                    boolean nonRepuAllowed = ((Boolean)keyUsage.get(
+                            KeyUsageExtension.NON_REPUDIATION)).booleanValue();
+
+                    if (!digSigAllowed && !nonRepuAllowed) {
+                        throw new SignatureException("Key usage restricted: "
+                                                     + "cannot be used for "
+                                                     + "digital signatures");
+                    }
+                }
+
+                PublicKey key = cert.getPublicKey();
+                sig.initVerify(key);
+                return new PKCS7Verifier(si, md, sig);
+            } catch (IOException e) {
+                throw new SignatureException("IO error verifying signature:\n" +
+                                             e.getMessage());
+
+            } catch (InvalidKeyException e) {
+                throw new SignatureException("InvalidKey: " + e.getMessage());
+
+            }
+        }
+
+        public void update(byte[] data, int off, int end)
+                throws SignatureException {
+            if (md != null) {
+                md.update(data, off, end-off);
+            } else {
+                sig.update(data, off, end-off);
+            }
+        }
+
+        public SignerInfo verify() throws SignatureException {
+            try {
+                // if there are authenticate attributes, get the message
+                // digest and compare it with the digest of data
+                if (md != null) {
+                    // now, check message digest
+                    byte[] messageDigest = (byte[])
+                        si.authenticatedAttributes.getAttributeValue(
+                             PKCS9Attribute.MESSAGE_DIGEST_OID);
+
+                    byte[] computedMessageDigest = md.digest();
+
+                    if (!MessageDigest.isEqual(
+                            messageDigest, computedMessageDigest)) {
+                        return null;
+                    }
+
+                    // message digest attribute matched
+                    // digest of original data
+
+                    // the data actually signed is the DER encoding of
+                    // the authenticated attributes (tagged with
+                    // the "SET OF" tag, not 0xA0).
+                    byte[] dataSigned = si.authenticatedAttributes.getDerEncoding();
+                    sig.update(dataSigned);
+                }
+
+                if (sig.verify(si.getEncryptedDigest())) {
+                    return si;
+                }
+
+            } catch (IOException e) {
+                throw new SignatureException("IO error verifying signature:\n" +
+                                             e.getMessage());
+            }
+            return null;
+        }
+    }
+
+    /**
      * This verifies a given SignerInfo.
      *
      * @param info the signer information.
@@ -554,19 +717,16 @@
     public SignerInfo[] verify(byte[] bytes)
     throws NoSuchAlgorithmException, SignatureException {
 
-        Vector<SignerInfo> intResult = new Vector<SignerInfo>();
+        List<SignerInfo> intResult = new ArrayList<>();
         for (int i = 0; i < signerInfos.length; i++) {
 
             SignerInfo signerInfo = verify(signerInfos[i], bytes);
             if (signerInfo != null) {
-                intResult.addElement(signerInfo);
+                intResult.add(signerInfo);
             }
         }
-        if (intResult.size() != 0) {
-
-            SignerInfo[] result = new SignerInfo[intResult.size()];
-            intResult.copyInto(result);
-            return result;
+        if (!intResult.isEmpty()) {
+            return intResult.toArray(new SignerInfo[intResult.size()]);
         }
         return null;
     }
--- a/src/share/classes/sun/security/pkcs/SignerInfo.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/sun/security/pkcs/SignerInfo.java	Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -230,7 +230,7 @@
         if (userCert == null)
             return null;
 
-        ArrayList<X509Certificate> certList = new ArrayList<X509Certificate>();
+        ArrayList<X509Certificate> certList = new ArrayList<>();
         certList.add(userCert);
 
         X509Certificate[] pkcsCerts = block.getCertificates();
@@ -276,132 +276,20 @@
     /* Returns null if verify fails, this signerInfo if
        verify succeeds. */
     SignerInfo verify(PKCS7 block, byte[] data)
-    throws NoSuchAlgorithmException, SignatureException {
+            throws NoSuchAlgorithmException, SignatureException {
 
-        try {
-
-            ContentInfo content = block.getContentInfo();
-            if (data == null) {
-                data = content.getContentBytes();
+        PKCS7.PKCS7Verifier p7v = PKCS7.PKCS7Verifier.from(block, this);
+        if (p7v == null) return null;
+        if (data == null) {
+            try {
+                data = block.getContentInfo().getContentBytes();
+            } catch (IOException e) {
+                throw new SignatureException("IO error verifying signature:\n" +
+                                             e.getMessage());
             }
-
-            String digestAlgname = getDigestAlgorithmId().getName();
-
-            byte[] dataSigned;
-
-            // if there are authenticate attributes, get the message
-            // digest and compare it with the digest of data
-            if (authenticatedAttributes == null) {
-                dataSigned = data;
-            } else {
-
-                // first, check content type
-                ObjectIdentifier contentType = (ObjectIdentifier)
-                       authenticatedAttributes.getAttributeValue(
-                         PKCS9Attribute.CONTENT_TYPE_OID);
-                if (contentType == null ||
-                    !contentType.equals(content.contentType))
-                    return null;  // contentType does not match, bad SignerInfo
-
-                // now, check message digest
-                byte[] messageDigest = (byte[])
-                    authenticatedAttributes.getAttributeValue(
-                         PKCS9Attribute.MESSAGE_DIGEST_OID);
-
-                if (messageDigest == null) // fail if there is no message digest
-                    return null;
-
-                MessageDigest md = MessageDigest.getInstance(digestAlgname);
-                byte[] computedMessageDigest = md.digest(data);
-
-                if (messageDigest.length != computedMessageDigest.length)
-                    return null;
-                for (int i = 0; i < messageDigest.length; i++) {
-                    if (messageDigest[i] != computedMessageDigest[i])
-                        return null;
-                }
-
-                // message digest attribute matched
-                // digest of original data
-
-                // the data actually signed is the DER encoding of
-                // the authenticated attributes (tagged with
-                // the "SET OF" tag, not 0xA0).
-                dataSigned = authenticatedAttributes.getDerEncoding();
-            }
-
-            // put together digest algorithm and encryption algorithm
-            // to form signing algorithm
-            String encryptionAlgname =
-                getDigestEncryptionAlgorithmId().getName();
-
-            // Workaround: sometimes the encryptionAlgname is actually
-            // a signature name
-            String tmp = AlgorithmId.getEncAlgFromSigAlg(encryptionAlgname);
-            if (tmp != null) encryptionAlgname = tmp;
-            String algname = AlgorithmId.makeSigAlg(
-                    digestAlgname, encryptionAlgname);
-
-            Signature sig = Signature.getInstance(algname);
-            X509Certificate cert = getCertificate(block);
-
-            if (cert == null) {
-                return null;
-            }
-            if (cert.hasUnsupportedCriticalExtension()) {
-                throw new SignatureException("Certificate has unsupported "
-                                             + "critical extension(s)");
-            }
-
-            // Make sure that if the usage of the key in the certificate is
-            // restricted, it can be used for digital signatures.
-            // XXX We may want to check for additional extensions in the
-            // future.
-            boolean[] keyUsageBits = cert.getKeyUsage();
-            if (keyUsageBits != null) {
-                KeyUsageExtension keyUsage;
-                try {
-                    // We don't care whether or not this extension was marked
-                    // critical in the certificate.
-                    // We're interested only in its value (i.e., the bits set)
-                    // and treat the extension as critical.
-                    keyUsage = new KeyUsageExtension(keyUsageBits);
-                } catch (IOException ioe) {
-                    throw new SignatureException("Failed to parse keyUsage "
-                                                 + "extension");
-                }
-
-                boolean digSigAllowed = ((Boolean)keyUsage.get(
-                        KeyUsageExtension.DIGITAL_SIGNATURE)).booleanValue();
-
-                boolean nonRepuAllowed = ((Boolean)keyUsage.get(
-                        KeyUsageExtension.NON_REPUDIATION)).booleanValue();
-
-                if (!digSigAllowed && !nonRepuAllowed) {
-                    throw new SignatureException("Key usage restricted: "
-                                                 + "cannot be used for "
-                                                 + "digital signatures");
-                }
-            }
-
-            PublicKey key = cert.getPublicKey();
-            sig.initVerify(key);
-
-            sig.update(dataSigned);
-
-            if (sig.verify(encryptedDigest)) {
-                return this;
-            }
-
-        } catch (IOException e) {
-            throw new SignatureException("IO error verifying signature:\n" +
-                                         e.getMessage());
-
-        } catch (InvalidKeyException e) {
-            throw new SignatureException("InvalidKey: " + e.getMessage());
-
         }
-        return null;
+        p7v.update(data, 0, data.length);
+        return p7v.verify();
     }
 
     /* Verify the content of the pkcs7 block. */
--- a/src/share/classes/sun/security/ssl/CipherSuiteList.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/sun/security/ssl/CipherSuiteList.java	Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -40,10 +40,6 @@
  */
 final class CipherSuiteList {
 
-    // lists of supported and default enabled ciphersuites
-    // created on demand
-    private static CipherSuiteList supportedSuites, defaultSuites;
-
     private final Collection<CipherSuite> cipherSuites;
     private String[] suiteNames;
 
@@ -206,57 +202,8 @@
      */
     static synchronized void clearAvailableCache() {
         if (CipherSuite.DYNAMIC_AVAILABILITY) {
-            supportedSuites = null;
-            defaultSuites = null;
             CipherSuite.BulkCipher.clearAvailableCache();
             JsseJce.clearEcAvailable();
         }
     }
-
-    /**
-     * Return the list of all available CipherSuites with a priority of
-     * minPriority or above.
-     * Should be called with the Class lock held.
-     */
-    private static CipherSuiteList buildAvailableCache(int minPriority) {
-        // SortedSet automatically arranges ciphersuites in default
-        // preference order
-        Set<CipherSuite> cipherSuites = new TreeSet<>();
-        Collection<CipherSuite> allowedCipherSuites =
-                                    CipherSuite.allowedCipherSuites();
-        for (CipherSuite c : allowedCipherSuites) {
-            if ((c.allowed == false) || (c.priority < minPriority)) {
-                continue;
-            }
-
-            if (c.isAvailable()) {
-                cipherSuites.add(c);
-            }
-        }
-
-        return new CipherSuiteList(cipherSuites);
-    }
-
-    /**
-     * Return supported CipherSuites in preference order.
-     */
-    static synchronized CipherSuiteList getSupported() {
-        if (supportedSuites == null) {
-            supportedSuites =
-                buildAvailableCache(CipherSuite.SUPPORTED_SUITES_PRIORITY);
-        }
-        return supportedSuites;
-    }
-
-    /**
-     * Return default enabled CipherSuites in preference order.
-     */
-    static synchronized CipherSuiteList getDefault() {
-        if (defaultSuites == null) {
-            defaultSuites =
-                buildAvailableCache(CipherSuite.DEFAULT_SUITES_PRIORITY);
-        }
-        return defaultSuites;
-    }
-
 }
--- a/src/share/classes/sun/security/ssl/DefaultSSLContextImpl.java	Fri Apr 08 10:31:14 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,193 +0,0 @@
-/*
- * Copyright (c) 2005, 2007, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.ssl;
-
-import java.io.*;
-import java.util.*;
-
-import java.security.*;
-
-import javax.net.ssl.*;
-
-/**
- * "Default" SSLContext as returned by SSLContext.getDefault(). It comes
- * initialized with default KeyManagers and TrustManagers created using
- * various system properties.
- *
- * @since   1.6
- */
-public final class DefaultSSLContextImpl extends SSLContextImpl {
-
-    private static final String NONE = "NONE";
-    private static final String P11KEYSTORE = "PKCS11";
-    private static final Debug debug = Debug.getInstance("ssl");
-
-    private static volatile SSLContextImpl defaultImpl;
-
-    private static TrustManager[] defaultTrustManagers;
-
-    private static KeyManager[] defaultKeyManagers;
-
-    public DefaultSSLContextImpl() throws Exception {
-        super(defaultImpl);
-        try {
-            super.engineInit(getDefaultKeyManager(), getDefaultTrustManager(), null);
-        } catch (Exception e) {
-            if (debug != null && Debug.isOn("defaultctx")) {
-                System.out.println("default context init failed: " + e);
-            }
-            throw e;
-        }
-        if (defaultImpl == null) {
-            defaultImpl = this;
-        }
-    }
-
-    protected void engineInit(KeyManager[] km, TrustManager[] tm,
-            SecureRandom sr) throws KeyManagementException {
-        throw new KeyManagementException
-            ("Default SSLContext is initialized automatically");
-    }
-
-    static synchronized SSLContextImpl getDefaultImpl() throws Exception {
-        if (defaultImpl == null) {
-            new DefaultSSLContextImpl();
-        }
-        return defaultImpl;
-    }
-
-    private static synchronized TrustManager[] getDefaultTrustManager() throws Exception {
-        if (defaultTrustManagers != null) {
-            return defaultTrustManagers;
-        }
-
-        KeyStore ks = TrustManagerFactoryImpl.getCacertsKeyStore("defaultctx");
-
-        TrustManagerFactory tmf = TrustManagerFactory.getInstance(
-            TrustManagerFactory.getDefaultAlgorithm());
-        tmf.init(ks);
-        defaultTrustManagers = tmf.getTrustManagers();
-        return defaultTrustManagers;
-    }
-
-    private static synchronized KeyManager[] getDefaultKeyManager() throws Exception {
-        if (defaultKeyManagers != null) {
-            return defaultKeyManagers;
-        }
-
-        final Map<String,String> props = new HashMap<>();
-        AccessController.doPrivileged(
-                    new PrivilegedExceptionAction<Object>() {
-            public Object run() throws Exception {
-                props.put("keyStore",  System.getProperty(
-                            "javax.net.ssl.keyStore", ""));
-                props.put("keyStoreType", System.getProperty(
-                            "javax.net.ssl.keyStoreType",
-                            KeyStore.getDefaultType()));
-                props.put("keyStoreProvider", System.getProperty(
-                            "javax.net.ssl.keyStoreProvider", ""));
-                props.put("keyStorePasswd", System.getProperty(
-                            "javax.net.ssl.keyStorePassword", ""));
-                return null;
-            }
-        });
-
-        final String defaultKeyStore = props.get("keyStore");
-        String defaultKeyStoreType = props.get("keyStoreType");
-        String defaultKeyStoreProvider = props.get("keyStoreProvider");
-        if (debug != null && Debug.isOn("defaultctx")) {
-            System.out.println("keyStore is : " + defaultKeyStore);
-            System.out.println("keyStore type is : " +
-                                    defaultKeyStoreType);
-            System.out.println("keyStore provider is : " +
-                                    defaultKeyStoreProvider);
-        }
-
-        if (P11KEYSTORE.equals(defaultKeyStoreType) &&
-                !NONE.equals(defaultKeyStore)) {
-            throw new IllegalArgumentException("if keyStoreType is "
-                + P11KEYSTORE + ", then keyStore must be " + NONE);
-        }
-
-        FileInputStream fs = null;
-        if (defaultKeyStore.length() != 0 && !NONE.equals(defaultKeyStore)) {
-            fs = AccessController.doPrivileged(
-                    new PrivilegedExceptionAction<FileInputStream>() {
-                public FileInputStream run() throws Exception {
-                    return new FileInputStream(defaultKeyStore);
-                }
-            });
-        }
-
-        String defaultKeyStorePassword = props.get("keyStorePasswd");
-        char[] passwd = null;
-        if (defaultKeyStorePassword.length() != 0) {
-            passwd = defaultKeyStorePassword.toCharArray();
-        }
-
-        /**
-         * Try to initialize key store.
-         */
-        KeyStore ks = null;
-        if ((defaultKeyStoreType.length()) != 0) {
-            if (debug != null && Debug.isOn("defaultctx")) {
-                System.out.println("init keystore");
-            }
-            if (defaultKeyStoreProvider.length() == 0) {
-                ks = KeyStore.getInstance(defaultKeyStoreType);
-            } else {
-                ks = KeyStore.getInstance(defaultKeyStoreType,
-                                    defaultKeyStoreProvider);
-            }
-
-            // if defaultKeyStore is NONE, fs will be null
-            ks.load(fs, passwd);
-        }
-        if (fs != null) {
-            fs.close();
-            fs = null;
-        }
-
-        /*
-         * Try to initialize key manager.
-         */
-        if (debug != null && Debug.isOn("defaultctx")) {
-            System.out.println("init keymanager of type " +
-                KeyManagerFactory.getDefaultAlgorithm());
-        }
-        KeyManagerFactory kmf = KeyManagerFactory.getInstance(
-            KeyManagerFactory.getDefaultAlgorithm());
-
-        if (P11KEYSTORE.equals(defaultKeyStoreType)) {
-            kmf.init(ks, null); // do not pass key passwd if using token
-        } else {
-            kmf.init(ks, passwd);
-        }
-
-        defaultKeyManagers = kmf.getKeyManagers();
-        return defaultKeyManagers;
-    }
-}
--- a/src/share/classes/sun/security/ssl/JsseJce.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/sun/security/ssl/JsseJce.java	Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -247,9 +247,9 @@
                 // the SunJSSE implementation does the actual crypto using
                 // a NONEwithRSA signature obtained from the cryptoProvider.
                 if (cryptoProvider.getService("Signature", algorithm) == null) {
-                    // Calling Signature.getInstance() and catching the exception
-                    // would be cleaner, but exceptions are a little expensive.
-                    // So we check directly via getService().
+                    // Calling Signature.getInstance() and catching the
+                    // exception would be cleaner, but exceptions are a little
+                    // expensive. So we check directly via getService().
                     try {
                         return Signature.getInstance(algorithm, "SunJSSE");
                     } catch (NoSuchProviderException e) {
--- a/src/share/classes/sun/security/ssl/ProtocolList.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/sun/security/ssl/ProtocolList.java	Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,10 +37,6 @@
  */
 final class ProtocolList {
 
-    private static final ProtocolList SUPPORTED;
-    private static final ProtocolList CLIENT_DEFAULT;
-    private static final ProtocolList SERVER_DEFAULT;
-
     // the sorted protocol version list
     private final ArrayList<ProtocolVersion> protocols;
 
@@ -154,66 +150,4 @@
     public String toString() {
         return protocols.toString();
     }
-
-    /**
-     * Return the list of default enabled protocols.
-     */
-    static ProtocolList getDefault(boolean isServer) {
-        return isServer ? SERVER_DEFAULT : CLIENT_DEFAULT;
-    }
-
-    /**
-     * Return whether a protocol list is the original default enabled
-     * protocols.  See: SSLSocket/SSLEngine.setEnabledProtocols()
-     */
-    static boolean isDefaultProtocolList(ProtocolList protocols) {
-        return protocols == CLIENT_DEFAULT || protocols == SERVER_DEFAULT;
-    }
-
-    /**
-     * Return the list of supported protocols.
-     */
-    static ProtocolList getSupported() {
-        return SUPPORTED;
-    }
-
-    static {
-        if (SunJSSE.isFIPS()) {
-            SUPPORTED = new ProtocolList(new String[] {
-                ProtocolVersion.TLS10.name,
-                ProtocolVersion.TLS11.name,
-                ProtocolVersion.TLS12.name
-            });
-
-            SERVER_DEFAULT = SUPPORTED;
-            CLIENT_DEFAULT = new ProtocolList(new String[] {
-                ProtocolVersion.TLS10.name
-            });
-        } else {
-            SUPPORTED = new ProtocolList(new String[] {
-                ProtocolVersion.SSL20Hello.name,
-                ProtocolVersion.SSL30.name,
-                ProtocolVersion.TLS10.name,
-                ProtocolVersion.TLS11.name,
-                ProtocolVersion.TLS12.name
-            });
-
-            SERVER_DEFAULT = SUPPORTED;
-
-            /*
-             * RFC 5246 says that sending SSLv2 backward-compatible
-             * hello SHOULD NOT be done any longer.
-             *
-             * We are not enabling TLS 1.1/1.2 by default yet on clients
-             * out of concern for interop with existing
-             * SSLv3/TLS1.0-only servers.  When these versions of TLS
-             * gain more traction, we'll enable them.
-             */
-            CLIENT_DEFAULT = new ProtocolList(new String[] {
-                ProtocolVersion.SSL30.name,
-                ProtocolVersion.TLS10.name
-            });
-        }
-    }
-
 }
--- a/src/share/classes/sun/security/ssl/SSLContextImpl.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/sun/security/ssl/SSLContextImpl.java	Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
 
 import java.net.Socket;
 
+import java.io.*;
 import java.util.*;
 import java.security.*;
 import java.security.cert.*;
@@ -36,7 +37,7 @@
 
 import sun.security.provider.certpath.AlgorithmChecker;
 
-public class SSLContextImpl extends SSLContextSpi {
+public abstract class SSLContextImpl extends SSLContextSpi {
 
     private static final Debug debug = Debug.getInstance("ssl");
 
@@ -50,20 +51,24 @@
     private X509TrustManager trustManager;
     private SecureRandom secureRandom;
 
-    public SSLContextImpl() {
-        this(null);
-    }
+    // The default algrithm constraints
+    private AlgorithmConstraints defaultAlgorithmConstraints =
+                                 new SSLAlgorithmConstraints(null);
 
-    SSLContextImpl(SSLContextImpl other) {
-        if (other == null) {
-            ephemeralKeyManager = new EphemeralKeyManager();
-            clientCache = new SSLSessionContextImpl();
-            serverCache = new SSLSessionContextImpl();
-        } else {
-            ephemeralKeyManager = other.ephemeralKeyManager;
-            clientCache = other.clientCache;
-            serverCache = other.serverCache;
-        }
+    // supported and default protocols
+    private ProtocolList defaultServerProtocolList;
+    private ProtocolList defaultClientProtocolList;
+    private ProtocolList supportedProtocolList;
+
+    // supported and default cipher suites
+    private CipherSuiteList defaultServerCipherSuiteList;
+    private CipherSuiteList defaultClientCipherSuiteList;
+    private CipherSuiteList supportedCipherSuiteList;
+
+    SSLContextImpl() {
+        ephemeralKeyManager = new EphemeralKeyManager();
+        clientCache = new SSLSessionContextImpl();
+        serverCache = new SSLSessionContextImpl();
     }
 
     protected void engineInit(KeyManager[] km, TrustManager[] tm,
@@ -177,7 +182,7 @@
             throw new IllegalStateException(
                 "SSLContextImpl is not initialized");
         }
-        return new SSLSocketFactoryImpl(this);
+       return new SSLSocketFactoryImpl(this);
     }
 
     protected SSLServerSocketFactory engineGetServerSocketFactory() {
@@ -227,6 +232,535 @@
         return ephemeralKeyManager;
     }
 
+    abstract SSLParameters getDefaultServerSSLParams();
+    abstract SSLParameters getDefaultClientSSLParams();
+    abstract SSLParameters getSupportedSSLParams();
+
+    // Get suported ProtoclList.
+    ProtocolList getSuportedProtocolList() {
+        if (supportedProtocolList == null) {
+            supportedProtocolList =
+                new ProtocolList(getSupportedSSLParams().getProtocols());
+        }
+
+        return supportedProtocolList;
+    }
+
+    // Get default ProtoclList.
+    ProtocolList getDefaultProtocolList(boolean roleIsServer) {
+        if (roleIsServer) {
+            if (defaultServerProtocolList == null) {
+                defaultServerProtocolList = new ProtocolList(
+                        getDefaultServerSSLParams().getProtocols());
+            }
+
+            return defaultServerProtocolList;
+        } else {
+            if (defaultClientProtocolList == null) {
+                defaultClientProtocolList = new ProtocolList(
+                        getDefaultClientSSLParams().getProtocols());
+            }
+
+            return defaultClientProtocolList;
+        }
+    }
+
+    // Get suported CipherSuiteList.
+    CipherSuiteList getSuportedCipherSuiteList() {
+        // Clear cache of available ciphersuites.
+        clearAvailableCache();
+
+        if (supportedCipherSuiteList == null) {
+            supportedCipherSuiteList =
+                getApplicableCipherSuiteList(getSuportedProtocolList(), false);
+        }
+
+        return supportedCipherSuiteList;
+    }
+
+    // Get default CipherSuiteList.
+    CipherSuiteList getDefaultCipherSuiteList(boolean roleIsServer) {
+        // Clear cache of available ciphersuites.
+        clearAvailableCache();
+
+        if (roleIsServer) {
+            if (defaultServerCipherSuiteList == null) {
+                defaultServerCipherSuiteList = getApplicableCipherSuiteList(
+                        getDefaultProtocolList(true), true);
+            }
+
+            return defaultServerCipherSuiteList;
+        } else {
+            if (defaultClientCipherSuiteList == null) {
+                defaultClientCipherSuiteList = getApplicableCipherSuiteList(
+                        getDefaultProtocolList(false), true);
+            }
+
+            return defaultClientCipherSuiteList;
+        }
+    }
+
+    /**
+     * Return whether a protocol list is the original default enabled
+     * protocols.  See: SSLSocket/SSLEngine.setEnabledProtocols()
+     */
+    boolean isDefaultProtocolList(ProtocolList protocols) {
+        return (protocols == defaultServerProtocolList) ||
+               (protocols == defaultClientProtocolList);
+    }
+
+
+    /*
+     * Return the list of all available CipherSuites with a priority of
+     * minPriority or above.
+     */
+    private CipherSuiteList getApplicableCipherSuiteList(
+            ProtocolList protocols, boolean onlyEnabled) {
+
+        int minPriority = CipherSuite.SUPPORTED_SUITES_PRIORITY;
+        if (onlyEnabled) {
+            minPriority = CipherSuite.DEFAULT_SUITES_PRIORITY;
+        }
+
+        Collection<CipherSuite> allowedCipherSuites =
+                                    CipherSuite.allowedCipherSuites();
+
+        ArrayList<CipherSuite> suites = new ArrayList<>();
+        if (!(protocols.collection().isEmpty()) &&
+                protocols.min.v != ProtocolVersion.NONE.v) {
+            for (CipherSuite suite : allowedCipherSuites) {
+                if (suite.allowed == false || suite.priority < minPriority) {
+                    continue;
+                }
+
+                if (suite.isAvailable() &&
+                        suite.obsoleted > protocols.min.v &&
+                        suite.supported <= protocols.max.v) {
+                    if (defaultAlgorithmConstraints.permits(
+                            EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
+                            suite.name, null)) {
+                        suites.add(suite);
+                    }
+                } else if (debug != null &&
+                        Debug.isOn("sslctx") && Debug.isOn("verbose")) {
+                    if (suite.obsoleted <= protocols.min.v) {
+                        System.out.println(
+                            "Ignoring obsoleted cipher suite: " + suite);
+                    } else if (suite.supported > protocols.max.v) {
+                        System.out.println(
+                            "Ignoring unsupported cipher suite: " + suite);
+                    } else {
+                        System.out.println(
+                            "Ignoring unavailable cipher suite: " + suite);
+                    }
+                }
+            }
+        }
+
+        return new CipherSuiteList(suites);
+    }
+
+    /**
+     * Clear cache of available ciphersuites. If we support all ciphers
+     * internally, there is no need to clear the cache and calling this
+     * method has no effect.
+     */
+    synchronized void clearAvailableCache() {
+        if (CipherSuite.DYNAMIC_AVAILABILITY) {
+            supportedCipherSuiteList = null;
+            defaultServerCipherSuiteList = null;
+            defaultClientCipherSuiteList = null;
+            CipherSuite.BulkCipher.clearAvailableCache();
+            JsseJce.clearEcAvailable();
+        }
+    }
+
+    /*
+     * The SSLContext implementation for TLS/SSL algorithm
+     *
+     * SSL/TLS protocols specify the forward compatibility and version
+     * roll-back attack protections, however, a number of SSL/TLS server
+     * vendors did not implement these aspects properly, and some current
+     * SSL/TLS servers may refuse to talk to a TLS 1.1 or later client.
+     *
+     * Considering above interoperability issues, SunJSSE will not set
+     * TLS 1.1 and TLS 1.2 as the enabled protocols for client by default.
+     *
+     * For SSL/TLS servers, there is no such interoperability issues as
+     * SSL/TLS clients. In SunJSSE, TLS 1.1 or later version will be the
+     * enabled protocols for server by default.
+     *
+     * We may change the behavior when popular TLS/SSL vendors support TLS
+     * forward compatibility properly.
+     *
+     * SSLv2Hello is no longer necessary.  This interoperability option was
+     * put in place in the late 90's when SSLv3/TLS1.0 were relatively new
+     * and there were a fair number of SSLv2-only servers deployed.  Because
+     * of the security issues in SSLv2, it is rarely (if ever) used, as
+     * deployments should now be using SSLv3 and TLSv1.
+     *
+     * Considering the issues of SSLv2Hello, we should not enable SSLv2Hello
+     * by default. Applications still can use it by enabling SSLv2Hello with
+     * the series of setEnabledProtocols APIs.
+     */
+
+    /*
+     * The conservative SSLContext implementation for TLS, SSL, SSLv3 and
+     * TLS10 algorithm.
+     *
+     * This is a super class of DefaultSSLContext and TLS10Context.
+     *
+     * @see SSLContext
+     */
+    private static class ConservativeSSLContext extends SSLContextImpl {
+        // parameters
+        private static SSLParameters defaultServerSSLParams;
+        private static SSLParameters defaultClientSSLParams;
+        private static SSLParameters supportedSSLParams;
+
+        static {
+            if (SunJSSE.isFIPS()) {
+                supportedSSLParams = new SSLParameters();
+                supportedSSLParams.setProtocols(new String[] {
+                    ProtocolVersion.TLS10.name,
+                    ProtocolVersion.TLS11.name,
+                    ProtocolVersion.TLS12.name
+                });
+
+                defaultServerSSLParams = supportedSSLParams;
+
+                defaultClientSSLParams = new SSLParameters();
+                defaultClientSSLParams.setProtocols(new String[] {
+                    ProtocolVersion.TLS10.name
+                });
+
+            } else {
+                supportedSSLParams = new SSLParameters();
+                supportedSSLParams.setProtocols(new String[] {
+                    ProtocolVersion.SSL20Hello.name,
+                    ProtocolVersion.SSL30.name,
+                    ProtocolVersion.TLS10.name,
+                    ProtocolVersion.TLS11.name,
+                    ProtocolVersion.TLS12.name
+                });
+
+                defaultServerSSLParams = supportedSSLParams;
+
+                defaultClientSSLParams = new SSLParameters();
+                defaultClientSSLParams.setProtocols(new String[] {
+                    ProtocolVersion.SSL30.name,
+                    ProtocolVersion.TLS10.name
+                });
+            }
+        }
+
+        SSLParameters getDefaultServerSSLParams() {
+            return defaultServerSSLParams;
+        }
+
+        SSLParameters getDefaultClientSSLParams() {
+            return defaultClientSSLParams;
+        }
+
+        SSLParameters getSupportedSSLParams() {
+            return supportedSSLParams;
+        }
+    }
+
+    /*
+     * The SSLContext implementation for default algorithm
+     *
+     * @see SSLContext
+     */
+    public static final class DefaultSSLContext extends ConservativeSSLContext {
+        private static final String NONE = "NONE";
+        private static final String P11KEYSTORE = "PKCS11";
+
+        private static volatile SSLContextImpl defaultImpl;
+
+        private static TrustManager[] defaultTrustManagers;
+        private static KeyManager[] defaultKeyManagers;
+
+        public DefaultSSLContext() throws Exception {
+            try {
+                super.engineInit(getDefaultKeyManager(),
+                        getDefaultTrustManager(), null);
+            } catch (Exception e) {
+                if (debug != null && Debug.isOn("defaultctx")) {
+                    System.out.println("default context init failed: " + e);
+                }
+                throw e;
+            }
+
+            if (defaultImpl == null) {
+                defaultImpl = this;
+            }
+        }
+
+        protected void engineInit(KeyManager[] km, TrustManager[] tm,
+            SecureRandom sr) throws KeyManagementException {
+            throw new KeyManagementException
+                ("Default SSLContext is initialized automatically");
+        }
+
+        static synchronized SSLContextImpl getDefaultImpl() throws Exception {
+            if (defaultImpl == null) {
+                new DefaultSSLContext();
+            }
+            return defaultImpl;
+        }
+
+        private static synchronized TrustManager[] getDefaultTrustManager()
+                throws Exception {
+            if (defaultTrustManagers != null) {
+                return defaultTrustManagers;
+            }
+
+            KeyStore ks =
+                TrustManagerFactoryImpl.getCacertsKeyStore("defaultctx");
+
+            TrustManagerFactory tmf = TrustManagerFactory.getInstance(
+                TrustManagerFactory.getDefaultAlgorithm());
+            tmf.init(ks);
+            defaultTrustManagers = tmf.getTrustManagers();
+            return defaultTrustManagers;
+        }
+
+        private static synchronized KeyManager[] getDefaultKeyManager()
+                throws Exception {
+            if (defaultKeyManagers != null) {
+                return defaultKeyManagers;
+            }
+
+            final Map<String,String> props = new HashMap<>();
+            AccessController.doPrivileged(
+                        new PrivilegedExceptionAction<Object>() {
+                public Object run() throws Exception {
+                    props.put("keyStore",  System.getProperty(
+                                "javax.net.ssl.keyStore", ""));
+                    props.put("keyStoreType", System.getProperty(
+                                "javax.net.ssl.keyStoreType",
+                                KeyStore.getDefaultType()));
+                    props.put("keyStoreProvider", System.getProperty(
+                                "javax.net.ssl.keyStoreProvider", ""));
+                    props.put("keyStorePasswd", System.getProperty(
+                                "javax.net.ssl.keyStorePassword", ""));
+                    return null;
+                }
+            });
+
+            final String defaultKeyStore = props.get("keyStore");
+            String defaultKeyStoreType = props.get("keyStoreType");
+            String defaultKeyStoreProvider = props.get("keyStoreProvider");
+            if (debug != null && Debug.isOn("defaultctx")) {
+                System.out.println("keyStore is : " + defaultKeyStore);
+                System.out.println("keyStore type is : " +
+                                        defaultKeyStoreType);
+                System.out.println("keyStore provider is : " +
+                                        defaultKeyStoreProvider);
+            }
+
+            if (P11KEYSTORE.equals(defaultKeyStoreType) &&
+                    !NONE.equals(defaultKeyStore)) {
+                throw new IllegalArgumentException("if keyStoreType is "
+                    + P11KEYSTORE + ", then keyStore must be " + NONE);
+            }
+
+            FileInputStream fs = null;
+            if (defaultKeyStore.length() != 0 && !NONE.equals(defaultKeyStore)) {
+                fs = AccessController.doPrivileged(
+                        new PrivilegedExceptionAction<FileInputStream>() {
+                    public FileInputStream run() throws Exception {
+                        return new FileInputStream(defaultKeyStore);
+                    }
+                });
+            }
+
+            String defaultKeyStorePassword = props.get("keyStorePasswd");
+            char[] passwd = null;
+            if (defaultKeyStorePassword.length() != 0) {
+                passwd = defaultKeyStorePassword.toCharArray();
+            }
+
+            /**
+             * Try to initialize key store.
+             */
+            KeyStore ks = null;
+            if ((defaultKeyStoreType.length()) != 0) {
+                if (debug != null && Debug.isOn("defaultctx")) {
+                    System.out.println("init keystore");
+                }
+                if (defaultKeyStoreProvider.length() == 0) {
+                    ks = KeyStore.getInstance(defaultKeyStoreType);
+                } else {
+                    ks = KeyStore.getInstance(defaultKeyStoreType,
+                                        defaultKeyStoreProvider);
+                }
+
+                // if defaultKeyStore is NONE, fs will be null
+                ks.load(fs, passwd);
+            }
+            if (fs != null) {
+                fs.close();
+                fs = null;
+            }
+
+            /*
+             * Try to initialize key manager.
+             */
+            if (debug != null && Debug.isOn("defaultctx")) {
+                System.out.println("init keymanager of type " +
+                    KeyManagerFactory.getDefaultAlgorithm());
+            }
+            KeyManagerFactory kmf = KeyManagerFactory.getInstance(
+                KeyManagerFactory.getDefaultAlgorithm());
+
+            if (P11KEYSTORE.equals(defaultKeyStoreType)) {
+                kmf.init(ks, null); // do not pass key passwd if using token
+            } else {
+                kmf.init(ks, passwd);
+            }
+
+            defaultKeyManagers = kmf.getKeyManagers();
+            return defaultKeyManagers;
+        }
+    }
+
+    /*
+     * The SSLContext implementation for TLS, SSL, SSLv3 and TLS10 algorithm
+     *
+     * @see SSLContext
+     */
+    public static final class TLS10Context extends ConservativeSSLContext {
+        // use the default constructor and methods
+    }
+
+    /*
+     * The SSLContext implementation for TLS11 algorithm
+     *
+     * @see SSLContext
+     */
+    public static final class TLS11Context extends SSLContextImpl {
+        // parameters
+        private static SSLParameters defaultServerSSLParams;
+        private static SSLParameters defaultClientSSLParams;
+        private static SSLParameters supportedSSLParams;
+
+        static {
+            if (SunJSSE.isFIPS()) {
+                supportedSSLParams = new SSLParameters();
+                supportedSSLParams.setProtocols(new String[] {
+                    ProtocolVersion.TLS10.name,
+                    ProtocolVersion.TLS11.name,
+                    ProtocolVersion.TLS12.name
+                });
+
+                defaultServerSSLParams = supportedSSLParams;
+
+                defaultClientSSLParams = new SSLParameters();
+                defaultClientSSLParams.setProtocols(new String[] {
+                    ProtocolVersion.TLS10.name,
+                    ProtocolVersion.TLS11.name
+                });
+
+            } else {
+                supportedSSLParams = new SSLParameters();
+                supportedSSLParams.setProtocols(new String[] {
+                    ProtocolVersion.SSL20Hello.name,
+                    ProtocolVersion.SSL30.name,
+                    ProtocolVersion.TLS10.name,
+                    ProtocolVersion.TLS11.name,
+                    ProtocolVersion.TLS12.name
+                });
+
+                defaultServerSSLParams = supportedSSLParams;
+
+                defaultClientSSLParams = new SSLParameters();
+                defaultClientSSLParams.setProtocols(new String[] {
+                    ProtocolVersion.SSL30.name,
+                    ProtocolVersion.TLS10.name,
+                    ProtocolVersion.TLS11.name
+                });
+            }
+        }
+
+        SSLParameters getDefaultServerSSLParams() {
+            return defaultServerSSLParams;
+        }
+
+        SSLParameters getDefaultClientSSLParams() {
+            return defaultClientSSLParams;
+        }
+
+        SSLParameters getSupportedSSLParams() {
+            return supportedSSLParams;
+        }
+    }
+
+    /*
+     * The SSLContext implementation for TLS12 algorithm
+     *
+     * @see SSLContext
+     */
+    public static final class TLS12Context extends SSLContextImpl {
+        // parameters
+        private static SSLParameters defaultServerSSLParams;
+        private static SSLParameters defaultClientSSLParams;
+        private static SSLParameters supportedSSLParams;
+
+        static {
+            if (SunJSSE.isFIPS()) {
+                supportedSSLParams = new SSLParameters();
+                supportedSSLParams.setProtocols(new String[] {
+                    ProtocolVersion.TLS10.name,
+                    ProtocolVersion.TLS11.name,
+                    ProtocolVersion.TLS12.name
+                });
+
+                defaultServerSSLParams = supportedSSLParams;
+
+                defaultClientSSLParams = new SSLParameters();
+                defaultClientSSLParams.setProtocols(new String[] {
+                    ProtocolVersion.TLS10.name,
+                    ProtocolVersion.TLS11.name,
+                    ProtocolVersion.TLS12.name
+                });
+
+            } else {
+                supportedSSLParams = new SSLParameters();
+                supportedSSLParams.setProtocols(new String[] {
+                    ProtocolVersion.SSL20Hello.name,
+                    ProtocolVersion.SSL30.name,
+                    ProtocolVersion.TLS10.name,
+                    ProtocolVersion.TLS11.name,
+                    ProtocolVersion.TLS12.name
+                });
+
+                defaultServerSSLParams = supportedSSLParams;
+
+                defaultClientSSLParams = new SSLParameters();
+                defaultClientSSLParams.setProtocols(new String[] {
+                    ProtocolVersion.SSL30.name,
+                    ProtocolVersion.TLS10.name,
+                    ProtocolVersion.TLS11.name,
+                    ProtocolVersion.TLS12.name
+                });
+            }
+        }
+
+        SSLParameters getDefaultServerSSLParams() {
+            return defaultServerSSLParams;
+        }
+
+        SSLParameters getDefaultClientSSLParams() {
+            return defaultClientSSLParams;
+        }
+
+        SSLParameters getSupportedSSLParams() {
+            return supportedSSLParams;
+        }
+    }
+
 }
 
 
--- a/src/share/classes/sun/security/ssl/SSLEngineImpl.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/sun/security/ssl/SSLEngineImpl.java	Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -374,8 +374,10 @@
         clientVerifyData = new byte[0];
         serverVerifyData = new byte[0];
 
-        enabledCipherSuites = CipherSuiteList.getDefault();
-        enabledProtocols = ProtocolList.getDefault(roleIsServer);
+        enabledCipherSuites =
+                sslContext.getDefaultCipherSuiteList(roleIsServer);
+        enabledProtocols =
+                sslContext.getDefaultProtocolList(roleIsServer);
 
         wrapLock = new Object();
         unwrapLock = new Object();
@@ -1883,8 +1885,8 @@
              * change them to the corresponding default ones.
              */
             if (roleIsServer != (!flag) &&
-                    ProtocolList.isDefaultProtocolList(enabledProtocols)) {
-                enabledProtocols = ProtocolList.getDefault(!flag);
+                    sslContext.isDefaultProtocolList(enabledProtocols)) {
+                enabledProtocols = sslContext.getDefaultProtocolList(!flag);
             }
 
             roleIsServer = !flag;
@@ -1907,8 +1909,8 @@
                  * change them to the corresponding default ones.
                  */
                 if (roleIsServer != (!flag) &&
-                        ProtocolList.isDefaultProtocolList(enabledProtocols)) {
-                    enabledProtocols = ProtocolList.getDefault(!flag);
+                        sslContext.isDefaultProtocolList(enabledProtocols)) {
+                    enabledProtocols = sslContext.getDefaultProtocolList(!flag);
                 }
 
                 roleIsServer = !flag;
@@ -1951,8 +1953,7 @@
      * @return an array of cipher suite names
      */
     public String[] getSupportedCipherSuites() {
-        CipherSuiteList.clearAvailableCache();
-        return CipherSuiteList.getSupported().toStringArray();
+        return sslContext.getSuportedCipherSuiteList().toStringArray();
     }
 
     /**
@@ -1992,7 +1993,7 @@
      * @return an array of protocol names.
      */
     public String[] getSupportedProtocols() {
-        return ProtocolList.getSupported().toStringArray();
+        return sslContext.getSuportedProtocolList().toStringArray();
     }
 
     /**
--- a/src/share/classes/sun/security/ssl/SSLServerSocketFactoryImpl.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/sun/security/ssl/SSLServerSocketFactoryImpl.java	Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -49,7 +49,7 @@
      * java.security file is set.
      */
     public SSLServerSocketFactoryImpl() throws Exception {
-        this.context = DefaultSSLContextImpl.getDefaultImpl();
+        this.context = SSLContextImpl.DefaultSSLContext.getDefaultImpl();
     }
 
     /**
@@ -99,8 +99,7 @@
      * is encrypted to provide confidentiality.
      */
     public String[] getDefaultCipherSuites() {
-        CipherSuiteList.clearAvailableCache();
-        return CipherSuiteList.getDefault().toStringArray();
+        return context.getDefaultCipherSuiteList(true).toStringArray();
     }
 
     /**
@@ -114,8 +113,7 @@
      * @return an array of cipher suite names
      */
     public String[] getSupportedCipherSuites() {
-        CipherSuiteList.clearAvailableCache();
-        return CipherSuiteList.getSupported().toStringArray();
+        return context.getSuportedCipherSuiteList().toStringArray();
     }
 
 }
--- a/src/share/classes/sun/security/ssl/SSLServerSocketImpl.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/sun/security/ssl/SSLServerSocketImpl.java	Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -153,8 +153,8 @@
             throw new SSLException("No Authentication context given");
         }
         sslContext = context;
-        enabledCipherSuites = CipherSuiteList.getDefault();
-        enabledProtocols = ProtocolList.getDefault(true);
+        enabledCipherSuites = sslContext.getDefaultCipherSuiteList(true);
+        enabledProtocols = sslContext.getDefaultProtocolList(true);
     }
 
     /**
@@ -168,8 +168,7 @@
      * @return an array of cipher suite names
      */
     public String[] getSupportedCipherSuites() {
-        CipherSuiteList.clearAvailableCache();
-        return CipherSuiteList.getSupported().toStringArray();
+        return sslContext.getSuportedCipherSuiteList().toStringArray();
     }
 
     /**
@@ -194,7 +193,7 @@
     }
 
     public String[] getSupportedProtocols() {
-        return ProtocolList.getSupported().toStringArray();
+        return sslContext.getSuportedProtocolList().toStringArray();
     }
 
     /**
@@ -253,8 +252,8 @@
          * change them to the corresponding default ones.
          */
         if (useServerMode != (!flag) &&
-                ProtocolList.isDefaultProtocolList(enabledProtocols)) {
-            enabledProtocols = ProtocolList.getDefault(!flag);
+                sslContext.isDefaultProtocolList(enabledProtocols)) {
+            enabledProtocols = sslContext.getDefaultProtocolList(!flag);
         }
 
         useServerMode = !flag;
--- a/src/share/classes/sun/security/ssl/SSLSocketFactoryImpl.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/sun/security/ssl/SSLSocketFactoryImpl.java	Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -42,20 +42,18 @@
  *
  * @author David Brownell
  */
-final
-public class SSLSocketFactoryImpl extends SSLSocketFactory
-{
+final public class SSLSocketFactoryImpl extends SSLSocketFactory {
+
     private static SSLContextImpl defaultContext;
     private SSLContextImpl context;
 
-
     /**
      * Constructor used to instantiate the default factory. This method is
      * only called if the old "ssl.SocketFactory.provider" property in the
      * java.security file is set.
      */
     public SSLSocketFactoryImpl() throws Exception {
-        this.context = DefaultSSLContextImpl.getDefaultImpl();
+        this.context = SSLContextImpl.DefaultSSLContext.getDefaultImpl();
     }
 
     /**
@@ -167,11 +165,9 @@
      * is encrypted to provide confidentiality.
      */
     public String[] getDefaultCipherSuites() {
-        CipherSuiteList.clearAvailableCache();
-        return CipherSuiteList.getDefault().toStringArray();
+        return context.getDefaultCipherSuiteList(false).toStringArray();
     }
 
-
     /**
      * Returns the names of the cipher suites which could be enabled for use
      * on an SSL connection.  Normally, only a subset of these will actually
@@ -181,7 +177,6 @@
      * certain kinds of certificates to use certain cipher suites.
      */
     public String[] getSupportedCipherSuites() {
-        CipherSuiteList.clearAvailableCache();
-        return CipherSuiteList.getSupported().toStringArray();
+        return context.getSuportedCipherSuiteList().toStringArray();
     }
 }
--- a/src/share/classes/sun/security/ssl/SSLSocketImpl.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/sun/security/ssl/SSLSocketImpl.java	Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -562,8 +562,11 @@
         clientVerifyData = new byte[0];
         serverVerifyData = new byte[0];
 
-        enabledCipherSuites = CipherSuiteList.getDefault();
-        enabledProtocols = ProtocolList.getDefault(roleIsServer);
+        enabledCipherSuites =
+                sslContext.getDefaultCipherSuiteList(roleIsServer);
+        enabledProtocols =
+                sslContext.getDefaultProtocolList(roleIsServer);
+
         inrec = null;
 
         // save the acc
@@ -2170,8 +2173,8 @@
              * change them to the corresponding default ones.
              */
             if (roleIsServer != (!flag) &&
-                    ProtocolList.isDefaultProtocolList(enabledProtocols)) {
-                enabledProtocols = ProtocolList.getDefault(!flag);
+                    sslContext.isDefaultProtocolList(enabledProtocols)) {
+                enabledProtocols = sslContext.getDefaultProtocolList(!flag);
             }
             roleIsServer = !flag;
             break;
@@ -2192,8 +2195,8 @@
                  * change them to the corresponding default ones.
                  */
                 if (roleIsServer != (!flag) &&
-                        ProtocolList.isDefaultProtocolList(enabledProtocols)) {
-                    enabledProtocols = ProtocolList.getDefault(!flag);
+                        sslContext.isDefaultProtocolList(enabledProtocols)) {
+                    enabledProtocols = sslContext.getDefaultProtocolList(!flag);
                 }
                 roleIsServer = !flag;
                 connectionState = cs_START;
@@ -2230,8 +2233,7 @@
      * @return an array of cipher suite names
      */
     public String[] getSupportedCipherSuites() {
-        CipherSuiteList.clearAvailableCache();
-        return CipherSuiteList.getSupported().toStringArray();
+        return sslContext.getSuportedCipherSuiteList().toStringArray();
     }
 
     /**
@@ -2271,7 +2273,7 @@
      * @return an array of protocol names.
      */
     public String[] getSupportedProtocols() {
-        return ProtocolList.getSupported().toStringArray();
+        return sslContext.getSuportedProtocolList().toStringArray();
     }
 
     /**
--- a/src/share/classes/sun/security/ssl/SunJSSE.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/sun/security/ssl/SunJSSE.java	Tue Apr 12 14:23:03 2011 -0700
@@ -204,22 +204,21 @@
         put("Alg.Alias.TrustManagerFactory.SunPKIX", "PKIX");
         put("Alg.Alias.TrustManagerFactory.X509", "PKIX");
         put("Alg.Alias.TrustManagerFactory.X.509", "PKIX");
+
+        put("SSLContext.TLSv1",
+            "sun.security.ssl.SSLContextImpl$TLS10Context");
+        put("Alg.Alias.SSLContext.TLS", "TLSv1");
         if (isfips == false) {
-            put("SSLContext.SSL",
-                "sun.security.ssl.SSLContextImpl");
-            put("SSLContext.SSLv3",
-                "sun.security.ssl.SSLContextImpl");
+            put("Alg.Alias.SSLContext.SSL", "TLSv1");
+            put("Alg.Alias.SSLContext.SSLv3", "TLSv1");
         }
-        put("SSLContext.TLS",
-            "sun.security.ssl.SSLContextImpl");
-        put("SSLContext.TLSv1",
-            "sun.security.ssl.SSLContextImpl");
+
         put("SSLContext.TLSv1.1",
-            "sun.security.ssl.SSLContextImpl");
+            "sun.security.ssl.SSLContextImpl$TLS11Context");
         put("SSLContext.TLSv1.2",
-            "sun.security.ssl.SSLContextImpl");
+            "sun.security.ssl.SSLContextImpl$TLS12Context");
         put("SSLContext.Default",
-            "sun.security.ssl.DefaultSSLContextImpl");
+            "sun.security.ssl.SSLContextImpl$DefaultSSLContext");
 
         /*
          * KeyStore
--- a/src/share/classes/sun/security/util/ManifestEntryVerifier.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/sun/security/util/ManifestEntryVerifier.java	Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -191,8 +191,8 @@
      *
      *
      */
-    public CodeSigner[] verify(Hashtable<String, CodeSigner[]> verifiedSigners,
-                Hashtable<String, CodeSigner[]> sigFileSigners)
+    public CodeSigner[] verify(Map<String, CodeSigner[]> verifiedSigners,
+                Map<String, CodeSigner[]> sigFileSigners)
         throws JarException
     {
         if (skip) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/sun/security/util/SignatureFileManifest.java	Tue Apr 12 14:23:03 2011 -0700
@@ -0,0 +1,251 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+
+/**
+ * This class provides streaming mode reading of manifest files.
+ * Used by {@link SignatureFileVerifier}.
+ */
+class SignatureFileManifest extends Manifest {
+
+    /*
+     * Reading a manifest into this object by calling update(byte[]) on chunks.
+     * During the reading, the bytes are saved in (@code current} until a line
+     * is complete and the key-value pair is saved in {@code currentAttr}. When
+     * a section is complete, {@code consumeAttr} is called to merge
+     * {@code currentAttr} into main attributes or a named entry.
+     */
+
+    // Internal state during update() style reading
+    // 0. not in update mode
+    // 1, in update mode but main attributes not completed yet
+    // 2. main attributes completed, still reading the entries
+    private int state = 0;
+
+    // The partial line read
+    private byte[] current;
+
+    // Number of bytes in current
+    private int currentPos = 0;
+
+    // The current Attribute
+    private Attributes currentAttr;
+
+    /**
+     * Reads a manifest in chunks.
+     * <p>
+     * This method must be called in a row, reading chunks from a single
+     * manifest file by order. After all chunks are read, caller must call
+     * {@code update(null)} to fully consume the manifest.
+     * <p>
+     * The entry names and attributes read will be merged in with the current
+     * manifest entries. The {@link #read} method cannot be called inside a
+     * row of update calls.
+     * <p>
+     * Along with the calls, caller can call {@link #getMainAttributes()},
+     * {@link #getAttributes(java.lang.String)} or {@link #getEntries()}
+     * to get already available contents. However, in order not to return
+     * partial result, when the main attributes in the new manifest is not
+     * consumed completely, {@link #getMainAttributes()} throws an
+     * {@code IllegalStateException}. When a certain named entry is not
+     * consumed completely, {@link #getAttributes(java.lang.String)}
+     * returns the old {@code Attributes} for the name (if it exists).
+     *
+     * @param data null for last call, otherwise, feeding chunks
+     * @param offset offset into data to begin read
+     * @param length length of data after offset to read
+     * @exception IOException if an I/O error has occurred
+     * @exception IllegalStateException if {@code update(null)} is called
+     * without any previous {@code update(non-null)} call
+     */
+    public void update(byte[] data, int offset, int length) throws IOException {
+
+        // The last call
+        if (data == null) {
+            if (state == 0) {
+                throw new IllegalStateException("No data to update");
+            }
+            // We accept manifest not ended with \n or \n\n
+            if (hasLastByte()) {
+                consumeCurrent();
+            }
+            // We accept empty lines at the end
+            if (!currentAttr.isEmpty()) {
+                consumeAttr();
+            }
+            state = 0;  // back to non-update state
+            current = null;
+            currentAttr = null;
+            return;
+        }
+
+        // The first call
+        if (state == 0) {
+            current = new byte[1024];
+            currentAttr = super.getMainAttributes(); // the main attribute
+            state = 1;
+        }
+
+        int end = offset + length;
+
+        while (offset < end) {
+            switch (data[offset]) {
+                case '\r':
+                    break;  // always skip
+                case '\n':
+                    if (hasLastByte() && lastByte() == '\n') {  // new section
+                        consumeCurrent();
+                        consumeAttr();
+                        if (state == 1) {
+                            state = 2;
+                        }
+                        currentAttr = new Attributes(2);
+                    } else {
+                        if (hasLastByte()) {
+                            // save \n into current but do not parse,
+                            // there might be a continuation later
+                            ensureCapacity();
+                            current[currentPos++] = data[offset];
+                        } else if (state == 1) {
+                            // there can be multiple empty lines between
+                            // sections, but cannot be at the beginning
+                            throw new IOException("invalid manifest format");
+                        }
+                    }
+                    break;
+                case ' ':
+                    if (!hasLastByte()) {
+                        throw new IOException("invalid manifest format");
+                    } else if (lastByte() == '\n') {
+                        currentPos--;   // continuation, remove last \n
+                    } else {    // a very normal ' '
+                        ensureCapacity();
+                        current[currentPos++] = data[offset];
+                    }
+                    break;
+                default:
+                    if (hasLastByte() && lastByte() == '\n') {
+                        // The start of a new pair, not continuation
+                        consumeCurrent();   // the last line read
+                    }
+                    ensureCapacity();
+                    current[currentPos++] = data[offset];
+                    break;
+            }
+            offset++;
+        }
+    }
+
+    /**
+     * Returns the main Attributes for the Manifest.
+     * @exception IllegalStateException the main attributes is being read
+     * @return the main Attributes for the Manifest
+     */
+    public Attributes getMainAttributes() {
+        if (state == 1) {
+            throw new IllegalStateException();
+        }
+        return super.getMainAttributes();
+    }
+
+    /**
+     * Reads the Manifest from the specified InputStream. The entry
+     * names and attributes read will be merged in with the current
+     * manifest entries.
+     *
+     * @param is the input stream
+     * @exception IOException if an I/O error has occurred
+     * @exception IllegalStateException if called between two {@link #update}
+     * calls
+     */
+    public void read(InputStream is) throws IOException {
+        if (state != 0) {
+            throw new IllegalStateException("Cannot call read between updates");
+        }
+        super.read(is);
+    }
+
+    /*
+     * ----------  Helper methods  -----------------
+     */
+
+    private void ensureCapacity() {
+        if (currentPos >= current.length-1) {
+            current = Arrays.copyOf(current, current.length*2);
+        }
+    }
+
+    private boolean hasLastByte() {
+        return currentPos > 0;
+    }
+
+    private byte lastByte() {
+        return current[currentPos-1];
+    }
+
+    // Parse current as key:value and save into currentAttr.
+    // There MUST be something inside current.
+    private void consumeCurrent() throws IOException {
+        // current normally has a \n end, except for the last line
+        if (current[currentPos-1] == '\n') currentPos--;
+        for (int i=0; i<currentPos; i++) {
+            if (current[i] == ':') {
+                String key = new String(current, 0, 0, i);
+                i++;
+                while (i < currentPos && current[i] == ' ') { i++; }
+                String value = new String(current, i, currentPos-i, "UTF-8");
+                currentAttr.putValue(key, value);
+                currentPos = 0;
+                return;
+            }
+        }
+        throw new IOException("invalid header field");
+    }
+
+    // Merge currentAttr into Manifest
+    private void consumeAttr() throws IOException {
+        // Only needed for named entries. For the main attribute, key/value
+        // is added into attr directly, but since getMainAttributes() throws
+        // an exception, the partial data is not leaked.
+        if (state != 1) {
+            String name = currentAttr.getValue("Name");
+            if (name != null) {
+                currentAttr.remove(new Attributes.Name("Name"));
+                Attributes old = getAttributes(name);
+                if (old != null) old.putAll(currentAttr);
+                else getEntries().put(name, currentAttr);
+            } else {
+                throw new IOException("invalid manifest format");
+            }
+        }
+    }
+}
--- a/src/share/classes/sun/security/util/SignatureFileVerifier.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/sun/security/util/SignatureFileVerifier.java	Tue Apr 12 14:23:03 2011 -0700
@@ -55,8 +55,8 @@
     /** the PKCS7 block for this .DSA/.RSA/.EC file */
     private PKCS7 block;
 
-    /** the raw bytes of the .SF file */
-    private byte sfBytes[];
+    // the content of the raw .SF file as an InputStream
+    private InputStream sfStream;
 
     /** the name of the signature block file, uppercased and without
      *  the extension (.DSA/.RSA/.EC)
@@ -66,6 +66,9 @@
     /** the ManifestDigester */
     private ManifestDigester md;
 
+    /** The MANIFEST.MF */
+    private Manifest man;
+
     /** cache of created MessageDigest objects */
     private HashMap<String, MessageDigest> createdDigests;
 
@@ -83,6 +86,7 @@
      * @param rawBytes the raw bytes of the signature block file
      */
     public SignatureFileVerifier(ArrayList<CodeSigner[]> signerCache,
+                                 Manifest man,
                                  ManifestDigester md,
                                  String name,
                                  byte rawBytes[])
@@ -94,13 +98,18 @@
         try {
             obj = Providers.startJarVerification();
             block = new PKCS7(rawBytes);
-            sfBytes = block.getContentInfo().getData();
+            byte[] contentData = block.getContentInfo().getData();
+            if (contentData != null) {
+                sfStream = new ByteArrayInputStream(contentData);
+            }
             certificateFactory = CertificateFactory.getInstance("X509");
         } finally {
             Providers.stopJarVerification(obj);
         }
         this.name = name.substring(0, name.lastIndexOf("."))
                                                    .toUpperCase(Locale.ENGLISH);
+
+        this.man = man;
         this.md = md;
         this.signerCache = signerCache;
     }
@@ -108,31 +117,13 @@
     /**
      * returns true if we need the .SF file
      */
-    public boolean needSignatureFileBytes()
+    public boolean needSignatureFile()
     {
-
-        return sfBytes == null;
+        return sfStream == null;
     }
 
-
-    /**
-     * returns true if we need this .SF file.
-     *
-     * @param name the name of the .SF file without the extension
-     *
-     */
-    public boolean needSignatureFile(String name)
-    {
-        return this.name.equalsIgnoreCase(name);
-    }
-
-    /**
-     * used to set the raw bytes of the .SF file when it
-     * is external to the signature block file.
-     */
-    public void setSignatureFile(byte sfBytes[])
-    {
-        this.sfBytes = sfBytes;
+    public void setSignatureFile(InputStream ins) {
+        this.sfStream = ins;
     }
 
     /**
@@ -145,12 +136,18 @@
      *          Signature File or PKCS7 block file name
      */
     public static boolean isBlockOrSF(String s) {
-        // we currently only support DSA and RSA PKCS7 blocks
-        if (s.endsWith(".SF") || s.endsWith(".DSA") ||
-                s.endsWith(".RSA") || s.endsWith(".EC")) {
-            return true;
-        }
-        return false;
+        return s.endsWith(".SF") || isBlock(s);
+    }
+
+    /**
+     * Utility method used by JarVerifier to determine PKCS7 block
+     * files names that are supported
+     *
+     * @param s file name
+     * @return true if the input file name is a PKCS7 block file name
+     */
+    public static boolean isBlock(String s) {
+        return s.endsWith(".DSA") || s.endsWith(".RSA") || s.endsWith(".EC");
     }
 
     /** get digest from cache */
@@ -180,7 +177,7 @@
      *
      *
      */
-    public void process(Hashtable<String, CodeSigner[]> signers,
+    public void process(Map<String, CodeSigner[]> signers,
             List manifestDigests)
         throws IOException, SignatureException, NoSuchAlgorithmException,
             JarException, CertificateException
@@ -197,31 +194,86 @@
 
     }
 
-    private void processImpl(Hashtable<String, CodeSigner[]> signers,
+    private void processImpl(Map<String, CodeSigner[]> signers,
             List manifestDigests)
         throws IOException, SignatureException, NoSuchAlgorithmException,
             JarException, CertificateException
     {
-        Manifest sf = new Manifest();
-        sf.read(new ByteArrayInputStream(sfBytes));
+        SignatureFileManifest sf = new SignatureFileManifest();
+        InputStream ins = sfStream;
 
-        String version =
-            sf.getMainAttributes().getValue(Attributes.Name.SIGNATURE_VERSION);
+        byte[] buffer = new byte[4096];
+        int sLen = block.getSignerInfos().length;
+        boolean mainOK = false;         // main attributes of SF is available...
+        boolean manifestSigned = false; // and it matches MANIFEST.MF
+        BASE64Decoder decoder = new BASE64Decoder();
 
-        if ((version == null) || !(version.equalsIgnoreCase("1.0"))) {
-            // XXX: should this be an exception?
-            // for now we just ignore this signature file
-            return;
+        PKCS7.PKCS7Verifier[] pvs = new PKCS7.PKCS7Verifier[sLen];
+        for (int i=0; i<sLen; i++) {
+            pvs[i] = PKCS7.PKCS7Verifier.from(block, block.getSignerInfos()[i]);
         }
 
-        SignerInfo[] infos = block.verify(sfBytes);
+        /*
+         * Verify SF in streaming mode. The chunks of the file are fed into
+         * the Manifest object sf and all PKCS7Verifiers. As soon as the main
+         * attributes is available, we'll check if manifestSigned is true. If
+         * yes, there is no need to fill in sf's entries field, since it should
+         * be identical to entries in man.
+         */
+        while (true) {
+            int len = ins.read(buffer);
+            if (len < 0) {
+                if (!manifestSigned) {
+                    sf.update(null, 0, 0);
+                }
+                break;
+            } else {
+                for (int i=0; i<sLen; i++) {
+                    if (pvs[i] != null) pvs[i].update(buffer, 0, len);
+                }
+                // Continue reading if verifyManifestHash fails (or, the
+                // main attributes is not available yet)
+                if (!manifestSigned) {
+                    sf.update(buffer, 0, len);
+                    if (!mainOK) {
+                        try {
+                            Attributes attr = sf.getMainAttributes();
+                            String version = attr.getValue(
+                                    Attributes.Name.SIGNATURE_VERSION);
 
-        if (infos == null) {
+                            if ((version == null) ||
+                                    !(version.equalsIgnoreCase("1.0"))) {
+                                // XXX: should this be an exception?
+                                // for now we just ignore this signature file
+                                return;
+                            }
+
+                            mainOK = true;
+                            manifestSigned = verifyManifestHash(
+                                    sf, md, decoder, manifestDigests);
+                        } catch (IllegalStateException ise) {
+                            // main attributes not available yet
+                        }
+                    }
+                }
+            }
+        }
+        List<SignerInfo> intResult = new ArrayList<>(sLen);
+        for (int i = 0; i < sLen; i++) {
+            if (pvs[i] != null) {
+                SignerInfo signerInfo = pvs[i].verify();
+                if (signerInfo != null) {
+                    intResult.add(signerInfo);
+                }
+            }
+        }
+        if (intResult.isEmpty()) {
             throw new SecurityException("cannot verify signature block file " +
                                         name);
         }
 
-        BASE64Decoder decoder = new BASE64Decoder();
+        SignerInfo[] infos =
+                intResult.toArray(new SignerInfo[intResult.size()]);
 
         CodeSigner[] newSigners = getSigners(infos, block);
 
@@ -229,26 +281,37 @@
         if (newSigners == null)
             return;
 
-        Iterator<Map.Entry<String,Attributes>> entries =
-                                sf.getEntries().entrySet().iterator();
-
-        // see if we can verify the whole manifest first
-        boolean manifestSigned = verifyManifestHash(sf, md, decoder, manifestDigests);
-
         // verify manifest main attributes
         if (!manifestSigned && !verifyManifestMainAttrs(sf, md, decoder)) {
             throw new SecurityException
                 ("Invalid signature file digest for Manifest main attributes");
         }
 
-        // go through each section in the signature file
+        Iterator<Map.Entry<String,Attributes>> entries;
+
+        if (manifestSigned) {
+            if (debug != null) {
+                debug.println("full manifest signature match, "
+                        + "update signer info from MANIFEST.MF");
+            }
+            entries = man.getEntries().entrySet().iterator();
+        } else {
+            if (debug != null) {
+                debug.println("full manifest signature unmatch, "
+                        + "update signer info from SF file");
+            }
+            entries = sf.getEntries().entrySet().iterator();
+        }
+
+        // go through each section
+
         while(entries.hasNext()) {
 
             Map.Entry<String,Attributes> e = entries.next();
             String name = e.getKey();
 
             if (manifestSigned ||
-                (verifySection(e.getValue(), name, md, decoder))) {
+                    (verifySection(e.getValue(), name, md, decoder))) {
 
                 if (name.startsWith("./"))
                     name = name.substring(2);
@@ -593,7 +656,6 @@
         if (set == subset)
             return true;
 
-        boolean match;
         for (int i = 0; i < subset.length; i++) {
             if (!contains(set, subset[i]))
                 return false;
@@ -613,8 +675,6 @@
         if ((oldSigners == null) && (signers == newSigners))
             return true;
 
-        boolean match;
-
         // make sure all oldSigners are in signers
         if ((oldSigners != null) && !isSubSet(oldSigners, signers))
             return false;
@@ -638,7 +698,7 @@
     }
 
     void updateSigners(CodeSigner[] newSigners,
-        Hashtable<String, CodeSigner[]> signers, String name) {
+        Map<String, CodeSigner[]> signers, String name) {
 
         CodeSigner[] oldSigners = signers.get(name);
 
--- a/src/share/classes/sun/util/calendar/ZoneInfoFile.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/classes/sun/util/calendar/ZoneInfoFile.java	Tue Apr 12 14:23:03 2011 -0700
@@ -479,7 +479,7 @@
                 String zi = System.getProperty("java.home") +
                     File.separator + "lib" + File.separator + "zi";
                 try {
-                    zi = FileSystems.getDefault().getPath(zi).toRealPath(true).toString();
+                    zi = FileSystems.getDefault().getPath(zi).toRealPath().toString();
                 } catch(Exception e) {
                 }
                 return zi;
--- a/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystemProvider.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystemProvider.java	Tue Apr 12 14:23:03 2011 -0700
@@ -99,7 +99,7 @@
         synchronized(filesystems) {
             Path realPath = null;
             if (ensureFile(path)) {
-                realPath = path.toRealPath(true);
+                realPath = path.toRealPath();
                 if (filesystems.containsKey(realPath))
                     throw new FileSystemAlreadyExistsException();
             }
@@ -154,7 +154,7 @@
         synchronized (filesystems) {
             ZipFileSystem zipfs = null;
             try {
-                zipfs = filesystems.get(uriToPath(uri).toRealPath(true));
+                zipfs = filesystems.get(uriToPath(uri).toRealPath());
             } catch (IOException x) {
                 // ignore the ioe from toRealPath(), return FSNFE
             }
@@ -310,7 +310,7 @@
     //////////////////////////////////////////////////////////////
     void removeFileSystem(Path zfpath, ZipFileSystem zfs) throws IOException {
         synchronized (filesystems) {
-            zfpath = zfpath.toRealPath(true);
+            zfpath = zfpath.toRealPath();
             if (filesystems.get(zfpath) == zfs)
                 filesystems.remove(zfpath);
         }
--- a/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipPath.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipPath.java	Tue Apr 12 14:23:03 2011 -0700
@@ -150,7 +150,7 @@
     }
 
     @Override
-    public ZipPath toRealPath(boolean resolveLinks) throws IOException {
+    public ZipPath toRealPath(LinkOption... options) throws IOException {
         ZipPath realPath = new ZipPath(zfs, getResolvedPath()).toAbsolutePath();
         realPath.checkAccess();
         return realPath;
--- a/src/share/native/java/util/zip/Deflater.c	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/native/java/util/zip/Deflater.c	Tue Apr 12 14:23:03 2011 -0700
@@ -129,34 +129,28 @@
     if ((*env)->GetBooleanField(env, this, setParamsID)) {
         int level = (*env)->GetIntField(env, this, levelID);
         int strategy = (*env)->GetIntField(env, this, strategyID);
-
-        in_buf = (jbyte *) malloc(this_len);
-        if (in_buf == 0) {
+        in_buf = (*env)->GetPrimitiveArrayCritical(env, this_buf, 0);
+        if (in_buf == NULL) {
             // Throw OOME only when length is not zero
             if (this_len != 0)
                 JNU_ThrowOutOfMemoryError(env, 0);
             return 0;
         }
-        (*env)->GetByteArrayRegion(env, this_buf, this_off, this_len, in_buf);
-        out_buf = (jbyte *) malloc(len);
-        if (out_buf == 0) {
-            free(in_buf);
+        out_buf = (*env)->GetPrimitiveArrayCritical(env, b, 0);
+        if (out_buf == NULL) {
+            (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0);
             if (len != 0)
                 JNU_ThrowOutOfMemoryError(env, 0);
             return 0;
         }
 
-        strm->next_in = (Bytef *) in_buf;
-        strm->next_out = (Bytef *) out_buf;
+        strm->next_in = (Bytef *) (in_buf + this_off);
+        strm->next_out = (Bytef *) (out_buf + off);
         strm->avail_in = this_len;
         strm->avail_out = len;
         res = deflateParams(strm, level, strategy);
-
-        if (res == Z_OK) {
-            (*env)->SetByteArrayRegion(env, b, off, len - strm->avail_out, out_buf);
-        }
-        free(out_buf);
-        free(in_buf);
+        (*env)->ReleasePrimitiveArrayCritical(env, b, out_buf, 0);
+        (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0);
 
         switch (res) {
         case Z_OK:
@@ -174,33 +168,28 @@
         }
     } else {
         jboolean finish = (*env)->GetBooleanField(env, this, finishID);
-        in_buf = (jbyte *) malloc(this_len);
-        if (in_buf == 0) {
+        in_buf = (*env)->GetPrimitiveArrayCritical(env, this_buf, 0);
+        if (in_buf == NULL) {
             if (this_len != 0)
                 JNU_ThrowOutOfMemoryError(env, 0);
             return 0;
         }
-        (*env)->GetByteArrayRegion(env, this_buf, this_off, this_len, in_buf);
-
-        out_buf = (jbyte *) malloc(len);
-        if (out_buf == 0) {
-            free(in_buf);
+        out_buf = (*env)->GetPrimitiveArrayCritical(env, b, 0);
+        if (out_buf == NULL) {
+            (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0);
             if (len != 0)
                 JNU_ThrowOutOfMemoryError(env, 0);
+
             return 0;
         }
 
-        strm->next_in = (Bytef *) in_buf;
-        strm->next_out = (Bytef *) out_buf;
+        strm->next_in = (Bytef *) (in_buf + this_off);
+        strm->next_out = (Bytef *) (out_buf + off);
         strm->avail_in = this_len;
         strm->avail_out = len;
         res = deflate(strm, finish ? Z_FINISH : flush);
-
-        if (res == Z_STREAM_END || res == Z_OK) {
-            (*env)->SetByteArrayRegion(env, b, off, len - strm->avail_out, out_buf);
-        }
-        free(out_buf);
-        free(in_buf);
+        (*env)->ReleasePrimitiveArrayCritical(env, b, out_buf, 0);
+        (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0);
 
         switch (res) {
         case Z_STREAM_END:
--- a/src/share/native/java/util/zip/Inflater.c	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/share/native/java/util/zip/Inflater.c	Tue Apr 12 14:23:03 2011 -0700
@@ -38,8 +38,6 @@
 #include "zlib.h"
 #include "java_util_zip_Inflater.h"
 
-#define MIN2(x, y)  ((x) < (y) ? (x) : (y))
-
 #define ThrowDataFormatException(env, msg) \
         JNU_ThrowByName(env, "java/util/zip/DataFormatException", msg)
 
@@ -111,71 +109,50 @@
                                          jarray b, jint off, jint len)
 {
     z_stream *strm = jlong_to_ptr(addr);
-
     jarray this_buf = (jarray)(*env)->GetObjectField(env, this, bufID);
     jint this_off = (*env)->GetIntField(env, this, offID);
     jint this_len = (*env)->GetIntField(env, this, lenID);
+
     jbyte *in_buf;
     jbyte *out_buf;
     int ret;
-    /*
-     * Avoid excess copying.
-     *   zlib stream usually has a few bytes of overhead for header info
-     *   (depends on the underlying data)
-     *
-     *   (a) 5 bytes per 16KB
-     *   (b) 6 bytes for entire stream
-     *   (c) 4 bytes for gzip header
-     *   (d) 2 bytes for crc
-     *
-     * Use 20 bytes as the "safe cutoff" number.
-     */
-    jint in_len = MIN2(this_len, len + 20);
-    jint consumed;
 
-    in_buf = (jbyte *) malloc(in_len);
-    if (in_buf == 0) {
-        if (in_len != 0)
+    in_buf  = (*env)->GetPrimitiveArrayCritical(env, this_buf, 0);
+    if (in_buf == NULL) {
+        if (this_len != 0)
             JNU_ThrowOutOfMemoryError(env, 0);
         return 0;
     }
-    (*env)->GetByteArrayRegion(env, this_buf, this_off, in_len, in_buf);
-
-    out_buf = (jbyte *) malloc(len);
-    if (out_buf == 0) {
-        free(in_buf);
+    out_buf = (*env)->GetPrimitiveArrayCritical(env, b, 0);
+    if (out_buf == NULL) {
+        (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0);
         if (len != 0)
             JNU_ThrowOutOfMemoryError(env, 0);
         return 0;
     }
-
-    strm->next_in  = (Bytef *) in_buf;
-    strm->next_out = (Bytef *) out_buf;
-    strm->avail_in  = in_len;
+    strm->next_in  = (Bytef *) (in_buf + this_off);
+    strm->next_out = (Bytef *) (out_buf + off);
+    strm->avail_in  = this_len;
     strm->avail_out = len;
     ret = inflate(strm, Z_PARTIAL_FLUSH);
-
-    if (ret == Z_STREAM_END || ret == Z_OK) {
-        (*env)->SetByteArrayRegion(env, b, off, len - strm->avail_out, out_buf);
-    }
-    free(out_buf);
-    free(in_buf);
+    (*env)->ReleasePrimitiveArrayCritical(env, b, out_buf, 0);
+    (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0);
 
     switch (ret) {
     case Z_STREAM_END:
         (*env)->SetBooleanField(env, this, finishedID, JNI_TRUE);
         /* fall through */
     case Z_OK:
-        consumed = in_len - strm->avail_in;
-        (*env)->SetIntField(env, this, offID, this_off + consumed);
-        (*env)->SetIntField(env, this, lenID, this_len - consumed);
+        this_off += this_len - strm->avail_in;
+        (*env)->SetIntField(env, this, offID, this_off);
+        (*env)->SetIntField(env, this, lenID, strm->avail_in);
         return len - strm->avail_out;
     case Z_NEED_DICT:
         (*env)->SetBooleanField(env, this, needDictID, JNI_TRUE);
         /* Might have consumed some input here! */
-        consumed = in_len - strm->avail_in;
-        (*env)->SetIntField(env, this, offID, this_off + consumed);
-        (*env)->SetIntField(env, this, lenID, this_len - consumed);
+        this_off += this_len - strm->avail_in;
+        (*env)->SetIntField(env, this, offID, this_off);
+        (*env)->SetIntField(env, this, lenID, strm->avail_in);
         return 0;
     case Z_BUF_ERROR:
         return 0;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/sample/forkjoin/mergesort/MergeDemo.java	Tue Apr 12 14:23:03 2011 -0700
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. 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 Oracle 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.util.Arrays;
+import java.util.Random;
+
+import static java.lang.Integer.parseInt;
+
+/**
+ * MergeExample is a class that runs a demo benchmark of the {@code ForkJoin} framework
+ * by benchmarking a {@link MergeSort} algorithm that is implemented using
+ * {@link java.util.concurrent.RecursiveAction}.
+ * The {@code ForkJoin} framework is setup with different parallelism levels
+ * and the sort is executed with arrays of different sizes to see the
+ * trade offs by using multiple threads for different sizes of the array.
+ */
+public class MergeDemo {
+    // Use a fixed seed to always get the same random values back
+    private final Random random = new Random(759123751834L);
+    private static final int ITERATIONS = 10;
+
+    /**
+     * Represents the formula {@code f(n) = start + (step * n)} for n = 0 & n < iterations
+     */
+    private static class Range {
+        private final int start;
+        private final int step;
+        private final int iterations;
+
+        private Range(int start, int step, int iterations) {
+            this.start = start;
+            this.step = step;
+            this.iterations = iterations;
+        }
+
+        /**
+         * Parses start, step and iterations from args
+         * @param args the string array containing the arguments
+         * @param start which element to start the start argument from
+         * @return the constructed range
+         */
+        public static Range parse(String[] args, int start) {
+            if (args.length < start + 3) {
+                throw new IllegalArgumentException("Too few elements in array");
+            }
+            return new Range(parseInt(args[start]), parseInt(args[start + 1]), parseInt(args[start + 2]));
+        }
+
+        public int get(int iteration) {
+            return start + (step * iteration);
+        }
+
+        public int getIterations() {
+            return iterations;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder builder = new StringBuilder();
+            builder.append(start).append(" ").append(step).append(" ").append(iterations);
+            return builder.toString();
+        }
+    }
+
+    /**
+     * Wraps the different parameters that is used when running the MergeExample.
+     * {@code sizes} represents the different array sizes
+     * {@code parallelism} represents the different parallelism levels
+     */
+    private static class Configuration {
+        private final Range sizes;
+        private final Range parallelism;
+
+        private final static Configuration defaultConfig = new Configuration(new Range(20000, 20000, 10),
+                new Range(2, 2, 10));
+
+        private Configuration(Range sizes, Range parallelism) {
+            this.sizes = sizes;
+            this.parallelism = parallelism;
+        }
+
+        /**
+         * Parses the arguments and attempts to create a configuration containing the
+         * parameters for creating the array sizes and parallelism sizes
+         * @param args the input arguments
+         * @return the configuration
+         */
+        public static Configuration parse(String[] args) {
+            if (args.length == 0) {
+                return defaultConfig;
+            } else {
+                try {
+                    if (args.length == 6) {
+                        return new Configuration(Range.parse(args, 0), Range.parse(args, 3));
+                    }
+                } catch (NumberFormatException e) {
+                    System.err.println("MergeExample: error: Argument was not a number.");
+                }
+                System.err.println("MergeExample <size start> <size step> <size steps> <parallel start> <parallel step>" +
+                        " <parallel steps>");
+                System.err.println("example: MergeExample 20000 10000 3 1 1 4");
+                System.err.println("example: will run with arrays of sizes 20000, 30000, 40000" +
+                        " and parallelism: 1, 2, 3, 4");
+                return null;
+            }
+        }
+
+        /**
+         * Creates an array for reporting the test result time in
+         * @return an array containing {@code sizes.iterations * parallelism.iterations} elements
+         */
+        private long[][] createTimesArray() {
+            return new long[sizes.getIterations()][parallelism.getIterations()];
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder builder = new StringBuilder("");
+            if (this == defaultConfig) {
+                builder.append("Default configuration. ");
+            }
+            builder.append("Running with parameters: ");
+            builder.append(sizes);
+            builder.append(" ");
+            builder.append(parallelism);
+            return builder.toString();
+        }
+    }
+
+    /**
+     * Generates an array of {@code elements} random elements
+     * @param elements the number of elements requested in the array
+     * @return an array of {@code elements} random elements
+     */
+    private int[] generateArray(int elements) {
+        int[] array = new int[elements];
+        for (int i = 0; i < elements; ++i) {
+            array[i] = random.nextInt();
+        }
+        return array;
+    }
+
+    /**
+     * Runs the test
+     * @param config contains the settings for the test
+     */
+    private void run(Configuration config) {
+        Range sizes = config.sizes;
+        Range parallelism = config.parallelism;
+
+        // Run a couple of sorts to make the JIT compile / optimize the code
+        // which should produce somewhat more fair times
+        warmup();
+
+        long[][] times = config.createTimesArray();
+
+        for (int size = 0; size < sizes.getIterations(); size++) {
+            runForSize(parallelism, sizes.get(size), times, size);
+        }
+
+        printResults(sizes, parallelism, times);
+    }
+
+    /**
+     * Prints the results as a table
+     * @param sizes the different sizes of the arrays
+     * @param parallelism the different parallelism levels used
+     * @param times the median times for the different sizes / parallelism
+     */
+    private void printResults(Range sizes, Range parallelism, long[][] times) {
+        System.out.println("Time in milliseconds. Y-axis: number of elements. X-axis parallelism used.");
+        long[] sums = new long[times[0].length];
+        System.out.format("%8s  ", "");
+        for (int i = 0; i < times[0].length; i++) {
+            System.out.format("%4d ", parallelism.get(i));
+        }
+        System.out.println("");
+        for (int size = 0; size < sizes.getIterations(); size++) {
+            System.out.format("%8d: ", sizes.get(size));
+            for (int i = 0; i < times[size].length; i++) {
+                sums[i] += times[size][i];
+                System.out.format("%4d ", times[size][i]);
+            }
+            System.out.println("");
+        }
+        System.out.format("%8s: ", "Total");
+        for (long sum : sums) {
+            System.out.format("%4d ", sum);
+        }
+        System.out.println("");
+    }
+
+    private void runForSize(Range parallelism, int elements, long[][] times, int size) {
+        for (int step = 0; step < parallelism.getIterations(); step++) {
+            long time = runForParallelism(ITERATIONS, elements, parallelism.get(step));
+            times[size][step] = time;
+        }
+    }
+
+    /**
+     * Runs <i>iterations</i> number of test sorts of a random array of <i>element</i> length
+     * @param iterations number of iterations
+     * @param elements number of elements in the random array
+     * @param parallelism parallelism for the ForkJoin framework
+     * @return the median time of runs
+     */
+    private long runForParallelism(int iterations, int elements, int parallelism) {
+        MergeSort mergeSort = new MergeSort(parallelism);
+        long[] times = new long[iterations];
+
+        for (int i = 0; i < iterations; i++) {
+            // Suggest the VM to run a garbage collection to reduce the risk of getting one
+            // while running the test run
+            System.gc();
+            long start = System.currentTimeMillis();
+            mergeSort.sort(generateArray(elements));
+            times[i] = System.currentTimeMillis() - start;
+        }
+
+        return medianValue(times);
+    }
+
+    /**
+     * Calculates the median value of the array
+     * @param times array of times
+     * @return the median value
+     */
+    private long medianValue(long[] times) {
+        if (times.length == 0) {
+            throw new IllegalArgumentException("Empty array");
+        }
+        // Make a copy of times to avoid having side effects on the parameter value
+        Arrays.sort(times.clone());
+        long median = times[times.length / 2];
+        if (times.length > 1 && times.length % 2 != 0) {
+            median = (median + times[times.length / 2 + 1]) / 2;
+        }
+        return median;
+    }
+
+    /**
+     * Generates 1000 arrays of 1000 elements and sorts them as a warmup
+     */
+    private void warmup() {
+        MergeSort mergeSort = new MergeSort(Runtime.getRuntime().availableProcessors());
+        for (int i = 0; i < 1000; i++) {
+            mergeSort.sort(generateArray(1000));
+        }
+    }
+
+    public static void main(String[] args) {
+        Configuration configuration = Configuration.parse(args);
+        if (configuration == null) {
+            System.exit(1);
+        }
+        System.out.println(configuration);
+        new MergeDemo().run(configuration);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/sample/forkjoin/mergesort/MergeSort.java	Tue Apr 12 14:23:03 2011 -0700
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. 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 Oracle 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.util.Arrays;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ForkJoinTask;
+import java.util.concurrent.RecursiveAction;
+
+/**
+ * A class for sorting an array of {@code ints} in parallel.
+ * A {@code ForkJoinPool} is used for the parallelism, using the merge sort
+ * algorithm the array is split into halves and a new sub task is created
+ * for each part. Each sub task is dispatched to the {@code ForkJoinPool}
+ * which will schedule the task to a {@code Thread}.
+ * This happens until the size of the array is at most 2
+ * elements long. At this point the array is sorted using a simple compare
+ * and possibly a swap. The tasks then finish by using insert sort to
+ * merge the two just sorted arrays.
+ *
+ * The idea of this class is to demonstrate the usage of RecursiveAction not
+ * to implement the best possible parallel merge sort. This version creates
+ * a small array for each merge (creating a lot of objects), this could
+ * be avoided by keeping a single array.
+ */
+public class MergeSort {
+    private final ForkJoinPool pool;
+
+    private static class MergeSortTask extends RecursiveAction {
+        private final int[] array;
+        private final int low;
+        private final int high;
+        private static final int THRESHOLD = 8;
+
+        /**
+         * Creates a {@code MergeSortTask} containing the array and the bounds of the array
+         *
+         * @param array the array to sort
+         * @param low the lower element to start sorting at
+         * @param high the non-inclusive high element to sort to
+         */
+        protected MergeSortTask(int[] array, int low, int high) {
+            this.array = array;
+            this.low = low;
+            this.high = high;
+        }
+
+        @Override
+        protected void compute() {
+            if (high - low <= THRESHOLD) {
+                Arrays.sort(array, low, high);
+            } else {
+                int middle = low + ((high - low) >> 1);
+                // Execute the sub tasks and wait for them to finish
+                invokeAll(new MergeSortTask(array, low, middle), new MergeSortTask(array, middle, high));
+                // Then merge the results
+                merge(middle);
+            }
+        }
+
+        /**
+         * Merges the two sorted arrays this.low, middle - 1 and middle, this.high - 1
+         * @param middle the index in the array where the second sorted list begins
+         */
+        private void merge(int middle) {
+            if (array[middle - 1] < array[middle]) {
+                return; // the arrays are already correctly sorted, so we can skip the merge
+            }
+            int[] copy = new int[high - low];
+            System.arraycopy(array, low, copy, 0, copy.length);
+            int copyLow = 0;
+            int copyHigh = high - low;
+            int copyMiddle = middle - low;
+
+            for (int i = low, p = copyLow, q = copyMiddle; i < high; i++) {
+                if (q >= copyHigh || (p < copyMiddle && copy[p] < copy[q]) ) {
+                    array[i] = copy[p++];
+                } else {
+                    array[i] = copy[q++];
+                }
+            }
+        }
+    }
+
+    /**
+     * Creates a {@code MergeSort} containing a ForkJoinPool with the indicated parallelism level
+     * @param parallelism the parallelism level used
+     */
+    public MergeSort(int parallelism) {
+        pool = new ForkJoinPool(parallelism);
+    }
+
+    /**
+     * Sorts all the elements of the given array using the ForkJoin framework
+     * @param array the array to sort
+     */
+    public void sort(int[] array) {
+        ForkJoinTask<Void> job = pool.submit(new MergeSortTask(array, 0, array.length));
+        job.join();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/sample/nio/chatserver/ChatServer.java	Tue Apr 12 14:23:03 2011 -0700
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2011 Oracle and/or its affiliates. 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 Oracle 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.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.net.StandardSocketOption;
+import java.nio.channels.*;
+import java.util.*;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Implements a chat server, this class holds the list of {@code clients} connected to the server.
+ * It sets up a server socket using AsynchronousServerSocketChannel listening to a specified port.
+ */
+public class ChatServer implements Runnable {
+    private final List<Client> connections = Collections.synchronizedList(new ArrayList<Client>());
+    private int port;
+    private final AsynchronousServerSocketChannel listener;
+    private final AsynchronousChannelGroup channelGroup;
+
+    /**
+     *
+     * @param port to listen to
+     * @throws java.io.IOException when failing to start the server
+     */
+    public ChatServer(int port) throws IOException {
+        channelGroup = AsynchronousChannelGroup.withFixedThreadPool(Runtime.getRuntime().availableProcessors(),
+                Executors.defaultThreadFactory());
+        this.port = port;
+        listener = createListener(channelGroup);
+    }
+
+    /**
+     *
+     * @return The socket address that the server is bound to
+     * @throws java.io.IOException if an I/O error occurs
+     */
+    public SocketAddress getSocketAddress() throws IOException {
+        return listener.getLocalAddress();
+    }
+
+    /**
+     * Start accepting connections
+     */
+    public void run() {
+
+        // call accept to wait for connections, tell it to call our CompletionHandler when there
+        // is a new incoming connection
+        listener.accept(null, new CompletionHandler<AsynchronousSocketChannel, Void>() {
+            @Override
+            public void completed(AsynchronousSocketChannel result, Void attachment) {
+                // request a new accept and handle the incoming connection
+                listener.accept(null, this);
+                handleNewConnection(result);
+            }
+
+            @Override
+            public void failed(Throwable exc, Void attachment) {
+            }
+        });
+    }
+
+    /**
+     * Shuts down the server
+     * @throws InterruptedException if terminated while waiting for shutdown
+     * @throws IOException if failing to shutdown the channel group
+     */
+    public void shutdown() throws InterruptedException, IOException {
+        channelGroup.shutdownNow();
+        channelGroup.awaitTermination(1, TimeUnit.SECONDS);
+    }
+
+    /*
+    * Creates a listener and starts accepting connections
+    */
+    private AsynchronousServerSocketChannel createListener(AsynchronousChannelGroup channelGroup) throws IOException {
+        final AsynchronousServerSocketChannel listener = openChannel(channelGroup);
+        listener.setOption(StandardSocketOption.SO_REUSEADDR, true);
+        listener.bind(new InetSocketAddress(port));
+        return listener;
+    }
+
+    private AsynchronousServerSocketChannel openChannel(AsynchronousChannelGroup channelGroup) throws IOException {
+        return AsynchronousServerSocketChannel.open(channelGroup);
+    }
+
+    /**
+     * Creates a new client and adds it to the list of connections.
+     * Sets the clients handler to the initial state of NameReader
+     *
+     * @param channel the newly accepted channel
+     */
+    private void handleNewConnection(AsynchronousSocketChannel channel) {
+        Client client = new Client(channel, new ClientReader(this, new NameReader(this)));
+        try {
+            channel.setOption(StandardSocketOption.TCP_NODELAY, true);
+        } catch (IOException e) {
+            // ignore
+        }
+        connections.add(client);
+        client.run();
+    }
+
+    /**
+     * Sends a message to all clients except the source.
+     * The method is synchronized as it is desired that messages are sent to
+     * all clients in the same order as received.
+     *
+     * @param client the message source
+     * @param message the message to be sent
+     */
+    public void writeMessageToClients(Client client, String message) {
+        synchronized (connections) {
+            for (Client clientConnection : connections) {
+                if (clientConnection != client) {
+                    clientConnection.writeMessageFrom(client, message);
+                }
+            }
+        }
+    }
+
+    public void removeClient(Client client) {
+        connections.remove(client);
+    }
+
+    private static void usage() {
+        System.err.println("ChatServer [-port <port number>]");
+        System.exit(1);
+    }
+
+    public static void main(String[] args) throws IOException {
+        int port = 5000;
+        if (args.length != 0 && args.length != 2) {
+            usage();
+        } else if (args.length == 2) {
+            try {
+                if (args[0].equals("-port")) {
+                    port = Integer.parseInt(args[1]);
+                } else {
+                    usage();
+                }
+            } catch (NumberFormatException e) {
+                usage();
+            }
+        }
+        System.out.println("Running on port " + port);
+        new ChatServer(port).run();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/sample/nio/chatserver/Client.java	Tue Apr 12 14:23:03 2011 -0700
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2011 Oracle and/or its affiliates. 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 Oracle 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.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.AsynchronousSocketChannel;
+import java.nio.channels.CompletionHandler;
+import java.util.LinkedList;
+import java.util.Queue;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * Client represents a remote connection to the chat server.
+ * It contains methods for reading and writing messages from the
+ * channel.
+ * Messages are considered to be separated by newline, so incomplete
+ * messages are buffered in the {@code Client}.
+ *
+ * All reads and writes are asynchronous and uses the nio2 asynchronous
+ * elements.
+ */
+class Client {
+    private final AsynchronousSocketChannel channel;
+    private AtomicReference<ClientReader> reader;
+    private String userName;
+    private final StringBuilder messageBuffer = new StringBuilder();
+
+    private final Queue<ByteBuffer> queue = new LinkedList<ByteBuffer>();
+    private boolean writing = false;
+
+    public Client(AsynchronousSocketChannel channel, ClientReader reader) {
+        this.channel = channel;
+        this.reader = new AtomicReference<ClientReader>(reader);
+    }
+
+    /**
+     * Enqueues a write of the buffer to the channel.
+     * The call is asynchronous so the buffer is not safe to modify after
+     * passing the buffer here.
+     *
+     * @param buffer the buffer to send to the channel
+     */
+    private void writeMessage(final ByteBuffer buffer) {
+        boolean threadShouldWrite = false;
+
+        synchronized(queue) {
+            queue.add(buffer);
+            // Currently no thread writing, make this thread dispatch a write
+            if (!writing) {
+                writing = true;
+                threadShouldWrite = true;
+            }
+        }
+
+        if (threadShouldWrite) {
+            writeFromQueue();
+        }
+    }
+
+    private void writeFromQueue() {
+        ByteBuffer buffer;
+
+        synchronized (queue) {
+            buffer = queue.poll();
+            if (buffer == null) {
+                writing = false;
+            }
+        }
+
+        // No new data in buffer to write
+        if (writing) {
+            writeBuffer(buffer);
+        }
+    }
+
+    private void writeBuffer(ByteBuffer buffer) {
+        channel.write(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() {
+            @Override
+            public void completed(Integer result, ByteBuffer buffer) {
+                if (buffer.hasRemaining()) {
+                    channel.write(buffer, buffer, this);
+                } else {
+                    // Go back and check if there is new data to write
+                    writeFromQueue();
+                }
+            }
+
+            @Override
+            public void failed(Throwable exc, ByteBuffer attachment) {
+            }
+        });
+    }
+
+    /**
+     * Sends a message
+     * @param string the message
+     */
+    public void writeStringMessage(String string) {
+        writeMessage(ByteBuffer.wrap(string.getBytes()));
+    }
+
+    /**
+     * Send a message from a specific client
+     * @param client the message is sent from
+     * @param message to send
+     */
+    public void writeMessageFrom(Client client, String message) {
+        if (reader.get().acceptsMessages()) {
+            writeStringMessage(client.getUserName() + ": " + message);
+        }
+    }
+
+    /**
+     * Enqueue a read
+     * @param completionHandler callback on completed read
+     */
+    public void read(CompletionHandler<Integer, ? super ByteBuffer> completionHandler) {
+        ByteBuffer input = ByteBuffer.allocate(256);
+        if (!channel.isOpen()) {
+            return;
+        }
+        channel.read(input, input, completionHandler);
+    }
+
+    /**
+     * Closes the channel
+     */
+    public void close() {
+        try {
+            channel.close();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Run the current states actions.
+     */
+    public void run() {
+        reader.get().run(this);
+    }
+
+    public void setUserName(String userName) {
+        this.userName = userName;
+    }
+
+    public void setReader(ClientReader reader) {
+        this.reader.set(reader);
+    }
+
+    public String getUserName() {
+        return userName;
+    }
+
+    public void appendMessage(String message) {
+        synchronized (messageBuffer) {
+            messageBuffer.append(message);
+        }
+    }
+
+    /**
+     * @return the next newline separated message in the buffer. null is returned if the buffer
+     * doesn't contain any newline.
+     */
+    public String nextMessage() {
+        synchronized(messageBuffer) {
+            int nextNewline = messageBuffer.indexOf("\n");
+            if (nextNewline == -1) {
+                return null;
+            }
+            String message = messageBuffer.substring(0, nextNewline + 1);
+            messageBuffer.delete(0, nextNewline + 1);
+            return message;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/sample/nio/chatserver/ClientReader.java	Tue Apr 12 14:23:03 2011 -0700
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2011 Oracle and/or its affiliates. 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 Oracle 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.channels.CompletionHandler;
+
+/**
+ * Handles a cycle of reading / writing on the {@code Client}.
+ */
+class ClientReader {
+    private final DataReader callback;
+    private final ChatServer chatServer;
+
+    ClientReader(ChatServer chatServer, DataReader callback) {
+        this.chatServer = chatServer;
+        this.callback = callback;
+    }
+
+    public boolean acceptsMessages() {
+        return callback.acceptsMessages();
+    }
+
+    /**
+     * Runs a cycle of doing a beforeRead action and then enqueing a new
+     * read on the client. Handles closed channels and errors while reading.
+     * If the client is still connected a new round of actions are called.
+     */
+    public void run(final Client client) {
+        callback.beforeRead(client);
+        client.read(new CompletionHandler<Integer, ByteBuffer>() {
+            @Override
+            public void completed(Integer result, ByteBuffer buffer) {
+                // if result is negative or zero the connection has been closed or something gone wrong
+                if (result < 1) {
+                    client.close();
+                    System.out.println("Closing connection to " + client);
+                    chatServer.removeClient(client);
+                } else {
+                    callback.onData(client, buffer, result);
+                    // enqueue next round of actions
+                    client.run();
+                }
+            }
+
+            @Override
+            public void failed(Throwable exc, ByteBuffer buffer) {
+                client.close();
+                chatServer.removeClient(client);
+            }
+        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/sample/nio/chatserver/DataReader.java	Tue Apr 12 14:23:03 2011 -0700
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2011 Oracle and/or its affiliates. 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 Oracle 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;
+
+public interface DataReader {
+    void beforeRead(Client client);
+    void onData(Client client, ByteBuffer buffer, int bytes);
+    boolean acceptsMessages();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/sample/nio/chatserver/MessageReader.java	Tue Apr 12 14:23:03 2011 -0700
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2011 Oracle and/or its affiliates. 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 Oracle 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;
+
+/**
+ * Writes all messages in our buffer to the other clients
+ * and appends new data read from the socket to our buffer
+ */
+class MessageReader implements DataReader {
+    private final ChatServer chatServer;
+
+    public MessageReader(ChatServer chatServer) {
+        this.chatServer = chatServer;
+    }
+
+    public boolean acceptsMessages() {
+        return true;
+    }
+
+    /**
+     * Write all full messages in our buffer to
+     * the other clients
+     *
+     * @param client the client to read messages from
+     */
+    @Override
+    public void beforeRead(Client client) {
+        // Check if we have any messages buffered and send them
+        String message = client.nextMessage();
+        while (message != null) {
+            chatServer.writeMessageToClients(client, message);
+            message = client.nextMessage();
+        }
+    }
+
+    /**
+     * Append the read buffer to the clients message buffer
+     * @param client the client to append messages to
+     * @param buffer the buffer we received from the socket
+     * @param bytes the number of bytes read into the buffer
+     */
+    @Override
+    public void onData(Client client, ByteBuffer buffer, int bytes) {
+        buffer.flip();
+        // Just append the message on the buffer
+        client.appendMessage(new String(buffer.array(), 0, bytes));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/sample/nio/chatserver/NameReader.java	Tue Apr 12 14:23:03 2011 -0700
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2011 Oracle and/or its affiliates. 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 Oracle 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;
+
+/**
+ * The first state a newly connected {@code Client} is in, this
+ * handles writing out the welcoming message and reads the response
+ * up to a newline. When a newline character have been received
+ * it changes the handler from NameReader to MessageReader on the
+ * client.
+ */
+class NameReader implements DataReader {
+    private final StringBuilder buffer = new StringBuilder();
+    private final ChatServer chatServer;
+    private boolean once = true;
+    private static final String NEWLINE = "\n";
+
+    public NameReader(ChatServer chatServer) {
+        this.chatServer = chatServer;
+    }
+
+    /**
+     * Writes the welcoming message to the client the first time this method
+     * is called.
+     *
+     * @param client the client to receive the message
+     */
+    @Override
+    public void beforeRead(Client client) {
+        // if it is a long name that takes more than one read we only want to display Name: once.
+        if (once) {
+            client.writeStringMessage("Name: ");
+            once = false;
+        }
+    }
+
+    public boolean acceptsMessages() {
+        return false;
+    }
+
+    /**
+     * Receives incoming data from the socket, searches for a newline
+     * and tries to set the username if one is found
+     */
+    @Override
+    public void onData(Client client, ByteBuffer buffer, int bytes) {
+        buffer.flip();
+        String name;
+        name = this.buffer.append(new String(buffer.array(), 0, bytes)).toString();
+        if (name.contains(NEWLINE)) {
+            onUserNameRead(client, name);
+        }
+    }
+
+    /**
+     * Splits the name on the newlines, takes the first as the username
+     * and appends everything else to the clients message buffer.
+     * Sets the clients handler to MessageReader.
+     *
+     * @param client the client to set the username for
+     * @param name the string containing the buffered input
+     */
+    private void onUserNameRead(Client client, String name) {
+        String[] strings = name.split(NEWLINE, 2);
+        client.setUserName(strings[0].trim());
+        sendRemainingParts(client, strings);
+        client.setReader(new ClientReader(chatServer, new MessageReader(chatServer)));
+        client.writeStringMessage("Welcome " + client.getUserName() + "\n");
+    }
+
+    /**
+     * Appends the remaining parts to the clients message buffer
+     *
+     * @param client the client
+     * @param strings the messages to append to the buffer
+     */
+    private void sendRemainingParts(Client client, String[] strings) {
+        for (int i = 1; i < strings.length; ++i) {
+            client.appendMessage(strings[i]);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/sample/nio/chatserver/README.txt	Tue Apr 12 14:23:03 2011 -0700
@@ -0,0 +1,62 @@
+A Simple Chat Server Example
+
+INTRODUCTION
+============
+This directory contains a very simple chat server, the server takes input from a
+socket ("user") and sends it to all other connected sockets ("users") along with
+the provided name the user was asked for when first connecting.
+
+The server was written to demonstrate the asynchronous I/O API in JDK 7. 
+The sample assumes the reader has some familiarity with the subject matter.
+
+SETUP
+=====
+
+The server must be built with version 7 (or later) of the JDK.
+The server is built with:
+
+    % mkdir build
+    % javac -source 7 -target 7 -d build *.java
+
+EXECUTION
+=========
+
+    % java -classpath build ChatServer [-port <port number>]
+
+    Usage:  ChatServer [options]
+        options:
+            -port port      port number
+                default: 5000
+
+CLIENT EXECUTION
+================
+
+No client binary is included in the sample.
+Connections can be made using for example the telnet command or any program
+that supports a raw TCP connection to a port.
+
+SOURCE CODE OVERVIEW
+====================
+ChatServer is the main class, it handles the startup and handles incoming
+connections on the listening sockets. It keeps a list of connected client
+and provides methods for sending a message to them.
+
+Client represents a connected user, it provides methods for reading/writing
+from/to the underlying socket. It also contains a buffer of input read from
+the user.
+
+DataReader provides the interface of the two states a user can
+be in. Waiting for a name (and not receiving any messages while doing so, implemented
+by NameReader) and waiting for messages from the user (implemented by MessageReader).
+
+ClientReader contains the "main loop" for a connected client. 
+
+NameReader is the initial state for a new client, it sends the user a string and
+waits for a response before changing the state to MessageReader.
+
+MessageReader is the main state for a client, it checks for new messages to send to
+other clients and reads messages from the client.
+
+FINALLY
+=======
+This is a sample: it is not production quality and isn't optimized for performance.
--- a/src/solaris/bin/java_md.c	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/solaris/bin/java_md.c	Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -46,6 +46,10 @@
 #define JVM_DLL "libjvm.so"
 #define JAVA_DLL "libjava.so"
 
+/* help jettison the LD_LIBRARY_PATH settings in the future */
+#ifndef SETENV_REQUIRED
+#define SETENV_REQUIRED
+#endif
 /*
  * If a processor / os combination has the ability to run binaries of
  * two data models and cohabitation of jre/jdk bits with both data
@@ -106,10 +110,22 @@
  * Previously the launcher modified the LD_LIBRARY_PATH appropriately for the
  * desired data model path, regardless if data models matched or not. The
  * launcher subsequently exec'ed the desired executable, in order to make the
- * LD_LIBRARY_PATH path available for the runtime linker. This is no longer the
- * case, the launcher dlopens the target libjvm.so. All other required
- * libraries are loaded by the runtime linker, by virtue of the $ORIGIN paths
- * baked into the shared libraries, by the build infrastructure at compile time.
+ * LD_LIBRARY_PATH path available, for the runtime linker.
+ *
+ * Now, in most cases,the launcher will dlopen the target libjvm.so. All
+ * required libraries are loaded by the runtime linker, using the
+ * $RPATH/$ORIGIN baked into the shared libraries at compile time. Therefore,
+ * in most cases, the launcher will only exec, if the data models are
+ * mismatched, and will not set any environment variables, regardless of the
+ * data models.
+ *
+ * However, if the environment contains a LD_LIBRARY_PATH, this will cause the
+ * launcher to inspect the LD_LIBRARY_PATH. The launcher will check
+ *  a. if the LD_LIBRARY_PATH's first component is the the path to the desired
+ *     libjvm.so
+ *  b. if any other libjvm.so is found in any of the paths.
+ * If case b is true, then the launcher will set the LD_LIBRARY_PATH to the
+ * desired JRE and reexec, in order to propagate the environment.
  *
  *  Main
  *  (incoming argv)
@@ -137,11 +153,11 @@
  *  |                                          |
  *  |                                          |
  * \|/                                        \|/
- * YES                              (find the desired executable and exec child)
+ * YES                             Find the desired executable/library
  *  |                                          |
  *  |                                          |
  * \|/                                        \|/
- * CheckJvmType                                Main
+ * CheckJvmType                          RequiresSetenv
  * (removes -client, -server, etc.)
  *  |
  *  |
@@ -156,7 +172,42 @@
  *  processes version options,
  *  creates argument list for vm,
  *  etc.)
- *
+ *   |
+ *   |
+ *  \|/
+ * RequiresSetenv
+ * Is LD_LIBRARY_PATH
+ * and friends set ? --> NO --> Have Desired Model ? NO --> Re-exec --> Main
+ *  YES                              YES --> Continue
+ *   |
+ *   |
+ *  \|/
+ * Path is desired JRE ? YES --> Have Desired Model ? NO --> Re-exec --> Main
+ *  NO                               YES --> Continue
+ *   |
+ *   |
+ *  \|/
+ * Paths have well known
+ * jvm paths ?       --> NO --> Have Desired Model ? NO --> Re-exec --> Main
+ *  YES                              YES --> Continue
+ *   |
+ *   |
+ *  \|/
+ *  Does libjvm.so exit
+ *  in any of them ? --> NO --> Have Desired Model ? NO --> Re-exec --> Main
+ *   YES                             YES --> Continue
+ *   |
+ *   |
+ *  \|/
+ *  Set the LD_LIBRARY_PATH
+ *   |
+ *   |
+ *  \|/
+ * Re-exec
+ *   |
+ *   |
+ *  \|/
+ * Main
  */
 
 static const char * SetExecname(char **argv);
@@ -182,6 +233,130 @@
     }
 }
 
+#ifdef SETENV_REQUIRED
+static jboolean
+JvmExists(const char *path) {
+    char tmp[PATH_MAX + 1];
+    struct stat statbuf;
+    JLI_Snprintf(tmp, PATH_MAX, "%s/%s", path, JVM_DLL);
+    if (stat(tmp, &statbuf) == 0) {
+        return JNI_TRUE;
+    }
+    return JNI_FALSE;
+}
+/*
+ * contains a lib/$LIBARCH/{server,client}/libjvm.so ?
+ */
+static jboolean
+ContainsLibJVM(int wanted, const char *env) {
+    char clientPattern[PATH_MAX + 1];
+    char serverPattern[PATH_MAX + 1];
+    char *envpath;
+    char *path;
+    jboolean clientPatternFound;
+    jboolean serverPatternFound;
+
+    /* fastest path */
+    if (env == NULL) {
+        return JNI_FALSE;
+    }
+
+    /* the usual suspects */
+    JLI_Snprintf(clientPattern, PATH_MAX, "lib/%s/client", GetArchPath(wanted));
+    JLI_Snprintf(serverPattern, PATH_MAX, "lib/%s/server", GetArchPath(wanted));
+
+    /* to optimize for time, test if any of our usual suspects are present. */
+    clientPatternFound = JLI_StrStr(env, clientPattern) != NULL;
+    serverPatternFound = JLI_StrStr(env, serverPattern) != NULL;
+    if (clientPatternFound == JNI_FALSE && serverPatternFound == JNI_FALSE) {
+        return JNI_FALSE;
+    }
+
+    /*
+     * we have a suspicious path component, check if it contains a libjvm.so
+     */
+    envpath = JLI_StringDup(env);
+    for (path = JLI_StrTok(envpath, ":"); path != NULL; path = JLI_StrTok(NULL, ":")) {
+        if (clientPatternFound && JLI_StrStr(path, clientPattern) != NULL) {
+            if (JvmExists(path)) {
+                JLI_MemFree(envpath);
+                return JNI_TRUE;
+            }
+        }
+        if (serverPatternFound && JLI_StrStr(path, serverPattern)  != NULL) {
+            if (JvmExists(path)) {
+                JLI_MemFree(envpath);
+                return JNI_TRUE;
+            }
+        }
+    }
+    JLI_MemFree(envpath);
+    return JNI_FALSE;
+}
+
+/*
+ * Test whether the environment variable needs to be set, see flowchart.
+ */
+static jboolean
+RequiresSetenv(int wanted, const char *jvmpath) {
+    char jpath[PATH_MAX + 1];
+    char *llp;
+    char *dmllp = NULL;
+    char *p; /* a utility pointer */
+
+    llp = getenv("LD_LIBRARY_PATH");
+#ifdef __solaris__
+    dmllp = (CURRENT_DATA_MODEL == 32)
+            ? getenv("LD_LIBRARY_PATH_32")
+            : getenv("LD_LIBRARY_PATH_64");
+#endif /* __solaris__ */
+    /* no environment variable is a good environment variable */
+    if (llp == NULL && dmllp == NULL) {
+        return JNI_FALSE;
+    }
+#ifdef __linux
+    /*
+     * On linux, if a binary is running as sgid or suid, glibc sets
+     * LD_LIBRARY_PATH to the empty string for security purposes. (In contrast,
+     * on Solaris the LD_LIBRARY_PATH variable for a privileged binary does not
+     * lose its settings; but the dynamic linker does apply more scrutiny to the
+     * path.) The launcher uses the value of LD_LIBRARY_PATH to prevent an exec
+     * loop, here and further downstream. Therefore, if we are running sgid or
+     * suid, this function's setting of LD_LIBRARY_PATH will be ineffective and
+     * we should case a return from the calling function.  Getting the right
+     * libraries will be handled by the RPATH. In reality, this check is
+     * redundant, as the previous check for a non-null LD_LIBRARY_PATH will
+     * return back to the calling function forthwith, it is left here to safe
+     * guard against any changes, in the glibc's existing security policy.
+     */
+    if ((getgid() != getegid()) || (getuid() != geteuid())) {
+        return JNI_FALSE;
+    }
+#endif /* __linux */
+
+    /*
+     * Prevent recursions. Since LD_LIBRARY_PATH is the one which will be set by
+     * previous versions of the JRE, thus it is the only path that matters here.
+     * So we check to see if the desired JRE is set.
+     */
+    JLI_StrNCpy(jpath, jvmpath, PATH_MAX);
+    p = JLI_StrRChr(jpath, '/');
+    *p = '\0';
+    if (llp != NULL && JLI_StrNCmp(llp, jpath, JLI_StrLen(jpath)) == 0) {
+        return JNI_FALSE;
+    }
+
+    /* scrutinize all the paths further */
+    if (llp != NULL &&  ContainsLibJVM(wanted, llp)) {
+        return JNI_TRUE;
+    }
+    if (dmllp != NULL && ContainsLibJVM(wanted, dmllp)) {
+        return JNI_TRUE;
+    }
+    return JNI_FALSE;
+}
+#endif /* SETENV_REQUIRED */
+
 void
 CreateExecutionEnvironment(int *pargc, char ***pargv,
                            char jrepath[], jint so_jrepath,
@@ -195,7 +370,6 @@
    * informative to issue an error message based on whether or not the
    * os/processor combination has dual mode capabilities.
    */
-
     jboolean jvmpathExists;
 
     /* Compute/set the name of the executable */
@@ -207,13 +381,24 @@
       char * jvmtype    = NULL;
       int  argc         = *pargc;
       char **argv       = *pargv;
-
       int running       = CURRENT_DATA_MODEL;
 
       int wanted        = running;      /* What data mode is being
                                            asked for? Current model is
                                            fine unless another model
                                            is asked for */
+#ifdef SETENV_REQUIRED
+      jboolean mustsetenv = JNI_FALSE;
+      char *runpath     = NULL; /* existing effective LD_LIBRARY_PATH setting */
+      char* new_runpath = NULL; /* desired new LD_LIBRARY_PATH string */
+      char* newpath     = NULL; /* path on new LD_LIBRARY_PATH */
+      char* lastslash   = NULL;
+      char** newenvp    = NULL; /* current environment */
+#ifdef __solaris__
+      char*  dmpath     = NULL;  /* data model specific LD_LIBRARY_PATH,
+                                    Solaris only */
+#endif /* __solaris__ */
+#endif  /* SETENV_REQUIRED */
 
       char** newargv    = NULL;
       int    newargc    = 0;
@@ -300,9 +485,18 @@
         }
         /*
          * we seem to have everything we need, so without further ado
-         * we return back.
+         * we return back, otherwise proceed to set the environment.
          */
+#ifdef SETENV_REQUIRED
+        mustsetenv = RequiresSetenv(wanted, jvmpath);
+        JLI_TraceLauncher("mustsetenv: %s\n", mustsetenv ? "TRUE" : "FALSE");
+
+        if (mustsetenv == JNI_FALSE) {
+            return;
+        }
+#else
         return;
+#endif /* SETENV_REQUIRED */
       } else {  /* do the same speculatively or exit */
 #ifdef DUAL_MODE
         if (running != wanted) {
@@ -331,67 +525,240 @@
 
           /* exec child can do error checking on the existence of the path */
           jvmpathExists = GetJVMPath(jrepath, jvmtype, jvmpath, so_jvmpath, GetArchPath(wanted));
-
+#ifdef SETENV_REQUIRED
+          mustsetenv = RequiresSetenv(wanted, jvmpath);
+#endif /* SETENV_REQUIRED */
         }
 #else
         JLI_ReportErrorMessage(JRE_ERROR2, wanted);
         exit(1);
 #endif
-      }
+        }
+#ifdef SETENV_REQUIRED
+        if (mustsetenv) {
+            /*
+             * We will set the LD_LIBRARY_PATH as follows:
+             *
+             *     o          $JVMPATH (directory portion only)
+             *     o          $JRE/lib/$LIBARCHNAME
+             *     o          $JRE/../lib/$LIBARCHNAME
+             *
+             * followed by the user's previous effective LD_LIBRARY_PATH, if
+             * any.
+             */
 
-      {
-        char *newexec = execname;
+#ifdef __solaris__
+            /*
+             * Starting in Solaris 7, ld.so.1 supports three LD_LIBRARY_PATH
+             * variables:
+             *
+             * 1. LD_LIBRARY_PATH -- used for 32 and 64 bit searches if
+             * data-model specific variables are not set.
+             *
+             * 2. LD_LIBRARY_PATH_64 -- overrides and replaces LD_LIBRARY_PATH
+             * for 64-bit binaries.
+             *
+             * 3. LD_LIBRARY_PATH_32 -- overrides and replaces LD_LIBRARY_PATH
+             * for 32-bit binaries.
+             *
+             * The vm uses LD_LIBRARY_PATH to set the java.library.path system
+             * property.  To shield the vm from the complication of multiple
+             * LD_LIBRARY_PATH variables, if the appropriate data model
+             * specific variable is set, we will act as if LD_LIBRARY_PATH had
+             * the value of the data model specific variant and the data model
+             * specific variant will be unset.  Note that the variable for the
+             * *wanted* data model must be used (if it is set), not simply the
+             * current running data model.
+             */
+
+            switch (wanted) {
+                case 0:
+                    if (running == 32) {
+                        dmpath = getenv("LD_LIBRARY_PATH_32");
+                        wanted = 32;
+                    } else {
+                        dmpath = getenv("LD_LIBRARY_PATH_64");
+                        wanted = 64;
+                    }
+                    break;
+
+                case 32:
+                    dmpath = getenv("LD_LIBRARY_PATH_32");
+                    break;
+
+                case 64:
+                    dmpath = getenv("LD_LIBRARY_PATH_64");
+                    break;
+
+                default:
+                    JLI_ReportErrorMessage(JRE_ERROR3, __LINE__);
+                    exit(1); /* unknown value in wanted */
+                    break;
+            }
+
+            /*
+             * If dmpath is NULL, the relevant data model specific variable is
+             * not set and normal LD_LIBRARY_PATH should be used.
+             */
+            if (dmpath == NULL) {
+                runpath = getenv("LD_LIBRARY_PATH");
+            } else {
+                runpath = dmpath;
+            }
+#else
+            /*
+             * If not on Solaris, assume only a single LD_LIBRARY_PATH
+             * variable.
+             */
+            runpath = getenv("LD_LIBRARY_PATH");
+#endif /* __solaris__ */
+
+            /* runpath contains current effective LD_LIBRARY_PATH setting */
+
+            jvmpath = JLI_StringDup(jvmpath);
+            new_runpath = JLI_MemAlloc(((runpath != NULL) ? JLI_StrLen(runpath) : 0) +
+                    2 * JLI_StrLen(jrepath) + 2 * JLI_StrLen(arch) +
+                    JLI_StrLen(jvmpath) + 52);
+            newpath = new_runpath + JLI_StrLen("LD_LIBRARY_PATH=");
+
+
+            /*
+             * Create desired LD_LIBRARY_PATH value for target data model.
+             */
+            {
+                /* remove the name of the .so from the JVM path */
+                lastslash = JLI_StrRChr(jvmpath, '/');
+                if (lastslash)
+                    *lastslash = '\0';
+
+                sprintf(new_runpath, "LD_LIBRARY_PATH="
+                        "%s:"
+                        "%s/lib/%s:"
+                        "%s/../lib/%s",
+                        jvmpath,
 #ifdef DUAL_MODE
-        /*
-         * If the data model is being changed, the path to the
-         * executable must be updated accordingly; the executable name
-         * and directory the executable resides in are separate.  In the
-         * case of 32 => 64, the new bits are assumed to reside in, e.g.
-         * "olddir/LIBARCH64NAME/execname"; in the case of 64 => 32,
-         * the bits are assumed to be in "olddir/../execname".  For example,
-         *
-         * olddir/sparcv9/execname
-         * olddir/amd64/execname
-         *
-         * for Solaris SPARC and Linux amd64, respectively.
-         */
+                        jrepath, GetArchPath(wanted),
+                        jrepath, GetArchPath(wanted)
+#else
+                        jrepath, arch,
+                        jrepath, arch
+#endif
+                        );
 
-        if (running != wanted) {
-          char *oldexec = JLI_StrCpy(JLI_MemAlloc(JLI_StrLen(execname) + 1), execname);
-          char *olddir = oldexec;
-          char *oldbase = JLI_StrRChr(oldexec, '/');
 
+                /*
+                 * Check to make sure that the prefix of the current path is the
+                 * desired environment variable setting, though the RequiresSetenv
+                 * checks if the desired runpath exists, this logic does a more
+                 * comprehensive check.
+                 */
+                if (runpath != NULL &&
+                        JLI_StrNCmp(newpath, runpath, JLI_StrLen(newpath)) == 0 &&
+                        (runpath[JLI_StrLen(newpath)] == 0 || runpath[JLI_StrLen(newpath)] == ':') &&
+                        (running == wanted) /* data model does not have to be changed */
+#ifdef __solaris__
+                        && (dmpath == NULL) /* data model specific variables not set  */
+#endif
+                        ) {
 
-          newexec = JLI_MemAlloc(JLI_StrLen(execname) + 20);
-          *oldbase++ = 0;
-          sprintf(newexec, "%s/%s/%s", olddir,
-                  ((wanted==64) ? LIBARCH64NAME : ".."), oldbase);
-          argv[0] = newexec;
+                    return;
+
+                }
+            }
+
+            /*
+             * Place the desired environment setting onto the prefix of
+             * LD_LIBRARY_PATH.  Note that this prevents any possible infinite
+             * loop of execv() because we test for the prefix, above.
+             */
+            if (runpath != 0) {
+                JLI_StrCat(new_runpath, ":");
+                JLI_StrCat(new_runpath, runpath);
+            }
+
+            if (putenv(new_runpath) != 0) {
+                exit(1); /* problem allocating memory; LD_LIBRARY_PATH not set
+                    properly */
+            }
+
+            /*
+             * Unix systems document that they look at LD_LIBRARY_PATH only
+             * once at startup, so we have to re-exec the current executable
+             * to get the changed environment variable to have an effect.
+             */
+
+#ifdef __solaris__
+            /*
+             * If dmpath is not NULL, remove the data model specific string
+             * in the environment for the exec'ed child.
+             */
+            if (dmpath != NULL)
+                (void)UnsetEnv((wanted == 32) ? "LD_LIBRARY_PATH_32" : "LD_LIBRARY_PATH_64");
+#endif
+
+            newenvp = environ;
         }
-#endif
-        JLI_TraceLauncher("TRACER_MARKER:About to EXEC\n");
-        (void)fflush(stdout);
-        (void)fflush(stderr);
-        execv(newexec, argv);
-        JLI_ReportErrorMessageSys(JRE_ERROR4, newexec);
+#endif /* SETENV_REQUIRED */
+        {
+            char *newexec = execname;
+#ifdef DUAL_MODE
+            /*
+             * If the data model is being changed, the path to the
+             * executable must be updated accordingly; the executable name
+             * and directory the executable resides in are separate.  In the
+             * case of 32 => 64, the new bits are assumed to reside in, e.g.
+             * "olddir/LIBARCH64NAME/execname"; in the case of 64 => 32,
+             * the bits are assumed to be in "olddir/../execname".  For example,
+             *
+             * olddir/sparcv9/execname
+             * olddir/amd64/execname
+             *
+             * for Solaris SPARC and Linux amd64, respectively.
+             */
+
+            if (running != wanted) {
+                char *oldexec = JLI_StrCpy(JLI_MemAlloc(JLI_StrLen(execname) + 1), execname);
+                char *olddir = oldexec;
+                char *oldbase = JLI_StrRChr(oldexec, '/');
+
+
+                newexec = JLI_MemAlloc(JLI_StrLen(execname) + 20);
+                *oldbase++ = 0;
+                sprintf(newexec, "%s/%s/%s", olddir,
+                        ((wanted == 64) ? LIBARCH64NAME : ".."), oldbase);
+                argv[0] = newexec;
+            }
+#endif /* DUAL_MODE */
+            JLI_TraceLauncher("TRACER_MARKER:About to EXEC\n");
+            (void) fflush(stdout);
+            (void) fflush(stderr);
+#ifdef SETENV_REQUIRED
+            if (mustsetenv) {
+                execve(newexec, argv, newenvp);
+            } else {
+                execv(newexec, argv);
+            }
+#else
+            execv(newexec, argv);
+#endif /* SETENV_REQUIRED */
+            JLI_ReportErrorMessageSys(JRE_ERROR4, newexec);
 
 #ifdef DUAL_MODE
-        if (running != wanted) {
-          JLI_ReportErrorMessage(JRE_ERROR5, wanted, running);
-#  ifdef __solaris__
-#    ifdef __sparc
-          JLI_ReportErrorMessage(JRE_ERROR6);
-#    else
-          JLI_ReportErrorMessage(JRE_ERROR7);
-#    endif
+            if (running != wanted) {
+                JLI_ReportErrorMessage(JRE_ERROR5, wanted, running);
+#ifdef __solaris__
+#ifdef __sparc
+                JLI_ReportErrorMessage(JRE_ERROR6);
+#else
+                JLI_ReportErrorMessage(JRE_ERROR7);
+#endif  /* __sparc */
+            }
+#endif /* __solaris__ */
+#endif /* DUAL_MODE */
+
         }
-#  endif
-#endif
-
-      }
-      exit(1);
+        exit(1);
     }
-
 }
 
 /*
--- a/src/solaris/classes/sun/nio/fs/LinuxFileSystemProvider.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/solaris/classes/sun/nio/fs/LinuxFileSystemProvider.java	Tue Apr 12 14:23:03 2011 -0700
@@ -56,11 +56,11 @@
     {
         if (type == DosFileAttributeView.class) {
             return (V) new LinuxDosFileAttributeView(UnixPath.toUnixPath(obj),
-                                                     followLinks(options));
+                                                     Util.followLinks(options));
         }
         if (type == UserDefinedFileAttributeView.class) {
             return (V) new LinuxUserDefinedFileAttributeView(UnixPath.toUnixPath(obj),
-                                                             followLinks(options));
+                                                             Util.followLinks(options));
         }
         return super.getFileAttributeView(obj, type, options);
     }
@@ -72,11 +72,11 @@
     {
         if (name.equals("dos")) {
             return new LinuxDosFileAttributeView(UnixPath.toUnixPath(obj),
-                                                 followLinks(options));
+                                                 Util.followLinks(options));
         }
         if (name.equals("user")) {
             return new LinuxUserDefinedFileAttributeView(UnixPath.toUnixPath(obj),
-                                                         followLinks(options));
+                                                         Util.followLinks(options));
         }
         return super.getFileAttributeView(obj, name, options);
     }
--- a/src/solaris/classes/sun/nio/fs/SolarisFileSystemProvider.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/solaris/classes/sun/nio/fs/SolarisFileSystemProvider.java	Tue Apr 12 14:23:03 2011 -0700
@@ -57,11 +57,11 @@
     {
         if (type == AclFileAttributeView.class) {
             return (V) new SolarisAclFileAttributeView(UnixPath.toUnixPath(obj),
-                                                       followLinks(options));
+                                                       Util.followLinks(options));
         }
         if (type == UserDefinedFileAttributeView.class) {
             return(V) new SolarisUserDefinedFileAttributeView(UnixPath.toUnixPath(obj),
-                                                              followLinks(options));
+                                                              Util.followLinks(options));
         }
         return super.getFileAttributeView(obj, type, options);
     }
@@ -73,10 +73,10 @@
     {
         if (name.equals("acl"))
             return new SolarisAclFileAttributeView(UnixPath.toUnixPath(obj),
-                                                   followLinks(options));
+                                                   Util.followLinks(options));
         if (name.equals("user"))
             return new SolarisUserDefinedFileAttributeView(UnixPath.toUnixPath(obj),
-                                                           followLinks(options));
+                                                           Util.followLinks(options));
         return super.getFileAttributeView(obj, name, options);
     }
 }
--- a/src/solaris/classes/sun/nio/fs/UnixFileSystemProvider.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/solaris/classes/sun/nio/fs/UnixFileSystemProvider.java	Tue Apr 12 14:23:03 2011 -0700
@@ -105,20 +105,6 @@
         return (UnixPath)obj;
     }
 
-    boolean followLinks(LinkOption... options) {
-        boolean followLinks = true;
-        for (LinkOption option: options) {
-            if (option == LinkOption.NOFOLLOW_LINKS) {
-                followLinks = false;
-                continue;
-            }
-            if (option == null)
-                throw new NullPointerException();
-            throw new AssertionError("Should not get here");
-        }
-        return followLinks;
-    }
-
     @Override
     @SuppressWarnings("unchecked")
     public <V extends FileAttributeView> V getFileAttributeView(Path obj,
@@ -126,7 +112,7 @@
                                                                 LinkOption... options)
     {
         UnixPath file = UnixPath.toUnixPath(obj);
-        boolean followLinks =  followLinks(options);
+        boolean followLinks = Util.followLinks(options);
         if (type == BasicFileAttributeView.class)
             return (V) UnixFileAttributeViews.createBasicView(file, followLinks);
         if (type == PosixFileAttributeView.class)
@@ -163,7 +149,7 @@
                                                             LinkOption... options)
     {
         UnixPath file = UnixPath.toUnixPath(obj);
-        boolean followLinks = followLinks(options);
+        boolean followLinks = Util.followLinks(options);
         if (name.equals("basic"))
             return UnixFileAttributeViews.createBasicView(file, followLinks);
         if (name.equals("posix"))
--- a/src/solaris/classes/sun/nio/fs/UnixPath.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/solaris/classes/sun/nio/fs/UnixPath.java	Tue Apr 12 14:23:03 2011 -0700
@@ -819,13 +819,13 @@
     }
 
     @Override
-    public Path toRealPath(boolean resolveLinks) throws IOException {
+    public Path toRealPath(LinkOption... options) throws IOException {
         checkRead();
 
         UnixPath absolute = toAbsolutePath();
 
-        // if resolveLinks is true then use realpath
-        if (resolveLinks) {
+        // if resolving links then use realpath
+        if (Util.followLinks(options)) {
             try {
                 byte[] rp = realpath(absolute);
                 return new UnixPath(getFileSystem(), rp);
@@ -834,7 +834,7 @@
             }
         }
 
-        // if resolveLinks is false then eliminate "." and also ".."
+        // if not resolving links then eliminate "." and also ".."
         // where the previous element is not a link.
         UnixPath result = fs.rootDirectory();
         for (int i=0; i<absolute.getNameCount(); i++) {
--- a/src/solaris/classes/sun/nio/fs/UnixSecureDirectoryStream.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/solaris/classes/sun/nio/fs/UnixSecureDirectoryStream.java	Tue Apr 12 14:23:03 2011 -0700
@@ -81,20 +81,6 @@
         return (UnixPath)obj;
     }
 
-    private boolean followLinks(LinkOption... options) {
-        boolean followLinks = true;
-        for (LinkOption option: options) {
-            if (option == LinkOption.NOFOLLOW_LINKS) {
-                followLinks = false;
-                continue;
-            }
-            if (option == null)
-                throw new NullPointerException();
-            throw new AssertionError("Should not get here");
-        }
-        return followLinks;
-    }
-
     /**
      * Opens sub-directory in this directory
      */
@@ -105,7 +91,7 @@
     {
         UnixPath file = getName(obj);
         UnixPath child = ds.directory().resolve(file);
-        boolean followLinks = followLinks(options);
+        boolean followLinks = Util.followLinks(options);
 
         // permission check using name resolved against original path of directory
         SecurityManager sm = System.getSecurityManager();
@@ -316,7 +302,7 @@
                                                                 LinkOption... options)
     {
         UnixPath file = getName(obj);
-        boolean followLinks = followLinks(options);
+        boolean followLinks = Util.followLinks(options);
         return getFileAttributeViewImpl(file, type, followLinks);
     }
 
--- a/src/windows/classes/sun/nio/fs/WindowsFileSystem.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/windows/classes/sun/nio/fs/WindowsFileSystem.java	Tue Apr 12 14:23:03 2011 -0700
@@ -56,8 +56,9 @@
         // 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");
+        if ((result.type() != WindowsPathType.ABSOLUTE) &&
+            (result.type() != WindowsPathType.UNC))
+            throw new AssertionError("Default directory is not an absolute path");
         this.defaultDirectory = result.path();
         this.defaultRoot = result.root();
 
--- a/src/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java	Tue Apr 12 14:23:03 2011 -0700
@@ -150,20 +150,6 @@
         }
     }
 
-    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
@@ -172,7 +158,7 @@
         WindowsPath file = WindowsPath.toWindowsPath(obj);
         if (view == null)
             throw new NullPointerException();
-        boolean followLinks = followLinks(options);
+        boolean followLinks = Util.followLinks(options);
         if (view == BasicFileAttributeView.class)
             return (V) WindowsFileAttributeViews.createBasicView(file, followLinks);
         if (view == DosFileAttributeView.class)
@@ -209,7 +195,7 @@
     @Override
     public DynamicFileAttributeView getFileAttributeView(Path obj, String name, LinkOption... options) {
         WindowsPath file = WindowsPath.toWindowsPath(obj);
-        boolean followLinks = followLinks(options);
+        boolean followLinks = Util.followLinks(options);
         if (name.equals("basic"))
             return WindowsFileAttributeViews.createBasicView(file, followLinks);
         if (name.equals("dos"))
--- a/src/windows/classes/sun/nio/fs/WindowsPath.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/windows/classes/sun/nio/fs/WindowsPath.java	Tue Apr 12 14:23:03 2011 -0700
@@ -831,9 +831,9 @@
     }
 
     @Override
-    public WindowsPath toRealPath(boolean resolveLinks) throws IOException {
+    public WindowsPath toRealPath(LinkOption... options) throws IOException {
         checkRead();
-        String rp = WindowsLinkSupport.getRealPath(this, resolveLinks);
+        String rp = WindowsLinkSupport.getRealPath(this, Util.followLinks(options));
         return createFromNormalizedPath(getFileSystem(), rp);
     }
 
--- a/src/windows/native/com/sun/management/OperatingSystem_md.c	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/windows/native/com/sun/management/OperatingSystem_md.c	Tue Apr 12 14:23:03 2011 -0700
@@ -30,6 +30,7 @@
 #include "management.h"
 #include "com_sun_management_OperatingSystem.h"
 
+#include <psapi.h>
 #include <errno.h>
 #include <stdlib.h>
 
@@ -53,41 +54,12 @@
   return result;
 }
 
-// From psapi.h
-typedef struct _PROCESS_MEMORY_COUNTERS {
-    DWORD cb;
-    DWORD PageFaultCount;
-    SIZE_T PeakWorkingSetSize;
-    SIZE_T WorkingSetSize;
-    SIZE_T QuotaPeakPagedPoolUsage;
-    SIZE_T QuotaPagedPoolUsage;
-    SIZE_T QuotaPeakNonPagedPoolUsage;
-    SIZE_T QuotaNonPagedPoolUsage;
-    SIZE_T PagefileUsage;
-    SIZE_T PeakPagefileUsage;
-} PROCESS_MEMORY_COUNTERS;
-
-static HINSTANCE hInstPsapi = NULL;
-typedef BOOL (WINAPI *LPFNGETPROCESSMEMORYINFO)(HANDLE, PROCESS_MEMORY_COUNTERS*, DWORD);
-
-static jboolean is_nt = JNI_FALSE;
 static HANDLE main_process;
 
 JNIEXPORT void JNICALL
 Java_com_sun_management_OperatingSystem_initialize
   (JNIEnv *env, jclass cls)
 {
-    OSVERSIONINFO oi;
-    oi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
-    GetVersionEx(&oi);
-    switch(oi.dwPlatformId) {
-        case VER_PLATFORM_WIN32_WINDOWS: is_nt = JNI_FALSE; break;
-        case VER_PLATFORM_WIN32_NT:      is_nt = JNI_TRUE;  break;
-        default:
-            throw_internal_error(env, "Unsupported Platform");
-            return;
-    }
-
     main_process = GetCurrentProcess();
 }
 
@@ -95,31 +67,12 @@
 Java_com_sun_management_OperatingSystem_getCommittedVirtualMemorySize0
   (JNIEnv *env, jobject mbean)
 {
-
-    /*
-     * In bytes.  NT/2000/XP only - using GetProcessMemoryInfo from psapi.dll
-     */
-    static LPFNGETPROCESSMEMORYINFO lpfnGetProcessMemoryInfo = NULL;
-    static volatile jboolean psapi_inited = JNI_FALSE;
     PROCESS_MEMORY_COUNTERS pmc;
-
-    if (!is_nt) return -1;
-
-    if (!psapi_inited) {
-        psapi_inited = JNI_TRUE;
-        if ((hInstPsapi = LoadLibrary("PSAPI.DLL")) == NULL) return -1;
-        if ((lpfnGetProcessMemoryInfo = (LPFNGETPROCESSMEMORYINFO)
-               GetProcAddress( hInstPsapi, "GetProcessMemoryInfo")) == NULL) {
-            FreeLibrary(hInstPsapi);
-            return -1;
-        }
+    if (GetProcessMemoryInfo(main_process, &pmc, sizeof(PROCESS_MEMORY_COUNTERS)) == 0) {
+        return (jlong)-1L;
+    } else {
+        return (jlong) pmc.PagefileUsage;
     }
-
-    if (lpfnGetProcessMemoryInfo == NULL) return -1;
-
-    lpfnGetProcessMemoryInfo(main_process, &pmc,
-                             sizeof(PROCESS_MEMORY_COUNTERS));
-    return (jlong) pmc.PagefileUsage;
 }
 
 JNIEXPORT jlong JNICALL
@@ -148,20 +101,15 @@
     FILETIME process_creation_time, process_exit_time,
              process_user_time, process_kernel_time;
 
-    // Windows NT only
-    if (is_nt) {
-        // Using static variables declared above
-        // Units are 100-ns intervals.  Convert to ns.
-        GetProcessTimes(main_process, &process_creation_time,
-                        &process_exit_time,
-                        &process_kernel_time, &process_user_time);
-        return (jlong_from(process_user_time.dwHighDateTime,
-                           process_user_time.dwLowDateTime) +
-               jlong_from(process_kernel_time.dwHighDateTime,
-                           process_kernel_time.dwLowDateTime)) * 100;
-    } else {
-        return -1;
-    }
+    // Using static variables declared above
+    // Units are 100-ns intervals.  Convert to ns.
+    GetProcessTimes(main_process, &process_creation_time,
+                    &process_exit_time,
+                    &process_kernel_time, &process_user_time);
+    return (jlong_from(process_user_time.dwHighDateTime,
+                        process_user_time.dwLowDateTime) +
+            jlong_from(process_kernel_time.dwHighDateTime,
+                        process_kernel_time.dwLowDateTime)) * 100;
 }
 
 JNIEXPORT jlong JNICALL
--- a/src/windows/native/java/io/WinNTFileSystem_md.c	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/windows/native/java/io/WinNTFileSystem_md.c	Tue Apr 12 14:23:03 2011 -0700
@@ -23,9 +23,9 @@
  * questions.
  */
 
-/* Access APIs for Win2K and above */
+/* Access APIs for WinXP and above */
 #ifndef _WIN32_WINNT
-#define _WIN32_WINNT 0x0500
+#define _WIN32_WINNT 0x0501
 #endif
 
 #include <assert.h>
@@ -60,13 +60,17 @@
 JNIEXPORT void JNICALL
 Java_java_io_WinNTFileSystem_initIDs(JNIEnv *env, jclass cls)
 {
-    HANDLE handle;
+    HMODULE handle;
     jclass fileClass = (*env)->FindClass(env, "java/io/File");
     if (!fileClass) return;
     ids.path =
              (*env)->GetFieldID(env, fileClass, "path", "Ljava/lang/String;");
-    handle = LoadLibrary("kernel32");
-    if (handle != NULL) {
+
+    // GetFinalPathNameByHandle requires Windows Vista or newer
+    if (GetModuleHandleExW((GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
+                            GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT),
+                           (LPCWSTR)&CreateFileW, &handle) != 0)
+    {
         GetFinalPathNameByHandle_func = (GetFinalPathNameByHandleProc)
             GetProcAddress(handle, "GetFinalPathNameByHandleW");
     }
@@ -824,8 +828,6 @@
     return ret;
 }
 
-typedef BOOL (WINAPI* GetVolumePathNameProc) (LPCWSTR, LPWSTR, DWORD);
-
 JNIEXPORT jlong JNICALL
 Java_java_io_WinNTFileSystem_getSpace0(JNIEnv *env, jobject this,
                                        jobject file, jint t)
@@ -834,14 +836,7 @@
     jlong rv = 0L;
     WCHAR *pathbuf = fileToNTPath(env, file, ids.path);
 
-    HMODULE h = LoadLibrary("kernel32");
-    GetVolumePathNameProc getVolumePathNameW = NULL;
-    if (h) {
-        getVolumePathNameW
-            = (GetVolumePathNameProc)GetProcAddress(h, "GetVolumePathNameW");
-    }
-
-    if (getVolumePathNameW(pathbuf, volname, MAX_PATH_LENGTH)) {
+    if (GetVolumePathNameW(pathbuf, volname, MAX_PATH_LENGTH)) {
         ULARGE_INTEGER totalSpace, freeSpace, usableSpace;
         if (GetDiskFreeSpaceExW(volname, &usableSpace, &totalSpace, &freeSpace)) {
             switch(t) {
@@ -860,9 +855,6 @@
         }
     }
 
-    if (h) {
-        FreeLibrary(h);
-    }
     free(pathbuf);
     return rv;
 }
--- a/src/windows/native/java/lang/java_props_md.c	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/windows/native/java/lang/java_props_md.c	Tue Apr 12 14:23:03 2011 -0700
@@ -196,42 +196,23 @@
 /*
  * Code to figure out the user's home directory using shell32.dll
  */
-typedef HRESULT (WINAPI *GetSpecialFolderType)(HWND, int, LPITEMIDLIST *);
-typedef BOOL (WINAPI *GetPathFromIDListType)(LPCITEMIDLIST, LPSTR);
-
 WCHAR*
 getHomeFromShell32()
 {
-    HMODULE lib = LoadLibraryW(L"SHELL32.DLL");
-    GetSpecialFolderType do_get_folder;
-    GetPathFromIDListType do_get_path;
     HRESULT rc;
     LPITEMIDLIST item_list = 0;
     WCHAR *p;
     WCHAR path[MAX_PATH+1];
     int size = MAX_PATH+1;
 
-    if (lib == 0) {
-        // We can't load the library !!??
-        return NULL;
-    }
-
-    do_get_folder = (GetSpecialFolderType)GetProcAddress(lib, "SHGetSpecialFolderLocation");
-    do_get_path = (GetPathFromIDListType)GetProcAddress(lib, "SHGetPathFromIDListW");
-
-    if (do_get_folder == 0 || do_get_path == 0) {
-        // the library doesn't hold the right functions !!??
-        return NULL;
-    }
-
-    rc = (*do_get_folder)(NULL, CSIDL_DESKTOPDIRECTORY, &item_list);
+    rc = SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOPDIRECTORY, &item_list);
     if (!SUCCEEDED(rc)) {
         // we can't find the shell folder.
         return NULL;
     }
 
     path[0] = 0;
-    (*do_get_path)(item_list, (LPSTR)path);
+    SHGetPathFromIDListW(item_list, (LPWSTR)path);
 
     /* Get the parent of Desktop directory */
     p = wcsrchr(path, L'\\');
@@ -253,17 +234,7 @@
 static boolean
 haveMMX(void)
 {
-    boolean mmx = 0;
-    HMODULE lib = LoadLibrary("KERNEL32");
-    if (lib != NULL) {
-        BOOL (WINAPI *isProcessorFeaturePresent)(DWORD) =
-            (BOOL (WINAPI *)(DWORD))
-            GetProcAddress(lib, "IsProcessorFeaturePresent");
-        if (isProcessorFeaturePresent != NULL)
-            mmx = isProcessorFeaturePresent(PF_MMX_INSTRUCTIONS_AVAILABLE);
-        FreeLibrary(lib);
-    }
-    return mmx;
+    return IsProcessorFeaturePresent(PF_MMX_INSTRUCTIONS_AVAILABLE);
 }
 
 static const char *
@@ -532,10 +503,19 @@
         if (uname != NULL && wcslen(uname) > 0) {
             sprops.user_name = _wcsdup(uname);
         } else {
-            WCHAR buf[100];
-            int buflen = sizeof(buf);
-            sprops.user_name =
-                GetUserNameW(buf, &buflen) ? _wcsdup(buf) : L"unknown";
+            DWORD buflen = 0;
+            if (GetUserNameW(NULL, &buflen) == 0 &&
+                GetLastError() == ERROR_INSUFFICIENT_BUFFER)
+            {
+                uname = (WCHAR*)malloc(buflen * sizeof(WCHAR));
+                if (uname != NULL && GetUserNameW(uname, &buflen) == 0) {
+                    free(uname);
+                    uname = NULL;
+                }
+            } else {
+                uname = NULL;
+            }
+            sprops.user_name = (uname != NULL) ? uname : L"unknown";
         }
     }
 
@@ -633,8 +613,8 @@
     /* Current directory */
     {
         WCHAR buf[MAX_PATH];
-        GetCurrentDirectoryW(sizeof(buf), buf);
-        sprops.user_dir = _wcsdup(buf);
+        if (GetCurrentDirectoryW(sizeof(buf)/sizeof(WCHAR), buf) != 0)
+            sprops.user_dir = _wcsdup(buf);
     }
 
     sprops.file_separator = "\\";
--- a/src/windows/native/sun/management/FileSystemImpl.c	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/windows/native/sun/management/FileSystemImpl.c	Tue Apr 12 14:23:03 2011 -0700
@@ -37,45 +37,6 @@
 #define ANY_ACCESS (FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE)
 
 /*
- * Function prototypes for security functions - we can't statically
- * link because these functions aren't on Windows 9x.
- */
-typedef BOOL (WINAPI *GetFileSecurityFunc)
-    (LPCTSTR lpFileName, SECURITY_INFORMATION RequestedInformation,
-     PSECURITY_DESCRIPTOR pSecurityDescriptor, DWORD nLength,
-     LPDWORD lpnLengthNeeded);
-
-typedef BOOL (WINAPI *GetSecurityDescriptorOwnerFunc)
-    (PSECURITY_DESCRIPTOR pSecurityDescriptor, PSID *pOwner,
-     LPBOOL lpbOwnerDefaulted);
-
-typedef BOOL (WINAPI *GetSecurityDescriptorDaclFunc)
-    (PSECURITY_DESCRIPTOR pSecurityDescriptor, LPBOOL lpbDaclPresent,
-     PACL *pDacl, LPBOOL lpbDaclDefaulted);
-
-typedef BOOL (WINAPI *GetAclInformationFunc)
-    (PACL pAcl, LPVOID pAclInformation, DWORD nAclInformationLength,
-     ACL_INFORMATION_CLASS dwAclInformationClass);
-
-typedef BOOL (WINAPI *GetAceFunc)
-    (PACL pAcl, DWORD dwAceIndex, LPVOID *pAce);
-
-typedef BOOL (WINAPI *EqualSidFunc)(PSID pSid1, PSID pSid2);
-
-
-/* Addresses of the security functions */
-static GetFileSecurityFunc GetFileSecurity_func;
-static GetSecurityDescriptorOwnerFunc GetSecurityDescriptorOwner_func;
-static GetSecurityDescriptorDaclFunc GetSecurityDescriptorDacl_func;
-static GetAclInformationFunc GetAclInformation_func;
-static GetAceFunc GetAce_func;
-static EqualSidFunc EqualSid_func;
-
-/* True if this OS is NT kernel based (NT/2000/XP) */
-static int isNT;
-
-
-/*
  * Returns JNI_TRUE if the specified file is on a file system that supports
  * persistent ACLs (On NTFS file systems returns true, on FAT32 file systems
  * returns false).
@@ -165,7 +126,7 @@
     SECURITY_INFORMATION info =
         OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION;
 
-    (*GetFileSecurity_func)(path, info , 0, 0, &len);
+    GetFileSecurityA(path, info , 0, 0, &len);
     if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
         JNU_ThrowIOExceptionWithLastError(env, "GetFileSecurity failed");
         return NULL;
@@ -174,7 +135,7 @@
     if (sd == NULL) {
         JNU_ThrowOutOfMemoryError(env, 0);
     } else {
-        if (!(*GetFileSecurity_func)(path, info, sd, len, &len)) {
+        if (!(*GetFileSecurityA)(path, info, sd, len, &len)) {
             JNU_ThrowIOExceptionWithLastError(env, "GetFileSecurity failed");
             free(sd);
             return NULL;
@@ -191,7 +152,7 @@
     SID* owner;
     BOOL defaulted;
 
-    if (!(*GetSecurityDescriptorOwner_func)(sd, &owner, &defaulted)) {
+    if (!GetSecurityDescriptorOwner(sd, &owner, &defaulted)) {
         JNU_ThrowIOExceptionWithLastError(env, "GetSecurityDescriptorOwner failed");
         return NULL;
     }
@@ -206,7 +167,7 @@
     ACL *acl;
     int defaulted, present;
 
-    if (!(*GetSecurityDescriptorDacl_func)(sd, &present, &acl, &defaulted)) {
+    if (!GetSecurityDescriptorDacl(sd, &present, &acl, &defaulted)) {
         JNU_ThrowIOExceptionWithLastError(env, "GetSecurityDescriptorDacl failed");
         return NULL;
     }
@@ -235,8 +196,8 @@
     /*
      * Get the ACE count
      */
-    if (!(*GetAclInformation_func)(acl, (void *) &acl_size_info, sizeof(acl_size_info),
-                                  AclSizeInformation)) {
+    if (!GetAclInformation(acl, (void *) &acl_size_info, sizeof(acl_size_info),
+                           AclSizeInformation)) {
         JNU_ThrowIOExceptionWithLastError(env, "GetAclInformation failed");
         return JNI_FALSE;
     }
@@ -250,7 +211,7 @@
         ACCESS_ALLOWED_ACE *access;
         SID* sid;
 
-        if (!(*GetAce_func)(acl, i, &ace)) {
+        if (!GetAce(acl, i, &ace)) {
             JNU_ThrowIOExceptionWithLastError(env, "GetAce failed");
             return -1;
         }
@@ -280,51 +241,7 @@
 JNIEXPORT void JNICALL Java_sun_management_FileSystemImpl_init0
   (JNIEnv *env, jclass ignored)
 {
-    OSVERSIONINFO ver;
-    HINSTANCE hInst;
-
-    /*
-     * Get the OS version. If dwPlatformId is VER_PLATFORM_WIN32_NT
-     * it means we're running on a Windows NT, 2000, or XP machine.
-     */
-    ver.dwOSVersionInfoSize = sizeof(ver);
-    GetVersionEx(&ver);
-    isNT = (ver.dwPlatformId == VER_PLATFORM_WIN32_NT);
-    if (!isNT) {
-        return;
-    }
-
-    /*
-     * On NT/2000/XP we need the addresses of the security functions
-     */
-    hInst = LoadLibrary("ADVAPI32.DLL");
-    if (hInst == NULL) {
-        JNU_ThrowIOExceptionWithLastError(env, "Unable to load ADVAPI32.DLL");
-        return;
-    }
-
-
-    GetFileSecurity_func = (GetFileSecurityFunc)GetProcAddress(hInst, "GetFileSecurityA");
-    GetSecurityDescriptorOwner_func =
-        (GetSecurityDescriptorOwnerFunc)GetProcAddress(hInst, "GetSecurityDescriptorOwner");
-    GetSecurityDescriptorDacl_func =
-        (GetSecurityDescriptorDaclFunc)GetProcAddress(hInst, "GetSecurityDescriptorDacl");
-    GetAclInformation_func =
-        (GetAclInformationFunc)GetProcAddress(hInst, "GetAclInformation");
-    GetAce_func = (GetAceFunc)GetProcAddress(hInst, "GetAce");
-    EqualSid_func = (EqualSidFunc)GetProcAddress(hInst, "EqualSid");
-
-    if (GetFileSecurity_func == NULL ||
-        GetSecurityDescriptorDacl_func == NULL ||
-        GetSecurityDescriptorDacl_func == NULL ||
-        GetAclInformation_func == NULL ||
-        GetAce_func == NULL ||
-        EqualSid_func == NULL)
-    {
-        JNU_ThrowIOExceptionWithLastError(env,
-            "Unable to get address of security functions");
-        return;
-    }
+        /* nothing to do */
 }
 
 /*
@@ -339,10 +256,6 @@
     jboolean isCopy;
     const char* path;
 
-    if (!isNT) {
-        return JNI_FALSE;
-    }
-
     path = JNU_GetStringPlatformChars(env, str, &isCopy);
     if (path != NULL) {
         res = isSecuritySupported(env, path);
--- a/src/windows/native/sun/nio/fs/WindowsNativeDispatcher.c	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/windows/native/sun/nio/fs/WindowsNativeDispatcher.c	Tue Apr 12 14:23:03 2011 -0700
@@ -24,7 +24,7 @@
  */
 
 #ifndef _WIN32_WINNT
-#define _WIN32_WINNT 0x0500
+#define _WIN32_WINNT 0x0501
 #endif
 
 #include <stdio.h>
@@ -36,6 +36,7 @@
 #include <windows.h>
 #include <aclapi.h>
 #include <winioctl.h>
+#include <Sddl.h>
 
 #include "jni.h"
 #include "jni_util.h"
@@ -77,40 +78,20 @@
 
 
 /**
- * Win32 APIs not defined in Visual Studio 2003 header files
+ * Win32 APIs not available in Windows XP
  */
-
-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 HANDLE (WINAPI* FindFirstStream_Proc)(LPCWSTR, 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);
@@ -190,33 +171,23 @@
     backupResult_bytesTransferred = (*env)->GetFieldID(env, clazz, "bytesTransferred", "I");
     backupResult_context = (*env)->GetFieldID(env, clazz, "context", "J");
 
-
-    h = LoadLibrary("kernel32");
-    if (h != INVALID_HANDLE_VALUE) {
+    // get handle to kernel32
+    if (GetModuleHandleExW((GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
+                            GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT),
+                           (LPCWSTR)&CreateFileW, &h) != 0)
+    {
+        // requires Windows Server 2003 or newer
         FindFirstStream_func =
             (FindFirstStream_Proc)GetProcAddress(h, "FindFirstStreamW");
         FindNextStream_func =
             (FindNextStream_Proc)GetProcAddress(h, "FindNextStreamW");
+
+        // requires Windows Vista or newer
         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
@@ -413,7 +384,7 @@
 Java_sun_nio_fs_WindowsNativeDispatcher_FindFirstStream0(JNIEnv* env, jclass this,
     jlong address, jobject obj)
 {
-    MY_WIN32_FIND_STREAM_DATA data;
+    WIN32_FIND_STREAM_DATA data;
     LPCWSTR lpFileName = jlong_to_ptr(address);
     HANDLE handle;
 
@@ -443,7 +414,7 @@
 Java_sun_nio_fs_WindowsNativeDispatcher_FindNextStream(JNIEnv* env, jclass this,
     jlong handle)
 {
-    MY_WIN32_FIND_STREAM_DATA data;
+    WIN32_FIND_STREAM_DATA data;
     HANDLE h = (HANDLE)jlong_to_ptr(handle);
 
     if (FindNextStream_func == NULL) {
@@ -909,12 +880,7 @@
     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);
+    return (jint)GetLengthSid(sid);
 }
 
 
@@ -924,13 +890,7 @@
 {
     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) {
+    if (ConvertSidToStringSidW(sid, &string) == 0) {
         throwWindowsException(env, GetLastError());
         return NULL;
     } else {
@@ -947,15 +907,8 @@
 {
     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)
+    if (ConvertStringSidToSidW(lpStringSid, &pSid) == 0)
         throwWindowsException(env, GetLastError());
-
     return ptr_to_jlong(pSid);
 }
 
@@ -1137,11 +1090,7 @@
     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)
+    if (CreateHardLinkW(newFile, existingFile, NULL) == 0)
         throwWindowsException(env, GetLastError());
 }
 
--- a/src/windows/native/sun/security/provider/WinCAPISeedGenerator.c	Fri Apr 08 10:31:14 2011 -0700
+++ b/src/windows/native/sun/security/provider/WinCAPISeedGenerator.c	Tue Apr 12 14:23:03 2011 -0700
@@ -33,11 +33,6 @@
 #include <jni.h>
 #include "sun_security_provider_NativeSeedGenerator.h"
 
-/* Typedefs for runtime linking. */
-typedef BOOL (WINAPI *CryptAcquireContextType)(HCRYPTPROV*, LPCTSTR, LPCTSTR, DWORD, DWORD);
-typedef BOOL (WINAPI *CryptGenRandomType)(HCRYPTPROV, DWORD, BYTE*);
-typedef BOOL (WINAPI *CryptReleaseContextType)(HCRYPTPROV, DWORD);
-
 /*
  * Get a random seed from the MS CryptoAPI. Return true if successful, false
  * otherwise.
@@ -49,48 +44,27 @@
 JNIEXPORT jboolean JNICALL Java_sun_security_provider_NativeSeedGenerator_nativeGenerateSeed
   (JNIEnv *env, jclass clazz, jbyteArray randArray)
 {
-    HMODULE lib;
-    CryptAcquireContextType acquireContext;
-    CryptGenRandomType genRandom;
-    CryptReleaseContextType releaseContext;
-
     HCRYPTPROV hCryptProv;
     jboolean result = JNI_FALSE;
     jsize numBytes;
     jbyte* randBytes;
 
-    lib = LoadLibrary("ADVAPI32.DLL");
-    if (lib == NULL) {
-        return result;
-    }
-
-    acquireContext = (CryptAcquireContextType)GetProcAddress(lib, "CryptAcquireContextA");
-    genRandom = (CryptGenRandomType)GetProcAddress(lib, "CryptGenRandom");
-    releaseContext = (CryptReleaseContextType)GetProcAddress(lib, "CryptReleaseContext");
-
-    if (acquireContext == NULL || genRandom == NULL || releaseContext == NULL) {
-        FreeLibrary(lib);
-        return result;
-    }
-
-    if (acquireContext(&hCryptProv, "J2SE", NULL, PROV_RSA_FULL, 0) == FALSE) {
+    if (CryptAcquireContextA(&hCryptProv, "J2SE", NULL, PROV_RSA_FULL, 0) == FALSE) {
         /* If CSP context hasn't been created, create one. */
-        if (acquireContext(&hCryptProv, "J2SE", NULL, PROV_RSA_FULL,
+        if (CryptAcquireContextA(&hCryptProv, "J2SE", NULL, PROV_RSA_FULL,
                 CRYPT_NEWKEYSET) == FALSE) {
-            FreeLibrary(lib);
             return result;
         }
     }
 
     numBytes = (*env)->GetArrayLength(env, randArray);
     randBytes = (*env)->GetByteArrayElements(env, randArray, NULL);
-    if (genRandom(hCryptProv, numBytes, randBytes)) {
+    if (CryptGenRandom(hCryptProv, numBytes, randBytes)) {
         result = JNI_TRUE;
     }
     (*env)->ReleaseByteArrayElements(env, randArray, randBytes, 0);
 
-    releaseContext(hCryptProv, 0);
-    FreeLibrary(lib);
+    CryptReleaseContext(hCryptProv, 0);
 
     return result;
 }
--- a/test/java/lang/Character/CheckScript.java	Fri Apr 08 10:31:14 2011 -0700
+++ b/test/java/lang/Character/CheckScript.java	Tue Apr 12 14:23:03 2011 -0700
@@ -1,34 +1,58 @@
+
+/*
+ * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
 /**
  * @test
- * @bug 6945564 6959267
+ * @bug 6945564 6959267 7033561
  * @summary  Check that the j.l.Character.UnicodeScript
  */
 
 import java.io.*;
-import java.lang.reflect.*;
 import java.util.*;
 import java.util.regex.*;
 import java.lang.Character.UnicodeScript;
 
 public class CheckScript {
 
-    static BufferedReader open(String[] args) throws FileNotFoundException {
+    public static void main(String[] args) throws Exception {
+        File fScripts;
+        File fAliases;
         if (args.length == 0) {
-            return new BufferedReader(new FileReader(new File(System.getProperty("test.src", "."), "Scripts.txt")));
-        } else if (args.length == 1) {
-            return new BufferedReader(new FileReader(args[0]));
+            fScripts = new File(System.getProperty("test.src", "."), "Scripts.txt");
+            fAliases = new File(System.getProperty("test.src", "."), "PropertyValueAliases.txt");
+        } else if (args.length == 2) {
+            fScripts = new File(args[0]);
+            fAliases = new File(args[1]);
         } else {
-            System.out.println("java CharacterScript Scripts.txt");
+            System.out.println("java CharacterScript Scripts.txt PropertyValueAliases.txt");
             throw new RuntimeException("Datafile name should be specified.");
         }
-    }
-
-    public static void main(String[] args) throws Exception {
 
         Matcher m = Pattern.compile("(\\p{XDigit}+)(?:\\.{2}(\\p{XDigit}+))?\\s+;\\s+(\\w+)\\s+#.*").matcher("");
         String line = null;
         HashMap<String,ArrayList<Integer>> scripts = new HashMap<>();
-        try (BufferedReader sbfr = open(args)) {
+        try (BufferedReader sbfr = new BufferedReader(new FileReader(fScripts))) {
             while ((line = sbfr.readLine()) != null) {
                 if (line.length() <= 1 || line.charAt(0) == '#') {
                     continue;
@@ -107,5 +131,29 @@
                 }
             }
         }
+        // check all aliases
+        m = Pattern.compile("sc\\s*;\\s*(\\p{Alpha}{4})\\s*;\\s*([\\p{Alpha}|_]+)\\s*.*").matcher("");
+        line = null;
+        try (BufferedReader sbfr = new BufferedReader(new FileReader(fAliases))) {
+            while ((line = sbfr.readLine()) != null) {
+                if (line.length() <= 1 || line.charAt(0) == '#') {
+                    continue;
+                }
+                m.reset(line);
+                if (m.matches()) {
+                    String alias = m.group(1);
+                    String name = m.group(2);
+                    // HRKT -> Katakana_Or_Hiragana not supported
+                    if ("HRKT".equals(alias.toUpperCase(Locale.ENGLISH)))
+                        continue;
+                    if (Character.UnicodeScript.forName(alias) !=
+                        Character.UnicodeScript.forName(name)) {
+                        throw new RuntimeException(
+                            "UnicodeScript failed: alias<" + alias +
+                            "> does not map to <" + name + ">");
+                    }
+                }
+            }
+        }
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/Character/PropertyValueAliases.txt	Tue Apr 12 14:23:03 2011 -0700
@@ -0,0 +1,1178 @@
+# PropertyValueAliases-6.0.0.txt
+# Date: 2010-07-17, 22:44:06 GMT [MD]
+#
+# Unicode Character Database
+# Copyright (c) 1991-2010 Unicode, Inc.
+# For terms of use, see http://www.unicode.org/terms_of_use.html
+# For documentation, see http://www.unicode.org/reports/tr44/
+#
+# This file contains aliases for property values used in the UCD.
+# These names can be used for XML formats of UCD data, for regular-expression
+# property tests, and other programmatic textual descriptions of Unicode data.
+# For information on which properties are normative, see UCD.html.
+#
+# The names may be translated in appropriate environments, and additional
+# aliases may be useful.
+#
+# FORMAT
+#
+# Each line describes a property value name.
+# This consists of three or more fields, separated by semicolons.
+#
+# First Field: The first field describes the property for which that
+# property value name is used.
+#
+# Second Field: The second field is an abbreviated name.
+# If there is no abbreviated name available, the field is marked with "n/a".
+#
+# Third Field: The third field is a long name.
+#
+# In the case of ccc, there are 4 fields. The second field is numeric, third
+# is abbreviated, and fourth is long.
+#
+# The above are the preferred aliases. Other aliases may be listed in additional fields.
+#
+# Loose matching should be applied to all property names and property values, with
+# the exception of String Property values. With loose matching of property names and
+# values, the case distinctions, whitespace, and '_' are ignored. For Numeric Property
+# values, numeric equivalencies are applied: thus "01.00" is equivalent to "1".
+#
+# NOTE: Property value names are NOT unique across properties. For example:
+#
+#   AL means Arabic Letter for the Bidi_Class property, and
+#   AL means Above_Left for the Combining_Class property, and
+#   AL means Alphabetic for the Line_Break property.
+#
+# In addition, some property names may be the same as some property value names.
+# For example:
+#
+#   sc means the Script property, and
+#   Sc means the General_Category property value Currency_Symbol (Sc)
+#
+# The combination of property value and property name is, however, unique.
+#
+# For more information, see UTS #18: Unicode Regular Expressions
+# ================================================
+
+
+# ASCII_Hex_Digit (AHex)
+
+AHex; N        ; No                               ; F                                ; False
+AHex; Y        ; Yes                              ; T                                ; True
+
+# Age (age)
+
+age; n/a       ; 1.1
+age; n/a       ; 2.0
+age; n/a       ; 2.1
+age; n/a       ; 3.0
+age; n/a       ; 3.1
+age; n/a       ; 3.2
+age; n/a       ; 4.0
+age; n/a       ; 4.1
+age; n/a       ; 5.0
+age; n/a       ; 5.1
+age; n/a       ; 5.2
+age; n/a       ; 6.0
+age; n/a       ; unassigned
+
+# Alphabetic (Alpha)
+
+Alpha; N       ; No                               ; F                                ; False
+Alpha; Y       ; Yes                              ; T                                ; True
+
+# Bidi_Class (bc)
+
+bc ; AL        ; Arabic_Letter
+bc ; AN        ; Arabic_Number
+bc ; B         ; Paragraph_Separator
+bc ; BN        ; Boundary_Neutral
+bc ; CS        ; Common_Separator
+bc ; EN        ; European_Number
+bc ; ES        ; European_Separator
+bc ; ET        ; European_Terminator
+bc ; L         ; Left_To_Right
+bc ; LRE       ; Left_To_Right_Embedding
+bc ; LRO       ; Left_To_Right_Override
+bc ; NSM       ; Nonspacing_Mark
+bc ; ON        ; Other_Neutral
+bc ; PDF       ; Pop_Directional_Format
+bc ; R         ; Right_To_Left
+bc ; RLE       ; Right_To_Left_Embedding
+bc ; RLO       ; Right_To_Left_Override
+bc ; S         ; Segment_Separator
+bc ; WS        ; White_Space
+
+# Bidi_Control (Bidi_C)
+
+Bidi_C; N      ; No                               ; F                                ; False
+Bidi_C; Y      ; Yes                              ; T                                ; True
+
+# Bidi_Mirrored (Bidi_M)
+
+Bidi_M; N      ; No                               ; F                                ; False
+Bidi_M; Y      ; Yes                              ; T                                ; True
+
+# Bidi_Mirroring_Glyph (bmg)
+
+# @missing: 0000..10FFFF; Bidi_Mirroring_Glyph; <none>
+
+# Block (blk)
+
+blk; n/a       ; Aegean_Numbers
+blk; n/a       ; Alchemical_Symbols
+blk; n/a       ; Alphabetic_Presentation_Forms
+blk; n/a       ; Ancient_Greek_Musical_Notation
+blk; n/a       ; Ancient_Greek_Numbers
+blk; n/a       ; Ancient_Symbols
+blk; n/a       ; Arabic
+blk; n/a       ; Arabic_Presentation_Forms_A      ; Arabic_Presentation_Forms-A
+blk; n/a       ; Arabic_Presentation_Forms_B
+blk; n/a       ; Arabic_Supplement
+blk; n/a       ; Armenian
+blk; n/a       ; Arrows
+blk; n/a       ; Avestan
+blk; n/a       ; Balinese
+blk; n/a       ; Bamum
+blk; n/a       ; Bamum_Supplement
+blk; n/a       ; Basic_Latin                      ; ASCII
+blk; n/a       ; Batak
+blk; n/a       ; Bengali
+blk; n/a       ; Block_Elements
+blk; n/a       ; Bopomofo
+blk; n/a       ; Bopomofo_Extended
+blk; n/a       ; Box_Drawing
+blk; n/a       ; Brahmi
+blk; n/a       ; Braille_Patterns
+blk; n/a       ; Buginese
+blk; n/a       ; Buhid
+blk; n/a       ; Byzantine_Musical_Symbols
+blk; n/a       ; Carian
+blk; n/a       ; Cham
+blk; n/a       ; Cherokee
+blk; n/a       ; CJK_Compatibility
+blk; n/a       ; CJK_Compatibility_Forms
+blk; n/a       ; CJK_Compatibility_Ideographs
+blk; n/a       ; CJK_Compatibility_Ideographs_Supplement
+blk; n/a       ; CJK_Radicals_Supplement
+blk; n/a       ; CJK_Strokes
+blk; n/a       ; CJK_Symbols_And_Punctuation
+blk; n/a       ; CJK_Unified_Ideographs
+blk; n/a       ; CJK_Unified_Ideographs_Extension_A
+blk; n/a       ; CJK_Unified_Ideographs_Extension_B
+blk; n/a       ; CJK_Unified_Ideographs_Extension_C
+blk; n/a       ; CJK_Unified_Ideographs_Extension_D
+blk; n/a       ; Combining_Diacritical_Marks
+blk; n/a       ; Combining_Diacritical_Marks_For_Symbols; Combining_Marks_For_Symbols
+blk; n/a       ; Combining_Diacritical_Marks_Supplement
+blk; n/a       ; Combining_Half_Marks
+blk; n/a       ; Common_Indic_Number_Forms
+blk; n/a       ; Control_Pictures
+blk; n/a       ; Coptic
+blk; n/a       ; Counting_Rod_Numerals
+blk; n/a       ; Cuneiform
+blk; n/a       ; Cuneiform_Numbers_And_Punctuation
+blk; n/a       ; Currency_Symbols
+blk; n/a       ; Cypriot_Syllabary
+blk; n/a       ; Cyrillic
+blk; n/a       ; Cyrillic_Extended_A
+blk; n/a       ; Cyrillic_Extended_B
+blk; n/a       ; Cyrillic_Supplement              ; Cyrillic_Supplementary
+blk; n/a       ; Deseret
+blk; n/a       ; Devanagari
+blk; n/a       ; Devanagari_Extended
+blk; n/a       ; Dingbats
+blk; n/a       ; Domino_Tiles
+blk; n/a       ; Egyptian_Hieroglyphs
+blk; n/a       ; Emoticons
+blk; n/a       ; Enclosed_Alphanumeric_Supplement
+blk; n/a       ; Enclosed_Alphanumerics
+blk; n/a       ; Enclosed_CJK_Letters_And_Months
+blk; n/a       ; Enclosed_Ideographic_Supplement
+blk; n/a       ; Ethiopic
+blk; n/a       ; Ethiopic_Extended
+blk; n/a       ; Ethiopic_Extended_A
+blk; n/a       ; Ethiopic_Supplement
+blk; n/a       ; General_Punctuation
+blk; n/a       ; Geometric_Shapes
+blk; n/a       ; Georgian
+blk; n/a       ; Georgian_Supplement
+blk; n/a       ; Glagolitic
+blk; n/a       ; Gothic
+blk; n/a       ; Greek_And_Coptic                 ; Greek
+blk; n/a       ; Greek_Extended
+blk; n/a       ; Gujarati
+blk; n/a       ; Gurmukhi
+blk; n/a       ; Halfwidth_And_Fullwidth_Forms
+blk; n/a       ; Hangul_Compatibility_Jamo
+blk; n/a       ; Hangul_Jamo
+blk; n/a       ; Hangul_Jamo_Extended_A
+blk; n/a       ; Hangul_Jamo_Extended_B
+blk; n/a       ; Hangul_Syllables
+blk; n/a       ; Hanunoo
+blk; n/a       ; Hebrew
+blk; n/a       ; High_Private_Use_Surrogates
+blk; n/a       ; High_Surrogates
+blk; n/a       ; Hiragana
+blk; n/a       ; Ideographic_Description_Characters
+blk; n/a       ; Imperial_Aramaic
+blk; n/a       ; Inscriptional_Pahlavi
+blk; n/a       ; Inscriptional_Parthian
+blk; n/a       ; IPA_Extensions
+blk; n/a       ; Javanese
+blk; n/a       ; Kaithi
+blk; n/a       ; Kana_Supplement
+blk; n/a       ; Kanbun
+blk; n/a       ; Kangxi_Radicals
+blk; n/a       ; Kannada
+blk; n/a       ; Katakana
+blk; n/a       ; Katakana_Phonetic_Extensions
+blk; n/a       ; Kayah_Li
+blk; n/a       ; Kharoshthi
+blk; n/a       ; Khmer
+blk; n/a       ; Khmer_Symbols
+blk; n/a       ; Lao
+blk; n/a       ; Latin_1_Supplement               ; Latin_1
+blk; n/a       ; Latin_Extended_A
+blk; n/a       ; Latin_Extended_Additional
+blk; n/a       ; Latin_Extended_B
+blk; n/a       ; Latin_Extended_C
+blk; n/a       ; Latin_Extended_D
+blk; n/a       ; Lepcha
+blk; n/a       ; Letterlike_Symbols
+blk; n/a       ; Limbu
+blk; n/a       ; Linear_B_Ideograms
+blk; n/a       ; Linear_B_Syllabary
+blk; n/a       ; Lisu
+blk; n/a       ; Low_Surrogates
+blk; n/a       ; Lycian
+blk; n/a       ; Lydian
+blk; n/a       ; Mahjong_Tiles
+blk; n/a       ; Malayalam
+blk; n/a       ; Mandaic
+blk; n/a       ; Mathematical_Alphanumeric_Symbols
+blk; n/a       ; Mathematical_Operators
+blk; n/a       ; Meetei_Mayek
+blk; n/a       ; Miscellaneous_Mathematical_Symbols_A
+blk; n/a       ; Miscellaneous_Mathematical_Symbols_B
+blk; n/a       ; Miscellaneous_Symbols
+blk; n/a       ; Miscellaneous_Symbols_And_Arrows
+blk; n/a       ; Miscellaneous_Symbols_And_Pictographs
+blk; n/a       ; Miscellaneous_Technical
+blk; n/a       ; Modifier_Tone_Letters
+blk; n/a       ; Mongolian
+blk; n/a       ; Musical_Symbols
+blk; n/a       ; Myanmar
+blk; n/a       ; Myanmar_Extended_A
+blk; n/a       ; New_Tai_Lue
+blk; n/a       ; NKo
+blk; n/a       ; No_Block
+blk; n/a       ; Number_Forms
+blk; n/a       ; Ogham
+blk; n/a       ; Ol_Chiki
+blk; n/a       ; Old_Italic
+blk; n/a       ; Old_Persian
+blk; n/a       ; Old_South_Arabian
+blk; n/a       ; Old_Turkic
+blk; n/a       ; Optical_Character_Recognition
+blk; n/a       ; Oriya
+blk; n/a       ; Osmanya
+blk; n/a       ; Phags_Pa
+blk; n/a       ; Phaistos_Disc
+blk; n/a       ; Phoenician
+blk; n/a       ; Phonetic_Extensions
+blk; n/a       ; Phonetic_Extensions_Supplement
+blk; n/a       ; Playing_Cards
+blk; n/a       ; Private_Use_Area                 ; Private_Use
+blk; n/a       ; Rejang
+blk; n/a       ; Rumi_Numeral_Symbols
+blk; n/a       ; Runic
+blk; n/a       ; Samaritan
+blk; n/a       ; Saurashtra
+blk; n/a       ; Shavian
+blk; n/a       ; Sinhala
+blk; n/a       ; Small_Form_Variants
+blk; n/a       ; Spacing_Modifier_Letters
+blk; n/a       ; Specials
+blk; n/a       ; Sundanese
+blk; n/a       ; Superscripts_And_Subscripts
+blk; n/a       ; Supplemental_Arrows_A
+blk; n/a       ; Supplemental_Arrows_B
+blk; n/a       ; Supplemental_Mathematical_Operators
+blk; n/a       ; Supplemental_Punctuation
+blk; n/a       ; Supplementary_Private_Use_Area_A
+blk; n/a       ; Supplementary_Private_Use_Area_B
+blk; n/a       ; Syloti_Nagri
+blk; n/a       ; Syriac
+blk; n/a       ; Tagalog
+blk; n/a       ; Tagbanwa
+blk; n/a       ; Tags
+blk; n/a       ; Tai_Le
+blk; n/a       ; Tai_Tham
+blk; n/a       ; Tai_Viet
+blk; n/a       ; Tai_Xuan_Jing_Symbols
+blk; n/a       ; Tamil
+blk; n/a       ; Telugu
+blk; n/a       ; Thaana
+blk; n/a       ; Thai
+blk; n/a       ; Tibetan
+blk; n/a       ; Tifinagh
+blk; n/a       ; Transport_And_Map_Symbols
+blk; n/a       ; Ugaritic
+blk; n/a       ; Unified_Canadian_Aboriginal_Syllabics; Canadian_Syllabics
+blk; n/a       ; Unified_Canadian_Aboriginal_Syllabics_Extended
+blk; n/a       ; Vai
+blk; n/a       ; Variation_Selectors
+blk; n/a       ; Variation_Selectors_Supplement
+blk; n/a       ; Vedic_Extensions
+blk; n/a       ; Vertical_Forms
+blk; n/a       ; Yi_Radicals
+blk; n/a       ; Yi_Syllables
+blk; n/a       ; Yijing_Hexagram_Symbols
+
+# Canonical_Combining_Class (ccc)
+
+ccc;   0; NR   ; Not_Reordered
+ccc;   1; OV   ; Overlay
+ccc;   7; NK   ; Nukta
+ccc;   8; KV   ; Kana_Voicing
+ccc;   9; VR   ; Virama
+ccc; 200; ATBL ; Attached_Below_Left
+ccc; 202; ATB  ; Attached_Below
+ccc; 214; ATA  ; Attached_Above
+ccc; 216; ATAR ; Attached_Above_Right
+ccc; 218; BL   ; Below_Left
+ccc; 220; B    ; Below
+ccc; 222; BR   ; Below_Right
+ccc; 224; L    ; Left
+ccc; 226; R    ; Right
+ccc; 228; AL   ; Above_Left
+ccc; 230; A    ; Above
+ccc; 232; AR   ; Above_Right
+ccc; 233; DB   ; Double_Below
+ccc; 234; DA   ; Double_Above
+ccc; 240; IS   ; Iota_Subscript
+
+# Case_Folding (cf)
+
+# @missing: 0000..10FFFF; Case_Folding; <code point>
+
+# Case_Ignorable (CI)
+
+CI ; N         ; No                               ; F                                ; False
+CI ; Y         ; Yes                              ; T                                ; True
+
+# Cased (Cased)
+
+Cased; N       ; No                               ; F                                ; False
+Cased; Y       ; Yes                              ; T                                ; True
+
+# Changes_When_Casefolded (CWCF)
+
+CWCF; N        ; No                               ; F                                ; False
+CWCF; Y        ; Yes                              ; T                                ; True
+
+# Changes_When_Casemapped (CWCM)
+
+CWCM; N        ; No                               ; F                                ; False
+CWCM; Y        ; Yes                              ; T                                ; True
+
+# Changes_When_Lowercased (CWL)
+
+CWL; N         ; No                               ; F                                ; False
+CWL; Y         ; Yes                              ; T                                ; True
+
+# Changes_When_NFKC_Casefolded (CWKCF)
+
+CWKCF; N       ; No                               ; F                                ; False
+CWKCF; Y       ; Yes                              ; T                                ; True
+
+# Changes_When_Titlecased (CWT)
+
+CWT; N         ; No                               ; F                                ; False
+CWT; Y         ; Yes                              ; T                                ; True
+
+# Changes_When_Uppercased (CWU)
+
+CWU; N         ; No                               ; F                                ; False
+CWU; Y         ; Yes                              ; T                                ; True
+
+# Composition_Exclusion (CE)
+
+CE ; N         ; No                               ; F                                ; False
+CE ; Y         ; Yes                              ; T                                ; True
+
+# Dash (Dash)
+
+Dash; N        ; No                               ; F                                ; False
+Dash; Y        ; Yes                              ; T                                ; True
+
+# Decomposition_Mapping (dm)
+
+# @missing: 0000..10FFFF; Decomposition_Mapping; <code point>
+
+# Decomposition_Type (dt)
+
+dt ; Can       ; Canonical                        ; can
+dt ; Com       ; Compat                           ; com
+dt ; Enc       ; Circle                           ; enc
+dt ; Fin       ; Final                            ; fin
+dt ; Font      ; font
+dt ; Fra       ; Fraction                         ; fra
+dt ; Init      ; Initial                          ; init
+dt ; Iso       ; Isolated                         ; iso
+dt ; Med       ; Medial                           ; med
+dt ; Nar       ; Narrow                           ; nar
+dt ; Nb        ; Nobreak                          ; nb
+dt ; None      ; none
+dt ; Sml       ; Small                            ; sml
+dt ; Sqr       ; Square                           ; sqr
+dt ; Sub       ; sub
+dt ; Sup       ; Super                            ; sup
+dt ; Vert      ; Vertical                         ; vert
+dt ; Wide      ; wide
+
+# Default_Ignorable_Code_Point (DI)
+
+DI ; N         ; No                               ; F                                ; False
+DI ; Y         ; Yes                              ; T                                ; True
+
+# Deprecated (Dep)
+
+Dep; N         ; No                               ; F                                ; False
+Dep; Y         ; Yes                              ; T                                ; True
+
+# Diacritic (Dia)
+
+Dia; N         ; No                               ; F                                ; False
+Dia; Y         ; Yes                              ; T                                ; True
+
+# East_Asian_Width (ea)
+
+ea ; A         ; Ambiguous
+ea ; F         ; Fullwidth
+ea ; H         ; Halfwidth
+ea ; N         ; Neutral
+ea ; Na        ; Narrow
+ea ; W         ; Wide
+
+# Expands_On_NFC (XO_NFC)
+
+XO_NFC; N      ; No                               ; F                                ; False
+XO_NFC; Y      ; Yes                              ; T                                ; True
+
+# Expands_On_NFD (XO_NFD)
+
+XO_NFD; N      ; No                               ; F                                ; False
+XO_NFD; Y      ; Yes                              ; T                                ; True
+
+# Expands_On_NFKC (XO_NFKC)
+
+XO_NFKC; N     ; No                               ; F                                ; False
+XO_NFKC; Y     ; Yes                              ; T                                ; True
+
+# Expands_On_NFKD (XO_NFKD)
+
+XO_NFKD; N     ; No                               ; F                                ; False
+XO_NFKD; Y     ; Yes                              ; T                                ; True
+
+# Extender (Ext)
+
+Ext; N         ; No                               ; F                                ; False
+Ext; Y         ; Yes                              ; T                                ; True
+
+# FC_NFKC_Closure (FC_NFKC)
+
+# @missing: 0000..10FFFF; FC_NFKC_Closure; <code point>
+
+# Full_Composition_Exclusion (Comp_Ex)
+
+Comp_Ex; N     ; No                               ; F                                ; False
+Comp_Ex; Y     ; Yes                              ; T                                ; True
+
+# General_Category (gc)
+
+gc ; C         ; Other                            # Cc | Cf | Cn | Co | Cs
+gc ; Cc        ; Control                          ; cntrl
+gc ; Cf        ; Format
+gc ; Cn        ; Unassigned
+gc ; Co        ; Private_Use
+gc ; Cs        ; Surrogate
+gc ; L         ; Letter                           # Ll | Lm | Lo | Lt | Lu
+gc ; LC        ; Cased_Letter                     # Ll | Lt | Lu
+gc ; Ll        ; Lowercase_Letter
+gc ; Lm        ; Modifier_Letter
+gc ; Lo        ; Other_Letter
+gc ; Lt        ; Titlecase_Letter
+gc ; Lu        ; Uppercase_Letter
+gc ; M         ; Mark                             # Mc | Me | Mn
+gc ; Mc        ; Spacing_Mark
+gc ; Me        ; Enclosing_Mark
+gc ; Mn        ; Nonspacing_Mark
+gc ; N         ; Number                           # Nd | Nl | No
+gc ; Nd        ; Decimal_Number                   ; digit
+gc ; Nl        ; Letter_Number
+gc ; No        ; Other_Number
+gc ; P         ; Punctuation                      ; punct                            # Pc | Pd | Pe | Pf | Pi | Po | Ps
+gc ; Pc        ; Connector_Punctuation
+gc ; Pd        ; Dash_Punctuation
+gc ; Pe        ; Close_Punctuation
+gc ; Pf        ; Final_Punctuation
+gc ; Pi        ; Initial_Punctuation
+gc ; Po        ; Other_Punctuation
+gc ; Ps        ; Open_Punctuation
+gc ; S         ; Symbol                           # Sc | Sk | Sm | So
+gc ; Sc        ; Currency_Symbol
+gc ; Sk        ; Modifier_Symbol
+gc ; Sm        ; Math_Symbol
+gc ; So        ; Other_Symbol
+gc ; Z         ; Separator                        # Zl | Zp | Zs
+gc ; Zl        ; Line_Separator
+gc ; Zp        ; Paragraph_Separator
+gc ; Zs        ; Space_Separator
+
+# Grapheme_Base (Gr_Base)
+
+Gr_Base; N     ; No                               ; F                                ; False
+Gr_Base; Y     ; Yes                              ; T                                ; True
+
+# Grapheme_Cluster_Break (GCB)
+
+GCB; CN        ; Control
+GCB; CR        ; CR
+GCB; EX        ; Extend
+GCB; L         ; L
+GCB; LF        ; LF
+GCB; LV        ; LV
+GCB; LVT       ; LVT
+GCB; PP        ; Prepend
+GCB; SM        ; SpacingMark
+GCB; T         ; T
+GCB; V         ; V
+GCB; XX        ; Other
+
+# Grapheme_Extend (Gr_Ext)
+
+Gr_Ext; N      ; No                               ; F                                ; False
+Gr_Ext; Y      ; Yes                              ; T                                ; True
+
+# Grapheme_Link (Gr_Link)
+
+Gr_Link; N     ; No                               ; F                                ; False
+Gr_Link; Y     ; Yes                              ; T                                ; True
+
+# Hangul_Syllable_Type (hst)
+
+hst; L         ; Leading_Jamo
+hst; LV        ; LV_Syllable
+hst; LVT       ; LVT_Syllable
+hst; NA        ; Not_Applicable
+hst; T         ; Trailing_Jamo
+hst; V         ; Vowel_Jamo
+
+# Hex_Digit (Hex)
+
+Hex; N         ; No                               ; F                                ; False
+Hex; Y         ; Yes                              ; T                                ; True
+
+# Hyphen (Hyphen)
+
+Hyphen; N      ; No                               ; F                                ; False
+Hyphen; Y      ; Yes                              ; T                                ; True
+
+# IDS_Binary_Operator (IDSB)
+
+IDSB; N        ; No