changeset 2584:c5a436f053aa

Merge
author lana
date Mon, 12 Jul 2010 19:42:02 -0700
parents a93a7ed5018c 4e365ef6576d
children 13029a61b16b
files test/ProblemList.txt test/java/nio/channels/ServerSocketChannel/AcceptAddress.java test/java/nio/charset/coders/Surrogate.java test/tools/launcher/Makefile.SolarisRunpath test/tools/launcher/lib/i386/lib32/lib32/liblibrary.so test/tools/launcher/lib/i386/lib32/liblibrary.so test/tools/launcher/lib/sparc/lib32/lib32/liblibrary.so test/tools/launcher/lib/sparc/lib32/liblibrary.so test/tools/launcher/lib/sparc/lib64/lib64/liblibrary.so test/tools/launcher/lib/sparc/lib64/liblibrary.so
diffstat 179 files changed, 8621 insertions(+), 5285 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/common/shared/Defs-javadoc.gmk	Mon Jul 12 19:42:02 2010 -0700
@@ -0,0 +1,93 @@
+#
+# Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  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.
+#
+
+# Copyright year for beginning of Java and some of the apis
+#   (Needed when creating the javadocs)
+FIRST_COPYRIGHT_YEAR                = 1993
+DOMAPI_FIRST_COPYRIGHT_YEAR         = 2005
+MIRROR_FIRST_COPYRIGHT_YEAR         = 2004
+DOCLETAPI_FIRST_COPYRIGHT_YEAR      = 1993
+TAGLETAPI_FIRST_COPYRIGHT_YEAR      = 1993
+JDI_FIRST_COPYRIGHT_YEAR            = 1999
+JAAS_FIRST_COPYRIGHT_YEAR           = 1998
+JGSS_FIRST_COPYRIGHT_YEAR           = 2000
+SMARTCARDIO_FIRST_COPYRIGHT_YEAR    = 2005
+HTTPSERVER_FIRST_COPYRIGHT_YEAR     = 2005
+MGMT_FIRST_COPYRIGHT_YEAR           = 2003
+ATTACH_FIRST_COPYRIGHT_YEAR         = 2005
+JCONSOLE_FIRST_COPYRIGHT_YEAR       = 2006
+SCTPAPI_FIRST_COPYRIGHT_YEAR        = 2009
+TRACING_FIRST_COPYRIGHT_YEAR        = 2008
+TREEAPI_FIRST_COPYRIGHT_YEAR        = 2005
+JNLP_FIRST_COPYRIGHT_YEAR           = 1998
+PLUGIN2_FIRST_COPYRIGHT_YEAR        = 2007
+
+# Oracle name
+COMPANY_NAME = Oracle and/or its affiliates
+
+# Copyright address
+COMPANY_ADDRESS = 500 Oracle Parkway<br>Redwood Shores, CA 94065 USA.
+
+# The trademark symbol
+TRADEMARK = &trade;
+
+# Common copyright lines used
+#   The word "Copyright" might optionally be a link to the file cpyr.html.
+#   The first year of copyright may vary or not be available.
+#   The address to the company might be optional.
+COMMA:= ,
+EMPTY:=
+SPACE:=$(EMPTY) $(EMPTY)
+COPYRIGHT_SYMBOL = &\#x00a9;
+# Macros to handle the optional empty args.
+#   (The GNU make 3.78.1 "if" conditional is broken, fixed in GNU make 3.81)
+define OptionalCopyrightUrl # url
+$(shell \
+  if [ "$1" != "" ] ; then \
+    printf "<a href=\"%s\">Copyright</a>" "$1"; \
+  else \
+    printf "Copyright"; \
+  fi)
+endef
+define OptionalCopyrightFirstYear # year
+$(shell \
+  if [ "$1" != "" ] ; then \
+    printf "%s," "$1";\
+  fi)
+endef
+define OptionalCompanyAddress # address
+$(shell \
+  if [ "$1" != "" ] ; then \
+    printf "%s" "$1";\
+  fi)
+endef
+define CopyrightLine # optionalurl optionalfirstyear optionaladdress
+$(call OptionalCopyrightUrl,$1) $(COPYRIGHT_SYMBOL)\
+$(call OptionalCopyrightFirstYear,$2) $(COPYRIGHT_YEAR),\
+$(COMPANY_NAME).\
+$(call OptionalCompanyAddress,$3)\
+All rights reserved.
+endef
+
--- a/make/docs/Makefile	Mon Jul 12 19:35:11 2010 -0700
+++ b/make/docs/Makefile	Mon Jul 12 19:42:02 2010 -0700
@@ -1,5 +1,4 @@
-#
-# Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -30,6 +29,41 @@
 PRODUCT=docs
 include $(BUILDDIR)/common/Defs.gmk
 
+# Get CopyrightLine macro and other shared variables
+include $(BUILDDIR)/common/shared/Defs-javadoc.gmk
+
+# Url to root of documents
+DOCSDIR_URL = {@docroot}/$(GET2DOCSDIR)
+
+# Url to copyright html file
+COPYRIGHT_URL-7 = $(DOCSDIR_URL)/legal/cpyr.html
+COPYRIGHT_URL = $(COPYRIGHT_URL-$(JDK_MINOR_VERSION))
+
+# Url to bug filing site
+BUG_SUBMIT_URL = http://bugs.sun.com/services/bugreport/index.jsp
+
+# Common line for how to submit a bug or rfe
+BUG_SUBMIT_LINE = <a href=\"$(BUG_SUBMIT_URL)\">Submit a bug or feature</a>
+
+# Url to devdocs page
+#   Was: http://java.sun.com/javase/6/webnotes/devdocs-vs-specs.html
+DEV_DOCS_URL-5 = http://java.sun.com/j2se/1.5.0/docs
+DEV_DOCS_URL-6 = http://download.oracle.com/docs/cd/E17409_01/javase/6/docs
+DEV_DOCS_URL-7 = http://download.oracle.com/docs/cd/E17409_01/javase/7/docs
+DEV_DOCS_URL = $(DEV_DOCS_URL-$(JDK_MINOR_VERSION))
+
+# Url to Java Language Spec
+JLS3_URL = http://java.sun.com/docs/books/jls/
+
+# Common Java trademark line
+JAVA_TRADEMARK_LINE = Java is a trademark or registered trademark of \
+$(COMPANY_NAME) in the US and other countries.
+
+#
+# Definitions for imported components
+#
+include $(BUILDDIR)/common/internal/ImportComponents.gmk
+
 # We override whatever the max VM memory setting is here.
 #    NOTE: javadoc will not complete without these larger settings.
 #    WARNING: This could cause thrashing on low memory machines.
@@ -39,418 +73,155 @@
   MAX_VM_MEMORY = 512
 endif
 
+# List of all possible directories for javadoc to look for sources
+#    NOTE: Quotes are required around sourcepath argument only on Windows.
+#          Otherwise, you get "No packages or classes specified." due 
+#          to $(CLASSPATH_SEPARATOR) being interpreted as an end of 
+#          command (newline or shell ; character)
+ALL_SOURCE_DIRS = $(SHARE_SRC)/classes \
+                  $(IMPORTSRCDIR) \
+                  $(GENSRCDIR) \
+                  $(SHARE_SRC)/../solaris/classes \
+	          $(SHARE_SRC)/../windows/classes \
+		  $(SHARE_SRC)/doc/stub
+EMPTY:=
+SPACE:= $(EMPTY) $(EMPTY)
+RELEASEDOCS_SOURCEPATH = \
+    $(subst $(SPACE),$(CLASSPATH_SEPARATOR),$(strip $(ALL_SOURCE_DIRS)))
+
+# Prep for javadoc creation, assumes $@ is an index.html file
+define prep-javadoc
+@if [ -f "$@" -a "$?" != "" ] ; then \
+  $(ECHO) "# Dependencies have changed: $?"; \
+fi
+$(RM) -r $(@D)
+$(MKDIR) -p $(@D)
+endef
+
+# A cache of the directories in ALL_SOURCE_DIRS
+DIRECTORY_CACHE = $(DOCSTMPDIR)/directory.cache
+
+# Given a list of packages, return a list of files or dirs to be dependent on
+#   (Currently only returning a list of directories)
+define PackageDependencies # packages
+$(shell							\
+  if [ "$1" != "" -a -f $(DIRECTORY_CACHE) ] ; then	\
+    for p in $1 ; do 					\
+      pd=`$(ECHO) $${p} | $(SED) -e 's@[.]@/@g'`;	\
+      $(CAT) $(DIRECTORY_CACHE) | $(GREP) "/$${pd}/" ; 	\
+    done; 						\
+  fi							\
+)
+endef
+
+# Given a list of packages, add packages that exist to $@, print summary
+define PackageFilter # packages
+@if [ "$1" != "" ] ; then 				\
+  for p in $1 ; do 					\
+    pd=`$(ECHO) $${p} | $(SED) -e 's@[.]@/@g'`; 	\
+    found="false"; 					\
+    for cp in $(ALL_SOURCE_DIRS) ; do 			\
+      if [ -d $${cp}/$${pd} ] ; then 			\
+        $(ECHO) "$${p}" >> $@; 				\
+	found="true";					\
+	break; 						\
+      fi; 						\
+    done; 						\
+    if [ "$${found}" = "false" ] ; then 		\
+      $(ECHO) "WARNING: Package not found: $${p}"; 	\
+    fi; 						\
+  done; 						\
+fi
+endef
+
+# Print out a summary of the javadoc command about to be run
+define JavadocSummary # optionsfile packagesfile
+@$(ECHO) "# Summary for $@";\
+ $(ECHO) "# Options (`$(BASENAME) $1`):"; $(SED) -e 's@^@#   @' $1; \
+ $(ECHO) "# Packages (`$(BASENAME) $2`):";$(SED) -e 's@^@#   @' $2
+endef
+
 #
-# Variables used by docs target
+# Temporary directory for javadoc creation
 #
-DOCSTMPDIR          = $(TEMPDIR)/doctmp
+DOCSTMPDIR = $(TEMPDIR)/doctmp
 
+#
+# Different api directories created from root directory
+#
+COREAPI_DOCSDIR   = $(DOCSDIR)/api
+JDK_API_DOCSDIR   = $(DOCSDIR)/jdk/api
+JRE_API_DOCSDIR   = $(DOCSDIR)/jre/api
+PLATFORM_DOCSDIR  = $(DOCSDIR)/platform
+
+# The non-core api javadocs need to be able to access the root of the core
+#   api directory, so for jdk/api or jre/api to get to the core api/
+#   directory we would use this:
+JDKJRE2COREAPI    = ../../api
+
+# Common bottom argument
+define CommonBottom # year
+<font size=\"-1\"><p> $(call CopyrightLine,,$1,)</font>
+endef
+
+# Common trademark bottom argument (Not sure why this is used sometimes)
+define CommonTrademarkBottom # year
+<font size=\"-1\">\
+$(BUG_SUBMIT_LINE)<br>$(JAVA_TRADEMARK_LINE)<br>\
+$(call CopyrightLine,,$1,$(COMPANY_ADDRESS))\
+</font>
+endef
+
+# Core api bottom argument (with special sauce)
+COREAPI_BOTTOM = <font size=\"-1\"> $(BUG_SUBMIT_LINE)\
+<br>For further API reference and developer documentation, \
+see <a href=\"$(DEV_DOCS_URL)\" target=\"_blank\">Java SE Documentation</a>. \
+That documentation contains more detailed, developer-targeted descriptions, \
+with conceptual overviews, definitions of terms, workarounds, \
+and working code examples.<p>\
+$(call CopyrightLine,$(COPYRIGHT_URL),$(FIRST_COPYRIGHT_YEAR),)\
+</font>
+
+# Common javadoc options used by all
 COMMON_JAVADOCFLAGS =					\
-		$(NO_PROPRIETARY_API_WARNINGS)		\
+                $(NO_PROPRIETARY_API_WARNINGS)          \
 		-source 1.5				\
 		-quiet					\
                 -use					\
                 -keywords				\
-		$(JAVADOC_VM_MEMORY_FLAGS)		\
 		$(ADDITIONAL_JAVADOCFLAGS)
 ADDITIONAL_JAVADOCFLAGS =
 
-CORE_JAVADOCFLAGS  = $(COMMON_JAVADOCFLAGS)		\
-		$(TAGS)					\
-		-encoding ISO-8859-1			\
-		-splitIndex				\
-		-doctitle $(DOCTITLE_SWITCH)		\
-		-windowtitle $(WINDOWTITLE_SWITCH)	\
-		-header $(HEADER_SWITCH)		\
-		$(TOPOPTION) 				\
-		-bottom $(JAVADOCBOTTOM_SWITCH)		\
-		$(OVERVIEW_OPTION)
-
-DRAFT = '<br><strong>DRAFT&nbsp;'$(MILESTONE)-$(BUILD_NUMBER)'</strong>'
-THIS_YEAR := $(shell $(DATE) | $(SED) -e 's/  / /g' | $(CUT) -d' ' -f6)
-TRADEMARK = &\#x2122;
-
-IGNORED_TAGS =	beaninfo revised since.unbundled spec specdefault Note ToDo
-
-JLS3_URL = http://java.sun.com/docs/books/jls/
-JLS3_CITE = <a href="$(JLS3_URL)"> \
-		The Java Language Specification, Third Edition</a>
-TAG_JLS3 = -tag 'jls3:a:See <cite>$(JLS3_CITE)</cite>:'
-
-TAGS = $(IGNORED_TAGS:%=-tag %:X) $(TAG_JLS3)
-
-ifeq ($(MILESTONE), fcs)
-    DOCTITLE_SWITCH = $(JAVADOCTITLE)
-    WINDOWTITLE_SWITCH = $(JAVADOCWINDOWTITLE)
-    HEADER_SWITCH = $(JAVADOCHEADER)
-    TOPOPTION=
-    JAVADOCBOTTOM_SWITCH= $(JAVADOCBOTTOM)
-    OVERVIEW_OPTION = -overview $(JAVADOCOVERVIEW)
-else
-    DOCTITLE_SWITCH = $(JAVADOCTITLE_EARLYACCESS)$(DRAFT)
-    WINDOWTITLE_SWITCH = $(JAVADOCWINDOWTITLE)" $(BUILD_NUMBER)"
-    HEADER_SWITCH = $(JAVADOCHEADER)$(DRAFT)
-    JAVADOCBOTTOM_SWITCH= $(JAVADOCBOTTOM_EARLYACCESS)
-    TOPOPTION= -top $(JAVADOCTOP_EARLYACCESS)
-    OVERVIEW_OPTION =
+# Draft used for non-fcs documents
+JDK_IS_FCS = false
+DRAFT_HEADER =
+ifeq ($(JDK_MINOR_VERSION),5)
+  JDK_IS_FCS = true
+endif
+ifeq ($(JDK_MINOR_VERSION),6)
+  JDK_IS_FCS = true
+endif
+ifeq ($(JDK_IS_FCS),false)
+  ifneq ($(MILESTONE), fcs)
+    DRAFT_HEADER = <br><strong>DRAFT&nbsp;$(MILESTONE)-$(BUILD_NUMBER)</strong>
+    DRAFT_BOTTOM = <br><strong>DRAFT&nbsp;$(MILESTONE)-$(BUILD_NUMBER)</strong>
+    DRAFT_WINTITLE = $(BUILD_NUMBER)
+    # Early access top text (not used in FCS releases)
+    COREAPI_TOP_EARLYACCESS = \
+<div style=\"background-color: \#EEEEEE\"> \
+<div style=\"padding: 6px; margin-top: 2px; margin-bottom: 6px; \
+margin-left: 6px; margin-right: 6px; text-align: justify; \
+font-size: 80%; font-family: Helvetica, Arial, sans-serif; \
+font-weight: normal;\"> \
+Please note that the specifications and other information \
+contained herein are not final and are subject to change. \
+The information is being made available to you solely for purpose of \
+evaluation. \
+</div> </div>
+  endif
 endif
 
-JAVADOCTITLE  = 'Java$(TRADEMARK) Platform, Standard Edition $(JDK_MINOR_VERSION)<br>API Specification'
-JAVADOCWINDOWTITLE  = 'Java Platform SE $(JDK_MINOR_VERSION)'
-JAVADOCHEADER = '<strong>Java$(TRADEMARK)&nbsp;Platform<br>Standard&nbsp;Ed.&nbsp;$(JDK_MINOR_VERSION)</strong>'
-JAVADOCBOTTOM = '<font size="-1"><a href="http://bugs.sun.com/services/bugreport/index.jsp">Submit a bug or feature</a><br>For further API reference and developer documentation, see <a href="{@docroot}/../../webnotes/devdocs-vs-specs.html">Java SE Developer Documentation</a>. That documentation contains more detailed, developer-targeted descriptions, with conceptual overviews, definitions of terms, workarounds, and working code examples. <p>Copyright $(THIS_YEAR) Sun Microsystems, Inc. All Rights Reserved. Use is subject to <a href="{@docroot}/../legal/license.html">license terms</a>. Also see the <a href="http://java.sun.com/docs/redist.html">documentation redistribution policy</a>.</font>'
-JAVADOCOVERVIEW = $(SHARE_SRC)/classes/overview-core.html
-
-#
-# Early access top and bottom text (for snapshots, beta and rc)
-#
-JAVADOCTOP_EARLYACCESS = '<div style="background-color: \#EEEEEE"> <div style="padding: 6px; margin-top: 2px; margin-bottom: 6px; margin-left: 6px; margin-right: 6px; text-align: justify; font-size: 80%; font-family: Helvetica, Arial, sans-serif; font-weight: normal;"> Please note that this documentation is not final and is subject to change. </div> </div>'
-JAVADOCBOTTOM_EARLYACCESS = '<font size="-1"><a href="http://bugs.sun.com/services/bugreport/index.jsp">Submit a bug or feature</a> <p>Copyright $(THIS_YEAR) Sun Microsystems, Inc. All Rights Reserved. Use is subject to <a href="{@docroot}/../legal/license.html">license terms</a>.</font>'
-JAVADOCTITLE_EARLYACCESS = $(subst Specification,Documentation,$(JAVADOCTITLE))
-
-#
-# Variables used by domapidocs target
-#
-
-DOMAPI_JAVADOCFLAGS = $(COMMON_JAVADOCFLAGS)		      \
-		    -encoding ascii			      \
-                    -splitIndex                               \
-                    -doctitle $(DOMAPI_JAVADOCTITLE)          \
-                    -windowtitle $(DOMAPI_JAVADOCWINDOWTITLE) \
-                    -header $(DOMAPI_JAVADOCHEADER)           \
-                    -bottom $(DOMAPI_JAVADOCBOTTOM)           \
-                    -group $(DOMAPI_GROUPNAME) $(DOMAPI_REGEXP)
-DOMAPI_JAVADOCTITLE  = 'Common DOM API'
-DOMAPI_JAVADOCWINDOWTITLE  = 'Common DOM API'
-DOMAPI_JAVADOCHEADER = '<strong>Common DOM API</strong>'
-DOMAPI_JAVADOCBOTTOM = '<font size="-1"><a href="http://bugs.sun.com/services/bugreport/index.jsp">Submit a bug or feature</a><br>Java is a trademark or registered trademark of Sun Microsystems, Inc. in the US and other countries.<br>Copyright $(THIS_YEAR) Sun Microsystems, Inc. 4150 Network Circle<br>Santa Clara, California, 95054, U.S.A.  All Rights Reserved.</font>'
-DOMAPI_GROUPNAME = "Packages"
-DOMAPI_REGEXP = "com.sun.java.browser.dom:org.w3c.dom*"
-# DOMAPI_PKGS is located in NON_CORE_PKGS.gmk
-
-#
-# Variables used by mirrordocs target
-#
-
-MIRROR_JAVADOCFLAGS = $(COMMON_JAVADOCFLAGS)		        \
-                    -encoding ascii			        \
-                    -doctitle $(MIRROR_JAVADOCTITLE)            \
-                    -windowtitle $(MIRROR_JAVADOCWINDOWTITLE)   \
-                    -header $(MIRROR_JAVADOCHEADER)             \
-                    -bottom $(MIRROR_JAVADOCBOTTOM)             \
-                    -group $(MIRROR_GROUPNAME) $(MIRROR_REGEXP) \
-                    -overview $(MIRROR_OVERVIEW)
-MIRROR_JAVADOCTITLE = 'Mirror API'
-MIRROR_JAVADOCWINDOWTITLE = 'Mirror API'
-MIRROR_JAVADOCHEADER = '<strong>Mirror API</strong>'
-MIRROR_JAVADOCBOTTOM = '<font size="-1"><a href="http://bugs.sun.com/services/bugreport/index.jsp">Report a bug or request a feature.</a><br>Copyright $(THIS_YEAR) Sun Microsystems, Inc. All Rights Reserved. Use is subject to license terms.</font>'
-MIRROR_GROUPNAME = "Packages"
-MIRROR_OVERVIEW = $(IMPORTSRCDIR)/com/sun/mirror/overview.html
-MIRROR_REGEXP = "com.sun.mirror.*"
-MIRROR_DESTDIR = $(DOCSDIR)/jdk/api/apt/mirror
-MIRROR_LINKOPT = -linkoffline ../../../../api $(DOCSDIR)/api/
-# MIRROR_PKGS is located in NON_CORE_PKGS.gmk
-
-#
-# Variables used by docletapidocs target
-#
-
-DOCLETAPI_JAVADOCFLAGS = $(COMMON_JAVADOCFLAGS)			 \
-		    -breakiterator				 \
-		    -encoding ascii			         \
-                    -doctitle $(DOCLETAPI_JAVADOCTITLE)          \
-                    -windowtitle $(DOCLETAPI_JAVADOCWINDOWTITLE) \
-                    -header $(DOCLETAPI_JAVADOCHEADER)           \
-                    -bottom $(DOCLETAPI_JAVADOCBOTTOM)           \
-                    -group $(DOCLETAPI_GROUPNAME) $(DOCLETAPI_REGEXP)
-DOCLETAPI_JAVADOCTITLE  = 'Doclet API'
-DOCLETAPI_JAVADOCWINDOWTITLE  = 'Doclet API'
-DOCLETAPI_JAVADOCHEADER = '<strong>Doclet API</strong>'
-DOCLETAPI_JAVADOCBOTTOM = '<font size="-1"><a href="http://bugs.sun.com/services/bugreport/index.jsp">Submit a bug or feature</a><br>Java is a trademark or registered trademark of Sun Microsystems, Inc. in the US and other countries.<br>Copyright 1993-$(THIS_YEAR) Sun Microsystems, Inc. 4150 Network Circle<br>Santa Clara, California, 95054, U.S.A.  All Rights Reserved.</font>'
-DOCLETAPI_GROUPNAME = "Packages"
-DOCLETAPI_REGEXP = "com.sun.javadoc"
-DOCLETAPI_LINKOPT = -linkoffline ../../../../api $(DOCSDIR)/api/
-# DOCLETAPI_PKGS is located in NON_CORE_PKGS.gmk
-
-#
-# Variables used by tagletapidocs target
-#
-
-TAGLETAPI_JAVADOCFLAGS = $(COMMON_JAVADOCFLAGS)			\
-		    -encoding ascii			        \
-                    -nonavbar                                   \
-                    -noindex                                    \
-                    -bottom $(TAGLETAPI_JAVADOCBOTTOM)
-TAGLETAPI_JAVADOCBOTTOM = '<font size="-1"><a href="http://bugs.sun.com/services/bugreport/index.jsp">Submit a bug or feature</a><br>Java is a trademark or registered trademark of Sun Microsystems, Inc. in the US and other countries.<br>Copyright 1993-$(THIS_YEAR) Sun Microsystems, Inc. 4150 Network Circle<br>Santa Clara, California, 95054, U.S.A.  All Rights Reserved.</font>'
-# TAGLETAPI_FILE is located in NON_CORE_PKGS.gmk
-
-#
-# Variables used by jdi target
-#
-
-JPDA_SOURCEPATH  = $(TOPDIR)/src/share/classes
-
-JDI_JAVADOCFLAGS = $(COMMON_JAVADOCFLAGS)			 \
-		   -encoding ascii			         \
-                   -nodeprecatedlist                             \
-                   -d $(DOCSDIR)/jdk/api/jpda/jdi                  \
-                   -sourcepath $(JPDA_SOURCEPATH)                \
-                   -windowtitle $(JDI_WINDOWTITLE)               \
-                   -doctitle $(JDI_DOCTITLE)                     \
-                   -header $(JDI_HEADER)                         \
-                   -linkoffline ../../../../api $(DOCSDIR)/api/     \
-                   -overview $(JPDA_SOURCEPATH)/jdi-overview.html
-JDI_WINDOWTITLE = "Java Debug Interface"
-JDI_DOCTITLE    = "Java$(TRADEMARK) Debug Interface"
-JDI_HEADER      = "Java Debug Interface"
-# JDI_PKGS is located in NON_CORE_PKGS.gmk
-
-# Variables used by security components
-SECURITYAPI_JAVADOCBOTTOM = '<font size="-1"><a href="http://bugs.sun.com/services/bugreport/index.jsp">Report a bug or request a feature.</a><br>Copyright $(THIS_YEAR) Sun Microsystems, Inc. All Rights Reserved. Use is subject to license terms.</font>'
-
-#
-# Variables used by JAAS target
-#
-# NOTE: Quotes are required around sourcepath argument only on Windows.  Otherwise,
-#       you get "No packages or classes specified." due to $(CLASSPATH_SEPARATOR)
-#       being interpreted as an end of command (newline)
-
-JAAS_SOURCEPATH  = "$(TOPDIR)/src/share/classes$(CLASSPATH_SEPARATOR)$(TOPDIR)/src/solaris/classes$(CLASSPATH_SEPARATOR)$(TOPDIR)/src/windows/classes$(CLASSPATH_SEPARATOR)$(TOPDIR)/src/linux/classes"
-JAAS_DOCDIR	 = $(DOCSDIR)/jre/api/security/jaas/spec
-JAAS_JAVADOCFLAGS = $(COMMON_JAVADOCFLAGS)			 \
-		   -encoding ascii			         \
-                   -nodeprecatedlist                             \
-                   -d $(JAAS_DOCDIR)				 \
-                   -sourcepath $(JAAS_SOURCEPATH)                \
-                   -windowtitle $(JAAS_WINDOWTITLE)              \
-                   -doctitle $(JAAS_DOCTITLE)                    \
-                   -header $(JAAS_JAVADOCHEADER)                 \
-                   -bottom $(SECURITYAPI_JAVADOCBOTTOM)                      \
-                   -linkoffline ../../../../../api $(DOCSDIR)/api/	 \
-                   -overview $(TOPDIR)/src/share/classes/com/sun/security/auth/jaas-overview.html
-JAAS_WINDOWTITLE = "Java Authentication and Authorization Service "
-JAAS_DOCTITLE    = "Java$(TRADEMARK) Authentication and Authorization Service"
-JAAS_JAVADOCHEADER      = "JAAS"
-# JAAS_PKGS is located in NON_CORE_PKGS.gmk
-
-#
-# Variables used by JGSS target
-#
-
-JGSS_SOURCEPATH  = $(TOPDIR)/src/share/classes
-JGSS_DOCDIR	 = $(DOCSDIR)/jre/api/security/jgss/spec
-
-JGSS_JAVADOCFLAGS = $(COMMON_JAVADOCFLAGS)			\
-		   -encoding ascii			        \
-                   -nodeprecatedlist                            \
-                   -d $(JGSS_DOCDIR)				\
-                   -sourcepath $(JGSS_SOURCEPATH)               \
-                   -windowtitle $(JGSS_WINDOWTITLE)             \
-                   -doctitle $(JGSS_DOCTITLE)                   \
-                   -header $(JGSS_JAVADOCHEADER)                \
-                   -bottom $(SECURITYAPI_JAVADOCBOTTOM)                      \
-                   -linkoffline ../../../../../api $(DOCSDIR)/api/ \
-                   -overview $(JGSS_SOURCEPATH)/com/sun/security/jgss/jgss-overview.html
-
-JGSS_WINDOWTITLE = "Java GSS-API Utilities "
-JGSS_DOCTITLE    = "Java$(TRADEMARK) GSS-API Utilities"
-JGSS_JAVADOCHEADER      = "Java GSS-API Utilities"
-# JGSS_PKGS is located in NON_CORE_PKGS.gmk
-
-#
-# Variables used by SMARTCARDIO target
-#
-
-SMARTCARDIO_SOURCEPATH  = $(TOPDIR)/src/share/classes
-SMARTCARDIO_DOCDIR	 = $(DOCSDIR)/jre/api/security/smartcardio/spec
-
-SMARTCARDIO_JAVADOCFLAGS = $(COMMON_JAVADOCFLAGS)			\
-		   -encoding ascii			        \
-                   -nodeprecatedlist                            \
-                   -d $(SMARTCARDIO_DOCDIR)				\
-                   -sourcepath $(SMARTCARDIO_SOURCEPATH)               \
-                   -windowtitle $(SMARTCARDIO_WINDOWTITLE)             \
-                   -doctitle $(SMARTCARDIO_DOCTITLE)                   \
-                   -header $(SMARTCARDIO_JAVADOCHEADER)                \
-                   -bottom $(SECURITYAPI_JAVADOCBOTTOM)                      \
-                   -linkoffline ../../../../../api $(DOCSDIR)/api/
-
-SMARTCARDIO_WINDOWTITLE = "Java Smart Card I/O"
-SMARTCARDIO_DOCTITLE    = "Java$(TRADEMARK) Smart Card I/O"
-SMARTCARDIO_JAVADOCHEADER      = "Java Smart Card I/O"
-# SMARTCARDIO_PKGS is located in NON_CORE_PKGS.gmk
-
-#
-# Variables used by TRACING target
-#
-
-TRACING_SOURCEPATH  = $(TOPDIR)/src/share/classes
-TRACING_DOCDIR	 = $(DOCSDIR)/jre/api/tracing
-
-TRACING_JAVADOCFLAGS = $(COMMON_JAVADOCFLAGS)			    \
-		   -encoding ascii			            \
-                   -nodeprecatedlist                                \
-                   -d $(TRACING_DOCDIR)				    \
-                   -sourcepath $(TRACING_SOURCEPATH)                \
-                   -windowtitle $(TRACING_WINDOWTITLE)              \
-                   -doctitle $(TRACING_DOCTITLE)                    \
-                   -header $(TRACING_JAVADOCHEADER)                 \
-                   -linkoffline ../../../../../api $(DOCSDIR)/api/
-
-TRACING_WINDOWTITLE = "Tracing"
-TRACING_DOCTITLE    = "Java$(TRADEMARK) Platform Tracing"
-TRACING_JAVADOCHEADER      = "Platform Tracing"
-# TRACING_PKGS is located in NON_CORE_PKGS.gmk
-
-#
-# Variables used by HTTPSERVER target
-#
-
-HTTPSERVER_SOURCEPATH  = $(TOPDIR)/src/share/classes
-HTTPSERVER_DOCDIR	 = $(DOCSDIR)/jre/api/net/httpserver/spec
-
-HTTPSERVER_JAVADOCFLAGS = $(COMMON_JAVADOCFLAGS)			\
-		   -encoding ascii			        \
-                   -nodeprecatedlist                            \
-                   -d $(HTTPSERVER_DOCDIR)				\
-                   -sourcepath $(HTTPSERVER_SOURCEPATH)               \
-                   -windowtitle $(HTTPSERVER_WINDOWTITLE)             \
-                   -doctitle $(HTTPSERVER_DOCTITLE)                   \
-                   -header $(HTTPSERVER_JAVADOCHEADER)                \
-                   -linkoffline ../../../../../api $(DOCSDIR)/api/
-
-HTTPSERVER_WINDOWTITLE = "Java HTTP Server"
-HTTPSERVER_DOCTITLE    = "Java$(TRADEMARK) HTTP Server"
-HTTPSERVER_JAVADOCHEADER      = "Java HTTP Server"
-# HTTPSERVER_PKGS is located in NON_CORE_PKGS.gmk
-
-#
-# Variables used by sctp target
-#
-
-SCTPAPI_SOURCEPATH  = $(TOPDIR)/src/share/classes
-SCTPAPI_DOCDIR   = $(DOCSDIR)/jre/api/nio/sctp/spec
-
-SCTPAPI_JAVADOCFLAGS = $(COMMON_JAVADOCFLAGS)                           \
-                   -encoding ascii                                      \
-                   -nodeprecatedlist                                    \
-                   -d $(SCTPAPI_DOCDIR)                                 \
-                   -sourcepath $(SCTPAPI_SOURCEPATH)                    \
-                   -windowtitle $(SCTPAPI_WINDOWTITLE)                  \
-                   -doctitle $(SCTPAPI_DOCTITLE)                        \
-                   -header $(SCTPAPI_JAVADOCHEADER)                     \
-                   -bottom $(SCTPAPI_JAVADOCBOTTOM)			\
-                   -linkoffline ../../../../../api $(DOCSDIR)/api/
-
-SCTPAPI_WINDOWTITLE = "SCTP API"
-SCTPAPI_DOCTITLE    = "SCTP API"
-SCTPAPI_JAVADOCHEADER      = "SCTP API"
-SCTPAPI_JAVADOCBOTTOM = '<font size="-1"><a href="http://bugs.sun.com/services/bugreport/index.jsp">Report a bug or request a feature.</a><br>Copyright $(THIS_YEAR) Sun Microsystems, Inc. All Rights Reserved. Use is subject to license terms.</font>'
-# SCTPAPI_PKGS is located in NON_CORE_PKGS.gmk
-
-#
-# Variables used by jvmti target
-#
-JVMTI_DOCS_SUBDIR = platform/jvmti
-JVMTI_HTML        = $(HOTSPOT_DOCS_IMPORT_PATH)/$(JVMTI_DOCS_SUBDIR)/jvmti.html
-
-#
-# Variables used by mgmt target
-#
-MGMT_DOCDIR	   = $(DOCSDIR)/jre/api/management/
-MGMT_EXT_DIR	   = $(MGMT_DOCDIR)/extension
-MGMT_SOURCEPATH    = $(TOPDIR)/src/share/classes
-JVM_MIB_NAME       = JVM-MANAGEMENT-MIB.mib
-JVM_MIB_SRC        = $(CLOSED_SRC)/share/classes/sun/management/snmp/$(JVM_MIB_NAME)
-
-ifdef OPENJDK
-   COPY-MIB-TARGET =
-else
-   COPY-MIB-TARGET = copy-mib
-endif
-MGMT_JAVADOCFLAGS  = $(COMMON_JAVADOCFLAGS)			   \
-		     -encoding ascii			           \
-                     -nodeprecatedlist                             \
-                     -d $(MGMT_EXT_DIR) 		  	   \
-                     -sourcepath $(MGMT_SOURCEPATH)                \
-                     -windowtitle $(MGMT_WINDOWTITLE)              \
-                     -doctitle $(MGMT_DOCTITLE)                    \
-                     -header $(MGMT_HEADER)                        \
-		     -linkoffline ../../../../api $(DOCSDIR)/api/  \
-                     -overview $(MGMT_SOURCEPATH)/com/sun/management/mgmt-overview.html
-MGMT_WINDOWTITLE = "Monitoring and Management Interface for the Java Platform"
-MGMT_DOCTITLE    = "Monitoring and Management Interface for the Java$(TRADEMARK) Platform"
-MGMT_HEADER      = "Monitoring and Management Interface for the Java Platform"
-# MGMT_PKGS is located in NON_CORE_PKGS.gmk
-
-#
-# Variables used by attach target
-#
-
-ATTACH_SOURCEPATH  = $(TOPDIR)/src/share/classes
-ATTACH_DOCDIR      = $(DOCSDIR)/jdk/api/attach/spec
-ATTACH_JAVADOCFLAGS = $(COMMON_JAVADOCFLAGS)                        	\
-		   -encoding ascii                               	\
-                   -nodeprecatedlist                             	\
-		   -d $(ATTACH_DOCDIR)					\
-                   -sourcepath $(ATTACH_SOURCEPATH)                	\
-                   -windowtitle $(ATTACH_WINDOWTITLE)               	\
-                   -doctitle $(ATTACH_DOCTITLE)                     	\
-                   -header $(ATTACH_HEADER)                         	\
-		   -linkoffline ../../../../api $(DOCSDIR)/api/
-ATTACH_WINDOWTITLE = "Attach API"
-ATTACH_DOCTITLE    = "Attach API"
-ATTACH_HEADER      = "Attach API"
-# ATTACH_PKGS is located in NON_CORE_PKGS.gmk
-
-#
-# Variables used by jconsole target
-#
-
-JCONSOLE_SOURCEPATH  = $(TOPDIR)/src/share/classes
-JCONSOLE_DOCDIR      = $(DOCSDIR)/jdk/api/jconsole/spec
-JCONSOLE_JAVADOCFLAGS = $(COMMON_JAVADOCFLAGS)                        	\
-		   -encoding ascii                               	\
-                   -nodeprecatedlist                             	\
-		   -d $(JCONSOLE_DOCDIR)				\
-                   -sourcepath $(JCONSOLE_SOURCEPATH)                	\
-                   -windowtitle $(JCONSOLE_WINDOWTITLE)               	\
-                   -doctitle $(JCONSOLE_DOCTITLE)                     	\
-                   -header $(JCONSOLE_HEADER)                         	\
-		   -linkoffline ../../../../api $(DOCSDIR)/api/
-JCONSOLE_WINDOWTITLE = "JConsole API"
-JCONSOLE_DOCTITLE    = "JConsole API"
-JCONSOLE_HEADER      = "JConsole API"
-# JCONSOLE_PKGS is located in NON_CORE_PKGS.gmk
-
-#
-# Variables used by treeapidocs target
-#
-
-TREEAPI_JAVADOCFLAGS = $(COMMON_JAVADOCFLAGS)		        \
-                    -encoding ascii			        \
-                    -doctitle $(TREEAPI_JAVADOCTITLE)            \
-                    -windowtitle $(TREEAPI_JAVADOCWINDOWTITLE)   \
-                    -header $(TREEAPI_JAVADOCHEADER)             \
-                    -bottom $(TREEAPI_JAVADOCBOTTOM)             \
-                    -group $(TREEAPI_GROUPNAME) $(TREEAPI_REGEXP) 
-#
-#	            -overview $(TREEAPI_OVERVIEW)
-#
-TREEAPI_JAVADOCTITLE = 'Compiler Tree API'
-TREEAPI_JAVADOCWINDOWTITLE = 'Compiler Tree API'
-TREEAPI_JAVADOCHEADER = '<strong>Compiler Tree API</strong>'
-TREEAPI_JAVADOCBOTTOM = '<font size="-1"><a href="http://bugs.sun.com/services/bugreport/index.jsp">Report a bug or request a feature.</a><br>Copyright $(THIS_YEAR) Sun Microsystems, Inc. All Rights Reserved. Use is subject to license terms.</font>'
-TREEAPI_GROUPNAME = "Packages"
-TREEAPI_OVERVIEW = $(SHARE_SRC)/classes/com/sun/source/overview.html
-TREEAPI_REGEXP = "com.sun.source.*"
-TREEAPI_DESTDIR = $(DOCSDIR)/jdk/api/javac/tree
-TREEAPI_LINKOPT = -linkoffline ../../../../api $(DOCSDIR)/api/
-# TREEAPI_PKGS is located in NON_CORE_PKGS.gmk
-
-#
-# Path where javadoc should find source files for release docs
-#
-RELEASEDOCS_SRCPATH = "$(SHARE_SRC)/classes$(CLASSPATH_SEPARATOR)$(PLATFORM_SRC)/classes$(CLASSPATH_SEPARATOR)$(GENSRCDIR)$(CLASSPATH_SEPARATOR)$(SHARE_SRC)/doc/stub$(CLASSPATH_SEPARATOR)$(CLOSED_SRC)/share/classes$(CLASSPATH_SEPARATOR)$(IMPORTSRCDIR)"
+#################################################################
 
 #
 # CORE_PKGS environment variable has been moved to the following file
@@ -463,31 +234,14 @@
 #
 include NON_CORE_PKGS.gmk
 
-# Targets for all APIs other than the core platform APIs
-ALL_OTHER_TARGETS = \
-    mirrordocs \
-    docletapidocs \
-    tagletapidocs \
-    domapidocs \
-    jpdadocs \
-    jaasdocs \
-    jgssdocs \
-    smartcardiodocs \
-    tracingdocs \
-    httpserverdocs  \
-    sctpdocs \
-    mgmtdocs \
-    attachdocs \
-    jconsoledocs \
-    treeapidocs
+#################################################################
 
-.PHONY: all docs
+#
+# Default target is same as docs target, create core api and all others it can
+#
+
 all docs: coredocs otherdocs
 
-.PHONY: otherdocs
-otherdocs: ${ALL_OTHER_TARGETS}
-
-
 #################################################################
 # Production Targets -- USE THESE TARGETS WHEN:
 #    a) You're generating docs outside of release engineering's
@@ -496,9 +250,9 @@
 #       the downloaded doc bundle.
 #
 # See:  Notes.html#releaseTargets
-# Note: Spaces preceed ifdef/ifndef indents. Tabs preceed target commands (!)
+# Note: Spaces precede ifdef/ifndef indents. Tabs precede target commands (!)
 #
-.PHONY: sanitycheckcoredocs
+
 sanitycheckcoredocs:
 	@$(ECHO) ""
 	@$(ECHO) "Building core api docs with these values:"
@@ -512,199 +266,942 @@
 	exit 1
   endif
 
+#############################################################
+#
+# coredocs
+#
+COREAPI_DOCTITLE  = Java$(TRADEMARK) Platform, Standard Edition \
+$(JDK_MINOR_VERSION)<br>API Specification
+COREAPI_WINDOWTITLE  = Java Platform SE $(JDK_MINOR_VERSION)
+COREAPI_HEADER = \
+<strong>Java$(TRADEMARK)&nbsp;Platform<br>Standard&nbsp;Ed.&nbsp;$(JDK_MINOR_VERSION)</strong>
+
+# Ignored tags
+IGNORED_TAGS =	beaninfo revised since.unbundled spec specdefault Note ToDo
+
+# Java language specification cite
+JLS3_CITE = <a href=\"$(JLS3_URL)\"> \
+		The Java Language Specification, Third Edition</a>
+TAG_JLS3 = -tag 'jls3:a:See <cite>$(JLS3_CITE)</cite>:'
+
+TAGS = $(IGNORED_TAGS:%=-tag %:X) $(TAG_JLS3)
+
+# Overview file for core apis
+COREAPI_OVERVIEW = $(SHARE_SRC)/classes/overview-core.html
+
+# The index.html, options, and packages files
+COREAPI_INDEX_FILE    = $(COREAPI_DOCSDIR)/index.html
+COREAPI_OPTIONS_FILE  = $(DOCSTMPDIR)/coredocs.options
+COREAPI_PACKAGES_FILE = $(DOCSTMPDIR)/coredocs.packages
+
+coredocs: $(COREAPI_INDEX_FILE)
+
+# Set relative location to core api document root
+$(COREAPI_INDEX_FILE): GET2DOCSDIR=..
+
+# Run javadoc if the index file is out of date or missing
+$(COREAPI_INDEX_FILE): $(COREAPI_OPTIONS_FILE) $(COREAPI_PACKAGES_FILE)
+	$(prep-javadoc)
+	$(call JavadocSummary,$(COREAPI_OPTIONS_FILE),$(COREAPI_PACKAGES_FILE))
+	$(JAVADOC_CMD) $(JAVADOC_VM_MEMORY_FLAGS) -d $(@D) \
+	  @$(COREAPI_OPTIONS_FILE) @$(COREAPI_PACKAGES_FILE)
+
+# Create file with javadoc options in it
+$(COREAPI_OPTIONS_FILE): $(COREAPI_OVERVIEW)
+	$(prep-target)
+	@($(ECHO) "$(COMMON_JAVADOCFLAGS)"				; \
+	  $(ECHO) "-sourcepath \"$(RELEASEDOCS_SOURCEPATH)\""		; \
+	  $(ECHO) "$(TAGS)"						; \
+	  $(ECHO) "-encoding ISO-8859-1"				; \
+	  $(ECHO) "-splitIndex"						; \
+	  $(ECHO) "-overview $(COREAPI_OVERVIEW)" 			; \
+	  $(ECHO) "-doctitle '$(COREAPI_DOCTITLE)'"			; \
+	  $(ECHO) "-windowtitle '$(COREAPI_WINDOWTITLE) $(DRAFT_WINTITLE)'";\
+	  $(ECHO) "-header '$(COREAPI_HEADER)$(DRAFT_HEADER)'"		; \
+	  $(ECHO) "-bottom '$(COREAPI_BOTTOM)$(DRAFT_BOTTOM)'"		; \
+        ) >> $@
+ifdef COREAPI_TOP_EARLYACCESS
+	@$(ECHO) "-top '$(COREAPI_TOP_EARLYACCESS)'" >> $@
+endif
+
+# Create a file with the package names in it
+$(COREAPI_PACKAGES_FILE): $(DIRECTORY_CACHE) $(call PackageDependencies,$(CORE_PKGS))
+	$(prep-target)
+	$(call PackageFilter,$(CORE_PKGS))
+
+#############################################################
+#
+# mirrordocs
+#
+
+# Part of langtools
+ifdef LANGTOOLS_DIST
+  ALL_OTHER_TARGETS += mirrordocs
+endif
+
+MIRROR_DOCDIR      := $(JDK_API_DOCSDIR)/apt/mirror
+MIRROR2COREAPI     := ../../$(JDKJRE2COREAPI)
+MIRROR_DOCTITLE    := Mirror API
+MIRROR_WINDOWTITLE := Mirror API
+MIRROR_HEADER      := <strong>Mirror API</strong>
+MIRROR_BOTTOM      := $(call CommonBottom,$(MIRROR_FIRST_COPYRIGHT_YEAR))
+MIRROR_GROUPNAME   := Packages
+MIRROR_OVERVIEW    := $(IMPORTSRCDIR)/com/sun/mirror/overview.html
+MIRROR_REGEXP      := com.sun.mirror.*
+# MIRROR_PKGS is located in NON_CORE_PKGS.gmk
+
+# The index.html, options, and packages files
+MIRROR_INDEX_FILE    = $(MIRROR_DOCDIR)/index.html
+MIRROR_OPTIONS_FILE  = $(DOCSTMPDIR)/mirror.options
+MIRROR_PACKAGES_FILE = $(DOCSTMPDIR)/mirror.packages
+
+mirrordocs: $(MIRROR_INDEX_FILE)
+
+# Set relative location to core api document root
+$(MIRROR_INDEX_FILE): GET2DOCSDIR=$(MIRROR2COREAPI)/..
+
+# Run javadoc if the index file is out of date or missing
+$(MIRROR_INDEX_FILE): $(MIRROR_OPTIONS_FILE) $(MIRROR_PACKAGES_FILE)
+	$(prep-javadoc)
+	$(call JavadocSummary,$(MIRROR_OPTIONS_FILE),$(MIRROR_PACKAGES_FILE))
+	$(JAVADOC_CMD) $(JAVADOC_VM_MEMORY_FLAGS) -d $(@D) \
+	  @$(MIRROR_OPTIONS_FILE) @$(MIRROR_PACKAGES_FILE)
+
+# Create file with javadoc options in it
+$(MIRROR_OPTIONS_FILE): $(MIRROR_OVERVIEW)
+	$(prep-target)
+	@($(ECHO) "$(COMMON_JAVADOCFLAGS)"				; \
+	  $(ECHO) "-sourcepath \"$(RELEASEDOCS_SOURCEPATH)\""		; \
+	  $(ECHO) "-encoding ascii"					; \
+	  $(ECHO) "-overview $(MIRROR_OVERVIEW)" 			; \
+	  $(ECHO) "-doctitle '$(MIRROR_DOCTITLE)'"			; \
+	  $(ECHO) "-windowtitle '$(MIRROR_WINDOWTITLE) $(DRAFT_WINTITLE)'";\
+	  $(ECHO) "-header '$(MIRROR_HEADER)$(DRAFT_HEADER)'"		; \
+	  $(ECHO) "-bottom '$(MIRROR_BOTTOM)$(DRAFT_BOTTOM)'"		; \
+	  $(ECHO) "-group $(MIRROR_GROUPNAME) $(MIRROR_REGEXP)"		; \
+	  $(ECHO) "-linkoffline $(MIRROR2COREAPI) $(COREAPI_DOCSDIR)/"; \
+        ) >> $@
+
+# Create a file with the package names in it
+$(MIRROR_PACKAGES_FILE): $(DIRECTORY_CACHE) $(call PackageDependencies,$(MIRROR_PKGS))
+	$(prep-target)
+	$(call PackageFilter,$(MIRROR_PKGS))
+
+#############################################################
+#
+# docletapidocs
+#
+
+# Part of langtools
+ifdef LANGTOOLS_DIST
+  ALL_OTHER_TARGETS += docletapidocs
+endif
+
+DOCLETAPI_DOCDIR       := $(JDK_API_DOCSDIR)/javadoc/doclet
+DOCLETAPI2COREAPI      := ../../$(JDKJRE2COREAPI)
+DOCLETAPI_DOCTITLE     := Doclet API
+DOCLETAPI_WINDOWTITLE  := Doclet API
+DOCLETAPI_HEADER       := <strong>Doclet API</strong>
+DOCLETAPI_BOTTOM       := $(call CommonTrademarkBottom,$(DOCLETAPI_FIRST_COPYRIGHT_YEAR))
+DOCLETAPI_GROUPNAME    := Packages
+DOCLETAPI_REGEXP       := com.sun.javadoc
+# DOCLETAPI_PKGS is located in NON_CORE_PKGS.gmk
+
+# The index.html, options, and packages files
+DOCLETAPI_INDEX_FILE    = $(DOCLETAPI_DOCDIR)/index.html
+DOCLETAPI_OPTIONS_FILE  = $(DOCSTMPDIR)/docletapi.options
+DOCLETAPI_PACKAGES_FILE = $(DOCSTMPDIR)/docletapi.packages
+
+docletapidocs: $(DOCLETAPI_INDEX_FILE)
+
+# Set relative location to core api document root
+$(DOCLETAPI_INDEX_FILE): GET2DOCSDIR=$(DOCLETAPI2COREAPI)/..
+
+# Run javadoc if the index file is out of date or missing
+$(DOCLETAPI_INDEX_FILE): $(DOCLETAPI_OPTIONS_FILE) $(DOCLETAPI_PACKAGES_FILE)
+	$(prep-javadoc)
+	$(call JavadocSummary,$(DOCLETAPI_OPTIONS_FILE),$(DOCLETAPI_PACKAGES_FILE))
+	$(JAVADOC_CMD) $(JAVADOC_VM_MEMORY_FLAGS) -d $(@D) \
+	  @$(DOCLETAPI_OPTIONS_FILE) @$(DOCLETAPI_PACKAGES_FILE)
+
+# Create file with javadoc options in it
+$(DOCLETAPI_OPTIONS_FILE):
+	$(prep-target)
+	@($(ECHO) "$(COMMON_JAVADOCFLAGS)"				; \
+	  $(ECHO) "-sourcepath \"$(RELEASEDOCS_SOURCEPATH)\""		; \
+	  $(ECHO) "-breakiterator"					; \
+	  $(ECHO) "-encoding ascii"					; \
+	  $(ECHO) "-doctitle '$(DOCLETAPI_DOCTITLE)'"			; \
+	  $(ECHO) "-windowtitle '$(DOCLETAPI_WINDOWTITLE) $(DRAFT_WINTITLE)'";\
+	  $(ECHO) "-header '$(DOCLETAPI_HEADER)$(DRAFT_HEADER)'"	; \
+	  $(ECHO) "-bottom '$(DOCLETAPI_BOTTOM)$(DRAFT_BOTTOM)'"	; \
+	  $(ECHO) "-group $(DOCLETAPI_GROUPNAME) $(DOCLETAPI_REGEXP)"	; \
+	  $(ECHO) "-linkoffline $(DOCLETAPI2COREAPI) $(COREAPI_DOCSDIR)/"; \
+        ) >> $@
+
+# Create a file with the package names in it
+$(DOCLETAPI_PACKAGES_FILE): $(DIRECTORY_CACHE) $(call PackageDependencies,$(DOCLETAPI_PKGS))
+	$(prep-target)
+	$(call PackageFilter,$(DOCLETAPI_PKGS))
+
+#############################################################
+#
+# tagletapidocs
+#
+
+# Part of langtools
+ifdef LANGTOOLS_DIST
+  ALL_OTHER_TARGETS += tagletapidocs
+endif
+
+TAGLETAPI_DOCDIR   := $(JDK_API_DOCSDIR)/javadoc/taglet
+TAGLETAPI2COREAPI  := ../../$(JDKJRE2COREAPI)
+TAGLETAPI_BOTTOM   := $(call CommonTrademarkBottom,$(TAGLETAPI_FIRST_COPYRIGHT_YEAR))
+# TAGLETAPI_FILE is located in NON_CORE_PKGS.gmk
+
+# Temporary directory (special generation rules)
+TAGLETAPI_TEMPDIR       = $(DOCSTMPDIR)/taglets_temp
+
+# The index.html, options, and packages files
+TAGLETAPI_INDEX_FILE    = $(TAGLETAPI_DOCDIR)/index.html
+TAGLETAPI_OPTIONS_FILE  = $(DOCSTMPDIR)/tagletapi.options
+TAGLETAPI_PACKAGES_FILE = $(DOCSTMPDIR)/tagletapi.packages
+
+tagletapidocs: $(TAGLETAPI_INDEX_FILE)
+
+# Set relative location to core api document root
+$(TAGLETAPI_INDEX_FILE): GET2DOCSDIR=$(TAGLETAPI2COREAPI)/..
+
+# Run javadoc if the index file is out of date or missing
+$(TAGLETAPI_INDEX_FILE): $(TAGLETAPI_OPTIONS_FILE) $(TAGLETAPI_PACKAGES_FILE)
+	$(prep-javadoc)
+	$(RM) -r $(TAGLETAPI_TEMPDIR)
+	$(MKDIR) -p $(TAGLETAPI_TEMPDIR)
+	$(call JavadocSummary,$(TAGLETAPI_OPTIONS_FILE),$(TAGLETAPI_PACKAGES_FILE))
+	$(JAVADOC_CMD) $(JAVADOC_VM_MEMORY_FLAGS) -d $(TAGLETAPI_TEMPDIR) \
+	  @$(TAGLETAPI_OPTIONS_FILE) @$(TAGLETAPI_PACKAGES_FILE)
+	cp -r $(TAGLETAPI_TEMPDIR)/com $(@D)
+	cp $(TAGLETAPI_TEMPDIR)/stylesheet.css $(@D)
+	$(RM) -r $(TAGLETAPI_TEMPDIR)
+
+# Create file with javadoc options in it
+$(TAGLETAPI_OPTIONS_FILE):
+	$(prep-target)
+	@($(ECHO) "$(COMMON_JAVADOCFLAGS)"				; \
+	  $(ECHO) "-sourcepath \"$(RELEASEDOCS_SOURCEPATH)\""		; \
+	  $(ECHO) "-encoding ascii"					; \
+	  $(ECHO) "-nonavbar"						; \
+	  $(ECHO) "-noindex"						; \
+	  $(ECHO) "-bottom '$(TAGLETAPI_BOTTOM)$(DRAFT_BOTTOM)'"			; \
+	  $(ECHO) "-linkoffline $(TAGLETAPI2COREAPI) $(COREAPI_DOCSDIR)/"; \
+        ) >> $@
+
+# Create a file with the package names in it
+$(TAGLETAPI_PACKAGES_FILE): $(IMPORTSRCDIR)/$(TAGLETAPI_FILE)
+	$(prep-target)
+	@($(ECHO) "$(IMPORTSRCDIR)/$(TAGLETAPI_FILE)" ) > $@
+
+#############################################################
+#
+# domapidocs
+#
+
+ALL_OTHER_TARGETS += domapidocs
+
+DOMAPI_DOCDIR       := $(JRE_API_DOCSDIR)/plugin/dom
+DOMAPI2COREAPI      := ../../$(JDKJRE2COREAPI)
+DOMAPI_DOCTITLE     := Common DOM API
+DOMAPI_WINDOWTITLE  := Common DOM API
+DOMAPI_HEADER       := <strong>Common DOM API</strong>
+DOMAPI_BOTTOM       := $(call CommonTrademarkBottom,$(DOMAPI_FIRST_COPYRIGHT_YEAR))
+DOMAPI_GROUPNAME    := Packages
+DOMAPI_REGEXP       := com.sun.java.browser.dom:org.w3c.dom*
+# DOMAPI_PKGS is located in NON_CORE_PKGS.gmk
+
+# The index.html, options, and packages files
+DOMAPI_INDEX_FILE    = $(DOMAPI_DOCDIR)/index.html
+DOMAPI_OPTIONS_FILE  = $(DOCSTMPDIR)/domapi.options
+DOMAPI_PACKAGES_FILE = $(DOCSTMPDIR)/domapi.packages
+
+domapidocs: $(DOMAPI_INDEX_FILE)
+
+# Set relative location to core api document root
+$(DOMAPI_INDEX_FILE): GET2DOCSDIR=$(DOMAPI2COREAPI)/..
+
+# Run javadoc if the index file is out of date or missing
+$(DOMAPI_INDEX_FILE): $(DOMAPI_OPTIONS_FILE) $(DOMAPI_PACKAGES_FILE)
+	$(prep-javadoc)
+	$(call JavadocSummary,$(DOMAPI_OPTIONS_FILE),$(DOMAPI_PACKAGES_FILE))
+	$(JAVADOC_CMD) $(JAVADOC_VM_MEMORY_FLAGS) -d $(@D) \
+	  @$(DOMAPI_OPTIONS_FILE) @$(DOMAPI_PACKAGES_FILE)
+
+# Create file with javadoc options in it
+$(DOMAPI_OPTIONS_FILE):
+	$(prep-target)
+	@($(ECHO) "$(COMMON_JAVADOCFLAGS)"				; \
+	  $(ECHO) "-sourcepath \"$(RELEASEDOCS_SOURCEPATH)\""		; \
+	  $(ECHO) "-encoding ascii"					; \
+	  $(ECHO) "-splitIndex"						; \
+	  $(ECHO) "-doctitle '$(DOMAPI_DOCTITLE)'"			; \
+	  $(ECHO) "-windowtitle '$(DOMAPI_WINDOWTITLE) $(DRAFT_WINTITLE)'";\
+	  $(ECHO) "-header '$(DOMAPI_HEADER)$(DRAFT_HEADER)'"		; \
+	  $(ECHO) "-bottom '$(DOMAPI_BOTTOM)$(DRAFT_BOTTOM)'"		; \
+	  $(ECHO) "-group $(DOMAPI_GROUPNAME) $(DOMAPI_REGEXP)"		; \
+	  $(ECHO) "-linkoffline $(DOMAPI2COREAPI) $(COREAPI_DOCSDIR)/" 	; \
+        ) >> $@
+
+# Create a file with the package names in it
+$(DOMAPI_PACKAGES_FILE): $(DIRECTORY_CACHE) $(call PackageDependencies,$(DOMAPI_PKGS))
+	$(prep-target)
+	$(call PackageFilter,$(DOMAPI_PKGS))
+
+#############################################################
+#
+# jpdadocs
+#
+
+ALL_OTHER_TARGETS += jpdadocs
+
+jpdadocs: jdidocs jdwpdocs jvmtidocs
+
+#############################################################
+#
+# jdidocs
+#
+
+ALL_OTHER_TARGETS += jdidocs
+
+JDI_DOCDIR      := $(JDK_API_DOCSDIR)/jpda/jdi
+JDI2COREAPI     := ../../$(JDKJRE2COREAPI)
+JDI_DOCTITLE    := Java$(TRADEMARK) Debug Interface
+JDI_WINDOWTITLE := Java Debug Interface
+JDI_HEADER      := <strong>Java Debug Interface</strong>
+JDI_BOTTOM      := $(call CommonBottom,$(JDI_FIRST_COPYRIGHT_YEAR))
+JDI_OVERVIEW    := $(SHARE_SRC)/classes/jdi-overview.html
+# JDI_PKGS is located in NON_CORE_PKGS.gmk
+
+# The index.html, options, and packages files
+JDI_INDEX_FILE    = $(JDI_DOCDIR)/index.html
+JDI_OPTIONS_FILE  = $(DOCSTMPDIR)/jdi.options
+JDI_PACKAGES_FILE = $(DOCSTMPDIR)/jdi.packages
+
+jdidocs: $(JDI_INDEX_FILE)
+
+# Set relative location to core api document root
+$(JDI_INDEX_FILE): GET2DOCSDIR=$(JDI2COREAPI)/..
+
+# Run javadoc if the index file is out of date or missing
+$(JDI_INDEX_FILE): $(JDI_OPTIONS_FILE) $(JDI_PACKAGES_FILE)
+	$(prep-javadoc)
+	$(call JavadocSummary,$(JDI_OPTIONS_FILE),$(JDI_PACKAGES_FILE))
+	$(JAVADOC_CMD) $(JAVADOC_VM_MEMORY_FLAGS) -d $(@D) \
+	  @$(JDI_OPTIONS_FILE) @$(JDI_PACKAGES_FILE)
+
+# Create file with javadoc options in it
+$(JDI_OPTIONS_FILE): $(JDI_OVERVIEW)
+	$(prep-target)
+	@($(ECHO) "$(COMMON_JAVADOCFLAGS)"				; \
+	  $(ECHO) "-sourcepath \"$(RELEASEDOCS_SOURCEPATH)\""		; \
+	  $(ECHO) "-encoding ascii"					; \
+	  $(ECHO) "-overview $(JDI_OVERVIEW)" 				; \
+	  $(ECHO) "-doctitle '$(JDI_DOCTITLE)'"				; \
+	  $(ECHO) "-windowtitle '$(JDI_WINDOWTITLE) $(DRAFT_WINTITLE)'"	; \
+	  $(ECHO) "-header '$(JDI_HEADER)$(DRAFT_HEADER)'"		; \
+	  $(ECHO) "-bottom '$(JDI_BOTTOM)$(DRAFT_BOTTOM)'"		; \
+	  $(ECHO) "-linkoffline $(JDI2COREAPI) $(COREAPI_DOCSDIR)/" 	; \
+        ) >> $@
+
+# Create a file with the package names in it
+$(JDI_PACKAGES_FILE): $(DIRECTORY_CACHE) $(call PackageDependencies,$(JDI_PKGS))
+	$(prep-target)
+	$(call PackageFilter,$(JDI_PKGS))
+
+#############################################################
+#
+# jdwpdocs
+#
+
+ALL_OTHER_TARGETS += jdwpdocs
+
+JDWP_DOCDIR     = $(PLATFORM_DOCSDIR)/jpda/jdwp
+JDWP_SPEC       = $(BUILDDIR)/jpda/jdwp/jdwp.spec
+JDWPGEN_JARFILE = $(BUILDTOOLJARDIR)/jdwpgen.jar
+
+jdwpdocs: $(JDWP_DOCDIR)/jdwp-protocol.html
+$(JDWP_DOCDIR)/jdwp-protocol.html: $(JDWPGEN_JARFILE) $(JDWP_SPEC)
+	$(prep-javadoc)
+	$(BOOT_JAVA_CMD) -jar $(JDWPGEN_JARFILE) $(JDWP_SPEC) -doc $@
+
+#############################################################
+#
+# jvmtidocs
+#
+
+ALL_OTHER_TARGETS += jvmtidocs
+
+JVMTI_DOCDIR      = $(PLATFORM_DOCSDIR)/jvmti
+JVMTI_HTML        = $(HOTSPOT_DOCS_IMPORT_PATH)/platform/jvmti/jvmti.html
+
+jvmtidocs:  $(JVMTI_DOCDIR)/jvmti.html
+$(JVMTI_DOCDIR)/jvmti.html:
+	@$(prep-javadoc)
+	@if [ -f $(JVMTI_HTML) ] ; then		                           \
+	  $(ECHO) "$(CP) $(JVMTI_HTML) $@";                 	           \
+	  $(CP) $(JVMTI_HTML) $@; 	                 	           \
+	else 						                   \
+	  $(ECHO) "WARNING: Generated file does not exist: $(JVMTI_HTML)"; \
+	fi
+
+#############################################################
+#
+# jaasdocs
+#
+
+ALL_OTHER_TARGETS += jaasdocs
+
+JAAS_DOCDIR	 := $(JRE_API_DOCSDIR)/security/jaas/spec
+JAAS2COREAPI     := ../../../$(JDKJRE2COREAPI)
+JAAS_DOCTITLE    := Java$(TRADEMARK) Authentication and Authorization Service
+JAAS_WINDOWTITLE := Java Authentication and Authorization Service
+JAAS_HEADER      := <strong>Java Authentication and Authorization Service</strong>
+JAAS_BOTTOM      := $(call CommonBottom,$(JAAS_FIRST_COPYRIGHT_YEAR))
+# JAAS_PKGS is located in NON_CORE_PKGS.gmk
+JAAS_OVERVIEW    := $(SHARE_SRC)/classes/com/sun/security/auth/jaas-overview.html
+
+# The index.html, options, and packages files
+JAAS_INDEX_FILE    = $(JAAS_DOCDIR)/index.html
+JAAS_OPTIONS_FILE  = $(DOCSTMPDIR)/jaas.options
+JAAS_PACKAGES_FILE = $(DOCSTMPDIR)/jaas.packages
+
+jaasdocs: $(JAAS_INDEX_FILE)
+
+# Set relative location to core api document root
+$(JAAS_INDEX_FILE): GET2DOCSDIR=$(JAAS2COREAPI)/..
+
+# Run javadoc if the index file is out of date or missing
+$(JAAS_INDEX_FILE): $(JAAS_OPTIONS_FILE) $(JAAS_PACKAGES_FILE)
+	$(prep-javadoc)
+	$(call JavadocSummary,$(JAAS_OPTIONS_FILE),$(JAAS_PACKAGES_FILE))
+	$(JAVADOC_CMD) $(JAVADOC_VM_MEMORY_FLAGS) -d $(@D) \
+	  @$(JAAS_OPTIONS_FILE) @$(JAAS_PACKAGES_FILE)
+
+# Create file with javadoc options in it
+$(JAAS_OPTIONS_FILE): $(JAAS_OVERVIEW)
+	$(prep-target)
+	@($(ECHO) "$(COMMON_JAVADOCFLAGS)"				; \
+	  $(ECHO) "-sourcepath \"$(RELEASEDOCS_SOURCEPATH)\""		; \
+	  $(ECHO) "-encoding ascii"					; \
+	  $(ECHO) "-overview $(JAAS_OVERVIEW)" 				; \
+	  $(ECHO) "-doctitle '$(JAAS_DOCTITLE)'"			; \
+	  $(ECHO) "-windowtitle '$(JAAS_WINDOWTITLE) $(DRAFT_WINTITLE)'"; \
+	  $(ECHO) "-header '$(JAAS_HEADER)$(DRAFT_HEADER)'"		; \
+	  $(ECHO) "-bottom '$(JAAS_BOTTOM)$(DRAFT_BOTTOM)'"		; \
+	  $(ECHO) "-linkoffline $(JAAS2COREAPI) $(COREAPI_DOCSDIR)/" 	; \
+        ) >> $@
+
+# Create a file with the package names in it
+$(JAAS_PACKAGES_FILE): $(DIRECTORY_CACHE) $(call PackageDependencies,$(JAAS_PKGS))
+	$(prep-target)
+	$(call PackageFilter,$(JAAS_PKGS))
+
+#############################################################
+#
+# jgssdocs
+#
+
+ALL_OTHER_TARGETS += jgssdocs
+
+JGSS_DOCDIR	 := $(JRE_API_DOCSDIR)/security/jgss/spec
+JGSS2COREAPI     := ../../../$(JDKJRE2COREAPI)
+JGSS_DOCTITLE    := Java$(TRADEMARK) GSS-API Utilities
+JGSS_WINDOWTITLE := Java GSS-API Utilities
+JGSS_HEADER      := <strong>Java GSS-API Utilities</strong>
+JGSS_BOTTOM      := $(call CommonBottom,$(JGSS_FIRST_COPYRIGHT_YEAR))
+JGSS_OVERVIEW    := $(SHARE_SRC)/classes/com/sun/security/jgss/jgss-overview.html
+# JGSS_PKGS is located in NON_CORE_PKGS.gmk
+
+# The index.html, options, and packages files
+JGSS_INDEX_FILE    = $(JGSS_DOCDIR)/index.html
+JGSS_OPTIONS_FILE  = $(DOCSTMPDIR)/jgss.options
+JGSS_PACKAGES_FILE = $(DOCSTMPDIR)/jgss.packages
+
+jgssdocs: $(JGSS_INDEX_FILE)
+
+# Set relative location to core api document root
+$(JGSS_INDEX_FILE): GET2DOCSDIR=$(JGSS2COREAPI)/..
+
+# Run javadoc if the index file is out of date or missing
+$(JGSS_INDEX_FILE): $(JGSS_OPTIONS_FILE) $(JGSS_PACKAGES_FILE)
+	$(prep-javadoc)
+	$(call JavadocSummary,$(JGSS_OPTIONS_FILE),$(JGSS_PACKAGES_FILE))
+	$(JAVADOC_CMD) $(JAVADOC_VM_MEMORY_FLAGS) -d $(@D) \
+	  @$(JGSS_OPTIONS_FILE) @$(JGSS_PACKAGES_FILE)
+
+# Create file with javadoc options in it
+$(JGSS_OPTIONS_FILE): $(JGSS_OVERVIEW)
+	$(prep-target)
+	@($(ECHO) "$(COMMON_JAVADOCFLAGS)"				; \
+	  $(ECHO) "-sourcepath \"$(RELEASEDOCS_SOURCEPATH)\""		; \
+	  $(ECHO) "-encoding ascii"					; \
+	  $(ECHO) "-nodeprecatedlist"					; \
+	  $(ECHO) "-overview $(JGSS_OVERVIEW)" 				; \
+	  $(ECHO) "-doctitle '$(JGSS_DOCTITLE)'"			; \
+	  $(ECHO) "-windowtitle '$(JGSS_WINDOWTITLE) $(DRAFT_WINTITLE)'"; \
+	  $(ECHO) "-header '$(JGSS_HEADER)$(DRAFT_HEADER)'"		; \
+	  $(ECHO) "-bottom '$(JGSS_BOTTOM)$(DRAFT_BOTTOM)'"		; \
+	  $(ECHO) "-linkoffline $(JGSS2COREAPI) $(COREAPI_DOCSDIR)/" 	; \
+        ) >> $@
+
+# Create a file with the package names in it
+$(JGSS_PACKAGES_FILE): $(DIRECTORY_CACHE) $(call PackageDependencies,$(JGSS_PKGS))
+	$(prep-target)
+	$(call PackageFilter,$(JGSS_PKGS))
+
+#############################################################
+#
+# smartcardiodocs
+#
+
+ALL_OTHER_TARGETS += smartcardiodocs
+
+SMARTCARDIO_DOCDIR	:= $(JRE_API_DOCSDIR)/security/smartcardio/spec
+SMARTCARDIO2COREAPI     := ../../../$(JDKJRE2COREAPI)
+SMARTCARDIO_DOCTITLE    := Java$(TRADEMARK) Smart Card I/O
+SMARTCARDIO_WINDOWTITLE := Java Smart Card I/O
+SMARTCARDIO_HEADER      := <strong>Java Smart Card I/O</strong>
+SMARTCARDIO_BOTTOM      := $(call CommonBottom,$(SMARTCARDIO_FIRST_COPYRIGHT_YEAR))
+# SMARTCARDIO_PKGS is located in NON_CORE_PKGS.gmk
+
+# The index.html, options, and packages files
+SMARTCARDIO_INDEX_FILE    = $(SMARTCARDIO_DOCDIR)/index.html
+SMARTCARDIO_OPTIONS_FILE  = $(DOCSTMPDIR)/smartcardio.options
+SMARTCARDIO_PACKAGES_FILE = $(DOCSTMPDIR)/smartcardio.packages
+
+smartcardiodocs: $(SMARTCARDIO_INDEX_FILE)
+
+# Set relative location to core api document root
+$(SMARTCARDIO_INDEX_FILE): GET2DOCSDIR=$(SMARTCARDIO2COREAPI)/..
+
+# Run javadoc if the index file is out of date or missing
+$(SMARTCARDIO_INDEX_FILE): $(SMARTCARDIO_OPTIONS_FILE) $(SMARTCARDIO_PACKAGES_FILE)
+	$(prep-javadoc)
+	$(call JavadocSummary,$(SMARTCARDIO_OPTIONS_FILE),$(SMARTCARDIO_PACKAGES_FILE))
+	$(JAVADOC_CMD) $(JAVADOC_VM_MEMORY_FLAGS) -d $(@D) \
+	  @$(SMARTCARDIO_OPTIONS_FILE) @$(SMARTCARDIO_PACKAGES_FILE)
+
+# Create file with javadoc options in it
+$(SMARTCARDIO_OPTIONS_FILE):
+	$(prep-target)
+	@($(ECHO) "$(COMMON_JAVADOCFLAGS)"				; \
+	  $(ECHO) "-sourcepath \"$(RELEASEDOCS_SOURCEPATH)\""		; \
+	  $(ECHO) "-encoding ascii"					; \
+	  $(ECHO) "-nodeprecatedlist"					; \
+	  $(ECHO) "-doctitle '$(SMARTCARDIO_DOCTITLE)'"			; \
+	  $(ECHO) "-windowtitle '$(SMARTCARDIO_WINDOWTITLE) $(DRAFT_WINTITLE)'";\
+	  $(ECHO) "-header '$(SMARTCARDIO_HEADER)$(DRAFT_HEADER)'"	; \
+	  $(ECHO) "-bottom '$(SMARTCARDIO_BOTTOM)$(DRAFT_BOTTOM)'"	; \
+	  $(ECHO) "-linkoffline $(SMARTCARDIO2COREAPI) $(COREAPI_DOCSDIR)/"; \
+        ) >> $@
+
+# Create a file with the package names in it
+$(SMARTCARDIO_PACKAGES_FILE): $(DIRECTORY_CACHE) $(call PackageDependencies,$(SMARTCARDIO_PKGS))
+	$(prep-target)
+	$(call PackageFilter,$(SMARTCARDIO_PKGS))
+
+#############################################################
+#
+# httpserverdocs
+#
+
+ALL_OTHER_TARGETS += httpserverdocs
+
+HTTPSERVER_DOCDIR      := $(JRE_API_DOCSDIR)/net/httpserver/spec
+HTTPSERVER2COREAPI     := ../../../$(JDKJRE2COREAPI)
+HTTPSERVER_DOCTITLE    := Java$(TRADEMARK) HTTP Server
+HTTPSERVER_WINDOWTITLE := Java HTTP Server
+HTTPSERVER_HEADER      := <strong>Java HTTP Server</strong>
+HTTPSERVER_BOTTOM      := $(call CommonBottom,$(HTTPSERVER_FIRST_COPYRIGHT_YEAR))
+# HTTPSERVER_PKGS is located in NON_CORE_PKGS.gmk
+
+HTTPSERVER_INDEX_HTML    = $(HTTPSERVER_DOCDIR)/index.html
+HTTPSERVER_OPTIONS_FILE  = $(DOCSTMPDIR)/httpserver.options
+HTTPSERVER_PACKAGES_FILE = $(DOCSTMPDIR)/httpserver.packages
+
+httpserverdocs: $(HTTPSERVER_INDEX_HTML)
+
+# Set relative location to core api document root
+$(HTTPSERVER_INDEX_HTML): GET2DOCSDIR=$(HTTPSERVER2COREAPI)/..
+
+# Run javadoc if the index file is out of date or missing
+$(HTTPSERVER_INDEX_HTML): $(HTTPSERVER_OPTIONS_FILE) $(HTTPSERVER_PACKAGES_FILE)
+	$(prep-javadoc)
+	$(call JavadocSummary,$(HTTPSERVER_OPTIONS_FILE),$(HTTPSERVER_PACKAGES_FILE))
+	$(JAVADOC_CMD) $(JAVADOC_VM_MEMORY_FLAGS) -d $(@D) \
+	  @$(HTTPSERVER_OPTIONS_FILE) @$(HTTPSERVER_PACKAGES_FILE)
+
+# Create file with javadoc options in it
+$(HTTPSERVER_OPTIONS_FILE):
+	$(prep-target)
+	@($(ECHO) "$(COMMON_JAVADOCFLAGS)"				; \
+	  $(ECHO) "-sourcepath \"$(RELEASEDOCS_SOURCEPATH)\""		; \
+	  $(ECHO) "-encoding ascii"					; \
+	  $(ECHO) "-nodeprecatedlist"					; \
+	  $(ECHO) "-doctitle '$(HTTPSERVER_DOCTITLE)'"			; \
+	  $(ECHO) "-windowtitle '$(HTTPSERVER_WINDOWTITLE) $(DRAFT_WINTITLE)'";\
+	  $(ECHO) "-header '$(HTTPSERVER_HEADER)$(DRAFT_HEADER)'"	; \
+	  $(ECHO) "-bottom '$(HTTPSERVER_BOTTOM)$(DRAFT_BOTTOM)'"	; \
+	  $(ECHO) "-linkoffline $(HTTPSERVER2COREAPI) $(COREAPI_DOCSDIR)/"; \
+        ) >> $@
+
+# Create a file with the package names in it
+$(HTTPSERVER_PACKAGES_FILE): $(DIRECTORY_CACHE) $(call PackageDependencies,$(HTTPSERVER_PKGS))
+	$(prep-target)
+	$(call PackageFilter,$(HTTPSERVER_PKGS))
+
+#############################################################
+#
+# mgmtdocs
+#
+
+ALL_OTHER_TARGETS += mgmtdocs
+
+MGMT_DOCDIR	 := $(JRE_API_DOCSDIR)/management/extension
+MGMT2COREAPI     := ../../$(JDKJRE2COREAPI)
+JVM_MIB_NAME     := JVM-MANAGEMENT-MIB.mib
+JVM_MIB_SRC      := $(CLOSED_SRC)/share/classes/sun/management/snmp/$(JVM_MIB_NAME)
+MGMT_DOCTITLE    := Monitoring and Management Interface for the Java$(TRADEMARK) Platform
+MGMT_WINDOWTITLE := Monitoring and Management Interface for the Java Platform
+MGMT_HEADER      := <strong>Monitoring and Management Interface for the Java Platform</strong>
+MGMT_BOTTOM      := $(call CommonBottom,$(MGMT_FIRST_COPYRIGHT_YEAR))
+MGMT_OVERVIEW    := $(SHARE_SRC)/classes/com/sun/management/mgmt-overview.html
+# MGMT_PKGS is located in NON_CORE_PKGS.gmk
+
+# The index.html, options, and packages files
+MGMT_INDEX_FILE    = $(MGMT_DOCDIR)/index.html
+MGMT_OPTIONS_FILE  = $(DOCSTMPDIR)/mgmt.options
+MGMT_PACKAGES_FILE = $(DOCSTMPDIR)/mgmt.packages
+
+mgmtdocs: $(MGMT_INDEX_FILE)
+
+# Set relative location to core api document root
+$(MGMT_INDEX_FILE): GET2DOCSDIR=$(MGMT2COREAPI)/..
+
+# Run javadoc if the index file is out of date or missing
+$(MGMT_INDEX_FILE): $(MGMT_OPTIONS_FILE) $(MGMT_PACKAGES_FILE)
+	$(prep-javadoc)
+	@if [ -f $(JVM_MIB_SRC) ] ; then 				\
+	  $(ECHO) "$(CP) $(JVM_MIB_SRC) $(@D)/.."; 			\
+	  $(CP) $(JVM_MIB_SRC) $(@D)/.. ; 				\
+	else 								\
+	  $(ECHO) "WARNING: File $(JVM_MIB_NAME) not available."; 	\
+	fi
+	$(call JavadocSummary,$(MGMT_OPTIONS_FILE),$(MGMT_PACKAGES_FILE))
+	$(JAVADOC_CMD) $(JAVADOC_VM_MEMORY_FLAGS) -d $(@D) \
+	  @$(MGMT_OPTIONS_FILE) @$(MGMT_PACKAGES_FILE)
+
+# Create file with javadoc options in it
+$(MGMT_OPTIONS_FILE): $(MGMT_OVERVIEW)
+	$(prep-target)
+	@($(ECHO) "$(COMMON_JAVADOCFLAGS)"				; \
+	  $(ECHO) "-sourcepath \"$(RELEASEDOCS_SOURCEPATH)\""		; \
+	  $(ECHO) "-encoding ascii"					; \
+	  $(ECHO) "-nodeprecatedlist"					; \
+	  $(ECHO) "-overview $(MGMT_OVERVIEW)" 				; \
+	  $(ECHO) "-doctitle '$(MGMT_DOCTITLE)'"			; \
+	  $(ECHO) "-windowtitle '$(MGMT_WINDOWTITLE) $(DRAFT_WINTITLE)'"; \
+	  $(ECHO) "-header '$(MGMT_HEADER)$(DRAFT_HEADER)'"		; \
+	  $(ECHO) "-bottom '$(MGMT_BOTTOM)$(DRAFT_BOTTOM)'"		; \
+	  $(ECHO) "-linkoffline $(MGMT2COREAPI) $(COREAPI_DOCSDIR)/" 	; \
+        ) >> $@
+
+# Create a file with the package names in it
+$(MGMT_PACKAGES_FILE): $(DIRECTORY_CACHE) $(call PackageDependencies,$(MGMT_PKGS))
+	$(prep-target)
+	$(call PackageFilter,$(MGMT_PKGS))
+
+#############################################################
+#
+# attachdocs
+#
+
+ALL_OTHER_TARGETS += attachdocs
+
+ATTACH_DOCDIR      := $(JDK_API_DOCSDIR)/attach/spec
+ATTACH2COREAPI     := ../../$(JDKJRE2COREAPI)
+ATTACH_DOCTITLE    := Attach API
+ATTACH_WINDOWTITLE := Attach API
+ATTACH_HEADER      := <strong>Attach API</strong>
+ATTACH_BOTTOM      := $(call CommonBottom,$(ATTACH_FIRST_COPYRIGHT_YEAR))
+# ATTACH_PKGS is located in NON_CORE_PKGS.gmk
+
+ATTACH_INDEX_HTML    = $(ATTACH_DOCDIR)/index.html
+ATTACH_OPTIONS_FILE  = $(DOCSTMPDIR)/attach.options
+ATTACH_PACKAGES_FILE = $(DOCSTMPDIR)/attach.packages
+
+attachdocs: $(ATTACH_INDEX_HTML)
+
+# Set relative location to core api document root
+$(ATTACH_INDEX_HTML): GET2DOCSDIR=$(ATTACH2COREAPI)/..
+
+# Run javadoc if the index file is out of date or missing
+$(ATTACH_INDEX_HTML): $(ATTACH_OPTIONS_FILE) $(ATTACH_PACKAGES_FILE)
+	$(prep-javadoc)
+	$(call JavadocSummary,$(ATTACH_OPTIONS_FILE),$(ATTACH_PACKAGES_FILE))
+	$(JAVADOC_CMD) $(JAVADOC_VM_MEMORY_FLAGS) -d $(@D) \
+	  @$(ATTACH_OPTIONS_FILE) @$(ATTACH_PACKAGES_FILE)
+
+# Create file with javadoc options in it
+$(ATTACH_OPTIONS_FILE):
+	$(prep-target)
+	@($(ECHO) "$(COMMON_JAVADOCFLAGS)"				; \
+	  $(ECHO) "-sourcepath \"$(RELEASEDOCS_SOURCEPATH)\""		; \
+	  $(ECHO) "-encoding ascii"					; \
+	  $(ECHO) "-nodeprecatedlist"					; \
+	  $(ECHO) "-doctitle '$(ATTACH_DOCTITLE)'"			; \
+	  $(ECHO) "-windowtitle '$(ATTACH_WINDOWTITLE) $(DRAFT_WINTITLE)'";\
+	  $(ECHO) "-header '$(ATTACH_HEADER)$(DRAFT_HEADER)'"		; \
+	  $(ECHO) "-bottom '$(ATTACH_BOTTOM)$(DRAFT_BOTTOM)'"		; \
+	  $(ECHO) "-linkoffline $(ATTACH2COREAPI) $(COREAPI_DOCSDIR)/"	; \
+        ) >> $@
+
+# Create a file with the package names in it
+$(ATTACH_PACKAGES_FILE): $(DIRECTORY_CACHE) $(call PackageDependencies,$(ATTACH_PKGS))
+	$(prep-target)
+	$(call PackageFilter,$(ATTACH_PKGS))
+
+#############################################################
+#
+# jconsoledocs
+#
+
+ALL_OTHER_TARGETS += jconsoledocs
+
+JCONSOLE_DOCDIR      := $(JDK_API_DOCSDIR)/jconsole/spec
+JCONSOLE2COREAPI     := ../../$(JDKJRE2COREAPI)
+JCONSOLE_DOCTITLE    := JConsole API
+JCONSOLE_WINDOWTITLE := JConsole API
+JCONSOLE_HEADER      := <strong>JConsole API</strong>
+JCONSOLE_BOTTOM      := $(call CommonBottom,$(JCONSOLE_FIRST_COPYRIGHT_YEAR))
+# JCONSOLE_PKGS is located in NON_CORE_PKGS.gmk
+
+JCONSOLE_INDEX_HTML    = $(JCONSOLE_DOCDIR)/index.html
+JCONSOLE_OPTIONS_FILE  = $(DOCSTMPDIR)/jconsole.options
+JCONSOLE_PACKAGES_FILE = $(DOCSTMPDIR)/jconsole.packages
+
+jconsoledocs: $(JCONSOLE_INDEX_HTML)
+
+# Set relative location to core api document root
+$(JCONSOLE_INDEX_HTML): GET2DOCSDIR=$(JCONSOLE2COREAPI)/..
+
+# Run javadoc if the index file is out of date or missing
+$(JCONSOLE_INDEX_HTML): $(JCONSOLE_OPTIONS_FILE) $(JCONSOLE_PACKAGES_FILE)
+	$(prep-javadoc)
+	$(call JavadocSummary,$(JCONSOLE_OPTIONS_FILE),$(JCONSOLE_PACKAGES_FILE))
+	$(JAVADOC_CMD) $(JAVADOC_VM_MEMORY_FLAGS) -d $(@D) \
+	  @$(JCONSOLE_OPTIONS_FILE) @$(JCONSOLE_PACKAGES_FILE)
+
+# Create file with javadoc options in it
+$(JCONSOLE_OPTIONS_FILE):
+	$(prep-target)
+	@($(ECHO) "$(COMMON_JAVADOCFLAGS)"				; \
+	  $(ECHO) "-sourcepath \"$(RELEASEDOCS_SOURCEPATH)\""		; \
+	  $(ECHO) "-encoding ascii"					; \
+	  $(ECHO) "-nodeprecatedlist"					; \
+	  $(ECHO) "-doctitle '$(JCONSOLE_DOCTITLE)'"			; \
+	  $(ECHO) "-windowtitle '$(JCONSOLE_WINDOWTITLE) $(DRAFT_WINTITLE)'";\
+	  $(ECHO) "-header '$(JCONSOLE_HEADER)$(DRAFT_HEADER)'"		; \
+	  $(ECHO) "-bottom '$(JCONSOLE_BOTTOM)$(DRAFT_BOTTOM)'"		; \
+	  $(ECHO) "-linkoffline $(JCONSOLE2COREAPI) $(COREAPI_DOCSDIR)/"; \
+        ) >> $@
+
+# Create a file with the package names in it
+$(JCONSOLE_PACKAGES_FILE): $(DIRECTORY_CACHE) $(call PackageDependencies,$(JCONSOLE_PKGS))
+	$(prep-target)
+	$(call PackageFilter,$(JCONSOLE_PKGS))
+
+#############################################################
+#
+# treeapidocs
+#
+
+# Part of langtools
+ifdef LANGTOOLS_DIST
+  ALL_OTHER_TARGETS += treeapidocs
+endif
+
+TREEAPI_DOCDIR       := $(JDK_API_DOCSDIR)/javac/tree
+TREEAPI2COREAPI      := ../../$(JDKJRE2COREAPI)
+TREEAPI_DOCTITLE     := Compiler Tree API
+TREEAPI_WINDOWTITLE  := Compiler Tree API
+TREEAPI_HEADER       := <strong>Compiler Tree API</strong>
+TREEAPI_BOTTOM       := $(call CommonBottom,$(TREEAPI_FIRST_COPYRIGHT_YEAR))
+TREEAPI_GROUPNAME    := Packages
+TREEAPI_REGEXP       := com.sun.source.*
+# TREEAPI_PKGS is located in NON_CORE_PKGS.gmk
+
+TREEAPI_INDEX_HTML    = $(TREEAPI_DOCDIR)/index.html
+TREEAPI_OPTIONS_FILE  = $(DOCSTMPDIR)/treeapi.options
+TREEAPI_PACKAGES_FILE = $(DOCSTMPDIR)/treeapi.packages
+
+treeapidocs: $(TREEAPI_INDEX_HTML)
+
+# Set relative location to core api document root
+$(TREEAPI_INDEX_HTML): GET2DOCSDIR=$(TREEAPI2COREAPI)/..
+
+# Run javadoc if the index file is out of date or missing
+$(TREEAPI_INDEX_HTML): $(TREEAPI_OPTIONS_FILE) $(TREEAPI_PACKAGES_FILE)
+	$(prep-javadoc)
+	$(call JavadocSummary,$(TREEAPI_OPTIONS_FILE),$(TREEAPI_PACKAGES_FILE))
+	$(JAVADOC_CMD) $(JAVADOC_VM_MEMORY_FLAGS) -d $(@D) \
+	  @$(TREEAPI_OPTIONS_FILE) @$(TREEAPI_PACKAGES_FILE)
+
+# Create file with javadoc options in it
+$(TREEAPI_OPTIONS_FILE):
+	$(prep-target)
+	@($(ECHO) "$(COMMON_JAVADOCFLAGS)"				; \
+	  $(ECHO) "-sourcepath \"$(RELEASEDOCS_SOURCEPATH)\""		; \
+	  $(ECHO) "-encoding ascii"					; \
+	  $(ECHO) "-doctitle '$(TREEAPI_DOCTITLE)'"			; \
+	  $(ECHO) "-windowtitle '$(TREEAPI_WINDOWTITLE) $(DRAFT_WINTITLE)'";\
+	  $(ECHO) "-header '$(TREEAPI_HEADER)$(DRAFT_HEADER)'"		; \
+	  $(ECHO) "-bottom '$(TREEAPI_BOTTOM)$(DRAFT_BOTTOM)'"		; \
+	  $(ECHO) "-group $(TREEAPI_GROUPNAME) $(TREEAPI_REGEXP)"	; \
+	  $(ECHO) "-linkoffline $(TREEAPI2COREAPI) $(COREAPI_DOCSDIR)/"	; \
+        ) >> $@
+
+# Create a file with the package names in it
+$(TREEAPI_PACKAGES_FILE): $(DIRECTORY_CACHE) $(call PackageDependencies,$(TREEAPI_PKGS))
+	$(prep-target)
+	$(call PackageFilter,$(TREEAPI_PKGS))
+
+#############################################################
+#
+# sctpdocs
+#
+
+ALL_OTHER_TARGETS += sctpdocs
+
+SCTPAPI_DOCDIR      := $(JRE_API_DOCSDIR)/nio/sctp/spec
+SCTPAPI2COREAPI     := ../../../$(JDKJRE2COREAPI)
+SCTPAPI_DOCTITLE    := SCTP API
+SCTPAPI_WINDOWTITLE := SCTP API
+SCTPAPI_HEADER      := <strong>SCTP API</strong>
+SCTPAPI_BOTTOM      := $(call CommonBottom,$(SCTPAPI_FIRST_COPYRIGHT_YEAR))
+# SCTPAPI_PKGS is located in NON_CORE_PKGS.gmk
+
+SCTPAPI_INDEX_HTML    = $(SCTPAPI_DOCDIR)/index.html
+SCTPAPI_OPTIONS_FILE  = $(DOCSTMPDIR)/sctp.options
+SCTPAPI_PACKAGES_FILE = $(DOCSTMPDIR)/sctp.packages
+
+sctpdocs: $(SCTPAPI_INDEX_HTML)
+
+# Set relative location to core api document root
+$(SCTSCTSCTP: GET2DOCSDIR=$(SCTPAPI2COREAPI)/..
+
+# Run javadoc if the index file is out of date or missing
+$(SCTPAPI_INDEX_HTML): $(SCTPAPI_OPTIONS_FILE) $(SCTPAPI_PACKAGES_FILE)
+	$(prep-javadoc)
+	$(call JavadocSummary,$(SCTPAPI_OPTIONS_FILE),$(SCTPAPI_PACKAGES_FILE))
+	$(JAVADOC_CMD) $(JAVADOC_VM_MEMORY_FLAGS) -d $(@D) \
+	  @$(SCTPAPI_OPTIONS_FILE) @$(SCTPAPI_PACKAGES_FILE)
+
+# Create file with javadoc options in it
+$(SCTPAPI_OPTIONS_FILE):
+	$(prep-target)
+	@($(ECHO) "$(COMMON_JAVADOCFLAGS)"				; \
+	  $(ECHO) "-sourcepath \"$(RELEASEDOCS_SOURCEPATH)\""		; \
+	  $(ECHO) "-encoding ascii"					; \
+	  $(ECHO) "-nodeprecatedlist"					; \
+	  $(ECHO) "-doctitle '$(SCTPAPI_DOCTITLE)'"			; \
+	  $(ECHO) "-windowtitle '$(SCTPAPI_WINDOWTITLE) $(DRAFT_WINTITLE)'";\
+	  $(ECHO) "-header '$(SCTPAPI_HEADER)$(DRAFT_HEADER)'"		; \
+	  $(ECHO) "-bottom '$(SCTPAPI_BOTTOM)$(DRAFT_BOTTOM)'"		; \
+	  $(ECHO) "-linkoffline $(SCTPAPI2COREAPI) $(COREAPI_DOCSDIR)/"	; \
+        ) >> $@
+
+# Create a file with the package names in it
+$(SCTPAPI_PACKAGES_FILE): $(DIRECTORY_CACHE) $(call PackageDependencies,$(SCTPAPI_PKGS))
+	$(prep-target)
+	$(call PackageFilter,$(SCTPAPI_PKGS))
+
+#############################################################
+#
+# tracingdocs
+#
+
+ALL_OTHER_TARGETS += tracingdocs
+
+TRACING_DOCDIR      := $(JRE_API_DOCSDIR)/tracing
+TRACING2COREAPI     := ../$(JDKJRE2COREAPI)
+TRACING_DOCTITLE    := Java$(TRADEMARK) Platform Tracing
+TRACING_WINDOWTITLE := Platform Tracing
+TRACING_HEADER      := <strong>Platform Tracing</strong>
+TRACING_BOTTOM      := $(call CommonBottom,$(TRACING_FIRST_COPYRIGHT_YEAR))
+# TRACING_PKGS is located in NON_CORE_PKGS.gmk
+
+TRACING_INDEX_HTML    = $(TRACING_DOCDIR)/index.html
+TRACING_OPTIONS_FILE  = $(DOCSTMPDIR)/tracing.options
+TRACING_PACKAGES_FILE = $(DOCSTMPDIR)/tracing.packages
+
+tracingdocs: $(TRACING_INDEX_HTML)
+
+# Set relative location to core api document root
+$(TRACING_INDEX_HTML): GET2DOCSDIR=$(TRACING2COREAPI)/..
+
+# Run javadoc if the index file is out of date or missing
+$(TRACING_INDEX_HTML): $(TRACING_OPTIONS_FILE) $(TRACING_PACKAGES_FILE)
+	$(prep-javadoc)
+	$(call JavadocSummary,$(TRACING_OPTIONS_FILE),$(TRACING_PACKAGES_FILE))
+	$(JAVADOC_CMD) $(JAVADOC_VM_MEMORY_FLAGS) -d $(@D) \
+	  @$(TRACING_OPTIONS_FILE) @$(TRACING_PACKAGES_FILE)
+
+# Create file with javadoc options in it
+$(TRACING_OPTIONS_FILE):
+	$(prep-target)
+	@($(ECHO) "$(COMMON_JAVADOCFLAGS)"				; \
+	  $(ECHO) "-sourcepath \"$(RELEASEDOCS_SOURCEPATH)\""		; \
+	  $(ECHO) "-encoding ascii"					; \
+	  $(ECHO) "-nodeprecatedlist"					; \
+	  $(ECHO) "-doctitle '$(TRACING_DOCTITLE)'"			; \
+	  $(ECHO) "-windowtitle '$(TRACING_WINDOWTITLE) $(DRAFT_WINTITLE)'";\
+	  $(ECHO) "-header '$(TRACING_HEADER)$(DRAFT_HEADER)'"		; \
+	  $(ECHO) "-bottom '$(TRACING_BOTTOM)$(DRAFT_BOTTOM)'"		; \
+	  $(ECHO) "-linkoffline $(TRACING2COREAPI) $(COREAPI_DOCSDIR)/"	; \
+        ) >> $@
+
+# Create a file with the package names in it
+$(TRACING_PACKAGES_FILE): $(DIRECTORY_CACHE) $(call PackageDependencies,$(TRACING_PKGS))
+	$(prep-target)
+	$(call PackageFilter,$(TRACING_PKGS))
+
+#############################################################
+#
+# Get a cache of all the directories
+
+$(DIRECTORY_CACHE): $(ALL_SOURCE_DIRS)
+	$(prep-target)
+	@for cp in $(ALL_SOURCE_DIRS) ; do 		\
+	  $(ECHO) "$(FIND) $${cp} -type f >> $@"; 	\
+	  $(FIND) $${cp} -type f >> $@; 		\
+	done
+
+#############################################################
+#release version of core packages ########
 # Maximize performance and ensure that build number & milestone are set.
-.PHONY: rel-coredocs
+
 rel-coredocs: sanitycheckcoredocs
-	@# ######## release version of core packages ########
 	$(MAKE) coredocs
 
-.PHONY: rel-docs
-rel-docs: rel-coredocs ${ALL_OTHER_TARGETS}
+rel-docs: rel-coredocs $(ALL_OTHER_TARGETS)
 #
 # end of production targets
+
+otherdocs: $(ALL_OTHER_TARGETS)
+
+clean:
+	$(RM) -r $(DOCSDIR) $(DOCSTMPDIR)
+
 #############################################################
-
-.PHONY: coredocs
-coredocs:
-	@# ######## core packages #######################
-	$(RM) -r $(DOCSDIR)/api
-	$(MKDIR) -p $(DOCSDIR)/api
-	$(JAVADOC_CMD) $(CORE_JAVADOCFLAGS)            \
-                   -d $(DOCSDIR)/api                   \
-                   -sourcepath $(RELEASEDOCS_SRCPATH)  \
-                   $(CORE_PKGS)
-
-.PHONY: mirrordocs
-mirrordocs:
-	@# ######## mirror api for apt ##################
-	$(RM) -r $(MIRROR_DESTDIR)
-	$(MKDIR) -p $(MIRROR_DESTDIR)
-	$(JAVADOC_CMD) $(MIRROR_JAVADOCFLAGS)             \
-		   -d $(MIRROR_DESTDIR)               \
-		   -sourcepath $(RELEASEDOCS_SRCPATH) \
-		   $(MIRROR_LINKOPT)                  \
-		   $(MIRROR_PKGS)
-
-.PHONY: docletapidocs
-docletapidocs:
-	@# ######## doclet api ############################
-	$(RM) -r $(DOCSDIR)/jdk/api/javadoc/doclet
-	$(MKDIR) -p $(DOCSDIR)/jdk/api/javadoc/doclet
-	$(JAVADOC_CMD) $(DOCLETAPI_JAVADOCFLAGS)                 \
-                   -d $(DOCSDIR)/jdk/api/javadoc/doclet      \
-                   -sourcepath $(RELEASEDOCS_SRCPATH)        \
-                   $(DOCLETAPI_LINKOPT)                      \
-                   $(DOCLETAPI_PKGS)
-
-.PHONY: tagletapidocs
-tagletapidocs:
-	@# ######## taglet api ############################
-	$(RM) -r $(DOCSDIR)/jdk/api/javadoc/taglet
-	$(MKDIR) -p $(DOCSDIR)/jdk/api/javadoc/taglet
-	$(RM) -r $(DOCSTMPDIR)
-	$(MKDIR) -p $(DOCSTMPDIR)
-	$(JAVADOC_CMD) $(TAGLETAPI_JAVADOCFLAGS)                 \
-                   -d $(DOCSTMPDIR)                          \
-                   -linkoffline ../../../../api $(DOCSDIR)/api/ \
-                   $(IMPORTSRCDIR)/$(TAGLETAPI_FILE)
-	cp -r $(DOCSTMPDIR)/com $(DOCSDIR)/jdk/api/javadoc/taglet
-	cp $(DOCSTMPDIR)/stylesheet.css $(DOCSDIR)/jdk/api/javadoc/taglet
-	$(RM) -r $(DOCSTMPDIR)
-
-.PHONY: domapidocs
-domapidocs:
-	@# ######## dom api ############################
-	$(RM) -r $(DOCSDIR)/jre/api/plugin/dom
-	$(MKDIR) -p $(DOCSDIR)/jre/api/plugin/dom
-	$(JAVADOC_CMD) $(DOMAPI_JAVADOCFLAGS)		     \
-                   -d $(DOCSDIR)/jre/api/plugin/dom            \
-                   -sourcepath $(RELEASEDOCS_SRCPATH)        \
-                   -linkoffline ../../../../api $(DOCSDIR)/api/ \
-                   $(DOMAPI_PKGS)
-
-.PHONY: jpdadocs
-jpdadocs: jdidocs jdwpdocs jvmtidocs
-
-.PHONY: jdidocs
-jdidocs:
-	@# ######## jdi #################################
-	$(RM) -r $(DOCSDIR)/jdk/api/jpda/jdi
-	$(MKDIR) -p $(DOCSDIR)/jdk/api/jpda/jdi
-	$(JAVADOC_CMD) $(JDI_JAVADOCFLAGS)                       \
-                   $(JDI_PKGS)
-
-JDWP_SPEC       = $(BUILDDIR)/jpda/jdwp/jdwp.spec
-JDWP_DOC        = $(DOCSDIR)/platform/jpda/jdwp/jdwp-protocol.html
-JDWPGEN_JARFILE = $(BUILDTOOLJARDIR)/jdwpgen.jar
-
-.PHONY: jdwpdocs
-jdwpdocs: $(JDWP_DOC)
-
-$(JDWP_DOC): $(JDWPGEN_JARFILE) $(JDWP_SPEC)
-	$(prep-target)
-	$(BOOT_JAVA_CMD) -jar $(JDWPGEN_JARFILE) $(JDWP_SPEC) -doc $(JDWP_DOC)
-
-.PHONY: jvmtidocs
-jvmtidocs:
-	@# ######## jvmti #################################
-	@if [ -f $(JVMTI_HTML) ] ; then \
-	  $(RM) -r $(DOCSDIR)/$(JVMTI_DOCS_SUBDIR); \
-	  $(MKDIR) -p $(DOCSDIR)/$(JVMTI_DOCS_SUBDIR); \
-	  $(ECHO) $(CP) $(JVMTI_HTML) $(DOCSDIR)/$(JVMTI_DOCS_SUBDIR); \
-	  $(CP) $(JVMTI_HTML) $(DOCSDIR)/$(JVMTI_DOCS_SUBDIR); \
-	else \
-	  $(ECHO) "WARNING: Generated jvmti file does not exist: $(JVMTI_HTML)"; \
-	fi
-
-.PHONY: jaasdocs
-jaasdocs:
-	@# ######## api-jaas ############################
-	$(RM) -r $(JAAS_DOCDIR)
-	$(MKDIR) -p $(JAAS_DOCDIR)
-	$(JAVADOC_CMD) $(JAAS_JAVADOCFLAGS)                     \
-		   $(JAAS_PKGS)
-
-.PHONY: jgssdocs
-jgssdocs:
-	@# ######## api-jgss ############################
-	$(RM) -r $(JGSS_DOCDIR)
-	$(MKDIR) -p $(JGSS_DOCDIR)
-	$(JAVADOC_CMD) $(JGSS_JAVADOCFLAGS)                     \
-		   $(JGSS_PKGS)
-
-.PHONY: smartcardiodocs
-smartcardiodocs:
-	@# ######## api-smartcardio ############################
-	$(RM) -r $(SMARTCARDIO_DOCDIR)
-	$(MKDIR) -p $(SMARTCARDIO_DOCDIR)
-	$(JAVADOC_CMD) $(SMARTCARDIO_JAVADOCFLAGS)                     \
-		   $(SMARTCARDIO_PKGS)
-
-.PHONY: tracingdocs
-tracingdocs:
-	@# ######## api-tracing ############################
-	$(RM) -r $(TRACING_DOCDIR)
-	$(MKDIR) -p $(TRACING_DOCDIR)
-	$(JAVADOC_CMD) $(TRACING_JAVADOCFLAGS)                     \
-		   $(TRACING_PKGS)
-
-.PHONY: httpserverdocs
-httpserverdocs:
-	@# ######## api-httpserver #######################
-	$(RM) -r $(HTTPSERVER_DOCDIR)
-	$(MKDIR) -p $(HTTPSERVER_DOCDIR)
-	$(JAVADOC_CMD) $(HTTPSERVER_JAVADOCFLAGS)                     \
-		   $(HTTPSERVER_PKGS)
-
-.PHONY: sctpdocs
-sctpdocs:
-	@# ######## api-sctp #######################
-	$(RM) -r $(SCTPAPI_DOCDIR)
-	$(MKDIR) -p $(SCTPAPI_DOCDIR)
-	$(JAVADOC_CMD) $(SCTPAPI_JAVADOCFLAGS)                     \
-		$(SCTPAPI_PKGS)
-
-.PHONY: mgmtdocs
-mgmtdocs: $(COPY-MIB-TARGET)
-	@# ######## api-management ############################
-	$(RM) -r $(MGMT_EXT_DIR)
-	$(MKDIR) -p $(MGMT_EXT_DIR)
-	$(JAVADOC_CMD) $(MGMT_JAVADOCFLAGS)                     \
-		   $(MGMT_PKGS)
-
-copy-mib:
-	@# ######## copy-snmp-mib ############################
-	$(RM) $(MGMT_DOCDIR)/$(JVM_MIB_NAME)
-	$(MKDIR) -p $(MGMT_DOCDIR)
-	$(CP) $(JVM_MIB_SRC) $(MGMT_DOCDIR)
-
-.PHONY: attachdocs
-attachdocs:
-	@# ######## api-attach ############################
-	$(RM) -r $(ATTACH_DOCDIR)
-	$(MKDIR) -p $(ATTACH_DOCDIR)
-	$(JAVADOC_CMD) $(ATTACH_JAVADOCFLAGS)                     \
-		   $(ATTACH_PKGS)
-
-.PHONY: jconsoledocs
-jconsoledocs:
-	@# ######## api-jconsole ############################
-	$(RM) -r $(JCONSOLE_DOCDIR)
-	$(MKDIR) -p $(JCONSOLE_DOCDIR)
-	$(JAVADOC_CMD) $(JCONSOLE_JAVADOCFLAGS)                     \
-		   $(JCONSOLE_PKGS)
-
-.PHONY: treeapidocs
-treeapidocs:
-	@# ######## tree api for javac ##################
-	$(RM) -r $(TREEAPI_DESTDIR)
-	$(MKDIR) -p $(TREEAPI_DESTDIR)
-	$(JAVADOC_CMD) $(TREEAPI_JAVADOCFLAGS)             \
-		   -d $(TREEAPI_DESTDIR)               \
-		   -sourcepath $(RELEASEDOCS_SRCPATH) \
-		   $(TREEAPI_LINKOPT)                  \
-		   $(TREEAPI_PKGS)
-
 # DEBUG TARGET
 # List the values defined in the makefile hierarchy, to make sure everything
 # is set properly, and to help identify values we can use instead of making new ones.
@@ -714,9 +1211,14 @@
 #    * BUILD_NUMBER defaults to b00 if not set on command line with BUILD_NUMBER=<value>
 #    * MILESTONE defaults to internal unless set to beta, rc, or fcs on command line
 #
-.PHONY: echovalues
+
 echovalues:
 	@$(ECHO) ""
+	@$(ECHO) --------------Imports---------------------------
+	@$(ECHO) "IMPORT_PACKAGES = $(IMPORT_PACKAGES)"
+	@$(ECHO) "IMPORT_PACKAGE_FILTER = $(IMPORT_PACKAGE_FILTER)"
+	@$(ECHO) --------------Imports---------------------------
+	@$(ECHO) ""
 	@$(ECHO) --------------Shared---------------------------
 	@$(ECHO) BUILD_NUMBER = $(BUILD_NUMBER)
 	@$(ECHO) FULL_VERSION = $(FULL_VERSION)
@@ -736,11 +1238,16 @@
 	@$(ECHO) --------------Shared---------------------------
 	@$(ECHO) ""
 	@$(ECHO) --------------common/Defs---------------------------
-	@$(ECHO) "RELEASEDOCS_SRCPATH"
+	@$(ECHO) "RELEASEDOCS_SOURCEPATH"
 	@$(ECHO) "   SHARE_SRC/classes: $(SHARE_SRC)/classes"
 	@$(ECHO) "   PLATFORM_SRC/classes: $(PLATFORM_SRC)/classes"
 	@$(ECHO) "   GENSRCDIR: $(GENSRCDIR)"
+	@$(ECHO) "   SHARE_SRC/doc/stub: $(SHARE_SRC)/doc/stub"
 	@$(ECHO) "   IMPORTSRCDIR: $(IMPORTSRCDIR)"
-	@$(ECHO) "   SHARE_SRC/doc/stub: $(SHARE_SRC)/doc/stub"
 	@$(ECHO) --------------common/Defs---------------------------
 	@$(ECHO) ""
+
+#############################################################
+.PHONY: all docs coredocs rel-docs echovalues otherdocs rel-coredocs \
+        sanitycheckcoredocs $(ALL_OTHER_TARGETS)
+
--- a/make/java/java/FILES_java.gmk	Mon Jul 12 19:35:11 2010 -0700
+++ b/make/java/java/FILES_java.gmk	Mon Jul 12 19:42:02 2010 -0700
@@ -30,6 +30,7 @@
 #
 JAVA_JAVA_java = \
     java/lang/Object.java \
+    java/lang/AutoCloseable.java \
     java/lang/Class.java \
     java/lang/Thread.java \
     java/lang/Character.java \
--- a/make/java/security/Makefile	Mon Jul 12 19:35:11 2010 -0700
+++ b/make/java/security/Makefile	Mon Jul 12 19:42:02 2010 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1996, 2010 Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -62,6 +62,11 @@
 CACERTS_SRC =	$(CACERTS_FILE)
 CACERTS_BUILD = $(LIBDIR)/security/cacerts
 
+ifndef OPENJDK
+  BLACKLIST_SRC =	$(CLOSED_SHARE_SRC)/lib/security/blacklist
+  BLACKLIST_BUILD = $(LIBDIR)/security/blacklist
+endif
+
 FILES_class = $(FILES_java:%.java=$(CLASSBINDIR)/%.class)
 
 #
@@ -69,7 +74,11 @@
 #
 include $(BUILDDIR)/common/Rules.gmk
 
+ifdef OPENJDK
 build: properties policy cacerts
+else
+build: properties policy cacerts blacklist
+endif
 
 install: all
 
@@ -79,6 +88,8 @@
 
 cacerts: classes $(CACERTS_BUILD)
 
+blacklist: classes $(BLACKLIST_BUILD)
+
 $(PROPS_BUILD): $(PROPS_SRC)
 	$(install-file)
 
@@ -88,9 +99,12 @@
 $(CACERTS_BUILD): $(CACERTS_SRC)
 	$(install-file)
 
+$(BLACKLIST_BUILD): $(BLACKLIST_SRC)
+	$(install-file)
+
 clean clobber:: .delete.classlist
 	$(RM) -r $(CLASSBINDIR)/java/security
-	$(RM) $(PROPS_BUILD) $(POLICY_BUILD) $(CACERTS_BUILD)
+	$(RM) $(PROPS_BUILD) $(POLICY_BUILD) $(CACERTS_BUILD) $(BLACKLIST_BUILD)
 
 # Additional Rule for building sun.security.util
 $(CLASSBINDIR)/%.class: $(SHARE_SRC)/sun/%.java
--- a/make/tools/src/build/tools/jarreorder/JarReorder.java	Mon Jul 12 19:35:11 2010 -0700
+++ b/make/tools/src/build/tools/jarreorder/JarReorder.java	Mon Jul 12 19:42:02 2010 -0700
@@ -28,7 +28,6 @@
  * combine with an argument list of files and directories, and
  * write a list of items to be included in a jar file.
  */
-
 package build.tools.jarreorder;
 
 import java.io.BufferedReader;
@@ -36,74 +35,68 @@
 import java.io.FileNotFoundException;
 import java.io.FileReader;
 import java.io.IOException;
-import java.util.Arrays;
-import java.util.HashMap;
+import java.util.Collections;
 import java.util.HashSet;
-import java.util.Vector;
 import java.io.PrintStream;
 import java.io.FileOutputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
 
 public class JarReorder {
 
     // To deal with output
-    private static PrintStream out;
+    private PrintStream out;
 
-    private final static boolean useTopDir = false;
-
-    private static void usage() {
+    private void usage() {
         String help;
         help =
-            "Usage:  jar JarReorder [-o <outputfile>] <order_list> <exclude_list> <file> ...\n"
-          + "   order_list    is a file containing names of files to load\n"
-          + "                 in order at the end of a jar file.\n"
-          + "   exclude_list  is a file containing names of files/directories\n"
-          + "                 NOT to be included in a jar file.\n";
-        if (useTopDir)
-            help +=
-                "   top_dir       is the top of the directory structure to be searched;\n"
-              + "                 the contents of the lists and remaining arguments are\n"
-              + "                 relative to this.\n";
-        help +=
-            "\n"
-          + "The order_list or exclude_list may be replaced by a \"_\" if no\n"
-          + "data is to be provided.\n"
-          + "\n"
-          + "   The remaining arguments are files or directories to be included\n"
-          + "   in a jar file, from which will be excluded thse entries which\n"
-          + "   appear in the exclude list.\n";
+                "Usage:  jar JarReorder [-o <outputfile>] <order_list> <exclude_list> <file> ...\n"
+                + "   order_list    is a file containing names of files to load\n"
+                + "                 in order at the end of a jar file unless\n"
+                + "                 excluded in the exclude list.\n"
+                + "   exclude_list  is a file containing names of files/directories\n"
+                + "                 NOT to be included in a jar file.\n"
+                + "\n"
+                + "The order_list or exclude_list may be replaced by a \"-\" if no\n"
+                + "data is to be provided.\n"
+                + "\n"
+                + "   The remaining arguments are files or directories to be included\n"
+                + "   in a jar file, from which will be excluded those entries which\n"
+                + "   appear in the exclude list.\n";
         System.err.println(help);
-        System.exit(1);
     }
 
 
     /*
-     * Create a list of files to be included in a jar file, such that the
-     * some the files will appear in a specific order, and allowing certain
+     * Create the file list to be included in a jar file, such that the
+     * list will appear in a specific order, and allowing certain
      * files and directories to be excluded.
      *
-     * Command line arguments are
+     * Command path arguments are
      *    - optional -o outputfile
-     *    - name of a file containing a list of files to be included in a jar file.
-     *    - name of a file containing a list of files (or directories) to be
+     *    - name of a file containing a set of files to be included in a jar file.
+     *    - name of a file containing a set of files (or directories) to be
      *      excluded from the jar file.
      *    - names of files or directories to be searched for files to include
      *      in the jar file.
      */
     public static void main(String[] args) {
+        JarReorder jr = new JarReorder();
+        jr.run(args);
+    }
 
-        HashMap filesExcluded = new HashMap();
-        Vector filesIncluded = new Vector();
-        int fileArgs;
-        String topDirName = "";
+    private void run(String args[]) {
+
         int arglen = args.length;
         int argpos = 0;
 
         // Look for "-o outputfilename" option
-        if ( arglen > 0 ) {
-            if ( arglen >= 2 && args[0].equals("-o") ) {
+        if (arglen > 0) {
+            if (arglen >= 2 && args[0].equals("-o")) {
                 try {
                     out = new PrintStream(new FileOutputStream(args[1]));
-                } catch ( FileNotFoundException e ) {
+                } catch (FileNotFoundException e) {
                     System.err.println("Error: " + e.getMessage());
                     e.printStackTrace(System.err);
                     System.exit(1);
@@ -118,128 +111,111 @@
             out = System.out;
         }
 
-        fileArgs = useTopDir ? 3 : 2;
-
-        if (arglen <= fileArgs) {
+        // Should be 2 or more args left
+        if (arglen <= 2) {
             usage();
+            System.exit(1);
         }
 
-        // Read the ordered list of files to be included in rt.jar.
-        // Read the list of files/directories to be excluded from rt.jar.
+        // Read the ordered set of files to be included in rt.jar.
+        // Read the set of files/directories to be excluded from rt.jar.
+        String classListFile = args[argpos];
+        String excludeListFile = args[argpos + 1];
+        argpos += 2;
+        arglen -= 2;
 
-        Vector orderList = readListFromFile(args[argpos], true);
-        Vector excludeList = readListFromFile(args[argpos+1], false);
-        if (useTopDir) {
-            topDirName = args[argpos+2];
-            if (!topDirName.endsWith(File.separator))
-                topDirName = topDirName + File.separator;
-        }
+        // Create 2 lists and a set of processed files
+        List<String> orderList = readListFromFile(classListFile, true);
+        List<String> excludeList = readListFromFile(excludeListFile, false);
+        Set<String> processed = new HashSet<String>();
 
-        // Copy these lists into filesExcluded so that these files will be excluded
-        // from the file list. (The orderList files will be appended later.)
+        // Create set of all files and directories excluded, then expand
+        //   that list completely
+        Set<String> excludeSet = new HashSet<String>(excludeList);
+        Set<String> allFilesExcluded = expand(null, excludeSet, processed);
 
-        for (int i = 0; i < orderList.size(); ++i) {
-            String s = (String) orderList.elementAt(i);
-            filesExcluded.put(s, s);
-        }
-        for (int i = 0; i < excludeList.size(); ++i) {
-            String s = (String) excludeList.elementAt(i);
-            filesExcluded.put(s, s);
-        }
+        // Indicate all these have been processed, orderList too, kept to end.
+        processed.addAll(orderList);
 
         // The remaining arguments are names of files/directories to be included
         // in the jar file.
-
-        String[] files = new String[arglen - fileArgs];
-        for (int i = fileArgs; i < arglen; ++i) {
-            files[i-fileArgs] = args[argpos+i];
-            filesExcluded.put(args[argpos+i], args[argpos+i]);
+        Set<String> inputSet = new HashSet<String>();
+        for (int i = 0; i < arglen; ++i) {
+            String name = args[argpos + i];
+            name = cleanPath(new File(name));
+            if ( name != null && name.length() > 0 && !inputSet.contains(name) ) {
+                inputSet.add(name);
+            }
         }
 
-        // Expand file/directory list to file list excluding those
-        // read from the class list.
+        // Expand file/directory input so we get a complete set (except ordered)
+        //   Should be everything not excluded and not in order list.
+        Set<String> allFilesIncluded = expand(null, inputSet, processed);
 
-        if (useTopDir)
-            expand(new File(topDirName), files, filesIncluded, filesExcluded, topDirName);
-        else
-            expand(null, files, filesIncluded, filesExcluded, null);
+        // Create simple sorted list so we can add ordered items at end.
+        List<String> allFiles = new ArrayList<String>(allFilesIncluded);
+        Collections.sort(allFiles);
 
-        // Now add the ordered list to the end of the expanded list.
+        // Now add the ordered set to the end of the list.
         // Add in REVERSE ORDER, so that the first element is closest to
         // the end (and the index).
-
-        HashSet excludeSet = new HashSet(excludeList);
         for (int i = orderList.size() - 1; i >= 0; --i) {
-            String s = (String) orderList.elementAt(i);
-            if (excludeSet.contains(s)) {
-                System.err.println("Included file " + s + " is also excluded, skipping.");
-                continue;
+            String s = orderList.get(i);
+            if (allFilesExcluded.contains(s)) {
+                System.err.println("Included order file " + s
+                    + " is also excluded, skipping.");
+            } else if (new File(s).exists()) {
+                allFiles.add(s);
+            } else {
+                System.err.println("Included order file " + s
+                    + " missing, skipping.");
             }
-            if (new File(topDirName + s).exists())
-                filesIncluded.addElement(s);
-            else
-                System.err.println("Included file "+s+" missing, skipping.");
         }
 
-        // Print results.
-
-        for (int i = 0; i < filesIncluded.size(); ++i) {
-            if (useTopDir) {
-                out.print("-C ");
-                out.print(topDirName);
-                out.print(" ");
-            }
-            out.println((String)filesIncluded.elementAt(i));
+        // Print final results.
+        for (String str : allFiles) {
+            out.println(str);
         }
-
         out.flush();
         out.close();
     }
 
-
     /*
-     * Read a file containing a list of files into a Vector.
+     * Read a file containing a list of files and directories into a List.
      */
-    private static Vector readListFromFile(String fileName,
-                                           boolean addClassSuffix) {
+    private List<String> readListFromFile(String fileName,
+            boolean addClassSuffix) {
 
         BufferedReader br = null;
-        Vector v = new Vector(2000);
-
-        if ("-".equals(fileName))
-            return v;
-
+        List<String> list = new ArrayList<String>();
+        // If you see "-" for the name, just assume nothing was provided.
+        if ("-".equals(fileName)) {
+            return list;
+        }
         try {
             br = new BufferedReader(new FileReader(fileName));
-
-        // Read the input file a line at a time. # in column 1 is a comment.
-
+            // Read the input file a path at a time. # in column 1 is a comment.
             while (true) {
-                String line = null;
-                line = br.readLine();
-
-                if (line == null)
+                String path = br.readLine();
+                if (path == null) {
                     break;
-
-                if (line.length() == 0    ||
-                    line.charAt(0) == '#')
+                }
+                // Look for comments
+                path = path.trim();
+                if (path.length() == 0
+                        || path.charAt(0) == '#') {
                     continue;
-
-                // Convert forward or back slashes to the type expected for
-                // the current platform.
-
-                if (File.separatorChar == '/')
-                    line = line.replace('\\', '/');
-                else
-                    line = line.replace('/', '\\');
-
-                line = line.trim();
-                if (addClassSuffix) {
-                    if (!line.endsWith(".class")) {
-                        line = line + ".class";
-                    }
                 }
-                v.addElement(line);
+                // Add trailing .class if necessary
+                if (addClassSuffix && !path.endsWith(".class")) {
+                    path = path + ".class";
+                }
+                // Normalize the path
+                path = cleanPath(new File(path));
+                // Add to list
+                if (path != null && path.length() > 0 && !list.contains(path)) {
+                    list.add(path);
+                }
             }
             br.close();
         } catch (FileNotFoundException e) {
@@ -249,68 +225,89 @@
             e.printStackTrace();
             System.exit(2);
         }
-        return v;
+        return list;
     }
 
-
     /*
-     * Expands list of files to process into full list of all files that
+     * Expands inputSet (files or dirs) into full set of all files that
      * can be found by recursively descending directories.
+     * @param dir root directory
+     * @param inputSet set of files or dirs to look into
+     * @param processed files or dirs already processed
+     * @return set of files
      */
-    private static void expand(File dir, String[] files,
-                               Vector includedFiles, HashMap excludedFiles,
-                               String topDirName) {
-        if (files == null) {
-            return;
+    private Set<String> expand(File dir,
+            Set<String> inputSet,
+            Set<String> processed) {
+        Set<String> includedFiles = new HashSet<String>();
+        if (inputSet.isEmpty()) {
+            return includedFiles;
         }
-        for (int i = 0; i < files.length; i++) {
-            File f = (dir == null) ? new File(files[i])
-                                   : new File(dir, files[i]);
-            if (f.isFile()) {
-                String filePath = f.getPath();
-
-                if (useTopDir) {
-                    if (filePath.startsWith(topDirName))
-                        filePath = filePath.substring(topDirName.length());
+        for (String name : inputSet) {
+            // Depending on start location
+            File f = (dir == null) ? new File(name)
+                    : new File(dir, name);
+            // Normalized path to use
+            String path = cleanPath(f);
+            if (path != null && path.length() > 0
+                    && !processed.contains(path)) {
+                if (f.isFile()) {
+                    // Not in the excludeList, add it to both lists
+                    includedFiles.add(path);
+                    processed.add(path);
+                } else if (f.isDirectory()) {
+                    // Add the directory entries
+                    String[] dirList = f.list();
+                    Set<String> dirInputSet = new HashSet<String>();
+                    for (String x : dirList) {
+                        dirInputSet.add(x);
+                    }
+                    // Process all entries in this directory
+                    Set<String> subList = expand(f, dirInputSet, processed);
+                    includedFiles.addAll(subList);
+                    processed.add(path);
                 }
-
-                if (filePath.length() >= 2 &&
-                    filePath.charAt(0) == '.' &&
-                    filePath.charAt(1) == File.separatorChar)
-                    filePath = filePath.substring(2);
-
-                if (!excludedFiles.containsKey(filePath)) {
-                    excludedFiles.put(filePath, filePath);
-                    includedFiles.addElement(filePath);
-                }
-            } else if (f.isDirectory()) {
-                String dirPath = f.getPath();
-                dirPath = (dirPath.endsWith(File.separator)) ? dirPath :
-                    (dirPath + File.separator);
-
-                if (useTopDir) {
-                    if (dirPath.startsWith(topDirName))
-                        dirPath = dirPath.substring(topDirName.length());
-                }
-
-                if (dirPath.length() >= 2 &&
-                    dirPath.charAt(0) == '.' &&
-                    dirPath.charAt(1) == File.separatorChar)
-                    dirPath = dirPath.substring(2);
-
-                if (!excludedFiles.containsKey(dirPath)) {
-
-                    // Sort the directory list so that entries in the jar file
-                    // are in a repeatable order.  The order itself is not particularly
-                    // important.  [File.list() is unpredictable.]
-
-                    String[] dirList = f.list();
-                    Arrays.sort(dirList);
-                    expand(f, dirList, includedFiles, excludedFiles, topDirName);
-                }
-            } else {
-                System.err.println("Error accessing: " + f.getPath());
             }
         }
+        return includedFiles;
     }
+
+    private String cleanPath(File f) {
+        String path = f.getPath();
+        if (f.isFile()) {
+            path = cleanFilePath(path);
+        } else if (f.isDirectory()) {
+            path = cleanDirPath(path);
+        } else {
+            System.err.println("WARNING: Path does not exist as file or directory: " + path);
+            path = null;
+        }
+        return path;
+    }
+
+    private String cleanFilePath(String path) {
+        // Remove leading and trailing whitespace
+        path = path.trim();
+        // Make all / and \ chars one
+        if (File.separatorChar == '/') {
+            path = path.replace('\\', '/');
+        } else {
+            path = path.replace('/', '\\');
+        }
+        // Remove leading ./
+        if (path.startsWith("." + File.separator)) {
+            path = path.substring(2);
+        }
+        return path;
+    }
+
+    private String cleanDirPath(String path) {
+        path = cleanFilePath(path);
+        // Make sure it ends with a file separator
+        if (!path.endsWith(File.separator)) {
+            path = path + File.separator;
+        }
+        return path;
+    }
+
 }
--- a/src/share/bin/emessages.h	Mon Jul 12 19:35:11 2010 -0700
+++ b/src/share/bin/emessages.h	Mon Jul 12 19:42:02 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -44,7 +44,7 @@
 
 #define JVM_ERROR1      "Error: Could not create the Java Virtual Machine.\n" GEN_ERROR
 #define JVM_ERROR2      "Error: Could not detach main thread.\n" JNI_ERROR
-#define JVM_ERROR3      "Error: SPARC V8 processor detected; Server compiler requires V9 or better.\nUse Client compiler on V8 processors.\nCould not create the Java virtual machine."
+#define JVM_ERROR3      "Error: SPARC V8 processor detected;  Required V9 processors or better.\nUse JDK5 client compiler for V8 processors.\n" JVM_ERROR1
 
 #define JAR_ERROR1      "Error: Failed to load Main-Class manifest attribute from\n%s\n%s"
 #define JAR_ERROR2      "Error: Unable to access jarfile %s"
@@ -69,7 +69,8 @@
 #define CFG_ERROR5      "Error: Could not determine application home."
 #define CFG_ERROR6      "Error: could not open `%s'"
 #define CFG_ERROR7      "Error: no known VMs. (check for corrupt jvm.cfg file)"
-#define CFG_ERROR8      "Error: no `%s' JVM at `%s'."
+#define CFG_ERROR8      "Error: missing `%s' JVM at `%s'.\nPlease install or use the JRE or JDK that contains these missing components."
+#define CFG_ERROR9      "Error: could not determine JVM type."
 
 
 #define SPC_ERROR1      "Error: Syntax error in version specification \"%s\""
--- a/src/share/bin/java.c	Mon Jul 12 19:35:11 2010 -0700
+++ b/src/share/bin/java.c	Mon Jul 12 19:42:02 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1995, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -192,8 +192,8 @@
     int ret;
     InvocationFunctions ifn;
     jlong start, end;
-    char jrepath[MAXPATHLEN], jvmpath[MAXPATHLEN];
-    char ** original_argv = argv;
+    char jvmpath[MAXPATHLEN];
+    char jrepath[MAXPATHLEN];
 
     _fVersion = fullversion;
     _dVersion = dotversion;
@@ -225,14 +225,17 @@
      */
     SelectVersion(argc, argv, &main_class);
 
-    /* copy original argv */
-    JLI_TraceLauncher("Command line Args:\n");
-    original_argv = (JLI_CopyArgs(argc, (const char**)argv));
+    if (JLI_IsTraceLauncher()) {
+        int i;
+        printf("Command line args:\n");
+        for (i = 0; i < argc ; i++) {
+            printf("argv[%d] = %s\n", i, argv[i]);
+        }
+    }
 
     CreateExecutionEnvironment(&argc, &argv,
                                jrepath, sizeof(jrepath),
-                               jvmpath, sizeof(jvmpath),
-                               original_argv);
+                               jvmpath, sizeof(jvmpath));
 
     ifn.CreateJavaVM = 0;
     ifn.GetDefaultJavaVMInitArgs = 0;
@@ -301,22 +304,43 @@
     return ContinueInNewThread(&ifn, argc, argv, jarfile, classname, ret);
 
 }
+/*
+ * Always detach the main thread so that it appears to have ended when
+ * the application's main method exits.  This will invoke the
+ * uncaught exception handler machinery if main threw an
+ * exception.  An uncaught exception handler cannot change the
+ * launcher's return code except by calling System.exit.
+ *
+ * Wait for all non-daemon threads to end, then destroy the VM.
+ * This will actually create a trivial new Java waiter thread
+ * named "DestroyJavaVM", but this will be seen as a different
+ * thread from the one that executed main, even though they are
+ * the same C thread.  This allows mainThread.join() and
+ * mainThread.isAlive() to work as expected.
+ */
+#define LEAVE() \
+    if ((*vm)->DetachCurrentThread(vm) != 0) { \
+        JLI_ReportErrorMessage(JVM_ERROR2); \
+        ret = 1; \
+    } \
+    (*vm)->DestroyJavaVM(vm); \
+    return ret \
 
 #define CHECK_EXCEPTION_NULL_LEAVE(e) \
     if ((*env)->ExceptionOccurred(env)) { \
         JLI_ReportExceptionDescription(env); \
-        goto leave; \
+        LEAVE(); \
     } \
     if ((e) == NULL) { \
         JLI_ReportErrorMessage(JNI_ERROR); \
-        goto leave; \
+        LEAVE(); \
     }
 
 #define CHECK_EXCEPTION_LEAVE(rv) \
     if ((*env)->ExceptionOccurred(env)) { \
         JLI_ReportExceptionDescription(env); \
         ret = (rv); \
-        goto leave; \
+        LEAVE(); \
     }
 
 int JNICALL
@@ -349,8 +373,7 @@
         PrintJavaVersion(env, showVersion);
         CHECK_EXCEPTION_LEAVE(0);
         if (printVersion) {
-            ret = 0;
-            goto leave;
+            LEAVE();
         }
     }
 
@@ -358,7 +381,7 @@
     if (printXUsage || printUsage || (jarfile == 0 && classname == 0)) {
         PrintUsage(env, printXUsage);
         CHECK_EXCEPTION_LEAVE(1);
-        goto leave;
+        LEAVE();
     }
 
     FreeKnownVMs();  /* after last possible PrintUsage() */
@@ -430,30 +453,7 @@
      * System.exit) will be non-zero if main threw an exception.
      */
     ret = (*env)->ExceptionOccurred(env) == NULL ? 0 : 1;
-
-leave:
-    /*
-     * Always detach the main thread so that it appears to have ended when
-     * the application's main method exits.  This will invoke the
-     * uncaught exception handler machinery if main threw an
-     * exception.  An uncaught exception handler cannot change the
-     * launcher's return code except by calling System.exit.
-     */
-    if ((*vm)->DetachCurrentThread(vm) != 0) {
-        JLI_ReportErrorMessage(JVM_ERROR2);
-        ret = 1;
-    }
-    /*
-     * Wait for all non-daemon threads to end, then destroy the VM.
-     * This will actually create a trivial new Java waiter thread
-     * named "DestroyJavaVM", but this will be seen as a different
-     * thread from the one that executed main, even though they are
-     * the same C thread.  This allows mainThread.join() and
-     * mainThread.isAlive() to work as expected.
-     */
-    (*vm)->DestroyJavaVM(vm);
-
-    return ret;
+    LEAVE();
 }
 
 /*
@@ -1076,15 +1076,17 @@
     if (--argc >= 0) {
         if (jarflag) {
             *pjarfile = *argv++;
-            *pclassname = 0;
+            *pclassname = NULL;
         } else {
-            *pjarfile = 0;
+            *pjarfile = NULL;
             *pclassname = *argv++;
         }
         *pargc = argc;
         *pargv = argv;
     }
-
+    if (*pjarfile == NULL && *pclassname == NULL) {
+        *pret = 1;
+    }
     return JNI_TRUE;
 }
 
--- a/src/share/bin/java.h	Mon Jul 12 19:35:11 2010 -0700
+++ b/src/share/bin/java.h	Mon Jul 12 19:42:02 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -114,13 +114,19 @@
 
 #define GetArch() GetArchPath(CURRENT_DATA_MODEL)
 
-void CreateExecutionEnvironment(int *_argc,
-                                       char ***_argv,
-                                       char jrepath[],
-                                       jint so_jrepath,
-                                       char jvmpath[],
-                                       jint so_jvmpath,
-                                       char **original_argv);
+/*
+ * Different platforms will implement this, here
+ * pargc is a pointer to the original argc,
+ * pargv is a pointer to the original argv,
+ * jrepath is an accessible path to the jre as determined by the call
+ * so_jrepath is the length of the buffer jrepath
+ * jvmpath is an accessible path to the jvm as determined by the call
+ * so_jvmpath is the length of the buffer jvmpath
+ */
+void CreateExecutionEnvironment(int *argc, char ***argv,
+                                char *jrepath, jint so_jrepath,
+                                char *jvmpath, jint so_jvmpath);
+
 /* Reports an error message to stderr or a window as appropriate. */
 void JLI_ReportErrorMessage(const char * message, ...);
 
--- a/src/share/bin/jli_util.c	Mon Jul 12 19:35:11 2010 -0700
+++ b/src/share/bin/jli_util.c	Mon Jul 12 19:42:02 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -85,23 +85,6 @@
 }
 
 /*
- * Makes a copy of arguments
- */
-char**
-JLI_CopyArgs(int argc, const char **iargv)
-{
-    int i;
-    char** oargv = (char**)JLI_MemAlloc(sizeof(char*)*(argc+1));
-    for (i = 0 ; i < argc+1 ; i++) {
-        oargv[i] = (iargv[i] == NULL) ? NULL : JLI_StringDup(iargv[i]);
-        if (iargv[i] != NULL && JLI_IsTraceLauncher() == JNI_TRUE) {
-            printf("\targv[%d] = '%s'\n",i,iargv[i]);
-        }
-    }
-    return oargv;
-}
-
-/*
  * debug helpers we use
  */
 static jboolean _launcher_debug = JNI_FALSE;
--- a/src/share/bin/jli_util.h	Mon Jul 12 19:35:11 2010 -0700
+++ b/src/share/bin/jli_util.h	Mon Jul 12 19:42:02 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,7 +33,6 @@
 void *JLI_MemRealloc(void *ptr, size_t size);
 char *JLI_StringDup(const char *s1);
 void  JLI_MemFree(void *ptr);
-char **JLI_CopyArgs(int argc, const char **iargv);
 int   JLI_StrCCmp(const char *s1, const char* s2);
 
 
@@ -56,10 +55,12 @@
 #include <io.h>
 #define JLI_StrCaseCmp(p1, p2)          stricmp((p1), (p2))
 #define JLI_StrNCaseCmp(p1, p2, p3)     strnicmp((p1), (p2), (p3))
+#define JLI_Snprintf                    _snprintf
 #else
 #include <unistd.h>
 #define JLI_StrCaseCmp(p1, p2)          strcasecmp((p1), (p2))
 #define JLI_StrNCaseCmp(p1, p2, p3)     strncasecmp((p1), (p2), (p3))
+#define JLI_Snprintf                    snprintf
 #endif /* _WIN32 */
 
 /*
--- a/src/share/classes/java/beans/XMLDecoder.java	Mon Jul 12 19:35:11 2010 -0700
+++ b/src/share/classes/java/beans/XMLDecoder.java	Mon Jul 12 19:42:02 2010 -0700
@@ -60,7 +60,7 @@
  *
  * @author Philip Milne
  */
-public class XMLDecoder {
+public class XMLDecoder implements AutoCloseable {
     private final DocumentHandler handler = new DocumentHandler();
     private final InputSource input;
     private Object owner;
--- a/src/share/classes/java/beans/XMLEncoder.java	Mon Jul 12 19:35:11 2010 -0700
+++ b/src/share/classes/java/beans/XMLEncoder.java	Mon Jul 12 19:42:02 2010 -0700
@@ -204,7 +204,7 @@
  *
  * @author Philip Milne
  */
-public class XMLEncoder extends Encoder {
+public class XMLEncoder extends Encoder implements AutoCloseable {
 
     private final CharsetEncoder encoder;
     private final String charset;
--- a/src/share/classes/java/io/Bits.java	Mon Jul 12 19:35:11 2010 -0700
+++ b/src/share/classes/java/io/Bits.java	Mon Jul 12 19:42:02 2010 -0700
@@ -41,51 +41,39 @@
     }
 
     static char getChar(byte[] b, int off) {
-        return (char) (((b[off + 1] & 0xFF) << 0) +
-                       ((b[off + 0]) << 8));
+        return (char) ((b[off + 1] & 0xFF) +
+                       (b[off] << 8));
     }
 
     static short getShort(byte[] b, int off) {
-        return (short) (((b[off + 1] & 0xFF) << 0) +
-                        ((b[off + 0]) << 8));
+        return (short) ((b[off + 1] & 0xFF) +
+                        (b[off] << 8));
     }
 
     static int getInt(byte[] b, int off) {
-        return ((b[off + 3] & 0xFF) << 0) +
-               ((b[off + 2] & 0xFF) << 8) +
+        return ((b[off + 3] & 0xFF)      ) +
+               ((b[off + 2] & 0xFF) <<  8) +
                ((b[off + 1] & 0xFF) << 16) +
-               ((b[off + 0]) << 24);
+               ((b[off    ]       ) << 24);
     }
 
     static float getFloat(byte[] b, int off) {
-        int i = ((b[off + 3] & 0xFF) << 0) +
-                ((b[off + 2] & 0xFF) << 8) +
-                ((b[off + 1] & 0xFF) << 16) +
-                ((b[off + 0]) << 24);
-        return Float.intBitsToFloat(i);
+        return Float.intBitsToFloat(getInt(b, off));
     }
 
     static long getLong(byte[] b, int off) {
-        return ((b[off + 7] & 0xFFL) << 0) +
-               ((b[off + 6] & 0xFFL) << 8) +
+        return ((b[off + 7] & 0xFFL)      ) +
+               ((b[off + 6] & 0xFFL) <<  8) +
                ((b[off + 5] & 0xFFL) << 16) +
                ((b[off + 4] & 0xFFL) << 24) +
                ((b[off + 3] & 0xFFL) << 32) +
                ((b[off + 2] & 0xFFL) << 40) +
                ((b[off + 1] & 0xFFL) << 48) +
-               (((long) b[off + 0]) << 56);
+               (((long) b[off])      << 56);
     }
 
     static double getDouble(byte[] b, int off) {
-        long j = ((b[off + 7] & 0xFFL) << 0) +
-                 ((b[off + 6] & 0xFFL) << 8) +
-                 ((b[off + 5] & 0xFFL) << 16) +
-                 ((b[off + 4] & 0xFFL) << 24) +
-                 ((b[off + 3] & 0xFFL) << 32) +
-                 ((b[off + 2] & 0xFFL) << 40) +
-                 ((b[off + 1] & 0xFFL) << 48) +
-                 (((long) b[off + 0]) << 56);
-        return Double.longBitsToDouble(j);
+        return Double.longBitsToDouble(getLong(b, off));
     }
 
     /*
@@ -98,50 +86,38 @@
     }
 
     static void putChar(byte[] b, int off, char val) {
-        b[off + 1] = (byte) (val >>> 0);
-        b[off + 0] = (byte) (val >>> 8);
+        b[off + 1] = (byte) (val      );
+        b[off    ] = (byte) (val >>> 8);
     }
 
     static void putShort(byte[] b, int off, short val) {
-        b[off + 1] = (byte) (val >>> 0);
-        b[off + 0] = (byte) (val >>> 8);
+        b[off + 1] = (byte) (val      );
+        b[off    ] = (byte) (val >>> 8);
     }
 
     static void putInt(byte[] b, int off, int val) {
-        b[off + 3] = (byte) (val >>> 0);
-        b[off + 2] = (byte) (val >>> 8);
+        b[off + 3] = (byte) (val       );
+        b[off + 2] = (byte) (val >>>  8);
         b[off + 1] = (byte) (val >>> 16);
-        b[off + 0] = (byte) (val >>> 24);
+        b[off    ] = (byte) (val >>> 24);
     }
 
     static void putFloat(byte[] b, int off, float val) {
-        int i = Float.floatToIntBits(val);
-        b[off + 3] = (byte) (i >>> 0);
-        b[off + 2] = (byte) (i >>> 8);
-        b[off + 1] = (byte) (i >>> 16);
-        b[off + 0] = (byte) (i >>> 24);
+        putInt(b, off,  Float.floatToIntBits(val));
     }
 
     static void putLong(byte[] b, int off, long val) {
-        b[off + 7] = (byte) (val >>> 0);
-        b[off + 6] = (byte) (val >>> 8);
+        b[off + 7] = (byte) (val       );
+        b[off + 6] = (byte) (val >>>  8);
         b[off + 5] = (byte) (val >>> 16);
         b[off + 4] = (byte) (val >>> 24);
         b[off + 3] = (byte) (val >>> 32);
         b[off + 2] = (byte) (val >>> 40);
         b[off + 1] = (byte) (val >>> 48);
-        b[off + 0] = (byte) (val >>> 56);
+        b[off    ] = (byte) (val >>> 56);
     }
 
     static void putDouble(byte[] b, int off, double val) {
-        long j = Double.doubleToLongBits(val);
-        b[off + 7] = (byte) (j >>> 0);
-        b[off + 6] = (byte) (j >>> 8);
-        b[off + 5] = (byte) (j >>> 16);
-        b[off + 4] = (byte) (j >>> 24);
-        b[off + 3] = (byte) (j >>> 32);
-        b[off + 2] = (byte) (j >>> 40);
-        b[off + 1] = (byte) (j >>> 48);
-        b[off + 0] = (byte) (j >>> 56);
+        putLong(b, off, Double.doubleToLongBits(val));
     }
 }
--- a/src/share/classes/java/io/Closeable.java	Mon Jul 12 19:35:11 2010 -0700
+++ b/src/share/classes/java/io/Closeable.java	Mon Jul 12 19:42:02 2010 -0700
@@ -28,14 +28,14 @@
 import java.io.IOException;
 
 /**
- * A <tt>Closeable</tt> is a source or destination of data that can be closed.
+ * A {@code Closeable} is a source or destination of data that can be closed.
  * The close method is invoked to release resources that the object is
  * holding (such as open files).
  *
  * @since 1.5
  */
 
-public interface Closeable {
+public interface Closeable extends AutoCloseable {
 
     /**
      * Closes this stream and releases any system resources associated
@@ -45,5 +45,4 @@
      * @throws IOException if an I/O error occurs
      */
     public void close() throws IOException;
-
 }
--- a/src/share/classes/java/io/ObjectInput.java	Mon Jul 12 19:35:11 2010 -0700
+++ b/src/share/classes/java/io/ObjectInput.java	Mon Jul 12 19:42:02 2010 -0700
@@ -36,7 +36,7 @@
  * @see java.io.ObjectInputStream
  * @since   JDK1.1
  */
-public interface ObjectInput extends DataInput {
+public interface ObjectInput extends DataInput, AutoCloseable {
     /**
      * Read and return an object. The class that implements this interface
      * defines where the object is "read" from.
--- a/src/share/classes/java/io/ObjectOutput.java	Mon Jul 12 19:35:11 2010 -0700
+++ b/src/share/classes/java/io/ObjectOutput.java	Mon Jul 12 19:42:02 2010 -0700
@@ -36,7 +36,7 @@
  * @see java.io.ObjectInputStream
  * @since   JDK1.1
  */
-public interface ObjectOutput extends DataOutput {
+public interface ObjectOutput extends DataOutput, AutoCloseable {
     /**
      * Write an object to the underlying storage or stream.  The
      * class that implements this interface defines how the object is
--- a/src/share/classes/java/lang/AbstractStringBuilder.java	Mon Jul 12 19:35:11 2010 -0700
+++ b/src/share/classes/java/lang/AbstractStringBuilder.java	Mon Jul 12 19:42:02 2010 -0700
@@ -721,20 +721,19 @@
      * {@code codePoint} isn't a valid Unicode code point
      */
     public AbstractStringBuilder appendCodePoint(int codePoint) {
-        if (!Character.isValidCodePoint(codePoint)) {
+        final int count = this.count;
+
+        if (Character.isBmpCodePoint(codePoint)) {
+            ensureCapacityInternal(count + 1);
+            value[count] = (char) codePoint;
+            this.count = count + 1;
+        } else if (Character.isValidCodePoint(codePoint)) {
+            ensureCapacityInternal(count + 2);
+            Character.toSurrogates(codePoint, value, count);
+            this.count = count + 2;
+        } else {
             throw new IllegalArgumentException();
         }
-        int n = 1;
-        if (codePoint >= Character.MIN_SUPPLEMENTARY_CODE_POINT) {
-            n++;
-        }
-        ensureCapacityInternal(count + n);
-        if (n == 1) {
-            value[count++] = (char) codePoint;
-        } else {
-            Character.toSurrogates(codePoint, value, count);
-            count += n;
-        }
         return this;
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/lang/AutoCloseable.java	Mon Jul 12 19:42:02 2010 -0700
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.lang;
+
+/**
+ * A resource that must be closed when it is no longer needed.
+ *
+ * @author Josh Bloch
+ * @since 1.7
+ */
+public interface AutoCloseable {
+    /**
+     * Close this resource, relinquishing any underlying resources.
+     * This method is invoked automatically by the automatic resource
+     * management block construct.
+     *
+     * <p>Classes implementing this method are strongly encouraged to
+     * be declared to throw more specific exceptions (or no exception
+     * at all, if the close cannot fail).
+     *
+     * @throws Exception if this resource cannot be closed
+     */
+    void close() throws Exception;
+}
--- a/src/share/classes/java/lang/Character.java	Mon Jul 12 19:35:11 2010 -0700
+++ b/src/share/classes/java/lang/Character.java	Mon Jul 12 19:42:02 2010 -0700
@@ -24,6 +24,7 @@
  */
 
 package java.lang;
+
 import java.util.Arrays;
 import java.util.Map;
 import java.util.HashMap;
@@ -67,17 +68,16 @@
  * definition</i></a> of the U+<i>n</i> notation in the Unicode
  * standard.)
  *
- * <p>The set of characters from U+0000 to U+FFFF is sometimes
- * referred to as the <em>Basic Multilingual Plane (BMP)</em>. <a
- * name="supplementary">Characters</a> whose code points are greater
+ * <p><a name="BMP">The set of characters from U+0000 to U+FFFF is
+ * sometimes referred to as the <em>Basic Multilingual Plane (BMP)</em>.
+ * <a name="supplementary">Characters</a> whose code points are greater
  * than U+FFFF are called <em>supplementary character</em>s.  The Java
- * 2 platform uses the UTF-16 representation in <code>char</code>
- * arrays and in the <code>String</code> and <code>StringBuffer</code>
- * classes. In this representation, supplementary characters are
- * represented as a pair of <code>char</code> values, the first from
- * the <em>high-surrogates</em> range, (&#92;uD800-&#92;uDBFF), the
- * second from the <em>low-surrogates</em> range
- * (&#92;uDC00-&#92;uDFFF).
+ * platform uses the UTF-16 representation in <code>char</code> arrays and
+ * in the <code>String</code> and <code>StringBuffer</code> classes. In
+ * this representation, supplementary characters are represented as a pair
+ * of <code>char</code> values, the first from the <em>high-surrogates</em>
+ * range, (&#92;uD800-&#92;uDBFF), the second from the
+ * <em>low-surrogates</em> range (&#92;uDC00-&#92;uDFFF).
  *
  * <p>A <code>char</code> value, therefore, represents Basic
  * Multilingual Plane (BMP) code points, including the surrogate
@@ -115,10 +115,12 @@
  * @author  Lee Boynton
  * @author  Guy Steele
  * @author  Akira Tanaka
+ * @author  Martin Buchholz
+ * @author  Ulf Zibis
  * @since   1.0
  */
 public final
-class Character extends Object implements java.io.Serializable, Comparable<Character> {
+class Character implements java.io.Serializable, Comparable<Character> {
     /**
      * The minimum radix available for conversion to and from strings.
      * The constant value of this field is the smallest value permitted
@@ -127,10 +129,10 @@
      * method, and the <code>toString</code> method of class
      * <code>Integer</code>.
      *
-     * @see     java.lang.Character#digit(char, int)
-     * @see     java.lang.Character#forDigit(int, int)
-     * @see     java.lang.Integer#toString(int, int)
-     * @see     java.lang.Integer#valueOf(java.lang.String)
+     * @see     Character#digit(char, int)
+     * @see     Character#forDigit(int, int)
+     * @see     Integer#toString(int, int)
+     * @see     Integer#valueOf(String)
      */
     public static final int MIN_RADIX = 2;
 
@@ -142,10 +144,10 @@
      * method, and the <code>toString</code> method of class
      * <code>Integer</code>.
      *
-     * @see     java.lang.Character#digit(char, int)
-     * @see     java.lang.Character#forDigit(int, int)
-     * @see     java.lang.Integer#toString(int, int)
-     * @see     java.lang.Integer#valueOf(java.lang.String)
+     * @see     Character#digit(char, int)
+     * @see     Character#forDigit(int, int)
+     * @see     Integer#toString(int, int)
+     * @see     Integer#valueOf(String)
      */
     public static final int MAX_RADIX = 36;
 
@@ -155,7 +157,7 @@
      *
      * @since   1.0.2
      */
-    public static final char   MIN_VALUE = '\u0000';
+    public static final char MIN_VALUE = '\u0000';
 
     /**
      * The constant value of this field is the largest value of type
@@ -163,7 +165,7 @@
      *
      * @since   1.0.2
      */
-    public static final char   MAX_VALUE = '\uFFFF';
+    public static final char MAX_VALUE = '\uFFFF';
 
     /**
      * The <code>Class</code> instance representing the primitive type
@@ -171,230 +173,201 @@
      *
      * @since   1.1
      */
+    @SuppressWarnings("unchecked")
     public static final Class<Character> TYPE = Class.getPrimitiveClass("char");
 
-   /*
-    * Normative general types
-    */
-
-   /*
-    * General character types
-    */
-
-   /**
-    * General category "Cn" in the Unicode specification.
-    * @since   1.1
-    */
-    public static final byte
-        UNASSIGNED                  = 0;
-
-   /**
-    * General category "Lu" in the Unicode specification.
-    * @since   1.1
-    */
-    public static final byte
-        UPPERCASE_LETTER            = 1;
-
-   /**
-    * General category "Ll" in the Unicode specification.
-    * @since   1.1
-    */
-    public static final byte
-        LOWERCASE_LETTER            = 2;
-
-   /**
-    * General category "Lt" in the Unicode specification.
-    * @since   1.1
-    */
-    public static final byte
-        TITLECASE_LETTER            = 3;
-
-   /**
-    * General category "Lm" in the Unicode specification.
-    * @since   1.1
-    */
-    public static final byte
-        MODIFIER_LETTER             = 4;
-
-   /**
-    * General category "Lo" in the Unicode specification.
-    * @since   1.1
-    */
-    public static final byte
-        OTHER_LETTER                = 5;
-
-   /**
-    * General category "Mn" in the Unicode specification.
-    * @since   1.1
-    */
-    public static final byte
-        NON_SPACING_MARK            = 6;
-
-   /**
-    * General category "Me" in the Unicode specification.
-    * @since   1.1
-    */
-    public static final byte
-        ENCLOSING_MARK              = 7;
-
-   /**
-    * General category "Mc" in the Unicode specification.
-    * @since   1.1
-    */
-    public static final byte
-        COMBINING_SPACING_MARK      = 8;
-
-   /**
-    * General category "Nd" in the Unicode specification.
-    * @since   1.1
-    */
-    public static final byte
-        DECIMAL_DIGIT_NUMBER        = 9;
-
-   /**
-    * General category "Nl" in the Unicode specification.
-    * @since   1.1
-    */
-    public static final byte
-        LETTER_NUMBER               = 10;
-
-   /**
-    * General category "No" in the Unicode specification.
-    * @since   1.1
-    */
-    public static final byte
-        OTHER_NUMBER                = 11;
-
-   /**
-    * General category "Zs" in the Unicode specification.
-    * @since   1.1
-    */
-    public static final byte
-        SPACE_SEPARATOR             = 12;
-
-   /**
-    * General category "Zl" in the Unicode specification.
-    * @since   1.1
-    */
-    public static final byte
-        LINE_SEPARATOR              = 13;
-
-   /**
-    * General category "Zp" in the Unicode specification.
-    * @since   1.1
-    */
-    public static final byte
-        PARAGRAPH_SEPARATOR         = 14;
-
-   /**
-    * General category "Cc" in the Unicode specification.
-    * @since   1.1
-    */
-    public static final byte
-        CONTROL                     = 15;
-
-   /**
-    * General category "Cf" in the Unicode specification.
-    * @since   1.1
-    */
-    public static final byte
-        FORMAT                      = 16;
-
-   /**
-    * General category "Co" in the Unicode specification.
-    * @since   1.1
-    */
-    public static final byte
-        PRIVATE_USE                 = 18;
-
-   /**
-    * General category "Cs" in the Unicode specification.
-    * @since   1.1
-    */
-    public static final byte
-        SURROGATE                   = 19;
-
-   /**
-    * General category "Pd" in the Unicode specification.
-    * @since   1.1
-    */
-    public static final byte
-        DASH_PUNCTUATION            = 20;
-
-   /**
-    * General category "Ps" in the Unicode specification.
-    * @since   1.1
-    */
-    public static final byte
-        START_PUNCTUATION           = 21;
-
-   /**
-    * General category "Pe" in the Unicode specification.
-    * @since   1.1
-    */
-    public static final byte
-        END_PUNCTUATION             = 22;
-
-   /**
-    * General category "Pc" in the Unicode specification.
-    * @since   1.1
-    */
-    public static final byte
-        CONNECTOR_PUNCTUATION       = 23;
-
-   /**
-    * General category "Po" in the Unicode specification.
-    * @since   1.1
-    */
-    public static final byte
-        OTHER_PUNCTUATION           = 24;
-
-   /**
-    * General category "Sm" in the Unicode specification.
-    * @since   1.1
-    */
-    public static final byte
-        MATH_SYMBOL                 = 25;
-
-   /**
-    * General category "Sc" in the Unicode specification.
-    * @since   1.1
-    */
-    public static final byte
-        CURRENCY_SYMBOL             = 26;
-
-   /**
-    * General category "Sk" in the Unicode specification.
-    * @since   1.1
-    */
-    public static final byte
-        MODIFIER_SYMBOL             = 27;
-
-   /**
-    * General category "So" in the Unicode specification.
-    * @since   1.1
-    */
-    public static final byte
-        OTHER_SYMBOL                = 28;
-
-   /**
-    * General category "Pi" in the Unicode specification.
-    * @since   1.4
-    */
-    public static final byte
-        INITIAL_QUOTE_PUNCTUATION   = 29;
-
-   /**
-    * General category "Pf" in the Unicode specification.
-    * @since   1.4
-    */
-    public static final byte
-        FINAL_QUOTE_PUNCTUATION     = 30;
+    /*
+     * Normative general types
+     */
+
+    /*
+     * General character types
+     */
+
+    /**
+     * General category "Cn" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte UNASSIGNED = 0;
+
+    /**
+     * General category "Lu" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte UPPERCASE_LETTER = 1;
+
+    /**
+     * General category "Ll" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte LOWERCASE_LETTER = 2;
+
+    /**
+     * General category "Lt" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte TITLECASE_LETTER = 3;
+
+    /**
+     * General category "Lm" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte MODIFIER_LETTER = 4;
+
+    /**
+     * General category "Lo" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte OTHER_LETTER = 5;
+
+    /**
+     * General category "Mn" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte NON_SPACING_MARK = 6;
+
+    /**
+     * General category "Me" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte ENCLOSING_MARK = 7;
+
+    /**
+     * General category "Mc" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte COMBINING_SPACING_MARK = 8;
+
+    /**
+     * General category "Nd" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte DECIMAL_DIGIT_NUMBER        = 9;
+
+    /**
+     * General category "Nl" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte LETTER_NUMBER = 10;
+
+    /**
+     * General category "No" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte OTHER_NUMBER = 11;
+
+    /**
+     * General category "Zs" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte SPACE_SEPARATOR = 12;
+
+    /**
+     * General category "Zl" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte LINE_SEPARATOR = 13;
+
+    /**
+     * General category "Zp" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte PARAGRAPH_SEPARATOR = 14;
+
+    /**
+     * General category "Cc" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte CONTROL = 15;
+
+    /**
+     * General category "Cf" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte FORMAT = 16;
+
+    /**
+     * General category "Co" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte PRIVATE_USE = 18;
+
+    /**
+     * General category "Cs" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte SURROGATE = 19;
+
+    /**
+     * General category "Pd" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte DASH_PUNCTUATION = 20;
+
+    /**
+     * General category "Ps" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte START_PUNCTUATION = 21;
+
+    /**
+     * General category "Pe" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte END_PUNCTUATION = 22;
+
+    /**
+     * General category "Pc" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte CONNECTOR_PUNCTUATION = 23;
+
+    /**
+     * General category "Po" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte OTHER_PUNCTUATION = 24;
+
+    /**
+     * General category "Sm" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte MATH_SYMBOL = 25;
+
+    /**
+     * General category "Sc" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte CURRENCY_SYMBOL = 26;
+
+    /**
+     * General category "Sk" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte MODIFIER_SYMBOL = 27;
+
+    /**
+     * General category "So" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte OTHER_SYMBOL = 28;
+
+    /**
+     * General category "Pi" in the Unicode specification.
+     * @since   1.4
+     */
+    public static final byte INITIAL_QUOTE_PUNCTUATION = 29;
+
+    /**
+     * General category "Pf" in the Unicode specification.
+     * @since   1.4
+     */
+    public static final byte FINAL_QUOTE_PUNCTUATION = 30;
 
     /**
      * Error flag. Use int (code point) to avoid confusion with U+FFFF.
      */
-     static final int ERROR = 0xFFFFFFFF;
+    static final int ERROR = 0xFFFFFFFF;
 
 
     /**
@@ -402,7 +375,7 @@
      * values have undefined directionality in the Unicode specification.
      * @since 1.4
      */
-     public static final byte DIRECTIONALITY_UNDEFINED = -1;
+    public static final byte DIRECTIONALITY_UNDEFINED = -1;
 
     /**
      * Strong bidirectional character type "L" in the Unicode specification.
@@ -609,9 +582,9 @@
     /**
      * Instances of this class represent particular subsets of the Unicode
      * character set.  The only family of subsets defined in the
-     * <code>Character</code> class is <code>{@link Character.UnicodeBlock
-     * UnicodeBlock}</code>.  Other portions of the Java API may define other
-     * subsets for their own purposes.
+     * <code>Character</code> class is {@link Character.UnicodeBlock}.
+     * Other portions of the Java API may define other subsets for their
+     * own purposes.
      *
      * @since 1.2
      */
@@ -624,6 +597,7 @@
          *
          * @exception NullPointerException if name is <code>null</code>
          * @param  name  The name of this subset
+         * @exception NullPointerException if name is <code>null</code>
          */
         protected Subset(String name) {
             if (name == null) {
@@ -662,6 +636,9 @@
         }
     }
 
+    // See http://www.unicode.org/Public/UNIDATA/Blocks.txt
+    // for the latest specification of Unicode Blocks.
+
     /**
      * A family of character subsets representing the character blocks in the
      * Unicode specification. Character blocks generally define characters
@@ -672,37 +649,35 @@
      */
     public static final class UnicodeBlock extends Subset {
 
-        private static Map map = new HashMap();
-
-        /**
-         * Create a UnicodeBlock with the given identifier name.
+        private static Map<String, UnicodeBlock> map
+            = new HashMap<String, UnicodeBlock>(256);
+
+        /**
+         * Creates a UnicodeBlock with the given identifier name.
          * This name must be the same as the block identifier.
          */
         private UnicodeBlock(String idName) {
             super(idName);
-            map.put(idName.toUpperCase(Locale.US), this);
+            map.put(idName, this);
         }
 
         /**
-         * Create a UnicodeBlock with the given identifier name and
+         * Creates a UnicodeBlock with the given identifier name and
          * alias name.
          */
         private UnicodeBlock(String idName, String alias) {
             this(idName);
-            map.put(alias.toUpperCase(Locale.US), this);
+            map.put(alias, this);
         }
 
         /**
-         * Create a UnicodeBlock with the given identifier name and
+         * Creates a UnicodeBlock with the given identifier name and
          * alias names.
          */
-        private UnicodeBlock(String idName, String[] aliasName) {
+        private UnicodeBlock(String idName, String... aliases) {
             this(idName);
-            if (aliasName != null) {
-                for(int x=0; x<aliasName.length; ++x) {
-                    map.put(aliasName[x].toUpperCase(Locale.US), this);
-                }
-            }
+            for (String alias : aliases)
+                map.put(alias, this);
         }
 
         /**
@@ -710,51 +685,63 @@
          * @since 1.2
          */
         public static final UnicodeBlock  BASIC_LATIN =
-            new UnicodeBlock("BASIC_LATIN", new String[] {"Basic Latin", "BasicLatin" });
+            new UnicodeBlock("BASIC_LATIN",
+                             "BASIC LATIN",
+                             "BASICLATIN");
 
         /**
          * Constant for the "Latin-1 Supplement" Unicode character block.
          * @since 1.2
          */
         public static final UnicodeBlock LATIN_1_SUPPLEMENT =
-            new UnicodeBlock("LATIN_1_SUPPLEMENT", new String[]{ "Latin-1 Supplement", "Latin-1Supplement"});
+            new UnicodeBlock("LATIN_1_SUPPLEMENT",
+                             "LATIN-1 SUPPLEMENT",
+                             "LATIN-1SUPPLEMENT");
 
         /**
          * Constant for the "Latin Extended-A" Unicode character block.
          * @since 1.2
          */
         public static final UnicodeBlock LATIN_EXTENDED_A =
-            new UnicodeBlock("LATIN_EXTENDED_A", new String[]{ "Latin Extended-A", "LatinExtended-A"});
+            new UnicodeBlock("LATIN_EXTENDED_A",
+                             "LATIN EXTENDED-A",
+                             "LATINEXTENDED-A");
 
         /**
          * Constant for the "Latin Extended-B" Unicode character block.
          * @since 1.2
          */
         public static final UnicodeBlock LATIN_EXTENDED_B =
-            new UnicodeBlock("LATIN_EXTENDED_B", new String[] {"Latin Extended-B", "LatinExtended-B"});
+            new UnicodeBlock("LATIN_EXTENDED_B",
+                             "LATIN EXTENDED-B",
+                             "LATINEXTENDED-B");
 
         /**
          * Constant for the "IPA Extensions" Unicode character block.
          * @since 1.2
          */
         public static final UnicodeBlock IPA_EXTENSIONS =
-            new UnicodeBlock("IPA_EXTENSIONS", new String[] {"IPA Extensions", "IPAExtensions"});
+            new UnicodeBlock("IPA_EXTENSIONS",
+                             "IPA EXTENSIONS",
+                             "IPAEXTENSIONS");
 
         /**
          * Constant for the "Spacing Modifier Letters" Unicode character block.
          * @since 1.2
          */
         public static final UnicodeBlock SPACING_MODIFIER_LETTERS =
-            new UnicodeBlock("SPACING_MODIFIER_LETTERS", new String[] { "Spacing Modifier Letters",
-                                                                        "SpacingModifierLetters"});
+            new UnicodeBlock("SPACING_MODIFIER_LETTERS",
+                             "SPACING MODIFIER LETTERS",
+                             "SPACINGMODIFIERLETTERS");
 
         /**
          * Constant for the "Combining Diacritical Marks" Unicode character block.
          * @since 1.2
          */
         public static final UnicodeBlock COMBINING_DIACRITICAL_MARKS =
-            new UnicodeBlock("COMBINING_DIACRITICAL_MARKS", new String[] {"Combining Diacritical Marks",
-                                                                          "CombiningDiacriticalMarks" });
+            new UnicodeBlock("COMBINING_DIACRITICAL_MARKS",
+                             "COMBINING DIACRITICAL MARKS",
+                             "COMBININGDIACRITICALMARKS");
 
         /**
          * Constant for the "Greek and Coptic" Unicode character block.
@@ -763,8 +750,10 @@
          *
          * @since 1.2
          */
-        public static final UnicodeBlock GREEK
-            = new UnicodeBlock("GREEK", new String[] {"Greek and Coptic", "GreekandCoptic"});
+        public static final UnicodeBlock GREEK =
+            new UnicodeBlock("GREEK",
+                             "GREEK AND COPTIC",
+                             "GREEKANDCOPTIC");
 
         /**
          * Constant for the "Cyrillic" Unicode character block.
@@ -890,44 +879,54 @@
          * @since 1.2
          */
         public static final UnicodeBlock HANGUL_JAMO =
-            new UnicodeBlock("HANGUL_JAMO", new String[] {"Hangul Jamo", "HangulJamo"});
+            new UnicodeBlock("HANGUL_JAMO",
+                             "HANGUL JAMO",
+                             "HANGULJAMO");
 
         /**
          * Constant for the "Latin Extended Additional" Unicode character block.
          * @since 1.2
          */
         public static final UnicodeBlock LATIN_EXTENDED_ADDITIONAL =
-            new UnicodeBlock("LATIN_EXTENDED_ADDITIONAL", new String[] {"Latin Extended Additional",
-                                                                        "LatinExtendedAdditional"});
+            new UnicodeBlock("LATIN_EXTENDED_ADDITIONAL",
+                             "LATIN EXTENDED ADDITIONAL",
+                             "LATINEXTENDEDADDITIONAL");
 
         /**
          * Constant for the "Greek Extended" Unicode character block.
          * @since 1.2
          */
         public static final UnicodeBlock GREEK_EXTENDED =
-            new UnicodeBlock("GREEK_EXTENDED", new String[] {"Greek Extended", "GreekExtended"});
+            new UnicodeBlock("GREEK_EXTENDED",
+                             "GREEK EXTENDED",
+                             "GREEKEXTENDED");
 
         /**
          * Constant for the "General Punctuation" Unicode character block.
          * @since 1.2
          */
         public static final UnicodeBlock GENERAL_PUNCTUATION =
-            new UnicodeBlock("GENERAL_PUNCTUATION", new String[] {"General Punctuation", "GeneralPunctuation"});
+            new UnicodeBlock("GENERAL_PUNCTUATION",
+                             "GENERAL PUNCTUATION",
+                             "GENERALPUNCTUATION");
 
         /**
          * Constant for the "Superscripts and Subscripts" Unicode character block.
          * @since 1.2
          */
         public static final UnicodeBlock SUPERSCRIPTS_AND_SUBSCRIPTS =
-            new UnicodeBlock("SUPERSCRIPTS_AND_SUBSCRIPTS", new String[] {"Superscripts and Subscripts",
-                                                                          "SuperscriptsandSubscripts" });
+            new UnicodeBlock("SUPERSCRIPTS_AND_SUBSCRIPTS",
+                             "SUPERSCRIPTS AND SUBSCRIPTS",
+                             "SUPERSCRIPTSANDSUBSCRIPTS");
 
         /**
          * Constant for the "Currency Symbols" Unicode character block.
          * @since 1.2
          */
         public static final UnicodeBlock CURRENCY_SYMBOLS =
-            new UnicodeBlock("CURRENCY_SYMBOLS", new String[] { "Currency Symbols", "CurrencySymbols"});
+            new UnicodeBlock("CURRENCY_SYMBOLS",
+                             "CURRENCY SYMBOLS",
+                             "CURRENCYSYMBOLS");
 
         /**
          * Constant for the "Combining Diacritical Marks for Symbols" Unicode character block.
@@ -936,24 +935,29 @@
          * @since 1.2
          */
         public static final UnicodeBlock COMBINING_MARKS_FOR_SYMBOLS =
-            new UnicodeBlock("COMBINING_MARKS_FOR_SYMBOLS", new String[] {"Combining Diacritical Marks for Symbols",
-                                                                                                                                                   "CombiningDiacriticalMarksforSymbols",
-                                                                           "Combining Marks for Symbols",
-                                                                           "CombiningMarksforSymbols" });
+            new UnicodeBlock("COMBINING_MARKS_FOR_SYMBOLS",
+                             "COMBINING DIACRITICAL MARKS FOR SYMBOLS",
+                             "COMBININGDIACRITICALMARKSFORSYMBOLS",
+                             "COMBINING MARKS FOR SYMBOLS",
+                             "COMBININGMARKSFORSYMBOLS");
 
         /**
          * Constant for the "Letterlike Symbols" Unicode character block.
          * @since 1.2
          */
         public static final UnicodeBlock LETTERLIKE_SYMBOLS =
-            new UnicodeBlock("LETTERLIKE_SYMBOLS", new String[] { "Letterlike Symbols", "LetterlikeSymbols"});
+            new UnicodeBlock("LETTERLIKE_SYMBOLS",
+                             "LETTERLIKE SYMBOLS",
+                             "LETTERLIKESYMBOLS");
 
         /**
          * Constant for the "Number Forms" Unicode character block.
          * @since 1.2
          */
         public static final UnicodeBlock NUMBER_FORMS =
-            new UnicodeBlock("NUMBER_FORMS", new String[] {"Number Forms", "NumberForms"});
+            new UnicodeBlock("NUMBER_FORMS",
+                             "NUMBER FORMS",
+                             "NUMBERFORMS");
 
         /**
          * Constant for the "Arrows" Unicode character block.
@@ -967,68 +971,81 @@
          * @since 1.2
          */
         public static final UnicodeBlock MATHEMATICAL_OPERATORS =
-            new UnicodeBlock("MATHEMATICAL_OPERATORS", new String[] {"Mathematical Operators",
-                                                                     "MathematicalOperators"});
+            new UnicodeBlock("MATHEMATICAL_OPERATORS",
+                             "MATHEMATICAL OPERATORS",
+                             "MATHEMATICALOPERATORS");
 
         /**
          * Constant for the "Miscellaneous Technical" Unicode character block.
          * @since 1.2
          */
         public static final UnicodeBlock MISCELLANEOUS_TECHNICAL =
-            new UnicodeBlock("MISCELLANEOUS_TECHNICAL", new String[] {"Miscellaneous Technical",
-                                                                      "MiscellaneousTechnical"});
+            new UnicodeBlock("MISCELLANEOUS_TECHNICAL",
+                             "MISCELLANEOUS TECHNICAL",
+                             "MISCELLANEOUSTECHNICAL");
 
         /**
          * Constant for the "Control Pictures" Unicode character block.
          * @since 1.2
          */
         public static final UnicodeBlock CONTROL_PICTURES =
-            new UnicodeBlock("CONTROL_PICTURES", new String[] {"Control Pictures", "ControlPictures"});
+            new UnicodeBlock("CONTROL_PICTURES",
+                             "CONTROL PICTURES",
+                             "CONTROLPICTURES");
 
         /**
          * Constant for the "Optical Character Recognition" Unicode character block.
          * @since 1.2
          */
         public static final UnicodeBlock OPTICAL_CHARACTER_RECOGNITION =
-            new UnicodeBlock("OPTICAL_CHARACTER_RECOGNITION", new String[] {"Optical Character Recognition",
-                                                                            "OpticalCharacterRecognition"});
+            new UnicodeBlock("OPTICAL_CHARACTER_RECOGNITION",
+                             "OPTICAL CHARACTER RECOGNITION",
+                             "OPTICALCHARACTERRECOGNITION");
 
         /**
          * Constant for the "Enclosed Alphanumerics" Unicode character block.
          * @since 1.2
          */
         public static final UnicodeBlock ENCLOSED_ALPHANUMERICS =
-            new UnicodeBlock("ENCLOSED_ALPHANUMERICS", new String[] {"Enclosed Alphanumerics",
-                                                                     "EnclosedAlphanumerics"});
+            new UnicodeBlock("ENCLOSED_ALPHANUMERICS",
+                             "ENCLOSED ALPHANUMERICS",
+                             "ENCLOSEDALPHANUMERICS");
 
         /**
          * Constant for the "Box Drawing" Unicode character block.
          * @since 1.2
          */
         public static final UnicodeBlock BOX_DRAWING =
-            new UnicodeBlock("BOX_DRAWING", new String[] {"Box Drawing", "BoxDrawing"});
+            new UnicodeBlock("BOX_DRAWING",
+                             "BOX DRAWING",
+                             "BOXDRAWING");
 
         /**
          * Constant for the "Block Elements" Unicode character block.
          * @since 1.2
          */
         public static final UnicodeBlock BLOCK_ELEMENTS =
-            new UnicodeBlock("BLOCK_ELEMENTS", new String[] {"Block Elements", "BlockElements"});
+            new UnicodeBlock("BLOCK_ELEMENTS",
+                             "BLOCK ELEMENTS",
+                             "BLOCKELEMENTS");
 
         /**
          * Constant for the "Geometric Shapes" Unicode character block.
          * @since 1.2
          */
         public static final UnicodeBlock GEOMETRIC_SHAPES =
-            new UnicodeBlock("GEOMETRIC_SHAPES", new String[] {"Geometric Shapes", "GeometricShapes"});
+            new UnicodeBlock("GEOMETRIC_SHAPES",
+                             "GEOMETRIC SHAPES",
+                             "GEOMETRICSHAPES");
 
         /**
          * Constant for the "Miscellaneous Symbols" Unicode character block.
          * @since 1.2
          */
         public static final UnicodeBlock MISCELLANEOUS_SYMBOLS =
-            new UnicodeBlock("MISCELLANEOUS_SYMBOLS", new String[] {"Miscellaneous Symbols",
-                                                                    "MiscellaneousSymbols"});
+            new UnicodeBlock("MISCELLANEOUS_SYMBOLS",
+                             "MISCELLANEOUS SYMBOLS",
+                             "MISCELLANEOUSSYMBOLS");
 
         /**
          * Constant for the "Dingbats" Unicode character block.
@@ -1042,8 +1059,9 @@
          * @since 1.2
          */
         public static final UnicodeBlock CJK_SYMBOLS_AND_PUNCTUATION =
-            new UnicodeBlock("CJK_SYMBOLS_AND_PUNCTUATION", new String[] {"CJK Symbols and Punctuation",
-                                                                          "CJKSymbolsandPunctuation"});
+            new UnicodeBlock("CJK_SYMBOLS_AND_PUNCTUATION",
+                             "CJK SYMBOLS AND PUNCTUATION",
+                             "CJKSYMBOLSANDPUNCTUATION");
 
         /**
          * Constant for the "Hiragana" Unicode character block.
@@ -1071,8 +1089,9 @@
          * @since 1.2
          */
         public static final UnicodeBlock HANGUL_COMPATIBILITY_JAMO =
-            new UnicodeBlock("HANGUL_COMPATIBILITY_JAMO", new String[] {"Hangul Compatibility Jamo",
-                                                                        "HangulCompatibilityJamo"});
+            new UnicodeBlock("HANGUL_COMPATIBILITY_JAMO",
+                             "HANGUL COMPATIBILITY JAMO",
+                             "HANGULCOMPATIBILITYJAMO");
 
         /**
          * Constant for the "Kanbun" Unicode character block.
@@ -1086,37 +1105,45 @@
          * @since 1.2
          */
         public static final UnicodeBlock ENCLOSED_CJK_LETTERS_AND_MONTHS =
-            new UnicodeBlock("ENCLOSED_CJK_LETTERS_AND_MONTHS", new String[] {"Enclosed CJK Letters and Months",
-                                                                              "EnclosedCJKLettersandMonths"});
+            new UnicodeBlock("ENCLOSED_CJK_LETTERS_AND_MONTHS",
+                             "ENCLOSED CJK LETTERS AND MONTHS",
+                             "ENCLOSEDCJKLETTERSANDMONTHS");
 
         /**
          * Constant for the "CJK Compatibility" Unicode character block.
          * @since 1.2
          */
         public static final UnicodeBlock CJK_COMPATIBILITY =
-            new UnicodeBlock("CJK_COMPATIBILITY", new String[] {"CJK Compatibility", "CJKCompatibility"});
+            new UnicodeBlock("CJK_COMPATIBILITY",
+                             "CJK COMPATIBILITY",
+                             "CJKCOMPATIBILITY");
 
         /**
          * Constant for the "CJK Unified Ideographs" Unicode character block.
          * @since 1.2
          */
         public static final UnicodeBlock CJK_UNIFIED_IDEOGRAPHS =
-            new UnicodeBlock("CJK_UNIFIED_IDEOGRAPHS", new String[] {"CJK Unified Ideographs",
-                                                                     "CJKUnifiedIdeographs"});
+            new UnicodeBlock("CJK_UNIFIED_IDEOGRAPHS",
+                             "CJK UNIFIED IDEOGRAPHS",
+                             "CJKUNIFIEDIDEOGRAPHS");
 
         /**
          * Constant for the "Hangul Syllables" Unicode character block.
          * @since 1.2
          */
         public static final UnicodeBlock HANGUL_SYLLABLES =
-            new UnicodeBlock("HANGUL_SYLLABLES", new String[] {"Hangul Syllables", "HangulSyllables"});
+            new UnicodeBlock("HANGUL_SYLLABLES",
+                             "HANGUL SYLLABLES",
+                             "HANGULSYLLABLES");
 
         /**
          * Constant for the "Private Use Area" Unicode character block.
          * @since 1.2
          */
         public static final UnicodeBlock PRIVATE_USE_AREA =
-            new UnicodeBlock("PRIVATE_USE_AREA", new String[] {"Private Use Area", "PrivateUseArea"});
+            new UnicodeBlock("PRIVATE_USE_AREA",
+                             "PRIVATE USE AREA",
+                             "PRIVATEUSEAREA");
 
         /**
          * Constant for the "CJK Compatibility Ideographs" Unicode character block.
@@ -1124,56 +1151,62 @@
          */
         public static final UnicodeBlock CJK_COMPATIBILITY_IDEOGRAPHS =
             new UnicodeBlock("CJK_COMPATIBILITY_IDEOGRAPHS",
-                             new String[] {"CJK Compatibility Ideographs",
-                                           "CJKCompatibilityIdeographs"});
+                             "CJK COMPATIBILITY IDEOGRAPHS",
+                             "CJKCOMPATIBILITYIDEOGRAPHS");
 
         /**
          * Constant for the "Alphabetic Presentation Forms" Unicode character block.
          * @since 1.2
          */
         public static final UnicodeBlock ALPHABETIC_PRESENTATION_FORMS =
-            new UnicodeBlock("ALPHABETIC_PRESENTATION_FORMS", new String[] {"Alphabetic Presentation Forms",
-                                                                            "AlphabeticPresentationForms"});
+            new UnicodeBlock("ALPHABETIC_PRESENTATION_FORMS",
+                             "ALPHABETIC PRESENTATION FORMS",
+                             "ALPHABETICPRESENTATIONFORMS");
 
         /**
          * Constant for the "Arabic Presentation Forms-A" Unicode character block.
          * @since 1.2
          */
         public static final UnicodeBlock ARABIC_PRESENTATION_FORMS_A =
-            new UnicodeBlock("ARABIC_PRESENTATION_FORMS_A", new String[] {"Arabic Presentation Forms-A",
-                                                                          "ArabicPresentationForms-A"});
+            new UnicodeBlock("ARABIC_PRESENTATION_FORMS_A",
+                             "ARABIC PRESENTATION FORMS-A",
+                             "ARABICPRESENTATIONFORMS-A");
 
         /**
          * Constant for the "Combining Half Marks" Unicode character block.
          * @since 1.2
          */
         public static final UnicodeBlock COMBINING_HALF_MARKS =
-            new UnicodeBlock("COMBINING_HALF_MARKS", new String[] {"Combining Half Marks",
-                                                                   "CombiningHalfMarks"});
+            new UnicodeBlock("COMBINING_HALF_MARKS",
+                             "COMBINING HALF MARKS",
+                             "COMBININGHALFMARKS");
 
         /**
          * Constant for the "CJK Compatibility Forms" Unicode character block.
          * @since 1.2
          */
         public static final UnicodeBlock CJK_COMPATIBILITY_FORMS =
-            new UnicodeBlock("CJK_COMPATIBILITY_FORMS", new String[] {"CJK Compatibility Forms",
-                                                                      "CJKCompatibilityForms"});
+            new UnicodeBlock("CJK_COMPATIBILITY_FORMS",
+                             "CJK COMPATIBILITY FORMS",
+                             "CJKCOMPATIBILITYFORMS");
 
         /**
          * Constant for the "Small Form Variants" Unicode character block.
          * @since 1.2
          */
         public static final UnicodeBlock SMALL_FORM_VARIANTS =
-            new UnicodeBlock("SMALL_FORM_VARIANTS", new String[] {"Small Form Variants",
-                                                                  "SmallFormVariants"});
+            new UnicodeBlock("SMALL_FORM_VARIANTS",
+                             "SMALL FORM VARIANTS",
+                             "SMALLFORMVARIANTS");
 
         /**
          * Constant for the "Arabic Presentation Forms-B" Unicode character block.
          * @since 1.2
          */
         public static final UnicodeBlock ARABIC_PRESENTATION_FORMS_B =
-            new UnicodeBlock("ARABIC_PRESENTATION_FORMS_B", new String[] {"Arabic Presentation Forms-B",
-                                                                          "ArabicPresentationForms-B"});
+            new UnicodeBlock("ARABIC_PRESENTATION_FORMS_B",
+                             "ARABIC PRESENTATION FORMS-B",
+                             "ARABICPRESENTATIONFORMS-B");
 
         /**
          * Constant for the "Halfwidth and Fullwidth Forms" Unicode character block.
@@ -1181,8 +1214,8 @@
          */
         public static final UnicodeBlock HALFWIDTH_AND_FULLWIDTH_FORMS =
             new UnicodeBlock("HALFWIDTH_AND_FULLWIDTH_FORMS",
-                             new String[] {"Halfwidth and Fullwidth Forms",
-                                           "HalfwidthandFullwidthForms"});
+                             "HALFWIDTH AND FULLWIDTH FORMS",
+                             "HALFWIDTHANDFULLWIDTHFORMS");
 
         /**
          * Constant for the "Specials" Unicode character block.
@@ -1251,97 +1284,108 @@
          */
         public static final UnicodeBlock UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS =
             new UnicodeBlock("UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS",
-                             new String[] {"Unified Canadian Aboriginal Syllabics",
-                                           "UnifiedCanadianAboriginalSyllabics"});
+                             "UNIFIED CANADIAN ABORIGINAL SYLLABICS",
+                             "UNIFIEDCANADIANABORIGINALSYLLABICS");
 
         /**
          * Constant for the "Ogham" Unicode character block.
          * @since 1.4
          */
         public static final UnicodeBlock OGHAM =
-                             new UnicodeBlock("OGHAM");
+            new UnicodeBlock("OGHAM");
 
         /**
          * Constant for the "Runic" Unicode character block.
          * @since 1.4
          */
         public static final UnicodeBlock RUNIC =
-                             new UnicodeBlock("RUNIC");
+            new UnicodeBlock("RUNIC");
 
         /**
          * Constant for the "Khmer" Unicode character block.
          * @since 1.4
          */
         public static final UnicodeBlock KHMER =
-                             new UnicodeBlock("KHMER");
+            new UnicodeBlock("KHMER");
 
         /**
          * Constant for the "Mongolian" Unicode character block.
          * @since 1.4
          */
         public static final UnicodeBlock MONGOLIAN =
-                             new UnicodeBlock("MONGOLIAN");
+            new UnicodeBlock("MONGOLIAN");
 
         /**
          * Constant for the "Braille Patterns" Unicode character block.
          * @since 1.4
          */
         public static final UnicodeBlock BRAILLE_PATTERNS =
-            new UnicodeBlock("BRAILLE_PATTERNS", new String[] {"Braille Patterns",
-                                                               "BraillePatterns"});
+            new UnicodeBlock("BRAILLE_PATTERNS",
+                             "BRAILLE PATTERNS",
+                             "BRAILLEPATTERNS");
 
         /**
          * Constant for the "CJK Radicals Supplement" Unicode character block.
          * @since 1.4
          */
         public static final UnicodeBlock CJK_RADICALS_SUPPLEMENT =
-             new UnicodeBlock("CJK_RADICALS_SUPPLEMENT", new String[] {"CJK Radicals Supplement",
-                                                                       "CJKRadicalsSupplement"});
+            new UnicodeBlock("CJK_RADICALS_SUPPLEMENT",
+                             "CJK RADICALS SUPPLEMENT",
+                             "CJKRADICALSSUPPLEMENT");
 
         /**
          * Constant for the "Kangxi Radicals" Unicode character block.
          * @since 1.4
          */
         public static final UnicodeBlock KANGXI_RADICALS =
-            new UnicodeBlock("KANGXI_RADICALS", new String[] {"Kangxi Radicals", "KangxiRadicals"});
+            new UnicodeBlock("KANGXI_RADICALS",
+                             "KANGXI RADICALS",
+                             "KANGXIRADICALS");
 
         /**
          * Constant for the "Ideographic Description Characters" Unicode character block.
          * @since 1.4
          */
         public static final UnicodeBlock IDEOGRAPHIC_DESCRIPTION_CHARACTERS =
-            new UnicodeBlock("IDEOGRAPHIC_DESCRIPTION_CHARACTERS", new String[] {"Ideographic Description Characters",
-                                                                                 "IdeographicDescriptionCharacters"});
+            new UnicodeBlock("IDEOGRAPHIC_DESCRIPTION_CHARACTERS",
+                             "IDEOGRAPHIC DESCRIPTION CHARACTERS",
+                             "IDEOGRAPHICDESCRIPTIONCHARACTERS");
 
         /**
          * Constant for the "Bopomofo Extended" Unicode character block.
          * @since 1.4
          */
         public static final UnicodeBlock BOPOMOFO_EXTENDED =
-            new UnicodeBlock("BOPOMOFO_EXTENDED", new String[] {"Bopomofo Extended",
-                                                                "BopomofoExtended"});
+            new UnicodeBlock("BOPOMOFO_EXTENDED",
+                             "BOPOMOFO EXTENDED",
+                             "BOPOMOFOEXTENDED");
 
         /**
          * Constant for the "CJK Unified Ideographs Extension A" Unicode character block.
          * @since 1.4
          */
         public static final UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A =
-            new UnicodeBlock("CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A", new String[] {"CJK Unified Ideographs Extension A",
-                                                                                 "CJKUnifiedIdeographsExtensionA"});
+            new UnicodeBlock("CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A",
+                             "CJK UNIFIED IDEOGRAPHS EXTENSION A",
+                             "CJKUNIFIEDIDEOGRAPHSEXTENSIONA");
 
         /**
          * Constant for the "Yi Syllables" Unicode character block.
          * @since 1.4
          */
         public static final UnicodeBlock YI_SYLLABLES =
-            new UnicodeBlock("YI_SYLLABLES", new String[] {"Yi Syllables", "YiSyllables"});
+            new UnicodeBlock("YI_SYLLABLES",
+                             "YI SYLLABLES",
+                             "YISYLLABLES");
 
         /**
          * Constant for the "Yi Radicals" Unicode character block.
          * @since 1.4
          */
         public static final UnicodeBlock YI_RADICALS =
-            new UnicodeBlock("YI_RADICALS", new String[] {"Yi Radicals", "YiRadicals"});
+            new UnicodeBlock("YI_RADICALS",
+                             "YI RADICALS",
+                             "YIRADICALS");
 
 
         /**
@@ -1350,10 +1394,10 @@
          */
         public static final UnicodeBlock CYRILLIC_SUPPLEMENTARY =
             new UnicodeBlock("CYRILLIC_SUPPLEMENTARY",
-                             new String[] {"Cyrillic Supplementary",
-                                           "CyrillicSupplementary",
-                                           "Cyrillic Supplement",
-                                           "CyrillicSupplement"});
+                             "CYRILLIC SUPPLEMENTARY",
+                             "CYRILLICSUPPLEMENTARY",
+                             "CYRILLIC SUPPLEMENT",
+                             "CYRILLICSUPPLEMENT");
 
         /**
          * Constant for the "Tagalog" Unicode character block.
@@ -1395,21 +1439,27 @@
          * @since 1.5
          */
         public static final UnicodeBlock TAI_LE =
-            new UnicodeBlock("TAI_LE", new String[] {"Tai Le", "TaiLe"});
+            new UnicodeBlock("TAI_LE",
+                             "TAI LE",
+                             "TAILE");
 
         /**
          * Constant for the "Khmer Symbols" Unicode character block.
          * @since 1.5
          */
         public static final UnicodeBlock KHMER_SYMBOLS =
-            new UnicodeBlock("KHMER_SYMBOLS", new String[] {"Khmer Symbols", "KhmerSymbols"});
+            new UnicodeBlock("KHMER_SYMBOLS",
+                             "KHMER SYMBOLS",
+                             "KHMERSYMBOLS");
 
         /**
          * Constant for the "Phonetic Extensions" Unicode character block.
          * @since 1.5
          */
         public static final UnicodeBlock PHONETIC_EXTENSIONS =
-            new UnicodeBlock("PHONETIC_EXTENSIONS", new String[] {"Phonetic Extensions", "PhoneticExtensions"});
+            new UnicodeBlock("PHONETIC_EXTENSIONS",
+                             "PHONETIC EXTENSIONS",
+                             "PHONETICEXTENSIONS");
 
         /**
          * Constant for the "Miscellaneous Mathematical Symbols-A" Unicode character block.
@@ -1417,33 +1467,35 @@
          */
         public static final UnicodeBlock MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A =
             new UnicodeBlock("MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A",
-                             new String[]{"Miscellaneous Mathematical Symbols-A",
-                                          "MiscellaneousMathematicalSymbols-A"});
+                             "MISCELLANEOUS MATHEMATICAL SYMBOLS-A",
+                             "MISCELLANEOUSMATHEMATICALSYMBOLS-A");
 
         /**
          * Constant for the "Supplemental Arrows-A" Unicode character block.
          * @since 1.5
          */
         public static final UnicodeBlock SUPPLEMENTAL_ARROWS_A =
-            new UnicodeBlock("SUPPLEMENTAL_ARROWS_A", new String[] {"Supplemental Arrows-A",
-                                                                    "SupplementalArrows-A"});
+            new UnicodeBlock("SUPPLEMENTAL_ARROWS_A",
+                             "SUPPLEMENTAL ARROWS-A",
+                             "SUPPLEMENTALARROWS-A");
 
         /**
          * Constant for the "Supplemental Arrows-B" Unicode character block.
          * @since 1.5
          */
         public static final UnicodeBlock SUPPLEMENTAL_ARROWS_B =
-            new UnicodeBlock("SUPPLEMENTAL_ARROWS_B", new String[] {"Supplemental Arrows-B",
-                                                                    "SupplementalArrows-B"});
+            new UnicodeBlock("SUPPLEMENTAL_ARROWS_B",
+                             "SUPPLEMENTAL ARROWS-B",
+                             "SUPPLEMENTALARROWS-B");
 
         /**
          * Constant for the "Miscellaneous Mathematical Symbols-B" Unicode character block.
          * @since 1.5
          */
-        public static final UnicodeBlock MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B
-                = new UnicodeBlock("MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B",
-                                   new String[] {"Miscellaneous Mathematical Symbols-B",
-                                                 "MiscellaneousMathematicalSymbols-B"});
+        public static final UnicodeBlock MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B =
+            new UnicodeBlock("MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B",
+                             "MISCELLANEOUS MATHEMATICAL SYMBOLS-B",
+                             "MISCELLANEOUSMATHEMATICALSYMBOLS-B");
 
         /**
          * Constant for the "Supplemental Mathematical Operators" Unicode character block.
@@ -1451,127 +1503,151 @@
          */
         public static final UnicodeBlock SUPPLEMENTAL_MATHEMATICAL_OPERATORS =
             new UnicodeBlock("SUPPLEMENTAL_MATHEMATICAL_OPERATORS",
-                             new String[]{"Supplemental Mathematical Operators",
-                                          "SupplementalMathematicalOperators"} );
+                             "SUPPLEMENTAL MATHEMATICAL OPERATORS",
+                             "SUPPLEMENTALMATHEMATICALOPERATORS");
 
         /**
          * Constant for the "Miscellaneous Symbols and Arrows" Unicode character block.
          * @since 1.5
          */
         public static final UnicodeBlock MISCELLANEOUS_SYMBOLS_AND_ARROWS =
-            new UnicodeBlock("MISCELLANEOUS_SYMBOLS_AND_ARROWS", new String[] {"Miscellaneous Symbols and Arrows",
-                                                                               "MiscellaneousSymbolsandArrows"});
+            new UnicodeBlock("MISCELLANEOUS_SYMBOLS_AND_ARROWS",
+                             "MISCELLANEOUS SYMBOLS AND ARROWS",
+                             "MISCELLANEOUSSYMBOLSANDARROWS");
 
         /**
          * Constant for the "Katakana Phonetic Extensions" Unicode character block.
          * @since 1.5
          */
         public static final UnicodeBlock KATAKANA_PHONETIC_EXTENSIONS =
-            new UnicodeBlock("KATAKANA_PHONETIC_EXTENSIONS", new String[] {"Katakana Phonetic Extensions",
-                                                                           "KatakanaPhoneticExtensions"});
+            new UnicodeBlock("KATAKANA_PHONETIC_EXTENSIONS",
+                             "KATAKANA PHONETIC EXTENSIONS",
+                             "KATAKANAPHONETICEXTENSIONS");
 
         /**
          * Constant for the "Yijing Hexagram Symbols" Unicode character block.
          * @since 1.5
          */
         public static final UnicodeBlock YIJING_HEXAGRAM_SYMBOLS =
-            new UnicodeBlock("YIJING_HEXAGRAM_SYMBOLS", new String[] {"Yijing Hexagram Symbols",
-                                                                      "YijingHexagramSymbols"});
+            new UnicodeBlock("YIJING_HEXAGRAM_SYMBOLS",
+                             "YIJING HEXAGRAM SYMBOLS",
+                             "YIJINGHEXAGRAMSYMBOLS");
 
         /**
          * Constant for the "Variation Selectors" Unicode character block.
          * @since 1.5
          */
         public static final UnicodeBlock VARIATION_SELECTORS =
-            new UnicodeBlock("VARIATION_SELECTORS", new String[] {"Variation Selectors", "VariationSelectors"});
+            new UnicodeBlock("VARIATION_SELECTORS",
+                             "VARIATION SELECTORS",
+                             "VARIATIONSELECTORS");
 
         /**
          * Constant for the "Linear B Syllabary" Unicode character block.
          * @since 1.5
          */
         public static final UnicodeBlock LINEAR_B_SYLLABARY =
-            new UnicodeBlock("LINEAR_B_SYLLABARY", new String[] {"Linear B Syllabary", "LinearBSyllabary"});
+            new UnicodeBlock("LINEAR_B_SYLLABARY",
+                             "LINEAR B SYLLABARY",
+                             "LINEARBSYLLABARY");
 
         /**
          * Constant for the "Linear B Ideograms" Unicode character block.
          * @since 1.5
          */
         public static final UnicodeBlock LINEAR_B_IDEOGRAMS =
-            new UnicodeBlock("LINEAR_B_IDEOGRAMS", new String[] {"Linear B Ideograms", "LinearBIdeograms"});
+            new UnicodeBlock("LINEAR_B_IDEOGRAMS",
+                             "LINEAR B IDEOGRAMS",
+                             "LINEARBIDEOGRAMS");
 
         /**
          * Constant for the "Aegean Numbers" Unicode character block.
          * @since 1.5
          */
         public static final UnicodeBlock AEGEAN_NUMBERS =
-            new UnicodeBlock("AEGEAN_NUMBERS", new String[] {"Aegean Numbers", "AegeanNumbers"});
+            new UnicodeBlock("AEGEAN_NUMBERS",
+                             "AEGEAN NUMBERS",
+                             "AEGEANNUMBERS");
 
         /**
          * Constant for the "Old Italic" Unicode character block.
          * @since 1.5
          */
         public static final UnicodeBlock OLD_ITALIC =
-            new UnicodeBlock("OLD_ITALIC", new String[] {"Old Italic", "OldItalic"});
+            new UnicodeBlock("OLD_ITALIC",
+                             "OLD ITALIC",
+                             "OLDITALIC");
 
         /**
          * Constant for the "Gothic" Unicode character block.
          * @since 1.5
          */
-        public static final UnicodeBlock GOTHIC = new UnicodeBlock("GOTHIC");
+        public static final UnicodeBlock GOTHIC =
+            new UnicodeBlock("GOTHIC");
 
         /**
          * Constant for the "Ugaritic" Unicode character block.
          * @since 1.5
          */
-        public static final UnicodeBlock UGARITIC = new UnicodeBlock("UGARITIC");
+        public static final UnicodeBlock UGARITIC =
+            new UnicodeBlock("UGARITIC");
 
         /**
          * Constant for the "Deseret" Unicode character block.
          * @since 1.5
          */
-        public static final UnicodeBlock DESERET = new UnicodeBlock("DESERET");
+        public static final UnicodeBlock DESERET =
+            new UnicodeBlock("DESERET");
 
         /**
          * Constant for the "Shavian" Unicode character block.
          * @since 1.5
          */
-        public static final UnicodeBlock SHAVIAN = new UnicodeBlock("SHAVIAN");
+        public static final UnicodeBlock SHAVIAN =
+            new UnicodeBlock("SHAVIAN");
 
         /**
          * Constant for the "Osmanya" Unicode character block.
          * @since 1.5
          */
-        public static final UnicodeBlock OSMANYA = new UnicodeBlock("OSMANYA");
+        public static final UnicodeBlock OSMANYA =
+            new UnicodeBlock("OSMANYA");
 
         /**
          * Constant for the "Cypriot Syllabary" Unicode character block.
          * @since 1.5
          */
         public static final UnicodeBlock CYPRIOT_SYLLABARY =
-            new UnicodeBlock("CYPRIOT_SYLLABARY", new String[] {"Cypriot Syllabary", "CypriotSyllabary"});
+            new UnicodeBlock("CYPRIOT_SYLLABARY",
+                             "CYPRIOT SYLLABARY",
+                             "CYPRIOTSYLLABARY");
 
         /**
          * Constant for the "Byzantine Musical Symbols" Unicode character block.
          * @since 1.5
          */
         public static final UnicodeBlock BYZANTINE_MUSICAL_SYMBOLS =
-            new UnicodeBlock("BYZANTINE_MUSICAL_SYMBOLS", new String[] {"Byzantine Musical Symbols",
-                                                                        "ByzantineMusicalSymbols"});
+            new UnicodeBlock("BYZANTINE_MUSICAL_SYMBOLS",
+                             "BYZANTINE MUSICAL SYMBOLS",
+                             "BYZANTINEMUSICALSYMBOLS");
 
         /**
          * Constant for the "Musical Symbols" Unicode character block.
          * @since 1.5
          */
         public static final UnicodeBlock MUSICAL_SYMBOLS =
-            new UnicodeBlock("MUSICAL_SYMBOLS", new String[] {"Musical Symbols", "MusicalSymbols"});
+            new UnicodeBlock("MUSICAL_SYMBOLS",
+                             "MUSICAL SYMBOLS",
+                             "MUSICALSYMBOLS");
 
         /**
          * Constant for the "Tai Xuan Jing Symbols" Unicode character block.
          * @since 1.5
          */
         public static final UnicodeBlock TAI_XUAN_JING_SYMBOLS =
-            new UnicodeBlock("TAI_XUAN_JING_SYMBOLS", new String[] {"Tai Xuan Jing Symbols",
-                                                                     "TaiXuanJingSymbols"});
+            new UnicodeBlock("TAI_XUAN_JING_SYMBOLS",
+                             "TAI XUAN JING SYMBOLS",
+                             "TAIXUANJINGSYMBOLS");
 
         /**
          * Constant for the "Mathematical Alphanumeric Symbols" Unicode character block.
@@ -1579,7 +1655,8 @@
          */
         public static final UnicodeBlock MATHEMATICAL_ALPHANUMERIC_SYMBOLS =
             new UnicodeBlock("MATHEMATICAL_ALPHANUMERIC_SYMBOLS",
-                             new String[] {"Mathematical Alphanumeric Symbols", "MathematicalAlphanumericSymbols"});
+                             "MATHEMATICAL ALPHANUMERIC SYMBOLS",
+                             "MATHEMATICALALPHANUMERICSYMBOLS");
 
         /**
          * Constant for the "CJK Unified Ideographs Extension B" Unicode character block.
@@ -1587,7 +1664,8 @@
          */
         public static final UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B =
             new UnicodeBlock("CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B",
-                             new String[] {"CJK Unified Ideographs Extension B", "CJKUnifiedIdeographsExtensionB"});
+                             "CJK UNIFIED IDEOGRAPHS EXTENSION B",
+                             "CJKUNIFIEDIDEOGRAPHSEXTENSIONB");
 
         /**
          * Constant for the "CJK Compatibility Ideographs Supplement" Unicode character block.
@@ -1595,22 +1673,24 @@
          */
         public static final UnicodeBlock CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT =
             new UnicodeBlock("CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT",
-                             new String[]{"CJK Compatibility Ideographs Supplement",
-                                          "CJKCompatibilityIdeographsSupplement"});
+                             "CJK COMPATIBILITY IDEOGRAPHS SUPPLEMENT",
+                             "CJKCOMPATIBILITYIDEOGRAPHSSUPPLEMENT");
 
         /**
          * Constant for the "Tags" Unicode character block.
          * @since 1.5
          */
-        public static final UnicodeBlock TAGS = new UnicodeBlock("TAGS");
+        public static final UnicodeBlock TAGS =
+            new UnicodeBlock("TAGS");
 
         /**
          * Constant for the "Variation Selectors Supplement" Unicode character block.
          * @since 1.5
          */
         public static final UnicodeBlock VARIATION_SELECTORS_SUPPLEMENT =
-            new UnicodeBlock("VARIATION_SELECTORS_SUPPLEMENT", new String[] {"Variation Selectors Supplement",
-                                                                             "VariationSelectorsSupplement"});
+            new UnicodeBlock("VARIATION_SELECTORS_SUPPLEMENT",
+                             "VARIATION SELECTORS SUPPLEMENT",
+                             "VARIATIONSELECTORSSUPPLEMENT");
 
         /**
          * Constant for the "Supplementary Private Use Area-A" Unicode character block.
@@ -1618,8 +1698,8 @@
          */
         public static final UnicodeBlock SUPPLEMENTARY_PRIVATE_USE_AREA_A =
             new UnicodeBlock("SUPPLEMENTARY_PRIVATE_USE_AREA_A",
-                             new String[] {"Supplementary Private Use Area-A",
-                                           "SupplementaryPrivateUseArea-A"});
+                             "SUPPLEMENTARY PRIVATE USE AREA-A",
+                             "SUPPLEMENTARYPRIVATEUSEAREA-A");
 
         /**
          * Constant for the "Supplementary Private Use Area-B" Unicode character block.
@@ -1627,39 +1707,44 @@
          */
         public static final UnicodeBlock SUPPLEMENTARY_PRIVATE_USE_AREA_B =
             new UnicodeBlock("SUPPLEMENTARY_PRIVATE_USE_AREA_B",
-                             new String[] {"Supplementary Private Use Area-B",
-                                           "SupplementaryPrivateUseArea-B"});
+                             "SUPPLEMENTARY PRIVATE USE AREA-B",
+                             "SUPPLEMENTARYPRIVATEUSEAREA-B");
 
         /**
          * Constant for the "High Surrogates" Unicode character block.
          * This block represents codepoint values in the high surrogate
-         * range: 0xD800 through 0xDB7F
+         * range: U+D800 through U+DB7F
          *
          * @since 1.5
          */
         public static final UnicodeBlock HIGH_SURROGATES =
-            new UnicodeBlock("HIGH_SURROGATES", new String[] {"High Surrogates", "HighSurrogates"});
+            new UnicodeBlock("HIGH_SURROGATES",
+                             "HIGH SURROGATES",
+                             "HIGHSURROGATES");
 
         /**
          * Constant for the "High Private Use Surrogates" Unicode character block.
-         * This block represents codepoint values in the high surrogate
-         * range: 0xDB80 through 0xDBFF
+         * This block represents codepoint values in the private use high surrogate
+         * range: U+DB80 through U+DBFF
          *
          * @since 1.5
          */
         public static final UnicodeBlock HIGH_PRIVATE_USE_SURROGATES =
-            new UnicodeBlock("HIGH_PRIVATE_USE_SURROGATES", new String[] { "High Private Use Surrogates",
-                                                                           "HighPrivateUseSurrogates"});
+            new UnicodeBlock("HIGH_PRIVATE_USE_SURROGATES",
+                             "HIGH PRIVATE USE SURROGATES",
+                             "HIGHPRIVATEUSESURROGATES");
 
         /**
          * Constant for the "Low Surrogates" Unicode character block.
-         * This block represents codepoint values in the high surrogate
-         * range: 0xDC00 through 0xDFFF
+         * This block represents codepoint values in the low surrogate
+         * range: U+DC00 through U+DFFF
          *
          * @since 1.5
          */
         public static final UnicodeBlock LOW_SURROGATES =
-            new UnicodeBlock("LOW_SURROGATES", new String[] {"Low Surrogates", "LowSurrogates"});
+            new UnicodeBlock("LOW_SURROGATES",
+                             "LOW SURROGATES",
+                             "LOWSURROGATES");
 
         /**
          * Constant for the "Arabic Supplement" Unicode character block.
@@ -1667,14 +1752,15 @@
          */
         public static final UnicodeBlock ARABIC_SUPPLEMENT =
             new UnicodeBlock("ARABIC_SUPPLEMENT",
-                             new String[] { "Arabic Supplement",
-                                            "ArabicSupplement"});
+                             "ARABIC SUPPLEMENT",
+                             "ARABICSUPPLEMENT");
 
         /**
          * Constant for the "NKo" Unicode character block.
          * @since 1.7
          */
-        public static final UnicodeBlock NKO = new UnicodeBlock("NKO");
+        public static final UnicodeBlock NKO =
+            new UnicodeBlock("NKO");
 
         /**
          * Constant for the "Ethiopic Supplement" Unicode character block.
@@ -1682,8 +1768,8 @@
          */
         public static final UnicodeBlock ETHIOPIC_SUPPLEMENT =
             new UnicodeBlock("ETHIOPIC_SUPPLEMENT",
-                             new String[] { "Ethiopic Supplement",
-                                            "EthiopicSupplement"});
+                             "ETHIOPIC SUPPLEMENT",
+                             "ETHIOPICSUPPLEMENT");
 
         /**
          * Constant for the "New Tai Lue" Unicode character block.
@@ -1691,8 +1777,8 @@
          */
         public static final UnicodeBlock NEW_TAI_LUE =
             new UnicodeBlock("NEW_TAI_LUE",
-                             new String[] { "New Tai Lue",
-                                            "NewTaiLue"});
+                             "NEW TAI LUE",
+                             "NEWTAILUE");
 
         /**
          * Constant for the "Buginese" Unicode character block.
@@ -1719,7 +1805,8 @@
          * Constant for the "Lepcha" Unicode character block.
          * @since 1.7
          */
-        public static final UnicodeBlock LEPCHA = new UnicodeBlock("LEPCHA");
+        public static final UnicodeBlock LEPCHA =
+            new UnicodeBlock("LEPCHA");
 
         /**
          * Constant for the "Ol Chiki" Unicode character block.
@@ -1727,8 +1814,8 @@
          */
         public static final UnicodeBlock OL_CHIKI =
             new UnicodeBlock("OL_CHIKI",
-                             new String[] { "Ol Chiki",
-                                            "OlChiki"});
+                             "OL CHIKI",
+                             "OLCHIKI");
 
         /**
          * Constant for the "Phonetic Extensions Supplement" Unicode character
@@ -1737,8 +1824,8 @@
          */
         public static final UnicodeBlock PHONETIC_EXTENSIONS_SUPPLEMENT =
             new UnicodeBlock("PHONETIC_EXTENSIONS_SUPPLEMENT",
-                             new String[] { "Phonetic Extensions Supplement",
-                                            "PhoneticExtensionsSupplement"});
+                             "PHONETIC EXTENSIONS SUPPLEMENT",
+                             "PHONETICEXTENSIONSSUPPLEMENT");
 
         /**
          * Constant for the "Combining Diacritical Marks Supplement" Unicode
@@ -1747,8 +1834,8 @@
          */
         public static final UnicodeBlock COMBINING_DIACRITICAL_MARKS_SUPPLEMENT =
             new UnicodeBlock("COMBINING_DIACRITICAL_MARKS_SUPPLEMENT",
-                             new String[] { "Combining Diacritical Marks Supplement",
-                                            "CombiningDiacriticalMarksSupplement"});
+                             "COMBINING DIACRITICAL MARKS SUPPLEMENT",
+                             "COMBININGDIACRITICALMARKSSUPPLEMENT");
 
         /**
          * Constant for the "Glagolitic" Unicode character block.
@@ -1763,14 +1850,15 @@
          */
         public static final UnicodeBlock LATIN_EXTENDED_C =
             new UnicodeBlock("LATIN_EXTENDED_C",
-                             new String[] { "Latin Extended-C",
-                                            "LatinExtended-C"});
+                             "LATIN EXTENDED-C",
+                             "LATINEXTENDED-C");
 
         /**
          * Constant for the "Coptic" Unicode character block.
          * @since 1.7
          */
-        public static final UnicodeBlock COPTIC = new UnicodeBlock("COPTIC");
+        public static final UnicodeBlock COPTIC =
+            new UnicodeBlock("COPTIC");
 
         /**
          * Constant for the "Georgian Supplement" Unicode character block.
@@ -1778,8 +1866,8 @@
          */
         public static final UnicodeBlock GEORGIAN_SUPPLEMENT =
             new UnicodeBlock("GEORGIAN_SUPPLEMENT",
-                             new String[] { "Georgian Supplement",
-                                            "GeorgianSupplement"});
+                             "GEORGIAN SUPPLEMENT",
+                             "GEORGIANSUPPLEMENT");
 
         /**
          * Constant for the "Tifinagh" Unicode character block.
@@ -1794,8 +1882,8 @@
          */
         public static final UnicodeBlock ETHIOPIC_EXTENDED =
             new UnicodeBlock("ETHIOPIC_EXTENDED",
-                             new String[] { "Ethiopic Extended",
-                                            "EthiopicExtended"});
+                             "ETHIOPIC EXTENDED",
+                             "ETHIOPICEXTENDED");
 
         /**
          * Constant for the "Cyrillic Extended-A" Unicode character block.
@@ -1803,8 +1891,8 @@
          */
         public static final UnicodeBlock CYRILLIC_EXTENDED_A =
             new UnicodeBlock("CYRILLIC_EXTENDED_A",
-                             new String[] { "Cyrillic Extended-A",
-                                            "CyrillicExtended-A"});
+                             "CYRILLIC EXTENDED-A",
+                             "CYRILLICEXTENDED-A");
 
         /**
          * Constant for the "Supplemental Punctuation" Unicode character block.
@@ -1812,8 +1900,8 @@
          */
         public static final UnicodeBlock SUPPLEMENTAL_PUNCTUATION =
             new UnicodeBlock("SUPPLEMENTAL_PUNCTUATION",
-                             new String[] { "Supplemental Punctuation",
-                                            "SupplementalPunctuation"});
+                             "SUPPLEMENTAL PUNCTUATION",
+                             "SUPPLEMENTALPUNCTUATION");
 
         /**
          * Constant for the "CJK Strokes" Unicode character block.
@@ -1821,14 +1909,15 @@
          */
         public static final UnicodeBlock CJK_STROKES =
             new UnicodeBlock("CJK_STROKES",
-                             new String[] { "CJK Strokes",
-                                            "CJKStrokes"});
+                             "CJK STROKES",
+                             "CJKSTROKES");
 
         /**
          * Constant for the "Vai" Unicode character block.
          * @since 1.7
          */
-        public static final UnicodeBlock VAI = new UnicodeBlock("VAI");
+        public static final UnicodeBlock VAI =
+            new UnicodeBlock("VAI");
 
         /**
          * Constant for the "Cyrillic Extended-B" Unicode character block.
@@ -1836,8 +1925,8 @@
          */
         public static final UnicodeBlock CYRILLIC_EXTENDED_B =
             new UnicodeBlock("CYRILLIC_EXTENDED_B",
-                             new String[] { "Cyrillic Extended-B",
-                                            "CyrillicExtended-B"});
+                             "CYRILLIC EXTENDED-B",
+                             "CYRILLICEXTENDED-B");
 
         /**
          * Constant for the "Modifier Tone Letters" Unicode character block.
@@ -1845,8 +1934,8 @@
          */
         public static final UnicodeBlock MODIFIER_TONE_LETTERS =
             new UnicodeBlock("MODIFIER_TONE_LETTERS",
-                             new String[] { "Modifier Tone Letters",
-                                            "ModifierToneLetters"});
+                             "MODIFIER TONE LETTERS",
+                             "MODIFIERTONELETTERS");
 
         /**
          * Constant for the "Latin Extended-D" Unicode character block.
@@ -1854,8 +1943,8 @@
          */
         public static final UnicodeBlock LATIN_EXTENDED_D =
             new UnicodeBlock("LATIN_EXTENDED_D",
-                             new String[] { "Latin Extended-D",
-                                            "LatinExtended-D"});
+                             "LATIN EXTENDED-D",
+                             "LATINEXTENDED-D");
 
         /**
          * Constant for the "Syloti Nagri" Unicode character block.
@@ -1863,15 +1952,16 @@
          */
         public static final UnicodeBlock SYLOTI_NAGRI =
             new UnicodeBlock("SYLOTI_NAGRI",
-                             new String[] { "Syloti Nagri",
-                                            "SylotiNagri"});
+                             "SYLOTI NAGRI",
+                             "SYLOTINAGRI");
 
         /**
          * Constant for the "Phags-pa" Unicode character block.
          * @since 1.7
          */
         public static final UnicodeBlock PHAGS_PA =
-            new UnicodeBlock("PHAGS_PA", new String[] { "Phags-pa"});
+            new UnicodeBlock("PHAGS_PA",
+                             "PHAGS-PA");
 
         /**
          * Constant for the "Saurashtra" Unicode character block.
@@ -1886,20 +1976,22 @@
          */
         public static final UnicodeBlock KAYAH_LI =
             new UnicodeBlock("KAYAH_LI",
-                             new String[] { "Kayah Li",
-                                            "KayahLi"});
+                             "KAYAH LI",
+                             "KAYAHLI");
 
         /**
          * Constant for the "Rejang" Unicode character block.
          * @since 1.7
          */
-        public static final UnicodeBlock REJANG = new UnicodeBlock("REJANG");
+        public static final UnicodeBlock REJANG =
+            new UnicodeBlock("REJANG");
 
         /**
          * Constant for the "Cham" Unicode character block.
          * @since 1.7
          */
-        public static final UnicodeBlock CHAM = new UnicodeBlock("CHAM");
+        public static final UnicodeBlock CHAM =
+            new UnicodeBlock("CHAM");
 
         /**
          * Constant for the "Vertical Forms" Unicode character block.
@@ -1907,8 +1999,8 @@
          */
         public static final UnicodeBlock VERTICAL_FORMS =
             new UnicodeBlock("VERTICAL_FORMS",
-                             new String[] { "Vertical Forms",
-                                            "VerticalForms"});
+                             "VERTICAL FORMS",
+                             "VERTICALFORMS");
 
         /**
          * Constant for the "Ancient Greek Numbers" Unicode character block.
@@ -1916,8 +2008,8 @@
          */
         public static final UnicodeBlock ANCIENT_GREEK_NUMBERS =
             new UnicodeBlock("ANCIENT_GREEK_NUMBERS",
-                             new String[] { "Ancient Greek Numbers",
-                                            "AncientGreekNumbers"});
+                             "ANCIENT GREEK NUMBERS",
+                             "ANCIENTGREEKNUMBERS");
 
         /**
          * Constant for the "Ancient Symbols" Unicode character block.
@@ -1925,8 +2017,8 @@
          */
         public static final UnicodeBlock ANCIENT_SYMBOLS =
             new UnicodeBlock("ANCIENT_SYMBOLS",
-                             new String[] { "Ancient Symbols",
-                                            "AncientSymbols"});
+                             "ANCIENT SYMBOLS",
+                             "ANCIENTSYMBOLS");
 
         /**
          * Constant for the "Phaistos Disc" Unicode character block.
@@ -1934,20 +2026,22 @@
          */
         public static final UnicodeBlock PHAISTOS_DISC =
             new UnicodeBlock("PHAISTOS_DISC",
-                             new String[] { "Phaistos Disc",
-                                            "PhaistosDisc"});
+                             "PHAISTOS DISC",
+                             "PHAISTOSDISC");
 
         /**
          * Constant for the "Lycian" Unicode character block.
          * @since 1.7
          */
-        public static final UnicodeBlock LYCIAN = new UnicodeBlock("LYCIAN");
+        public static final UnicodeBlock LYCIAN =
+            new UnicodeBlock("LYCIAN");
 
         /**
          * Constant for the "Carian" Unicode character block.
          * @since 1.7
          */
-        public static final UnicodeBlock CARIAN = new UnicodeBlock("CARIAN");
+        public static final UnicodeBlock CARIAN =
+            new UnicodeBlock("CARIAN");
 
         /**
          * Constant for the "Old Persian" Unicode character block.
@@ -1955,8 +2049,8 @@
          */
         public static final UnicodeBlock OLD_PERSIAN =
             new UnicodeBlock("OLD_PERSIAN",
-                             new String[] { "Old Persian",
-                                            "OldPersian"});
+                             "OLD PERSIAN",
+                             "OLDPERSIAN");
 
         /**
          * Constant for the "Phoenician" Unicode character block.
@@ -1969,7 +2063,8 @@
          * Constant for the "Lydian" Unicode character block.
          * @since 1.7
          */
-        public static final UnicodeBlock LYDIAN = new UnicodeBlock("LYDIAN");
+        public static final UnicodeBlock LYDIAN =
+            new UnicodeBlock("LYDIAN");
 
         /**
          * Constant for the "Kharoshthi" Unicode character block.
@@ -1992,8 +2087,8 @@
          */
         public static final UnicodeBlock CUNEIFORM_NUMBERS_AND_PUNCTUATION =
             new UnicodeBlock("CUNEIFORM_NUMBERS_AND_PUNCTUATION",
-                             new String[] { "Cuneiform Numbers and Punctuation",
-                                            "CuneiformNumbersandPunctuation"});
+                             "CUNEIFORM NUMBERS AND PUNCTUATION",
+                             "CUNEIFORMNUMBERSANDPUNCTUATION");
 
         /**
          * Constant for the "Ancient Greek Musical Notation" Unicode character
@@ -2002,8 +2097,8 @@
          */
         public static final UnicodeBlock ANCIENT_GREEK_MUSICAL_NOTATION =
             new UnicodeBlock("ANCIENT_GREEK_MUSICAL_NOTATION",
-                             new String[] { "Ancient Greek Musical Notation",
-                                            "AncientGreekMusicalNotation"});
+                             "ANCIENT GREEK MUSICAL NOTATION",
+                             "ANCIENTGREEKMUSICALNOTATION");
 
         /**
          * Constant for the "Counting Rod Numerals" Unicode character block.
@@ -2011,8 +2106,8 @@
          */
         public static final UnicodeBlock COUNTING_ROD_NUMERALS =
             new UnicodeBlock("COUNTING_ROD_NUMERALS",
-                             new String[] { "Counting Rod Numerals",
-                                            "CountingRodNumerals"});
+                             "COUNTING ROD NUMERALS",
+                             "COUNTINGRODNUMERALS");
 
         /**
          * Constant for the "Mahjong Tiles" Unicode character block.
@@ -2020,8 +2115,8 @@
          */
         public static final UnicodeBlock MAHJONG_TILES =
             new UnicodeBlock("MAHJONG_TILES",
-                             new String[] { "Mahjong Tiles",
-                                            "MahjongTiles"});
+                             "MAHJONG TILES",
+                             "MAHJONGTILES");
 
         /**
          * Constant for the "Domino Tiles" Unicode character block.
@@ -2029,8 +2124,8 @@
          */
         public static final UnicodeBlock DOMINO_TILES =
             new UnicodeBlock("DOMINO_TILES",
-                             new String[] { "Domino Tiles",
-                                            "DominoTiles"});
+                             "DOMINO TILES",
+                             "DOMINOTILES");
 
         private static final int blockStarts[] = {
             0x0000,   // 0000..007F; Basic Latin
@@ -2046,7 +2141,7 @@
             0x0530,   // 0530..058F; Armenian
             0x0590,   // 0590..05FF; Hebrew
             0x0600,   // 0600..06FF; Arabic
-            0x0700,   // 0700..074F; Syria
+            0x0700,   // 0700..074F; Syriac
             0x0750,   // 0750..077F; Arabic Supplement
             0x0780,   // 0780..07BF; Thaana
             0x07C0,   // 07C0..07FF; NKo
@@ -2446,11 +2541,10 @@
          * given character, or <code>null</code> if the character is not a
          * member of a defined block.
          *
-                 * <p><b>Note:</b> This method cannot handle <a
-                 * href="Character.html#supplementary"> supplementary
-                 * characters</a>. To support all Unicode characters,
-                 * including supplementary characters, use the {@link
-                 * #of(int)} method.
+         * <p><b>Note:</b> This method cannot handle
+         * <a href="Character.html#supplementary"> supplementary
+         * characters</a>.  To support all Unicode characters, including
+         * supplementary characters, use the {@link #of(int)} method.
          *
          * @param   c  The character in question
          * @return  The <code>UnicodeBlock</code> instance representing the
@@ -2462,22 +2556,21 @@
             return of((int)c);
         }
 
-
         /**
          * Returns the object representing the Unicode block
          * containing the given character (Unicode code point), or
          * <code>null</code> if the character is not a member of a
          * defined block.
          *
-                 * @param   codePoint the character (Unicode code point) in question.
+         * @param   codePoint the character (Unicode code point) in question.
          * @return  The <code>UnicodeBlock</code> instance representing the
          *          Unicode block of which this character is a member, or
          *          <code>null</code> if the character is not a member of any
          *          Unicode block
-                 * @exception IllegalArgumentException if the specified
-                 * <code>codePoint</code> is an invalid Unicode code point.
-                 * @see Character#isValidCodePoint(int)
-                 * @since   1.5
+         * @exception IllegalArgumentException if the specified
+         * <code>codePoint</code> is an invalid Unicode code point.
+         * @see Character#isValidCodePoint(int)
+         * @since   1.5
          */
         public static UnicodeBlock of(int codePoint) {
             if (!isValidCodePoint(codePoint)) {
@@ -2519,7 +2612,7 @@
          * <li>The text representation of each constant UnicodeBlock identifier.
          * For example, this method will return the {@link #BASIC_LATIN} block if
          * provided with the "BASIC_LATIN" name. This form replaces all spaces and
-         *  hyphens in the canonical name with underscores.
+         * hyphens in the canonical name with underscores.
          * </ol>
          * Finally, character case is ignored for all of the valid block name forms.
          * For example, "BASIC_LATIN" and "basic_latin" are both valid block names.
@@ -2538,7 +2631,7 @@
          * @since 1.5
          */
         public static final UnicodeBlock forName(String blockName) {
-            UnicodeBlock block = (UnicodeBlock)map.get(blockName.toUpperCase(Locale.US));
+            UnicodeBlock block = map.get(blockName.toUpperCase(Locale.US));
             if (block == null) {
                 throw new IllegalArgumentException();
             }
@@ -3627,7 +3720,7 @@
 
         private static HashMap<String, Character.UnicodeScript> aliases;
         static {
-            aliases = new HashMap<String, UnicodeScript>();
+            aliases = new HashMap<String, UnicodeScript>(128);
             aliases.put("ARAB", ARABIC);
             aliases.put("ARMI", IMPERIAL_ARAMAIC);
             aliases.put("ARMN", ARMENIAN);
@@ -3809,7 +3902,7 @@
         static final Character cache[] = new Character[127 + 1];
 
         static {
-            for(int i = 0; i < cache.length; i++)
+            for (int i = 0; i < cache.length; i++)
                 cache[i] = new Character((char)i);
         }
     }
@@ -3832,7 +3925,7 @@
      * @since  1.5
      */
     public static Character valueOf(char c) {
-        if(c <= 127) { // must cache
+        if (c <= 127) { // must cache
             return CharacterCache.cache[(int)c];
         }
         return new Character(c);
@@ -3914,7 +4007,29 @@
      * @since  1.5
      */
     public static boolean isValidCodePoint(int codePoint) {
-        return codePoint >= MIN_CODE_POINT && codePoint <= MAX_CODE_POINT;
+        // Optimized form of:
+        //     codePoint >= MIN_CODE_POINT && codePoint <= MAX_CODE_POINT
+        int plane = codePoint >>> 16;
+        return plane < ((MAX_CODE_POINT + 1) >>> 16);
+    }
+
+    /**
+     * Determines whether the specified character (Unicode code point)
+     * is in the <a href="#BMP">Basic Multilingual Plane (BMP)</a>.
+     * Such code points can be represented using a single {@code char}.
+     *
+     * @param  codePoint the character (Unicode code point) to be tested
+     * @return {@code true} if the specified code point is between
+     *         {@link #MIN_VALUE} and {@link #MAX_VALUE} inclusive;
+     *         {@code false} otherwise.
+     * @since  1.7
+     */
+    public static boolean isBmpCodePoint(int codePoint) {
+        return codePoint >>> 16 == 0;
+        // Optimized form of:
+        //     codePoint >= MIN_VALUE && codePoint <= MAX_VALUE
+        // We consistently use logical shift (>>>) to facilitate
+        // additional runtime optimizations.
     }
 
     /**
@@ -3930,7 +4045,7 @@
      */
     public static boolean isSupplementaryCodePoint(int codePoint) {
         return codePoint >= MIN_SUPPLEMENTARY_CODE_POINT
-            && codePoint <= MAX_CODE_POINT;
+            && codePoint <  MAX_CODE_POINT + 1;
     }
 
     /**
@@ -3949,12 +4064,13 @@
      *         {@link #MIN_HIGH_SURROGATE} and
      *         {@link #MAX_HIGH_SURROGATE} inclusive;
      *         {@code false} otherwise.
-     * @see    #isLowSurrogate(char)
+     * @see    Character#isLowSurrogate(char)
      * @see    Character.UnicodeBlock#of(int)
      * @since  1.5
      */
     public static boolean isHighSurrogate(char ch) {
-        return ch >= MIN_HIGH_SURROGATE && ch <= MAX_HIGH_SURROGATE;
+        // Help VM constant-fold; MAX_HIGH_SURROGATE + 1 == MIN_LOW_SURROGATE
+        return ch >= MIN_HIGH_SURROGATE && ch < (MAX_HIGH_SURROGATE + 1);
     }
 
     /**
@@ -3973,11 +4089,11 @@
      *         {@link #MIN_LOW_SURROGATE} and
      *         {@link #MAX_LOW_SURROGATE} inclusive;
      *         {@code false} otherwise.
-     * @see    #isHighSurrogate(char)
+     * @see    Character#isHighSurrogate(char)
      * @since  1.5
      */
     public static boolean isLowSurrogate(char ch) {
-        return ch >= MIN_LOW_SURROGATE && ch <= MAX_LOW_SURROGATE;
+        return ch >= MIN_LOW_SURROGATE && ch < (MAX_LOW_SURROGATE + 1);
     }
 
     /**
@@ -4001,7 +4117,7 @@
      * @since  1.7
      */
     public static boolean isSurrogate(char ch) {
-        return ch >= MIN_SURROGATE && ch <= MAX_SURROGATE;
+        return ch >= MIN_SURROGATE && ch < (MAX_SURROGATE + 1);
     }
 
     /**
@@ -4039,11 +4155,11 @@
      *
      * @param   codePoint the character (Unicode code point) to be tested.
      * @return  2 if the character is a valid supplementary character; 1 otherwise.
-     * @see     #isSupplementaryCodePoint(int)
+     * @see     Character#isSupplementaryCodePoint(int)
      * @since   1.5
      */
     public static int charCount(int codePoint) {
-        return codePoint >= MIN_SUPPLEMENTARY_CODE_POINT? 2 : 1;
+        return codePoint >= MIN_SUPPLEMENTARY_CODE_POINT ? 2 : 1;
     }
 
     /**
@@ -4160,6 +4276,7 @@
         return codePointAtImpl(a, index, limit);
     }
 
+    // throws ArrayIndexOutofBoundsException if index out of bounds
     static int codePointAtImpl(char[] a, int index, int limit) {
         char c1 = a[index++];
         if (isHighSurrogate(c1)) {
@@ -4266,6 +4383,7 @@
         return codePointBeforeImpl(a, index, start);
     }
 
+    // throws ArrayIndexOutofBoundsException if index-1 out of bounds
     static int codePointBeforeImpl(char[] a, int index, int start) {
         char c2 = a[--index];
         if (isLowSurrogate(c2)) {
@@ -4280,6 +4398,63 @@
     }
 
     /**
+     * Returns the leading surrogate (a
+     * <a href="http://www.unicode.org/glossary/#high_surrogate_code_unit">
+     * high surrogate code unit</a>) of the
+     * <a href="http://www.unicode.org/glossary/#surrogate_pair">
+     * surrogate pair</a>
+     * representing the specified supplementary character (Unicode
+     * code point) in the UTF-16 encoding.  If the specified character
+     * is not a
+     * <a href="Character.html#supplementary">supplementary character</a>,
+     * an unspecified {@code char} is returned.
+     *
+     * <p>If
+     * {@link #isSupplementaryCodePoint isSupplementaryCodePoint(x)}
+     * is {@code true}, then
+     * {@link #isHighSurrogate isHighSurrogate}{@code (highSurrogate(x))} and
+     * {@link #toCodePoint toCodePoint}{@code (highSurrogate(x), }{@link #lowSurrogate lowSurrogate}{@code (x)) == x}
+     * are also always {@code true}.
+     *
+     * @param   codePoint a supplementary character (Unicode code point)
+     * @return  the leading surrogate code unit used to represent the
+     *          character in the UTF-16 encoding
+     * @since   1.7
+     */
+    public static char highSurrogate(int codePoint) {
+        return (char) ((codePoint >>> 10)
+            + (MIN_HIGH_SURROGATE - (MIN_SUPPLEMENTARY_CODE_POINT >>> 10)));
+    }
+
+    /**
+     * Returns the trailing surrogate (a
+     * <a href="http://www.unicode.org/glossary/#low_surrogate_code_unit">
+     * low surrogate code unit</a>) of the
+     * <a href="http://www.unicode.org/glossary/#surrogate_pair">
+     * surrogate pair</a>
+     * representing the specified supplementary character (Unicode
+     * code point) in the UTF-16 encoding.  If the specified character
+     * is not a
+     * <a href="Character.html#supplementary">supplementary character</a>,
+     * an unspecified {@code char} is returned.
+     *
+     * <p>If
+     * {@link #isSupplementaryCodePoint isSupplementaryCodePoint(x)}
+     * is {@code true}, then
+     * {@link #isLowSurrogate isLowSurrogate}{@code (lowSurrogate(x))} and
+     * {@link #toCodePoint toCodePoint}{@code (}{@link #highSurrogate highSurrogate}{@code (x), lowSurrogate(x)) == x}
+     * are also always {@code true}.
+     *
+     * @param   codePoint a supplementary character (Unicode code point)
+     * @return  the trailing surrogate code unit used to represent the
+     *          character in the UTF-16 encoding
+     * @since   1.7
+     */
+    public static char lowSurrogate(int codePoint) {
+        return (char) ((codePoint & 0x3ff) + MIN_LOW_SURROGATE);
+    }
+
+    /**
      * Converts the specified character (Unicode code point) to its
      * UTF-16 representation. If the specified code point is a BMP
      * (Basic Multilingual Plane or Plane 0) value, the same value is
@@ -4311,15 +4486,15 @@
      * @since  1.5
      */
     public static int toChars(int codePoint, char[] dst, int dstIndex) {
-        if (codePoint < 0 || codePoint > MAX_CODE_POINT) {
+        if (isBmpCodePoint(codePoint)) {
+            dst[dstIndex] = (char) codePoint;
+            return 1;
+        } else if (isValidCodePoint(codePoint)) {
+            toSurrogates(codePoint, dst, dstIndex);
+            return 2;
+        } else {
             throw new IllegalArgumentException();
         }
-        if (codePoint < MIN_SUPPLEMENTARY_CODE_POINT) {
-            dst[dstIndex] = (char) codePoint;
-            return 1;
-        }
-        toSurrogates(codePoint, dst, dstIndex);
-        return 2;
     }
 
     /**
@@ -4339,22 +4514,21 @@
      * @since  1.5
      */
     public static char[] toChars(int codePoint) {
-        if (codePoint < 0 || codePoint > MAX_CODE_POINT) {
+        if (isBmpCodePoint(codePoint)) {
+            return new char[] { (char) codePoint };
+        } else if (isValidCodePoint(codePoint)) {
+            char[] result = new char[2];
+            toSurrogates(codePoint, result, 0);
+            return result;
+        } else {
             throw new IllegalArgumentException();
         }
-        if (codePoint < MIN_SUPPLEMENTARY_CODE_POINT) {
-                return new char[] { (char) codePoint };
-        }
-        char[] result = new char[2];
-        toSurrogates(codePoint, result, 0);
-        return result;
     }
 
     static void toSurrogates(int codePoint, char[] dst, int index) {
         // We write elements "backwards" to guarantee all-or-nothing
-        dst[index+1] = (char)((codePoint & 0x3ff) + MIN_LOW_SURROGATE);
-        dst[index] = (char)((codePoint >>> 10)
-            + (MIN_HIGH_SURROGATE - (MIN_SUPPLEMENTARY_CODE_POINT >>> 10)));
+        dst[index+1] = lowSurrogate(codePoint);
+        dst[index] = highSurrogate(codePoint);
     }
 
     /**
@@ -4385,13 +4559,12 @@
         if (beginIndex < 0 || endIndex > length || beginIndex > endIndex) {
             throw new IndexOutOfBoundsException();
         }
-        int n = 0;
+        int n = endIndex - beginIndex;
         for (int i = beginIndex; i < endIndex; ) {
-            n++;
-            if (isHighSurrogate(seq.charAt(i++))) {
-                if (i < endIndex && isLowSurrogate(seq.charAt(i))) {
-                    i++;
-                }
+            if (isHighSurrogate(seq.charAt(i++)) && i < endIndex &&
+                isLowSurrogate(seq.charAt(i))) {
+                n--;
+                i++;
             }
         }
         return n;
@@ -4425,13 +4598,12 @@
 
     static int codePointCountImpl(char[] a, int offset, int count) {
         int endIndex = offset + count;
-        int n = 0;
+        int n = count;
         for (int i = offset; i < endIndex; ) {
-            n++;
-            if (isHighSurrogate(a[i++])) {
-                if (i < endIndex && isLowSurrogate(a[i])) {
-                    i++;
-                }
+            if (isHighSurrogate(a[i++]) && i < endIndex &&
+                isLowSurrogate(a[i])) {
+                n--;
+                i++;
             }
         }
         return n;
@@ -4470,10 +4642,9 @@
         if (codePointOffset >= 0) {
             int i;
             for (i = 0; x < length && i < codePointOffset; i++) {
-                if (isHighSurrogate(seq.charAt(x++))) {
-                    if (x < length && isLowSurrogate(seq.charAt(x))) {
-                        x++;
-                    }
+                if (isHighSurrogate(seq.charAt(x++)) && x < length &&
+                    isLowSurrogate(seq.charAt(x))) {
+                    x++;
                 }
             }
             if (i < codePointOffset) {
@@ -4482,10 +4653,9 @@
         } else {
             int i;
             for (i = codePointOffset; x > 0 && i < 0; i++) {
-                if (isLowSurrogate(seq.charAt(--x))) {
-                    if (x > 0 && isHighSurrogate(seq.charAt(x-1))) {
-                        x--;
-                    }
+                if (isLowSurrogate(seq.charAt(--x)) && x > 0 &&
+                    isHighSurrogate(seq.charAt(x-1))) {
+                    x--;
                 }
             }
             if (i < 0) {
@@ -4544,10 +4714,9 @@
             int limit = start + count;
             int i;
             for (i = 0; x < limit && i < codePointOffset; i++) {
-                if (isHighSurrogate(a[x++])) {
-                    if (x < limit && isLowSurrogate(a[x])) {
-                        x++;
-                    }
+                if (isHighSurrogate(a[x++]) && x < limit &&
+                    isLowSurrogate(a[x])) {
+                    x++;
                 }
             }
             if (i < codePointOffset) {
@@ -4556,10 +4725,9 @@
         } else {
             int i;
             for (i = codePointOffset; x > start && i < 0; i++) {
-                if (isLowSurrogate(a[--x])) {
-                    if (x > start && isHighSurrogate(a[x-1])) {
-                        x--;
-                    }
+                if (isLowSurrogate(a[--x]) && x > start &&
+                    isHighSurrogate(a[x-1])) {
+                    x--;
                 }
             }
             if (i < 0) {
@@ -4569,7 +4737,7 @@
         return x;
     }
 
-   /**
+    /**
      * Determines if the specified character is a lowercase character.
      * <p>
      * A character is lowercase if its general category type, provided
@@ -4594,10 +4762,10 @@
      * @param   ch   the character to be tested.
      * @return  <code>true</code> if the character is lowercase;
      *          <code>false</code> otherwise.
-     * @see     java.lang.Character#isLowerCase(char)
-     * @see     java.lang.Character#isTitleCase(char)
-     * @see     java.lang.Character#toLowerCase(char)
-     * @see     java.lang.Character#getType(char)
+     * @see     Character#isLowerCase(char)
+     * @see     Character#isTitleCase(char)
+     * @see     Character#toLowerCase(char)
+     * @see     Character#getType(char)
      */
     public static boolean isLowerCase(char ch) {
         return isLowerCase((int)ch);
@@ -4624,17 +4792,17 @@
      * @param   codePoint the character (Unicode code point) to be tested.
      * @return  <code>true</code> if the character is lowercase;
      *          <code>false</code> otherwise.
-     * @see     java.lang.Character#isLowerCase(int)
-     * @see     java.lang.Character#isTitleCase(int)
-     * @see     java.lang.Character#toLowerCase(int)
-     * @see     java.lang.Character#getType(int)
+     * @see     Character#isLowerCase(int)
+     * @see     Character#isTitleCase(int)
+     * @see     Character#toLowerCase(int)
+     * @see     Character#getType(int)
      * @since   1.5
      */
     public static boolean isLowerCase(int codePoint) {
         return getType(codePoint) == Character.LOWERCASE_LETTER;
     }
 
-   /**
+    /**
      * Determines if the specified character is an uppercase character.
      * <p>
      * A character is uppercase if its general category type, provided by
@@ -4658,10 +4826,10 @@
      * @param   ch   the character to be tested.
      * @return  <code>true</code> if the character is uppercase;
      *          <code>false</code> otherwise.
-     * @see     java.lang.Character#isLowerCase(char)
-     * @see     java.lang.Character#isTitleCase(char)
-     * @see     java.lang.Character#toUpperCase(char)
-     * @see     java.lang.Character#getType(char)
+     * @see     Character#isLowerCase(char)
+     * @see     Character#isTitleCase(char)
+     * @see     Character#toUpperCase(char)
+     * @see     Character#getType(char)
      * @since   1.0
      */
     public static boolean isUpperCase(char ch) {
@@ -4687,10 +4855,10 @@
      * @param   codePoint the character (Unicode code point) to be tested.
      * @return  <code>true</code> if the character is uppercase;
      *          <code>false</code> otherwise.
-     * @see     java.lang.Character#isLowerCase(int)
-     * @see     java.lang.Character#isTitleCase(int)
-     * @see     java.lang.Character#toUpperCase(int)
-     * @see     java.lang.Character#getType(int)
+     * @see     Character#isLowerCase(int)
+     * @see     Character#isTitleCase(int)
+     * @see     Character#toUpperCase(int)
+     * @see     Character#getType(int)
      * @since   1.5
      */
     public static boolean isUpperCase(int codePoint) {
@@ -4728,10 +4896,10 @@
      * @param   ch   the character to be tested.
      * @return  <code>true</code> if the character is titlecase;
      *          <code>false</code> otherwise.
-     * @see     java.lang.Character#isLowerCase(char)
-     * @see     java.lang.Character#isUpperCase(char)
-     * @see     java.lang.Character#toTitleCase(char)
-     * @see     java.lang.Character#getType(char)
+     * @see     Character#isLowerCase(char)
+     * @see     Character#isUpperCase(char)
+     * @see     Character#toTitleCase(char)
+     * @see     Character#getType(char)
      * @since   1.0.2
      */
     public static boolean isTitleCase(char ch) {
@@ -4764,10 +4932,10 @@
      * @param   codePoint the character (Unicode code point) to be tested.
      * @return  <code>true</code> if the character is titlecase;
      *          <code>false</code> otherwise.
-     * @see     java.lang.Character#isLowerCase(int)
-     * @see     java.lang.Character#isUpperCase(int)
-     * @see     java.lang.Character#toTitleCase(int)
-     * @see     java.lang.Character#getType(int)
+     * @see     Character#isLowerCase(int)
+     * @see     Character#isUpperCase(int)
+     * @see     Character#toTitleCase(int)
+     * @see     Character#getType(int)
      * @since   1.5
      */
     public static boolean isTitleCase(int codePoint) {
@@ -4805,9 +4973,9 @@
      * @param   ch   the character to be tested.
      * @return  <code>true</code> if the character is a digit;
      *          <code>false</code> otherwise.
-     * @see     java.lang.Character#digit(char, int)
-     * @see     java.lang.Character#forDigit(int, int)
-     * @see     java.lang.Character#getType(char)
+     * @see     Character#digit(char, int)
+     * @see     Character#forDigit(int, int)
+     * @see     Character#getType(char)
      */
     public static boolean isDigit(char ch) {
         return isDigit((int)ch);
@@ -4839,8 +5007,8 @@
      * @param   codePoint the character (Unicode code point) to be tested.
      * @return  <code>true</code> if the character is a digit;
      *          <code>false</code> otherwise.
-     * @see     java.lang.Character#forDigit(int, int)
-     * @see     java.lang.Character#getType(int)
+     * @see     Character#forDigit(int, int)
+     * @see     Character#getType(int)
      * @since   1.5
      */
     public static boolean isDigit(int codePoint) {
@@ -4864,12 +5032,12 @@
      * @param   ch   the character to be tested
      * @return  <code>true</code> if the character has a defined meaning
      *          in Unicode; <code>false</code> otherwise.
-     * @see     java.lang.Character#isDigit(char)
-     * @see     java.lang.Character#isLetter(char)
-     * @see     java.lang.Character#isLetterOrDigit(char)
-     * @see     java.lang.Character#isLowerCase(char)
-     * @see     java.lang.Character#isTitleCase(char)
-     * @see     java.lang.Character#isUpperCase(char)
+     * @see     Character#isDigit(char)
+     * @see     Character#isLetter(char)
+     * @see     Character#isLetterOrDigit(char)
+     * @see     Character#isLowerCase(char)
+     * @see     Character#isTitleCase(char)
+     * @see     Character#isUpperCase(char)
      * @since   1.0.2
      */
     public static boolean isDefined(char ch) {
@@ -4888,12 +5056,12 @@
      * @param   codePoint the character (Unicode code point) to be tested.
      * @return  <code>true</code> if the character has a defined meaning
      *          in Unicode; <code>false</code> otherwise.
-     * @see     java.lang.Character#isDigit(int)
-     * @see     java.lang.Character#isLetter(int)
-     * @see     java.lang.Character#isLetterOrDigit(int)
-     * @see     java.lang.Character#isLowerCase(int)
-     * @see     java.lang.Character#isTitleCase(int)
-     * @see     java.lang.Character#isUpperCase(int)
+     * @see     Character#isDigit(int)
+     * @see     Character#isLetter(int)
+     * @see     Character#isLetterOrDigit(int)
+     * @see     Character#isLowerCase(int)
+     * @see     Character#isTitleCase(int)
+     * @see     Character#isUpperCase(int)
      * @since   1.5
      */
     public static boolean isDefined(int codePoint) {
@@ -4925,15 +5093,15 @@
      * @param   ch   the character to be tested.
      * @return  <code>true</code> if the character is a letter;
      *          <code>false</code> otherwise.
-     * @see     java.lang.Character#isDigit(char)
-     * @see     java.lang.Character#isJavaIdentifierStart(char)
-     * @see     java.lang.Character#isJavaLetter(char)
-     * @see     java.lang.Character#isJavaLetterOrDigit(char)
-     * @see     java.lang.Character#isLetterOrDigit(char)
-     * @see     java.lang.Character#isLowerCase(char)
-     * @see     java.lang.Character#isTitleCase(char)
-     * @see     java.lang.Character#isUnicodeIdentifierStart(char)
-     * @see     java.lang.Character#isUpperCase(char)
+     * @see     Character#isDigit(char)
+     * @see     Character#isJavaIdentifierStart(char)
+     * @see     Character#isJavaLetter(char)
+     * @see     Character#isJavaLetterOrDigit(char)
+     * @see     Character#isLetterOrDigit(char)
+     * @see     Character#isLowerCase(char)
+     * @see     Character#isTitleCase(char)
+     * @see     Character#isUnicodeIdentifierStart(char)
+     * @see     Character#isUpperCase(char)
      */
     public static boolean isLetter(char ch) {
         return isLetter((int)ch);
@@ -4959,13 +5127,13 @@
      * @param   codePoint the character (Unicode code point) to be tested.
      * @return  <code>true</code> if the character is a letter;
      *          <code>false</code> otherwise.
-     * @see     java.lang.Character#isDigit(int)
-     * @see     java.lang.Character#isJavaIdentifierStart(int)
-     * @see     java.lang.Character#isLetterOrDigit(int)
-     * @see     java.lang.Character#isLowerCase(int)
-     * @see     java.lang.Character#isTitleCase(int)
-     * @see     java.lang.Character#isUnicodeIdentifierStart(int)
-     * @see     java.lang.Character#isUpperCase(int)
+     * @see     Character#isDigit(int)
+     * @see     Character#isJavaIdentifierStart(int)
+     * @see     Character#isLetterOrDigit(int)
+     * @see     Character#isLowerCase(int)
+     * @see     Character#isTitleCase(int)
+     * @see     Character#isUnicodeIdentifierStart(int)
+     * @see     Character#isUpperCase(int)
      * @since   1.5
      */
     public static boolean isLetter(int codePoint) {
@@ -4993,12 +5161,12 @@
      * @param   ch   the character to be tested.
      * @return  <code>true</code> if the character is a letter or digit;
      *          <code>false</code> otherwise.
-     * @see     java.lang.Character#isDigit(char)
-     * @see     java.lang.Character#isJavaIdentifierPart(char)
-     * @see     java.lang.Character#isJavaLetter(char)
-     * @see     java.lang.Character#isJavaLetterOrDigit(char)
-     * @see     java.lang.Character#isLetter(char)
-     * @see     java.lang.Character#isUnicodeIdentifierPart(char)
+     * @see     Character#isDigit(char)
+     * @see     Character#isJavaIdentifierPart(char)
+     * @see     Character#isJavaLetter(char)
+     * @see     Character#isJavaLetterOrDigit(char)
+     * @see     Character#isLetter(char)
+     * @see     Character#isUnicodeIdentifierPart(char)
      * @since   1.0.2
      */
     public static boolean isLetterOrDigit(char ch) {
@@ -5016,10 +5184,10 @@
      * @param   codePoint the character (Unicode code point) to be tested.
      * @return  <code>true</code> if the character is a letter or digit;
      *          <code>false</code> otherwise.
-     * @see     java.lang.Character#isDigit(int)
-     * @see     java.lang.Character#isJavaIdentifierPart(int)
-     * @see     java.lang.Character#isLetter(int)
-     * @see     java.lang.Character#isUnicodeIdentifierPart(int)
+     * @see     Character#isDigit(int)
+     * @see     Character#isJavaIdentifierPart(int)
+     * @see     Character#isLetter(int)
+     * @see     Character#isUnicodeIdentifierPart(int)
      * @since   1.5
      */
     public static boolean isLetterOrDigit(int codePoint) {
@@ -5048,12 +5216,12 @@
      * @param   ch the character to be tested.
      * @return  <code>true</code> if the character may start a Java
      *          identifier; <code>false</code> otherwise.
-     * @see     java.lang.Character#isJavaLetterOrDigit(char)
-     * @see     java.lang.Character#isJavaIdentifierStart(char)
-     * @see     java.lang.Character#isJavaIdentifierPart(char)
-     * @see     java.lang.Character#isLetter(char)
-     * @see     java.lang.Character#isLetterOrDigit(char)
-     * @see     java.lang.Character#isUnicodeIdentifierStart(char)
+     * @see     Character#isJavaLetterOrDigit(char)
+     * @see     Character#isJavaIdentifierStart(char)
+     * @see     Character#isJavaIdentifierPart(char)
+     * @see     Character#isLetter(char)
+     * @see     Character#isLetterOrDigit(char)
+     * @see     Character#isUnicodeIdentifierStart(char)
      * @since   1.02
      * @deprecated Replaced by isJavaIdentifierStart(char).
      */
@@ -5083,13 +5251,13 @@
      * @param   ch the character to be tested.
      * @return  <code>true</code> if the character may be part of a
      *          Java identifier; <code>false</code> otherwise.
-     * @see     java.lang.Character#isJavaLetter(char)
-     * @see     java.lang.Character#isJavaIdentifierStart(char)
-     * @see     java.lang.Character#isJavaIdentifierPart(char)
-     * @see     java.lang.Character#isLetter(char)
-     * @see     java.lang.Character#isLetterOrDigit(char)
-     * @see     java.lang.Character#isUnicodeIdentifierPart(char)
-     * @see     java.lang.Character#isIdentifierIgnorable(char)
+     * @see     Character#isJavaLetter(char)
+     * @see     Character#isJavaIdentifierStart(char)
+     * @see     Character#isJavaIdentifierPart(char)
+     * @see     Character#isLetter(char)
+     * @see     Character#isLetterOrDigit(char)
+     * @see     Character#isUnicodeIdentifierPart(char)
+     * @see     Character#isIdentifierIgnorable(char)
      * @since   1.02
      * @deprecated Replaced by isJavaIdentifierPart(char).
      */
@@ -5119,9 +5287,9 @@
      * @param   ch the character to be tested.
      * @return  <code>true</code> if the character may start a Java identifier;
      *          <code>false</code> otherwise.
-     * @see     java.lang.Character#isJavaIdentifierPart(char)
-     * @see     java.lang.Character#isLetter(char)
-     * @see     java.lang.Character#isUnicodeIdentifierStart(char)
+     * @see     Character#isJavaIdentifierPart(char)
+     * @see     Character#isLetter(char)
+     * @see     Character#isUnicodeIdentifierStart(char)
      * @see     javax.lang.model.SourceVersion#isIdentifier(CharSequence)
      * @since   1.1
      */
@@ -5148,9 +5316,9 @@
      * @param   codePoint the character (Unicode code point) to be tested.
      * @return  <code>true</code> if the character may start a Java identifier;
      *          <code>false</code> otherwise.
-     * @see     java.lang.Character#isJavaIdentifierPart(int)
-     * @see     java.lang.Character#isLetter(int)
-     * @see     java.lang.Character#isUnicodeIdentifierStart(int)
+     * @see     Character#isJavaIdentifierPart(int)
+     * @see     Character#isLetter(int)
+     * @see     Character#isUnicodeIdentifierStart(int)
      * @see     javax.lang.model.SourceVersion#isIdentifier(CharSequence)
      * @since   1.5
      */
@@ -5184,10 +5352,10 @@
      * @param   ch      the character to be tested.
      * @return <code>true</code> if the character may be part of a
      *          Java identifier; <code>false</code> otherwise.
-     * @see     java.lang.Character#isIdentifierIgnorable(char)
-     * @see     java.lang.Character#isJavaIdentifierStart(char)
-     * @see     java.lang.Character#isLetterOrDigit(char)
-     * @see     java.lang.Character#isUnicodeIdentifierPart(char)
+     * @see     Character#isIdentifierIgnorable(char)
+     * @see     Character#isJavaIdentifierStart(char)
+     * @see     Character#isLetterOrDigit(char)
+     * @see     Character#isUnicodeIdentifierPart(char)
      * @see     javax.lang.model.SourceVersion#isIdentifier(CharSequence)
      * @since   1.1
      */
@@ -5217,10 +5385,10 @@
      * @param   codePoint the character (Unicode code point) to be tested.
      * @return <code>true</code> if the character may be part of a
      *          Java identifier; <code>false</code> otherwise.
-     * @see     java.lang.Character#isIdentifierIgnorable(int)
-     * @see     java.lang.Character#isJavaIdentifierStart(int)
-     * @see     java.lang.Character#isLetterOrDigit(int)
-     * @see     java.lang.Character#isUnicodeIdentifierPart(int)
+     * @see     Character#isIdentifierIgnorable(int)
+     * @see     Character#isJavaIdentifierStart(int)
+     * @see     Character#isLetterOrDigit(int)
+     * @see     Character#isUnicodeIdentifierPart(int)
      * @see     javax.lang.model.SourceVersion#isIdentifier(CharSequence)
      * @since   1.5
      */
@@ -5248,9 +5416,9 @@
      * @param   ch      the character to be tested.
      * @return  <code>true</code> if the character may start a Unicode
      *          identifier; <code>false</code> otherwise.
-     * @see     java.lang.Character#isJavaIdentifierStart(char)
-     * @see     java.lang.Character#isLetter(char)
-     * @see     java.lang.Character#isUnicodeIdentifierPart(char)
+     * @see     Character#isJavaIdentifierStart(char)
+     * @see     Character#isLetter(char)
+     * @see     Character#isUnicodeIdentifierPart(char)
      * @since   1.1
      */
     public static boolean isUnicodeIdentifierStart(char ch) {
@@ -5272,9 +5440,9 @@
      * @param   codePoint the character (Unicode code point) to be tested.
      * @return  <code>true</code> if the character may start a Unicode
      *          identifier; <code>false</code> otherwise.
-     * @see     java.lang.Character#isJavaIdentifierStart(int)
-     * @see     java.lang.Character#isLetter(int)
-     * @see     java.lang.Character#isUnicodeIdentifierPart(int)
+     * @see     Character#isJavaIdentifierStart(int)
+     * @see     Character#isLetter(int)
+     * @see     Character#isUnicodeIdentifierPart(int)
      * @since   1.5
      */
     public static boolean isUnicodeIdentifierStart(int codePoint) {
@@ -5306,10 +5474,10 @@
      * @param   ch      the character to be tested.
      * @return  <code>true</code> if the character may be part of a
      *          Unicode identifier; <code>false</code> otherwise.
-     * @see     java.lang.Character#isIdentifierIgnorable(char)
-     * @see     java.lang.Character#isJavaIdentifierPart(char)
-     * @see     java.lang.Character#isLetterOrDigit(char)
-     * @see     java.lang.Character#isUnicodeIdentifierStart(char)
+     * @see     Character#isIdentifierIgnorable(char)
+     * @see     Character#isJavaIdentifierPart(char)
+     * @see     Character#isLetterOrDigit(char)
+     * @see     Character#isUnicodeIdentifierStart(char)
      * @since   1.1
      */
     public static boolean isUnicodeIdentifierPart(char ch) {
@@ -5335,10 +5503,10 @@
      * @param   codePoint the character (Unicode code point) to be tested.
      * @return  <code>true</code> if the character may be part of a
      *          Unicode identifier; <code>false</code> otherwise.
-     * @see     java.lang.Character#isIdentifierIgnorable(int)
-     * @see     java.lang.Character#isJavaIdentifierPart(int)
-     * @see     java.lang.Character#isLetterOrDigit(int)
-     * @see     java.lang.Character#isUnicodeIdentifierStart(int)
+     * @see     Character#isIdentifierIgnorable(int)
+     * @see     Character#isJavaIdentifierPart(int)
+     * @see     Character#isLetterOrDigit(int)
+     * @see     Character#isUnicodeIdentifierStart(int)
      * @since   1.5
      */
     public static boolean isUnicodeIdentifierPart(int codePoint) {
@@ -5372,8 +5540,8 @@
      * @return  <code>true</code> if the character is an ignorable control
      *          character that may be part of a Java or Unicode identifier;
      *           <code>false</code> otherwise.
-     * @see     java.lang.Character#isJavaIdentifierPart(char)
-     * @see     java.lang.Character#isUnicodeIdentifierPart(char)
+     * @see     Character#isJavaIdentifierPart(char)
+     * @see     Character#isUnicodeIdentifierPart(char)
      * @since   1.1
      */
     public static boolean isIdentifierIgnorable(char ch) {
@@ -5402,8 +5570,8 @@
      * @return  <code>true</code> if the character is an ignorable control
      *          character that may be part of a Java or Unicode identifier;
      *          <code>false</code> otherwise.
-     * @see     java.lang.Character#isJavaIdentifierPart(int)
-     * @see     java.lang.Character#isUnicodeIdentifierPart(int)
+     * @see     Character#isJavaIdentifierPart(int)
+     * @see     Character#isUnicodeIdentifierPart(int)
      * @since   1.5
      */
     public static boolean isIdentifierIgnorable(int codePoint) {
@@ -5419,7 +5587,7 @@
      * does not always return <code>true</code> for some ranges of
      * characters, particularly those that are symbols or ideographs.
      *
-     * <p>In general, {@link java.lang.String#toLowerCase()} should be used to map
+     * <p>In general, {@link String#toLowerCase()} should be used to map
      * characters to lowercase. <code>String</code> case mapping methods
      * have several benefits over <code>Character</code> case mapping methods.
      * <code>String</code> case mapping methods can perform locale-sensitive
@@ -5434,8 +5602,8 @@
      * @param   ch   the character to be converted.
      * @return  the lowercase equivalent of the character, if any;
      *          otherwise, the character itself.
-     * @see     java.lang.Character#isLowerCase(char)
-     * @see     java.lang.String#toLowerCase()
+     * @see     Character#isLowerCase(char)
+     * @see     String#toLowerCase()
      */
     public static char toLowerCase(char ch) {
         return (char)toLowerCase((int)ch);
@@ -5451,7 +5619,7 @@
      * does not always return <code>true</code> for some ranges of
      * characters, particularly those that are symbols or ideographs.
      *
-     * <p>In general, {@link java.lang.String#toLowerCase()} should be used to map
+     * <p>In general, {@link String#toLowerCase()} should be used to map
      * characters to lowercase. <code>String</code> case mapping methods
      * have several benefits over <code>Character</code> case mapping methods.
      * <code>String</code> case mapping methods can perform locale-sensitive
@@ -5461,8 +5629,8 @@
      * @param   codePoint   the character (Unicode code point) to be converted.
      * @return  the lowercase equivalent of the character (Unicode code
      *          point), if any; otherwise, the character itself.
-     * @see     java.lang.Character#isLowerCase(int)
-     * @see     java.lang.String#toLowerCase()
+     * @see     Character#isLowerCase(int)
+     * @see     String#toLowerCase()
      *
      * @since   1.5
      */
@@ -5479,7 +5647,7 @@
      * does not always return <code>true</code> for some ranges of
      * characters, particularly those that are symbols or ideographs.
      *
-     * <p>In general, {@link java.lang.String#toUpperCase()} should be used to map
+     * <p>In general, {@link String#toUpperCase()} should be used to map
      * characters to uppercase. <code>String</code> case mapping methods
      * have several benefits over <code>Character</code> case mapping methods.
      * <code>String</code> case mapping methods can perform locale-sensitive
@@ -5494,8 +5662,8 @@
      * @param   ch   the character to be converted.
      * @return  the uppercase equivalent of the character, if any;
      *          otherwise, the character itself.
-     * @see     java.lang.Character#isUpperCase(char)
-     * @see     java.lang.String#toUpperCase()
+     * @see     Character#isUpperCase(char)
+     * @see     String#toUpperCase()
      */
     public static char toUpperCase(char ch) {
         return (char)toUpperCase((int)ch);
@@ -5511,7 +5679,7 @@
      * does not always return <code>true</code> for some ranges of
      * characters, particularly those that are symbols or ideographs.
      *
-     * <p>In general, {@link java.lang.String#toUpperCase()} should be used to map
+     * <p>In general, {@link String#toUpperCase()} should be used to map
      * characters to uppercase. <code>String</code> case mapping methods
      * have several benefits over <code>Character</code> case mapping methods.
      * <code>String</code> case mapping methods can perform locale-sensitive
@@ -5521,8 +5689,8 @@
      * @param   codePoint   the character (Unicode code point) to be converted.
      * @return  the uppercase equivalent of the character, if any;
      *          otherwise, the character itself.
-     * @see     java.lang.Character#isUpperCase(int)
-     * @see     java.lang.String#toUpperCase()
+     * @see     Character#isUpperCase(int)
+     * @see     String#toUpperCase()
      *
      * @since   1.5
      */
@@ -5553,9 +5721,9 @@
      * @param   ch   the character to be converted.
      * @return  the titlecase equivalent of the character, if any;
      *          otherwise, the character itself.
-     * @see     java.lang.Character#isTitleCase(char)
-     * @see     java.lang.Character#toLowerCase(char)
-     * @see     java.lang.Character#toUpperCase(char)
+     * @see     Character#isTitleCase(char)
+     * @see     Character#toLowerCase(char)
+     * @see     Character#toUpperCase(char)
      * @since   1.0.2
      */
     public static char toTitleCase(char ch) {
@@ -5580,9 +5748,9 @@
      * @param   codePoint   the character (Unicode code point) to be converted.
      * @return  the titlecase equivalent of the character, if any;
      *          otherwise, the character itself.
-     * @see     java.lang.Character#isTitleCase(int)
-     * @see     java.lang.Character#toLowerCase(int)
-     * @see     java.lang.Character#toUpperCase(int)
+     * @see     Character#isTitleCase(int)
+     * @see     Character#toLowerCase(int)
+     * @see     Character#toUpperCase(int)
      * @since   1.5
      */
     public static int toTitleCase(int codePoint) {
@@ -5624,8 +5792,8 @@
      * @param   radix   the radix.
      * @return  the numeric value represented by the character in the
      *          specified radix.
-     * @see     java.lang.Character#forDigit(int, int)
-     * @see     java.lang.Character#isDigit(char)
+     * @see     Character#forDigit(int, int)
+     * @see     Character#isDigit(char)
      */
     public static int digit(char ch, int radix) {
         return digit((int)ch, radix);
@@ -5661,8 +5829,8 @@
      * @param   radix   the radix.
      * @return  the numeric value represented by the character in the
      *          specified radix.
-     * @see     java.lang.Character#forDigit(int, int)
-     * @see     java.lang.Character#isDigit(int)
+     * @see     Character#forDigit(int, int)
+     * @see     Character#isDigit(int)
      * @since   1.5
      */
     public static int digit(int codePoint, int radix) {
@@ -5699,8 +5867,8 @@
      * @return  the numeric value of the character, as a nonnegative <code>int</code>
      *           value; -2 if the character has a numeric value that is not a
      *          nonnegative integer; -1 if the character has no numeric value.
-     * @see     java.lang.Character#forDigit(int, int)
-     * @see     java.lang.Character#isDigit(char)
+     * @see     Character#forDigit(int, int)
+     * @see     Character#isDigit(char)
      * @since   1.1
      */
     public static int getNumericValue(char ch) {
@@ -5732,8 +5900,8 @@
      * @return  the numeric value of the character, as a nonnegative <code>int</code>
      *          value; -2 if the character has a numeric value that is not a
      *          nonnegative integer; -1 if the character has no numeric value.
-     * @see     java.lang.Character#forDigit(int, int)
-     * @see     java.lang.Character#isDigit(int)
+     * @see     Character#forDigit(int, int)
+     * @see     Character#isDigit(int)
      * @since   1.5
      */
     public static int getNumericValue(int codePoint) {
@@ -5760,8 +5928,8 @@
      * @param      ch   the character to be tested.
      * @return     <code>true</code> if the character is ISO-LATIN-1 white
      *             space; <code>false</code> otherwise.
-     * @see        java.lang.Character#isSpaceChar(char)
-     * @see        java.lang.Character#isWhitespace(char)
+     * @see        Character#isSpaceChar(char)
+     * @see        Character#isWhitespace(char)
      * @deprecated Replaced by isWhitespace(char).
      */
     @Deprecated
@@ -5795,7 +5963,7 @@
      * @param   ch      the character to be tested.
      * @return  <code>true</code> if the character is a space character;
      *          <code>false</code> otherwise.
-     * @see     java.lang.Character#isWhitespace(char)
+     * @see     Character#isWhitespace(char)
      * @since   1.1
      */
     public static boolean isSpaceChar(char ch) {
@@ -5818,7 +5986,7 @@
      * @param   codePoint the character (Unicode code point) to be tested.
      * @return  <code>true</code> if the character is a space character;
      *          <code>false</code> otherwise.
-     * @see     java.lang.Character#isWhitespace(int)
+     * @see     Character#isWhitespace(int)
      * @since   1.5
      */
     public static boolean isSpaceChar(int codePoint) {
@@ -5856,7 +6024,7 @@
      * @param   ch the character to be tested.
      * @return  <code>true</code> if the character is a Java whitespace
      *          character; <code>false</code> otherwise.
-     * @see     java.lang.Character#isSpaceChar(char)
+     * @see     Character#isSpaceChar(char)
      * @since   1.1
      */
     public static boolean isWhitespace(char ch) {
@@ -5888,7 +6056,7 @@
      * @param   codePoint the character (Unicode code point) to be tested.
      * @return  <code>true</code> if the character is a Java whitespace
      *          character; <code>false</code> otherwise.
-     * @see     java.lang.Character#isSpaceChar(int)
+     * @see     Character#isSpaceChar(int)
      * @since   1.5
      */
     public static boolean isWhitespace(int codePoint) {
@@ -5911,8 +6079,8 @@
      * @return  <code>true</code> if the character is an ISO control character;
      *          <code>false</code> otherwise.
      *
-     * @see     java.lang.Character#isSpaceChar(char)
-     * @see     java.lang.Character#isWhitespace(char)
+     * @see     Character#isSpaceChar(char)
+     * @see     Character#isWhitespace(char)
      * @since   1.1
      */
     public static boolean isISOControl(char ch) {
@@ -5929,13 +6097,16 @@
      * @param   codePoint the character (Unicode code point) to be tested.
      * @return  <code>true</code> if the character is an ISO control character;
      *          <code>false</code> otherwise.
-     * @see     java.lang.Character#isSpaceChar(int)
-     * @see     java.lang.Character#isWhitespace(int)
+     * @see     Character#isSpaceChar(int)
+     * @see     Character#isWhitespace(int)
      * @since   1.5
      */
     public static boolean isISOControl(int codePoint) {
-        return (codePoint >= 0x0000 && codePoint <= 0x001F) ||
-            (codePoint >= 0x007F && codePoint <= 0x009F);
+        // Optimized form of:
+        //     (codePoint >= 0x00 && codePoint <= 0x1F) ||
+        //     (codePoint >= 0x7F && codePoint <= 0x9F);
+        return codePoint <= 0x9F &&
+            (codePoint >= 0x7F || (codePoint >>> 5 == 0));
     }
 
     /**
@@ -5949,36 +6120,36 @@
      * @param   ch      the character to be tested.
      * @return  a value of type <code>int</code> representing the
      *          character's general category.
-     * @see     java.lang.Character#COMBINING_SPACING_MARK
-     * @see     java.lang.Character#CONNECTOR_PUNCTUATION
-     * @see     java.lang.Character#CONTROL
-     * @see     java.lang.Character#CURRENCY_SYMBOL
-     * @see     java.lang.Character#DASH_PUNCTUATION
-     * @see     java.lang.Character#DECIMAL_DIGIT_NUMBER
-     * @see     java.lang.Character#ENCLOSING_MARK
-     * @see     java.lang.Character#END_PUNCTUATION
-     * @see     java.lang.Character#FINAL_QUOTE_PUNCTUATION
-     * @see     java.lang.Character#FORMAT
-     * @see     java.lang.Character#INITIAL_QUOTE_PUNCTUATION
-     * @see     java.lang.Character#LETTER_NUMBER
-     * @see     java.lang.Character#LINE_SEPARATOR
-     * @see     java.lang.Character#LOWERCASE_LETTER
-     * @see     java.lang.Character#MATH_SYMBOL
-     * @see     java.lang.Character#MODIFIER_LETTER
-     * @see     java.lang.Character#MODIFIER_SYMBOL
-     * @see     java.lang.Character#NON_SPACING_MARK
-     * @see     java.lang.Character#OTHER_LETTER
-     * @see     java.lang.Character#OTHER_NUMBER
-     * @see     java.lang.Character#OTHER_PUNCTUATION
-     * @see     java.lang.Character#OTHER_SYMBOL
-     * @see     java.lang.Character#PARAGRAPH_SEPARATOR
-     * @see     java.lang.Character#PRIVATE_USE
-     * @see     java.lang.Character#SPACE_SEPARATOR
-     * @see     java.lang.Character#START_PUNCTUATION
-     * @see     java.lang.Character#SURROGATE
-     * @see     java.lang.Character#TITLECASE_LETTER
-     * @see     java.lang.Character#UNASSIGNED
-     * @see     java.lang.Character#UPPERCASE_LETTER
+     * @see     Character#COMBINING_SPACING_MARK
+     * @see     Character#CONNECTOR_PUNCTUATION
+     * @see     Character#CONTROL
+     * @see     Character#CURRENCY_SYMBOL
+     * @see     Character#DASH_PUNCTUATION
+     * @see     Character#DECIMAL_DIGIT_NUMBER
+     * @see     Character#ENCLOSING_MARK
+     * @see     Character#END_PUNCTUATION
+     * @see     Character#FINAL_QUOTE_PUNCTUATION
+     * @see     Character#FORMAT
+     * @see     Character#INITIAL_QUOTE_PUNCTUATION
+     * @see     Character#LETTER_NUMBER
+     * @see     Character#LINE_SEPARATOR
+     * @see     Character#LOWERCASE_LETTER
+     * @see     Character#MATH_SYMBOL
+     * @see     Character#MODIFIER_LETTER
+     * @see     Character#MODIFIER_SYMBOL
+     * @see     Character#NON_SPACING_MARK
+     * @see     Character#OTHER_LETTER
+     * @see     Character#OTHER_NUMBER
+     * @see     Character#OTHER_PUNCTUATION
+     * @see     Character#OTHER_SYMBOL
+     * @see     Character#PARAGRAPH_SEPARATOR
+     * @see     Character#PRIVATE_USE
+     * @see     Character#SPACE_SEPARATOR
+     * @see     Character#START_PUNCTUATION
+     * @see     Character#SURROGATE
+     * @see     Character#TITLECASE_LETTER
+     * @see     Character#UNASSIGNED
+     * @see     Character#UPPERCASE_LETTER
      * @since   1.1
      */
     public static int getType(char ch) {
@@ -6047,9 +6218,9 @@
      * @param   radix   the radix.
      * @return  the <code>char</code> representation of the specified digit
      *          in the specified radix.
-     * @see     java.lang.Character#MIN_RADIX
-     * @see     java.lang.Character#MAX_RADIX
-     * @see     java.lang.Character#digit(char, int)
+     * @see     Character#MIN_RADIX
+     * @see     Character#MAX_RADIX
+     * @see     Character#digit(char, int)
      */
     public static char forDigit(int digit, int radix) {
         if ((digit >= radix) || (digit < 0)) {
@@ -6230,10 +6401,10 @@
      * @return  either the uppercase equivalent of the character, if
      *          any, or an error flag (<code>Character.ERROR</code>)
      *          that indicates that a 1:M <code>char</code> mapping exists.
-     * @see     java.lang.Character#isLowerCase(char)
-     * @see     java.lang.Character#isUpperCase(char)
-     * @see     java.lang.Character#toLowerCase(char)
-     * @see     java.lang.Character#toTitleCase(char)
+     * @see     Character#isLowerCase(char)
+     * @see     Character#isUpperCase(char)
+     * @see     Character#toLowerCase(char)
+     * @see     Character#toTitleCase(char)
      * @since 1.4
      */
     static int toUpperCaseEx(int codePoint) {
@@ -6254,8 +6425,7 @@
      */
     static char[] toUpperCaseCharArray(int codePoint) {
         // As of Unicode 4.0, 1:M uppercasings only happen in the BMP.
-        assert isValidCodePoint(codePoint) &&
-               !isSupplementaryCodePoint(codePoint);
+        assert isBmpCodePoint(codePoint);
         return CharacterData.of(codePoint).toUpperCaseCharArray(codePoint);
     }
 
--- a/src/share/classes/java/lang/String.java	Mon Jul 12 19:35:11 2010 -0700
+++ b/src/share/classes/java/lang/String.java	Mon Jul 12 19:42:02 2010 -0700
@@ -38,7 +38,6 @@
 import java.util.regex.Pattern;
 import java.util.regex.PatternSyntaxException;
 
-
 /**
  * The <code>String</code> class represents character strings. All
  * string literals in Java programs, such as <code>"abc"</code>, are
@@ -99,6 +98,8 @@
  *
  * @author  Lee Boynton
  * @author  Arthur van Hoff
+ * @author  Martin Buchholz
+ * @author  Ulf Zibis
  * @see     java.lang.Object#toString()
  * @see     java.lang.StringBuffer
  * @see     java.lang.StringBuilder
@@ -273,32 +274,32 @@
             throw new StringIndexOutOfBoundsException(offset + count);
         }
 
+        final int end = offset + count;
+
         // Pass 1: Compute precise size of char[]
-        int n = 0;
-        for (int i = offset; i < offset + count; i++) {
+        int n = count;
+        for (int i = offset; i < end; i++) {
             int c = codePoints[i];
-            if (c >= Character.MIN_CODE_POINT &&
-                c <  Character.MIN_SUPPLEMENTARY_CODE_POINT)
-                n += 1;
-            else if (Character.isSupplementaryCodePoint(c))
-                n += 2;
+            if (Character.isBmpCodePoint(c))
+                continue;
+            else if (Character.isValidCodePoint(c))
+                n++;
             else throw new IllegalArgumentException(Integer.toString(c));
         }
 
         // Pass 2: Allocate and fill in char[]
-        char[] v = new char[n];
-        for (int i = offset, j = 0; i < offset + count; i++) {
+        final char[] v = new char[n];
+
+        for (int i = offset, j = 0; i < end; i++, j++) {
             int c = codePoints[i];
-            if (c < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
-                v[j++] = (char) c;
-            } else {
-                Character.toSurrogates(c, v, j);
-                j += 2;
-            }
+            if (Character.isBmpCodePoint(c))
+                v[j] = (char) c;
+            else
+                Character.toSurrogates(c, v, j++);
         }
 
         this.value  = v;
-        this.count  = v.length;
+        this.count  = n;
         this.offset = 0;
     }
 
@@ -1573,9 +1574,6 @@
      *          if the character does not occur.
      */
     public int indexOf(int ch, int fromIndex) {
-        int max = offset + count;
-        char v[] = value;
-
         if (fromIndex < 0) {
             fromIndex = 0;
         } else if (fromIndex >= count) {
@@ -1583,29 +1581,36 @@
             return -1;
         }
 
-        int i = offset + fromIndex;
         if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
             // handle most cases here (ch is a BMP code point or a
             // negative value (invalid code point))
-            for (; i < max ; i++) {
-                if (v[i] == ch) {
+            final char[] value = this.value;
+            final int offset = this.offset;
+            final int max = offset + count;
+            for (int i = offset + fromIndex; i < max ; i++) {
+                if (value[i] == ch) {
                     return i - offset;
                 }
             }
             return -1;
+        } else {
+            return indexOfSupplementary(ch, fromIndex);
         }
+    }
 
-        if (ch <= Character.MAX_CODE_POINT) {
-            // handle supplementary characters here
-            char[] surrogates = Character.toChars(ch);
-            for (; i < max; i++) {
-                if (v[i] == surrogates[0]) {
-                    if (i + 1 == max) {
-                        break;
-                    }
-                    if (v[i+1] == surrogates[1]) {
-                        return i - offset;
-                    }
+    /**
+     * Handles (rare) calls of indexOf with a supplementary character.
+     */
+    private int indexOfSupplementary(int ch, int fromIndex) {
+        if (Character.isValidCodePoint(ch)) {
+            final char[] value = this.value;
+            final int offset = this.offset;
+            final char hi = Character.highSurrogate(ch);
+            final char lo = Character.lowSurrogate(ch);
+            final int max = offset + count - 1;
+            for (int i = offset + fromIndex; i < max; i++) {
+                if (value[i] == hi && value[i+1] == lo) {
+                    return i - offset;
                 }
             }
         }
@@ -1674,34 +1679,36 @@
      *          if the character does not occur before that point.
      */
     public int lastIndexOf(int ch, int fromIndex) {
-        int min = offset;
-        char v[] = value;
-
-        int i = offset + ((fromIndex >= count) ? count - 1 : fromIndex);
-
         if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
             // handle most cases here (ch is a BMP code point or a
             // negative value (invalid code point))
-            for (; i >= min ; i--) {
-                if (v[i] == ch) {
+            final char[] value = this.value;
+            final int offset = this.offset;
+            int i = offset + Math.min(fromIndex, count - 1);
+            for (; i >= offset ; i--) {
+                if (value[i] == ch) {
                     return i - offset;
                 }
             }
             return -1;
+        } else {
+            return lastIndexOfSupplementary(ch, fromIndex);
         }
+    }
 
-        int max = offset + count;
-        if (ch <= Character.MAX_CODE_POINT) {
-            // handle supplementary characters here
-            char[] surrogates = Character.toChars(ch);
-            for (; i >= min; i--) {
-                if (v[i] == surrogates[0]) {
-                    if (i + 1 == max) {
-                        break;
-                    }
-                    if (v[i+1] == surrogates[1]) {
-                        return i - offset;
-                    }
+    /**
+     * Handles (rare) calls of lastIndexOf with a supplementary character.
+     */
+    private int lastIndexOfSupplementary(int ch, int fromIndex) {
+        if (Character.isValidCodePoint(ch)) {
+            final char[] value = this.value;
+            final int offset = this.offset;
+            char hi = Character.highSurrogate(ch);
+            char lo = Character.lowSurrogate(ch);
+            int i = offset + Math.min(fromIndex, count - 2);
+            for (; i >= offset; i--) {
+                if (value[i] == hi && value[i+1] == lo) {
+                    return i - offset;
                 }
             }
         }
@@ -1710,18 +1717,17 @@
 
     /**
      * Returns the index within this string of the first occurrence of the
-     * specified substring. The integer returned is the smallest value
-     * <i>k</i> such that:
+     * specified substring.
+     *
+     * <p>The returned index is the smallest value <i>k</i> for which:
      * <blockquote><pre>
      * this.startsWith(str, <i>k</i>)
      * </pre></blockquote>
-     * is <code>true</code>.
+     * If no such value of <i>k</i> exists, then {@code -1} is returned.
      *
-     * @param   str   any string.
-     * @return  if the string argument occurs as a substring within this
-     *          object, then the index of the first character of the first
-     *          such substring is returned; if it does not occur as a
-     *          substring, <code>-1</code> is returned.
+     * @param   str   the substring to search for.
+     * @return  the index of the first occurrence of the specified substring,
+     *          or {@code -1} if there is no such occurrence.
      */
     public int indexOf(String str) {
         return indexOf(str, 0);
@@ -1729,17 +1735,19 @@
 
     /**
      * Returns the index within this string of the first occurrence of the
-     * specified substring, starting at the specified index.  The integer
-     * returned is the smallest value <tt>k</tt> for which:
+     * specified substring, starting at the specified index.
+     *
+     * <p>The returned index is the smallest value <i>k</i> for which:
      * <blockquote><pre>
-     *     k &gt;= Math.min(fromIndex, this.length()) && this.startsWith(str, k)
+     * <i>k</i> &gt;= fromIndex && this.startsWith(str, <i>k</i>)
      * </pre></blockquote>
-     * If no such value of <i>k</i> exists, then -1 is returned.
+     * If no such value of <i>k</i> exists, then {@code -1} is returned.
      *
-     * @param   str         the substring for which to search.
+     * @param   str         the substring to search for.
      * @param   fromIndex   the index from which to start the search.
-     * @return  the index within this string of the first occurrence of the
-     *          specified substring, starting at the specified index.
+     * @return  the index of the first occurrence of the specified substring,
+     *          starting at the specified index,
+     *          or {@code -1} if there is no such occurrence.
      */
     public int indexOf(String str, int fromIndex) {
         return indexOf(value, offset, count,
@@ -1798,20 +1806,19 @@
     }
 
     /**
-     * Returns the index within this string of the rightmost occurrence
-     * of the specified substring.  The rightmost empty string "" is
-     * considered to occur at the index value <code>this.length()</code>.
-     * The returned index is the largest value <i>k</i> such that
+     * Returns the index within this string of the last occurrence of the
+     * specified substring.  The last occurrence of the empty string ""
+     * is considered to occur at the index value {@code this.length()}.
+     *
+     * <p>The returned index is the largest value <i>k</i> for which:
      * <blockquote><pre>
-     * this.startsWith(str, k)
+     * this.startsWith(str, <i>k</i>)
      * </pre></blockquote>
-     * is true.
+     * If no such value of <i>k</i> exists, then {@code -1} is returned.
      *
      * @param   str   the substring to search for.
-     * @return  if the string argument occurs one or more times as a substring
-     *          within this object, then the index of the first character of
-     *          the last such substring is returned. If it does not occur as
-     *          a substring, <code>-1</code> is returned.
+     * @return  the index of the last occurrence of the specified substring,
+     *          or {@code -1} if there is no such occurrence.
      */
     public int lastIndexOf(String str) {
         return lastIndexOf(str, count);
@@ -1820,16 +1827,18 @@
     /**
      * Returns the index within this string of the last occurrence of the
      * specified substring, searching backward starting at the specified index.
-     * The integer returned is the largest value <i>k</i> such that:
+     *
+     * <p>The returned index is the largest value <i>k</i> for which:
      * <blockquote><pre>
-     *     k &lt;= Math.min(fromIndex, this.length()) && this.startsWith(str, k)
+     * <i>k</i> &lt;= fromIndex && this.startsWith(str, <i>k</i>)
      * </pre></blockquote>
-     * If no such value of <i>k</i> exists, then -1 is returned.
+     * If no such value of <i>k</i> exists, then {@code -1} is returned.
      *
      * @param   str         the substring to search for.
      * @param   fromIndex   the index to start the search from.
-     * @return  the index within this string of the last occurrence of the
-     *          specified substring.
+     * @return  the index of the last occurrence of the specified substring,
+     *          searching backward from the specified index,
+     *          or {@code -1} if there is no such occurrence.
      */
     public int lastIndexOf(String str, int fromIndex) {
         return lastIndexOf(value, offset, count,
--- a/src/share/classes/java/lang/System.java	Mon Jul 12 19:35:11 2010 -0700
+++ b/src/share/classes/java/lang/System.java	Mon Jul 12 19:42:02 2010 -0700
@@ -69,7 +69,7 @@
      * corresponds to keyboard input or another input source specified by
      * the host environment or user.
      */
-    public final static InputStream in = nullInputStream();
+    public final static InputStream in = null;
 
     /**
      * The "standard" output stream. This stream is already
@@ -96,7 +96,7 @@
      * @see     java.io.PrintStream#println(java.lang.Object)
      * @see     java.io.PrintStream#println(java.lang.String)
      */
-    public final static PrintStream out = nullPrintStream();
+    public final static PrintStream out = null;
 
     /**
      * The "standard" error output stream. This stream is already
@@ -110,7 +110,7 @@
      * variable <code>out</code>, has been redirected to a file or other
      * destination that is typically not continuously monitored.
      */
-    public final static PrintStream err = nullPrintStream();
+    public final static PrintStream err = null;
 
     /* The security manager for the system.
      */
@@ -1093,26 +1093,6 @@
     public static native String mapLibraryName(String libname);
 
     /**
-     * The following two methods exist because in, out, and err must be
-     * initialized to null.  The compiler, however, cannot be permitted to
-     * inline access to them, since they are later set to more sensible values
-     * by initializeSystemClass().
-     */
-    private static InputStream nullInputStream() throws NullPointerException {
-        if (currentTimeMillis() > 0) {
-            return null;
-        }
-        throw new NullPointerException();
-    }
-
-    private static PrintStream nullPrintStream() throws NullPointerException {
-        if (currentTimeMillis() > 0) {
-            return null;
-        }
-        throw new NullPointerException();
-    }
-
-    /**
      * Initialize the system class.  Called after thread initialization.
      */
     private static void initializeSystemClass() {
--- a/src/share/classes/java/lang/Throwable.java	Mon Jul 12 19:35:11 2010 -0700
+++ b/src/share/classes/java/lang/Throwable.java	Mon Jul 12 19:42:02 2010 -0700
@@ -25,6 +25,7 @@
 
 package java.lang;
 import  java.io.*;
+import  java.util.*;
 
 /**
  * The <code>Throwable</code> class is the superclass of all errors and
@@ -102,7 +103,7 @@
  *         lowLevelOp();
  *     } catch (LowLevelException le) {
  *         throw (HighLevelException)
-                 new HighLevelException().initCause(le);  // Legacy constructor
+ *               new HighLevelException().initCause(le);  // Legacy constructor
  *     }
  * </pre>
  *
@@ -193,6 +194,24 @@
      */
 
     /**
+     * The list of suppressed exceptions, as returned by
+     * {@link #getSuppressedExceptions()}.
+     *
+     * @serial
+     * @since 1.7
+     */
+    private List<Throwable> suppressedExceptions = Collections.emptyList();
+
+    /** Message for trying to suppress a null exception. */
+    private static final String NULL_CAUSE_MESSAGE = "Cannot suppress a null exception.";
+
+    /** Caption  for labeling causative exception stack traces */
+    private static final String CAUSE_CAPTION = "Caused by: ";
+
+    /** Caption for labeling suppressed exception stack traces */
+    private static final String SUPPRESSED_CAPTION = "Suppressed: ";
+
+    /**
      * Constructs a new throwable with <code>null</code> as its detail message.
      * The cause is not initialized, and may subsequently be initialized by a
      * call to {@link #initCause}.
@@ -469,6 +488,52 @@
      * class LowLevelException extends Exception {
      * }
      * </pre>
+     * As of release 7, the platform supports the notion of
+     * <i>suppressed exceptions</i> (in conjunction with automatic
+     * resource management blocks). Any exceptions that were
+     * suppressed in order to deliver an exception are printed out
+     * beneath the stack trace.  The format of this information
+     * depends on the implementation, but the following example may be
+     * regarded as typical:
+     *
+     * <pre>
+     * Exception in thread "main" java.lang.Exception: Something happened
+     *  at Foo.bar(Foo.java:10)
+     *  at Foo.main(Foo.java:5)
+     *  Suppressed: Resource$CloseFailException: Resource ID = 0
+     *          at Resource.close(Resource.java:26)
+     *          at Foo.bar(Foo.java:9)
+     *          ... 1 more
+     * </pre>
+     * Note that the "... n more" notation is used on suppressed exceptions
+     * just at it is used on causes. Unlike causes, suppressed exceptions are
+     * indented beyond their "containing exceptions."
+     *
+     * <p>An exception can have both a cause and one or more suppressed
+     * exceptions:
+     * <pre>
+     * Exception in thread "main" java.lang.Exception: Main block
+     *  at Foo3.main(Foo3.java:7)
+     *  Suppressed: Resource$CloseFailException: Resource ID = 2
+     *          at Resource.close(Resource.java:26)
+     *          at Foo3.main(Foo3.java:5)
+     *  Suppressed: Resource$CloseFailException: Resource ID = 1
+     *          at Resource.close(Resource.java:26)
+     *          at Foo3.main(Foo3.java:5)
+     * Caused by: java.lang.Exception: I did it
+     *  at Foo3.main(Foo3.java:8)
+     * </pre>
+     * Likewise, a suppressed exception can have a cause:
+     * <pre>
+     * Exception in thread "main" java.lang.Exception: Main block
+     *  at Foo4.main(Foo4.java:6)
+     *  Suppressed: Resource2$CloseFailException: Resource ID = 1
+     *          at Resource2.close(Resource2.java:20)
+     *          at Foo4.main(Foo4.java:5)
+     *  Caused by: java.lang.Exception: Rats, you caught me
+     *          at Resource2$CloseFailException.<init>(Resource2.java:45)
+     *          ... 2 more
+     * </pre>
      */
     public void printStackTrace() {
         printStackTrace(System.err);
@@ -480,44 +545,71 @@
      * @param s <code>PrintStream</code> to use for output
      */
     public void printStackTrace(PrintStream s) {
-        synchronized (s) {
+        printStackTrace(new WrappedPrintStream(s));
+    }
+
+    private void printStackTrace(PrintStreamOrWriter s) {
+        Set<Throwable> dejaVu = new HashSet<Throwable>();
+        dejaVu.add(this);
+
+        synchronized (s.lock()) {
+            // Print our stack trace
             s.println(this);
             StackTraceElement[] trace = getOurStackTrace();
-            for (int i=0; i < trace.length; i++)
-                s.println("\tat " + trace[i]);
+            for (StackTraceElement traceElement : trace)
+                s.println("\tat " + traceElement);
 
+            // Print suppressed exceptions, if any
+            for (Throwable se : suppressedExceptions)
+                se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION, "\t", dejaVu);
+
+            // Print cause, if any
             Throwable ourCause = getCause();
             if (ourCause != null)
-                ourCause.printStackTraceAsCause(s, trace);
+                ourCause.printEnclosedStackTrace(s, trace, CAUSE_CAPTION, "", dejaVu);
         }
     }
 
     /**
-     * Print our stack trace as a cause for the specified stack trace.
+     * Print our stack trace as an enclosed exception for the specified
+     * stack trace.
      */
-    private void printStackTraceAsCause(PrintStream s,
-                                        StackTraceElement[] causedTrace)
-    {
-        // assert Thread.holdsLock(s);
+    private void printEnclosedStackTrace(PrintStreamOrWriter s,
+                                         StackTraceElement[] enclosingTrace,
+                                         String caption,
+                                         String prefix,
+                                         Set<Throwable> dejaVu) {
+        assert Thread.holdsLock(s.lock());
+        if (dejaVu.contains(this)) {
+            s.println("\t[CIRCULAR REFERENCE:" + this + "]");
+        } else {
+            dejaVu.add(this);
+            // Compute number of frames in common between this and enclosing trace
+            StackTraceElement[] trace = getOurStackTrace();
+            int m = trace.length - 1;
+            int n = enclosingTrace.length - 1;
+            while (m >= 0 && n >=0 && trace[m].equals(enclosingTrace[n])) {
+                m--; n--;
+            }
+            int framesInCommon = trace.length - 1 - m;
 
-        // Compute number of frames in common between this and caused
-        StackTraceElement[] trace = getOurStackTrace();
-        int m = trace.length-1, n = causedTrace.length-1;
-        while (m >= 0 && n >=0 && trace[m].equals(causedTrace[n])) {
-            m--; n--;
+            // Print our stack trace
+            s.println(prefix + caption + this);
+            for (int i = 0; i <= m; i++)
+                s.println(prefix + "\tat " + trace[i]);
+            if (framesInCommon != 0)
+                s.println(prefix + "\t... " + framesInCommon + " more");
+
+            // Print suppressed exceptions, if any
+            for (Throwable se : suppressedExceptions)
+                se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION,
+                                           prefix +"\t", dejaVu);
+
+            // Print cause, if any
+            Throwable ourCause = getCause();
+            if (ourCause != null)
+                ourCause.printEnclosedStackTrace(s, trace, CAUSE_CAPTION, prefix, dejaVu);
         }
-        int framesInCommon = trace.length - 1 - m;
-
-        s.println("Caused by: " + this);
-        for (int i=0; i <= m; i++)
-            s.println("\tat " + trace[i]);
-        if (framesInCommon != 0)
-            s.println("\t... " + framesInCommon + " more");
-
-        // Recurse if we have a cause
-        Throwable ourCause = getCause();
-        if (ourCause != null)
-            ourCause.printStackTraceAsCause(s, trace);
     }
 
     /**
@@ -528,44 +620,51 @@
      * @since   JDK1.1
      */
     public void printStackTrace(PrintWriter s) {
-        synchronized (s) {
-            s.println(this);
-            StackTraceElement[] trace = getOurStackTrace();
-            for (int i=0; i < trace.length; i++)
-                s.println("\tat " + trace[i]);
+        printStackTrace(new WrappedPrintWriter(s));
+    }
 
-            Throwable ourCause = getCause();
-            if (ourCause != null)
-                ourCause.printStackTraceAsCause(s, trace);
+    /**
+     * Wrapper class for PrintStream and PrintWriter to enable a single
+     * implementation of printStackTrace.
+     */
+    private abstract static class PrintStreamOrWriter {
+        /** Returns the object to be locked when using this StreamOrWriter */
+        abstract Object lock();
+
+        /** Prints the specified string as a line on this StreamOrWriter */
+        abstract void println(Object o);
+    }
+
+    private static class WrappedPrintStream extends PrintStreamOrWriter {
+        private final PrintStream printStream;
+
+        WrappedPrintStream(PrintStream printStream) {
+            this.printStream = printStream;
+        }
+
+        Object lock() {
+            return printStream;
+        }
+
+        void println(Object o) {
+            printStream.println(o);
         }
     }
 
-    /**
-     * Print our stack trace as a cause for the specified stack trace.
-     */
-    private void printStackTraceAsCause(PrintWriter s,
-                                        StackTraceElement[] causedTrace)
-    {
-        // assert Thread.holdsLock(s);
+    private static class WrappedPrintWriter extends PrintStreamOrWriter {
+        private final PrintWriter printWriter;
 
-        // Compute number of frames in common between this and caused
-        StackTraceElement[] trace = getOurStackTrace();
-        int m = trace.length-1, n = causedTrace.length-1;
-        while (m >= 0 && n >=0 && trace[m].equals(causedTrace[n])) {
-            m--; n--;
+        WrappedPrintWriter(PrintWriter printWriter) {
+            this.printWriter = printWriter;
         }
-        int framesInCommon = trace.length - 1 - m;
 
-        s.println("Caused by: " + this);
-        for (int i=0; i <= m; i++)
-            s.println("\tat " + trace[i]);
-        if (framesInCommon != 0)
-            s.println("\t... " + framesInCommon + " more");
+        Object lock() {
+            return printWriter;
+        }
 
-        // Recurse if we have a cause
-        Throwable ourCause = getCause();
-        if (ourCause != null)
-            ourCause.printStackTraceAsCause(s, trace);
+        void println(Object o) {
+            printWriter.println(o);
+        }
     }
 
     /**
@@ -667,10 +766,60 @@
      */
     native StackTraceElement getStackTraceElement(int index);
 
-    private synchronized void writeObject(java.io.ObjectOutputStream s)
+    private void readObject(ObjectInputStream s)
+        throws IOException, ClassNotFoundException {
+        s.defaultReadObject();     // read in all fields
+        List<Throwable> suppressed = Collections.emptyList();
+        if (suppressedExceptions != null &&
+            !suppressedExceptions.isEmpty()) { // Copy Throwables to new list
+            suppressed = new ArrayList<Throwable>();
+            for(Throwable t : suppressedExceptions) {
+                if (t == null)
+                    throw new NullPointerException(NULL_CAUSE_MESSAGE);
+                suppressed.add(t);
+            }
+        }
+        suppressedExceptions = suppressed;
+    }
+
+    private synchronized void writeObject(ObjectOutputStream s)
         throws IOException
     {
         getOurStackTrace();  // Ensure that stackTrace field is initialized.
         s.defaultWriteObject();
     }
+
+    /**
+     * Adds the specified exception to the list of exceptions that
+     * were suppressed, typically by the automatic resource management
+     * statement, in order to deliver this exception.
+     *
+     * @param exception the exception to be added to the list of
+     *        suppressed exceptions
+     * @throws NullPointerException if {@code exception} is null
+     * @since 1.7
+     */
+    public synchronized void addSuppressedException(Throwable exception) {
+        if (exception == null)
+            throw new NullPointerException(NULL_CAUSE_MESSAGE);
+
+        if (suppressedExceptions.size() == 0)
+            suppressedExceptions = new ArrayList<Throwable>();
+        suppressedExceptions.add(exception);
+    }
+
+    private static final Throwable[] EMPTY_THROWABLE_ARRAY = new Throwable[0];
+
+    /**
+     * Returns an array containing all of the exceptions that were
+     * suppressed, typically by the automatic resource management
+     * statement, in order to deliver this exception.
+     *
+     * @return an array containing all of the exceptions that were
+     *         suppressed to deliver this exception.
+     * @since 1.7
+     */
+    public Throwable[] getSuppressedExceptions() {
+        return suppressedExceptions.toArray(EMPTY_THROWABLE_ARRAY);
+    }
 }
--- a/src/share/classes/java/net/Inet6Address.java	Mon Jul 12 19:35:11 2010 -0700
+++ b/src/share/classes/java/net/Inet6Address.java	Mon Jul 12 19:42:02 2010 -0700
@@ -427,8 +427,9 @@
                     try {
                         scope_id = deriveNumericScope (scope_ifname);
                     } catch (UnknownHostException e) {
-                        // should not happen
-                        assert false;
+                        // typically should not happen, but it may be that
+                        // the machine being used for deserialization has
+                        // the same interface name but without IPv6 configured.
                     }
                 }
             } catch (SocketException e) {}
--- a/src/share/classes/java/nio/Bits.java	Mon Jul 12 19:35:11 2010 -0700
+++ b/src/share/classes/java/nio/Bits.java	Mon Jul 12 19:42:02 2010 -0700
@@ -41,25 +41,19 @@
     // -- Swapping --
 
     static short swap(short x) {
-        return (short)((x << 8) |
-                       ((char)x >>> 8));
+        return Short.reverseBytes(x);
     }
 
     static char swap(char x) {
-        return (char)((x << 8) |
-                      (x >>> 8));
+        return Character.reverseBytes(x);
     }
 
     static int swap(int x) {
-        return ((x << 24) |
-                ((x & 0x0000ff00) <<  8) |
-                ((x & 0x00ff0000) >>> 8) |
-                (x >>> 24));
+        return Integer.reverseBytes(x);
     }
 
     static long swap(long x) {
-        return (((long)swap((int)x) << 32) |
-                ((long)swap((int)(x >>> 32)) & 0xffffffffL));
+        return Long.reverseBytes(x);
     }
 
 
@@ -71,52 +65,52 @@
 
     static char getCharL(ByteBuffer bb, int bi) {
         return makeChar(bb._get(bi + 1),
-                        bb._get(bi + 0));
+                        bb._get(bi    ));
     }
 
     static char getCharL(long a) {
         return makeChar(_get(a + 1),
-                        _get(a + 0));
+                        _get(a    ));
     }
 
     static char getCharB(ByteBuffer bb, int bi) {
-        return makeChar(bb._get(bi + 0),
+        return makeChar(bb._get(bi    ),
                         bb._get(bi + 1));
     }
 
     static char getCharB(long a) {
-        return makeChar(_get(a + 0),
+        return makeChar(_get(a    ),
                         _get(a + 1));
     }
 
     static char getChar(ByteBuffer bb, int bi, boolean bigEndian) {
-        return (bigEndian ? getCharB(bb, bi) : getCharL(bb, bi));
+        return bigEndian ? getCharB(bb, bi) : getCharL(bb, bi);
     }
 
     static char getChar(long a, boolean bigEndian) {
-        return (bigEndian ? getCharB(a) : getCharL(a));
+        return bigEndian ? getCharB(a) : getCharL(a);
     }
 
     private static byte char1(char x) { return (byte)(x >> 8); }
-    private static byte char0(char x) { return (byte)(x >> 0); }
+    private static byte char0(char x) { return (byte)(x     ); }
 
     static void putCharL(ByteBuffer bb, int bi, char x) {
-        bb._put(bi + 0, char0(x));
+        bb._put(bi    , char0(x));
         bb._put(bi + 1, char1(x));
     }
 
     static void putCharL(long a, char x) {
-        _put(a + 0, char0(x));
+        _put(a    , char0(x));
         _put(a + 1, char1(x));
     }
 
     static void putCharB(ByteBuffer bb, int bi, char x) {
-        bb._put(bi + 0, char1(x));
+        bb._put(bi    , char1(x));
         bb._put(bi + 1, char0(x));
     }
 
     static void putCharB(long a, char x) {
-        _put(a + 0, char1(x));
+        _put(a    , char1(x));
         _put(a + 1, char0(x));
     }
 
@@ -143,52 +137,52 @@
 
     static short getShortL(ByteBuffer bb, int bi) {
         return makeShort(bb._get(bi + 1),
-                         bb._get(bi + 0));
+                         bb._get(bi    ));
     }
 
     static short getShortL(long a) {
         return makeShort(_get(a + 1),
-                         _get(a));
+                         _get(a    ));
     }
 
     static short getShortB(ByteBuffer bb, int bi) {
-        return makeShort(bb._get(bi + 0),
+        return makeShort(bb._get(bi    ),
                          bb._get(bi + 1));
     }
 
     static short getShortB(long a) {
-        return makeShort(_get(a),
+        return makeShort(_get(a    ),
                          _get(a + 1));
     }
 
     static short getShort(ByteBuffer bb, int bi, boolean bigEndian) {
-        return (bigEndian ? getShortB(bb, bi) : getShortL(bb, bi));
+        return bigEndian ? getShortB(bb, bi) : getShortL(bb, bi);
     }
 
     static short getShort(long a, boolean bigEndian) {
-        return (bigEndian ? getShortB(a) : getShortL(a));
+        return bigEndian ? getShortB(a) : getShortL(a);
     }
 
     private static byte short1(short x) { return (byte)(x >> 8); }
-    private static byte short0(short x) { return (byte)(x >> 0); }
+    private static byte short0(short x) { return (byte)(x     ); }
 
     static void putShortL(ByteBuffer bb, int bi, short x) {
-        bb._put(bi + 0, short0(x));
+        bb._put(bi    , short0(x));
         bb._put(bi + 1, short1(x));
     }
 
     static void putShortL(long a, short x) {
-        _put(a, short0(x));
+        _put(a    , short0(x));
         _put(a + 1, short1(x));
     }
 
     static void putShortB(ByteBuffer bb, int bi, short x) {
-        bb._put(bi + 0, short1(x));
+        bb._put(bi    , short1(x));
         bb._put(bi + 1, short0(x));
     }
 
     static void putShortB(long a, short x) {
-        _put(a, short1(x));
+        _put(a    , short1(x));
         _put(a + 1, short0(x));
     }
 
@@ -210,76 +204,76 @@
     // -- get/put int --
 
     static private int makeInt(byte b3, byte b2, byte b1, byte b0) {
-        return (((b3 & 0xff) << 24) |
+        return (((b3       ) << 24) |
                 ((b2 & 0xff) << 16) |
                 ((b1 & 0xff) <<  8) |
-                ((b0 & 0xff) <<  0));
+                ((b0 & 0xff)      ));
     }
 
     static int getIntL(ByteBuffer bb, int bi) {
         return makeInt(bb._get(bi + 3),
                        bb._get(bi + 2),
                        bb._get(bi + 1),
-                       bb._get(bi + 0));
+                       bb._get(bi    ));
     }
 
     static int getIntL(long a) {
         return makeInt(_get(a + 3),
                        _get(a + 2),
                        _get(a + 1),
-                       _get(a + 0));
+                       _get(a    ));
     }
 
     static int getIntB(ByteBuffer bb, int bi) {
-        return makeInt(bb._get(bi + 0),
+        return makeInt(bb._get(bi    ),
                        bb._get(bi + 1),
                        bb._get(bi + 2),
                        bb._get(bi + 3));
     }
 
     static int getIntB(long a) {
-        return makeInt(_get(a + 0),
+        return makeInt(_get(a    ),
                        _get(a + 1),
                        _get(a + 2),
                        _get(a + 3));
     }
 
     static int getInt(ByteBuffer bb, int bi, boolean bigEndian) {
-        return (bigEndian ? getIntB(bb, bi) : getIntL(bb, bi));
+        return bigEndian ? getIntB(bb, bi) : getIntL(bb, bi) ;
     }
 
     static int getInt(long a, boolean bigEndian) {
-        return (bigEndian ? getIntB(a) : getIntL(a));
+        return bigEndian ? getIntB(a) : getIntL(a) ;
     }
 
     private static byte int3(int x) { return (byte)(x >> 24); }
     private static byte int2(int x) { return (byte)(x >> 16); }
     private static byte int1(int x) { return (byte)(x >>  8); }
-    private static byte int0(int x) { return (byte)(x >>  0); }
+    private static byte int0(int x) { return (byte)(x      ); }
 
     static void putIntL(ByteBuffer bb, int bi, int x) {
         bb._put(bi + 3, int3(x));
         bb._put(bi + 2, int2(x));
         bb._put(bi + 1, int1(x));
-        bb._put(bi + 0, int0(x));
+        bb._put(bi    , int0(x));
     }
 
     static void putIntL(long a, int x) {
         _put(a + 3, int3(x));
         _put(a + 2, int2(x));
         _put(a + 1, int1(x));
-        _put(a + 0, int0(x));
+        _put(a    , int0(x));
     }
 
     static void putIntB(ByteBuffer bb, int bi, int x) {
-        bb._put(bi + 0, int3(x));
+        bb._put(bi    , int3(x));
         bb._put(bi + 1, int2(x));
         bb._put(bi + 2, int1(x));
         bb._put(bi + 3, int0(x));
     }
 
     static void putIntB(long a, int x) {
-        _put(a + 0, int3(x));
+        _put(a    , int3(x));
         _put(a + 1, int2(x));
         _put(a + 2, int1(x));
         _put(a + 3, int0(x));
@@ -305,14 +299,14 @@
     static private long makeLong(byte b7, byte b6, byte b5, byte b4,
                                  byte b3, byte b2, byte b1, byte b0)
     {
-        return ((((long)b7 & 0xff) << 56) |
+        return ((((long)b7       ) << 56) |
                 (((long)b6 & 0xff) << 48) |
                 (((long)b5 & 0xff) << 40) |
                 (((long)b4 & 0xff) << 32) |
                 (((long)b3 & 0xff) << 24) |
                 (((long)b2 & 0xff) << 16) |
                 (((long)b1 & 0xff) <<  8) |
-                (((long)b0 & 0xff) <<  0));
+                (((long)b0 & 0xff)      ));
     }
 
     static long getLongL(ByteBuffer bb, int bi) {
@@ -323,7 +317,7 @@
                         bb._get(bi + 3),
                         bb._get(bi + 2),
                         bb._get(bi + 1),
-                        bb._get(bi + 0));
+                        bb._get(bi    ));
     }
 
     static long getLongL(long a) {
@@ -334,11 +328,11 @@
                         _get(a + 3),
                         _get(a + 2),
                         _get(a + 1),
-                        _get(a + 0));
+                        _get(a    ));
     }
 
     static long getLongB(ByteBuffer bb, int bi) {
-        return makeLong(bb._get(bi + 0),
+        return makeLong(bb._get(bi    ),
                         bb._get(bi + 1),
                         bb._get(bi + 2),
                         bb._get(bi + 3),
@@ -349,7 +343,7 @@
     }
 
     static long getLongB(long a) {
-        return makeLong(_get(a + 0),
+        return makeLong(_get(a    ),
                         _get(a + 1),
                         _get(a + 2),
                         _get(a + 3),
@@ -360,11 +354,11 @@
     }
 
     static long getLong(ByteBuffer bb, int bi, boolean bigEndian) {
-        return (bigEndian ? getLongB(bb, bi) : getLongL(bb, bi));
+        return bigEndian ? getLongB(bb, bi) : getLongL(bb, bi);
     }
 
     static long getLong(long a, boolean bigEndian) {
-        return (bigEndian ? getLongB(a) : getLongL(a));
+        return bigEndian ? getLongB(a) : getLongL(a);
     }
 
     private static byte long7(long x) { return (byte)(x >> 56); }
@@ -374,7 +368,7 @@
     private static byte long3(long x) { return (byte)(x >> 24); }
     private static byte long2(long x) { return (byte)(x >> 16); }
     private static byte long1(long x) { return (byte)(x >>  8); }
-    private static byte long0(long x) { return (byte)(x >>  0); }
+    private static byte long0(long x) { return (byte)(x      ); }
 
     static void putLongL(ByteBuffer bb, int bi, long x) {
         bb._put(bi + 7, long7(x));
@@ -384,7 +378,7 @@
         bb._put(bi + 3, long3(x));
         bb._put(bi + 2, long2(x));
         bb._put(bi + 1, long1(x));
-        bb._put(bi + 0, long0(x));
+        bb._put(bi    , long0(x));
     }
 
     static void putLongL(long a, long x) {
@@ -395,11 +389,11 @@
         _put(a + 3, long3(x));
         _put(a + 2, long2(x));
         _put(a + 1, long1(x));
-        _put(a + 0, long0(x));
+        _put(a    , long0(x));
     }
 
     static void putLongB(ByteBuffer bb, int bi, long x) {
-        bb._put(bi + 0, long7(x));
+        bb._put(bi    , long7(x));
         bb._put(bi + 1, long6(x));
         bb._put(bi + 2, long5(x));
         bb._put(bi + 3, long4(x));
@@ -410,7 +404,7 @@
     }
 
     static void putLongB(long a, long x) {
-        _put(a + 0, long7(x));
+        _put(a    , long7(x));
         _put(a + 1, long6(x));
         _put(a + 2, long5(x));
         _put(a + 3, long4(x));
@@ -454,11 +448,11 @@
     }
 
     static float getFloat(ByteBuffer bb, int bi, boolean bigEndian) {
-        return (bigEndian ? getFloatB(bb, bi) : getFloatL(bb, bi));
+        return bigEndian ? getFloatB(bb, bi) : getFloatL(bb, bi);
     }
 
     static float getFloat(long a, boolean bigEndian) {
-        return (bigEndian ? getFloatB(a) : getFloatL(a));
+        return bigEndian ? getFloatB(a) : getFloatL(a);
     }
 
     static void putFloatL(ByteBuffer bb, int bi, float x) {
@@ -511,11 +505,11 @@
     }
 
     static double getDouble(ByteBuffer bb, int bi, boolean bigEndian) {
-        return (bigEndian ? getDoubleB(bb, bi) : getDoubleL(bb, bi));
+        return bigEndian ? getDoubleB(bb, bi) : getDoubleL(bb, bi);
     }
 
     static double getDouble(long a, boolean bigEndian) {
-        return (bigEndian ? getDoubleB(a) : getDoubleL(a));
+        return bigEndian ? getDoubleB(a) : getDoubleL(a);
     }
 
     static void putDoubleL(ByteBuffer bb, int bi, double x) {
@@ -794,7 +788,7 @@
     static native void copyFromIntArray(Object src, long srcPos, long dstAddr,
                                         long length);
     static native void copyToIntArray(long srcAddr, Object dst, long dstPos,
-                                        long length);
+                                      long length);
 
     static native void copyFromLongArray(Object src, long srcPos, long dstAddr,
                                          long length);
--- a/src/share/classes/java/nio/channels/FileLock.java	Mon Jul 12 19:35:11 2010 -0700
+++ b/src/share/classes/java/nio/channels/FileLock.java	Mon Jul 12 19:42:02 2010 -0700
@@ -116,7 +116,7 @@
  * @since 1.4
  */
 
-public abstract class FileLock {
+public abstract class FileLock implements AutoCloseable {
 
     private final Channel channel;
     private final long position;
@@ -299,6 +299,17 @@
     public abstract void release() throws IOException;
 
     /**
+     * This method invokes the {@link #release} method. It was added
+     * to the class so that it could be used in conjunction with the
+     * automatic resource management block construct.
+     *
+     * @since 1.7
+     */
+    public final void close() throws IOException {
+        release();
+    }
+
+    /**
      * Returns a string describing the range, type, and validity of this lock.
      *
      * @return  A descriptive string
--- a/src/share/classes/java/util/DualPivotQuicksort.java	Mon Jul 12 19:35:11 2010 -0700
+++ b/src/share/classes/java/util/DualPivotQuicksort.java	Mon Jul 12 19:42:02 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,7 @@
 
 /**
  * This class implements the Dual-Pivot Quicksort algorithm by
- * Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. The algorithm
+ * Vladimir Yaroslavskiy, Jon Bentley, and Josh Bloch. The algorithm
  * offers O(n log(n)) performance on many data sets that cause other
  * quicksorts to degrade to quadratic performance, and is typically
  * faster than traditional (one-pivot) Quicksort implementations.
@@ -36,7 +36,8 @@
  * @author Jon Bentley
  * @author Josh Bloch
  *
- * @version 2009.11.29 m765.827.12i
+ * @version 2010.06.21 m765.827.12i:5\7
+ * @since 1.7
  */
 final class DualPivotQuicksort {
 
@@ -68,7 +69,7 @@
     private static final int COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR = 32768;
 
     /*
-     * Sorting methods for 7 primitive types.
+     * Sorting methods for seven primitive types.
      */
 
     /**
@@ -77,7 +78,7 @@
      * @param a the array to be sorted
      */
     public static void sort(int[] a) {
-        doSort(a, 0, a.length - 1);
+        sort(a, 0, a.length - 1, true);
     }
 
     /**
@@ -95,98 +96,132 @@
      */
     public static void sort(int[] a, int fromIndex, int toIndex) {
         rangeCheck(a.length, fromIndex, toIndex);
-        doSort(a, fromIndex, toIndex - 1);
+        sort(a, fromIndex, toIndex - 1, true);
     }
 
     /**
-     * Sorts the specified range of the array into ascending order. This
-     * method differs from the public {@code sort} method in that the
-     * {@code right} index is inclusive, and it does no range checking
-     * on {@code left} or {@code right}.
+     * Sorts the specified range of the array into ascending order by the
+     * Dual-Pivot Quicksort algorithm. This method differs from the public
+     * {@code sort} method in that the {@code right} index is inclusive,
+     * it does no range checking on {@code left} or {@code right}, and has
+     * boolean flag whether insertion sort with sentinel is used or not.
      *
      * @param a the array to be sorted
      * @param left the index of the first element, inclusive, to be sorted
      * @param right the index of the last element, inclusive, to be sorted
+     * @param leftmost indicates if the part is the most left in the range
      */
-    private static void doSort(int[] a, int left, int right) {
+    private static void sort(int[] a, int left, int right, boolean leftmost) {
+        int length = right - left + 1;
+
         // Use insertion sort on tiny arrays
-        if (right - left + 1 < INSERTION_SORT_THRESHOLD) {
-            for (int i = left + 1; i <= right; i++) {
-                int ai = a[i];
-                int j;
-                for (j = i - 1; j >= left && ai < a[j]; j--) {
-                    a[j + 1] = a[j];
+        if (length < INSERTION_SORT_THRESHOLD) {
+            if (!leftmost) {
+                /*
+                 * Every element in adjoining part plays the role
+                 * of sentinel, therefore this allows us to avoid
+                 * the j >= left check on each iteration.
+                 */
+                for (int j, i = left + 1; i <= right; i++) {
+                    int ai = a[i];
+                    for (j = i - 1; ai < a[j]; j--) {
+                        // assert j >= left;
+                        a[j + 1] = a[j];
+                    }
+                    a[j + 1] = ai;
                 }
-                a[j + 1] = ai;
+            } else {
+                /*
+                 * For case of leftmost part traditional (without a sentinel)
+                 * insertion sort, optimized for server JVM, is used.
+                 */
+                for (int i = left, j = i; i < right; j = ++i) {
+                    int ai = a[i + 1];
+                    while (ai < a[j]) {
+                        a[j + 1] = a[j];
+                        if (j-- == left) {
+                            break;
+                        }
+                    }
+                    a[j + 1] = ai;
+                }
             }
-        } else { // Use Dual-Pivot Quicksort on large arrays
-            dualPivotQuicksort(a, left, right);
+            return;
         }
-    }
 
-    /**
-     * Sorts the specified range of the array into ascending order by the
-     * Dual-Pivot Quicksort algorithm.
-     *
-     * @param a the array to be sorted
-     * @param left the index of the first element, inclusive, to be sorted
-     * @param right the index of the last element, inclusive, to be sorted
-     */
-    private static void dualPivotQuicksort(int[] a, int left, int right) {
-        // Compute indices of five evenly spaced elements
-        int sixth = (right - left + 1) / 6;
-        int e1 = left  + sixth;
-        int e5 = right - sixth;
+        // Inexpensive approximation of length / 7
+        int seventh = (length >>> 3) + (length >>> 6) + 1;
+
+        /*
+         * Sort five evenly spaced elements around (and including) the
+         * center element in the range. These elements will be used for
+         * pivot selection as described below. The choice for spacing
+         * these elements was empirically determined to work well on
+         * a wide variety of inputs.
+         */
         int e3 = (left + right) >>> 1; // The midpoint
-        int e4 = e3 + sixth;
-        int e2 = e3 - sixth;
+        int e2 = e3 - seventh;
+        int e1 = e2 - seventh;
+        int e4 = e3 + seventh;
+        int e5 = e4 + seventh;
 
-        // Sort these elements using a 5-element sorting network
-        int ae1 = a[e1], ae2 = a[e2], ae3 = a[e3], ae4 = a[e4], ae5 = a[e5];
+        // Sort these elements using insertion sort
+        if (a[e2] < a[e1]) { int t = a[e2]; a[e2] = a[e1]; a[e1] = t; }
 
-        if (ae1 > ae2) { int t = ae1; ae1 = ae2; ae2 = t; }
-        if (ae4 > ae5) { int t = ae4; ae4 = ae5; ae5 = t; }
-        if (ae1 > ae3) { int t = ae1; ae1 = ae3; ae3 = t; }
-        if (ae2 > ae3) { int t = ae2; ae2 = ae3; ae3 = t; }
-        if (ae1 > ae4) { int t = ae1; ae1 = ae4; ae4 = t; }
-        if (ae3 > ae4) { int t = ae3; ae3 = ae4; ae4 = t; }
-        if (ae2 > ae5) { int t = ae2; ae2 = ae5; ae5 = t; }
-        if (ae2 > ae3) { int t = ae2; ae2 = ae3; ae3 = t; }
-        if (ae4 > ae5) { int t = ae4; ae4 = ae5; ae5 = t; }
-
-        a[e1] = ae1; a[e3] = ae3; a[e5] = ae5;
+        if (a[e3] < a[e2]) { int t = a[e3]; a[e3] = a[e2]; a[e2] = t;
+            if (t < a[e1]) { a[e2] = a[e1]; a[e1] = t; }
+        }
+        if (a[e4] < a[e3]) { int t = a[e4]; a[e4] = a[e3]; a[e3] = t;
+            if (t < a[e2]) { a[e3] = a[e2]; a[e2] = t;
+                if (t < a[e1]) { a[e2] = a[e1]; a[e1] = t; }
+            }
+        }
+        if (a[e5] < a[e4]) { int t = a[e5]; a[e5] = a[e4]; a[e4] = t;
+            if (t < a[e3]) { a[e4] = a[e3]; a[e3] = t;
+                if (t < a[e2]) { a[e3] = a[e2]; a[e2] = t;
+                    if (t < a[e1]) { a[e2] = a[e1]; a[e1] = t; }
+                }
+            }
+        }
 
         /*
          * Use the second and fourth of the five sorted elements as pivots.
          * These values are inexpensive approximations of the first and
          * second terciles of the array. Note that pivot1 <= pivot2.
-         *
-         * The pivots are stored in local variables, and the first and
-         * the last of the elements to be sorted are moved to the locations
-         * formerly occupied by the pivots. When partitioning is complete,
-         * the pivots are swapped back into their final positions, and
-         * excluded from subsequent sorting.
          */
-        int pivot1 = ae2; a[e2] = a[left];
-        int pivot2 = ae4; a[e4] = a[right];
+        int pivot1 = a[e2];
+        int pivot2 = a[e4];
 
         // Pointers
-        int less  = left  + 1; // The index of first element of center part
-        int great = right - 1; // The index before first element of right part
+        int less  = left;  // The index of the first element of center part
+        int great = right; // The index before the first element of right part
 
-        boolean pivotsDiffer = (pivot1 != pivot2);
+        if (pivot1 != pivot2) {
+            /*
+             * The first and the last elements to be sorted are moved to the
+             * locations formerly occupied by the pivots. When partitioning
+             * is complete, the pivots are swapped back into their final
+             * positions, and excluded from subsequent sorting.
+             */
+            a[e2] = a[left];
+            a[e4] = a[right];
 
-        if (pivotsDiffer) {
+            /*
+             * Skip elements, which are less or greater than pivot values.
+             */
+            while (a[++less] < pivot1);
+            while (a[--great] > pivot2);
+
             /*
              * Partitioning:
              *
-             *   left part         center part                    right part
-             * +------------------------------------------------------------+
-             * | < pivot1  |  pivot1 <= && <= pivot2  |    ?    |  > pivot2 |
-             * +------------------------------------------------------------+
-             *              ^                          ^       ^
-             *              |                          |       |
-             *             less                        k     great
+             *   left part           center part                   right part
+             * +--------------------------------------------------------------+
+             * |  < pivot1  |  pivot1 <= && <= pivot2  |    ?    |  > pivot2  |
+             * +--------------------------------------------------------------+
+             *               ^                          ^       ^
+             *               |                          |       |
+             *              less                        k     great
              *
              * Invariants:
              *
@@ -194,16 +229,14 @@
              *    pivot1 <= all in [less, k)     <= pivot2
              *              all in (great, right) > pivot2
              *
-             * Pointer k is the first index of ?-part
+             * Pointer k is the first index of ?-part.
              */
             outer:
             for (int k = less; k <= great; k++) {
                 int ak = a[k];
                 if (ak < pivot1) { // Move a[k] to left part
-                    if (k != less) {
-                        a[k] = a[less];
-                        a[less] = ak;
-                    }
+                    a[k] = a[less];
+                    a[less] = ak;
                     less++;
                 } else if (ak > pivot2) { // Move a[k] to right part
                     while (a[great] > pivot2) {
@@ -213,26 +246,107 @@
                     }
                     if (a[great] < pivot1) {
                         a[k] = a[less];
-                        a[less++] = a[great];
-                        a[great--] = ak;
+                        a[less] = a[great];
+                        less++;
                     } else { // pivot1 <= a[great] <= pivot2
                         a[k] = a[great];
-                        a[great--] = ak;
+                    }
+                    a[great] = ak;
+                    great--;
+                }
+            }
+
+            // Swap pivots into their final positions
+            a[left]  = a[less  - 1]; a[less  - 1] = pivot1;
+            a[right] = a[great + 1]; a[great + 1] = pivot2;
+
+            // Sort left and right parts recursively, excluding known pivots
+            sort(a, left, less - 2, leftmost);
+            sort(a, great + 2, right, false);
+
+            /*
+             * If center part is too large (comprises > 5/7 of the array),
+             * swap internal pivot values to ends.
+             */
+            if (less < e1 && e5 < great) {
+                /*
+                 * Skip elements, which are equal to pivot values.
+                 */
+                while (a[less] == pivot1) {
+                    less++;
+                }
+                while (a[great] == pivot2) {
+                    great--;
+                }
+
+                /*
+                 * Partitioning:
+                 *
+                 *   left part         center part                  right part
+                 * +----------------------------------------------------------+
+                 * | == pivot1 |  pivot1 < && < pivot2  |    ?    | == pivot2 |
+                 * +----------------------------------------------------------+
+                 *              ^                        ^       ^
+                 *              |                        |       |
+                 *             less                      k     great
+                 *
+                 * Invariants:
+                 *
+                 *              all in (*,  less) == pivot1
+                 *     pivot1 < all in [less,  k)  < pivot2
+                 *              all in (great, *) == pivot2
+                 *
+                 * Pointer k is the first index of ?-part.
+                 */
+                outer:
+                for (int k = less; k <= great; k++) {
+                    int ak = a[k];
+                    if (ak == pivot1) { // Move a[k] to left part
+                        a[k] = a[less];
+                        a[less] = ak;
+                        less++;
+                    } else if (ak == pivot2) { // Move a[k] to right part
+                        while (a[great] == pivot2) {
+                            if (great-- == k) {
+                                break outer;
+                            }
+                        }
+                        if (a[great] == pivot1) {
+                            a[k] = a[less];
+                            /*
+                             * Even though a[great] equals to pivot1, the
+                             * assignment a[less] = pivot1 may be incorrect,
+                             * if a[great] and pivot1 are floating-point zeros
+                             * of different signs. Therefore in float and
+                             * double sorting methods we have to use more
+                             * accurate assignment a[less] = a[great].
+                             */
+                            a[less] = pivot1;
+                            less++;
+                        } else { // pivot1 < a[great] < pivot2
+                            a[k] = a[great];
+                        }
+                        a[great] = ak;
+                        great--;
                     }
                 }
             }
+
+            // Sort center part recursively
+            sort(a, less, great, false);
+
         } else { // Pivots are equal
             /*
-             * Partition degenerates to the traditional 3-way,
-             * or "Dutch National Flag", partition:
+             * Partition degenerates to the traditional 3-way
+             * (or "Dutch National Flag") schema:
              *
-             *   left part   center part            right part
-             * +----------------------------------------------+
-             * |  < pivot  |  == pivot  |    ?    |  > pivot  |
-             * +----------------------------------------------+
-             *              ^            ^       ^
-             *              |            |       |
-             *             less          k     great
+             *   left part    center part              right part
+             * +-------------------------------------------------+
+             * |  < pivot  |   == pivot   |     ?    |  > pivot  |
+             * +-------------------------------------------------+
+             *              ^              ^        ^
+             *              |              |        |
+             *             less            k      great
              *
              * Invariants:
              *
@@ -240,20 +354,19 @@
              *   all in [less, k)     == pivot
              *   all in (great, right) > pivot
              *
-             * Pointer k is the first index of ?-part
+             * Pointer k is the first index of ?-part.
              */
-            for (int k = less; k <= great; k++) {
-                int ak = a[k];
-                if (ak == pivot1) {
+            for (int k = left; k <= great; k++) {
+                if (a[k] == pivot1) {
                     continue;
                 }
+                int ak = a[k];
+
                 if (ak < pivot1) { // Move a[k] to left part
-                    if (k != less) {
-                        a[k] = a[less];
-                        a[less] = ak;
-                    }
+                    a[k] = a[less];
+                    a[less] = ak;
                     less++;
-                } else { // (a[k] > pivot1) - Move a[k] to right part
+                } else { // a[k] > pivot1 - Move a[k] to right part
                     /*
                      * We know that pivot1 == a[e3] == pivot2. Thus, we know
                      * that great will still be >= k when the following loop
@@ -261,92 +374,33 @@
                      * In other words, a[e3] acts as a sentinel for great.
                      */
                     while (a[great] > pivot1) {
+                        // assert great > k;
                         great--;
                     }
                     if (a[great] < pivot1) {
                         a[k] = a[less];
-                        a[less++] = a[great];
-                        a[great--] = ak;
+                        a[less] = a[great];
+                        less++;
                     } else { // a[great] == pivot1
+                        /*
+                         * Even though a[great] equals to pivot1, the
+                         * assignment a[k] = pivot1 may be incorrect,
+                         * if a[great] and pivot1 are floating-point
+                         * zeros of different signs. Therefore in float
+                         * and double sorting methods we have to use
+                         * more accurate assignment a[k] = a[great].
+                         */
                         a[k] = pivot1;
-                        a[great--] = ak;
                     }
+                    a[great] = ak;
+                    great--;
                 }
             }
+
+            // Sort left and right parts recursively
+            sort(a, left, less - 1, leftmost);
+            sort(a, great + 1, right, false);
         }
-
-        // Swap pivots into their final positions
-        a[left]  = a[less  - 1]; a[less  - 1] = pivot1;
-        a[right] = a[great + 1]; a[great + 1] = pivot2;
-
-        // Sort left and right parts recursively, excluding known pivot values
-        doSort(a, left,   less - 2);
-        doSort(a, great + 2, right);
-
-        /*
-         * If pivot1 == pivot2, all elements from center
-         * part are equal and, therefore, already sorted
-         */
-        if (!pivotsDiffer) {
-            return;
-        }
-
-        /*
-         * If center part is too large (comprises > 2/3 of the array),
-         * swap internal pivot values to ends
-         */
-        if (less < e1 && great > e5) {
-            while (a[less] == pivot1) {
-                less++;
-            }
-            while (a[great] == pivot2) {
-                great--;
-            }
-
-            /*
-             * Partitioning:
-             *
-             *   left part       center part                   right part
-             * +----------------------------------------------------------+
-             * | == pivot1 |  pivot1 < && < pivot2  |    ?    | == pivot2 |
-             * +----------------------------------------------------------+
-             *              ^                        ^       ^
-             *              |                        |       |
-             *             less                      k     great
-             *
-             * Invariants:
-             *
-             *              all in (*, less)  == pivot1
-             *     pivot1 < all in [less, k)   < pivot2
-             *              all in (great, *) == pivot2
-             *
-             * Pointer k is the first index of ?-part
-             */
-            outer:
-            for (int k = less; k <= great; k++) {
-                int ak = a[k];
-                if (ak == pivot2) { // Move a[k] to right part
-                    while (a[great] == pivot2) {
-                        if (great-- == k) {
-                            break outer;
-                        }
-                    }
-                    if (a[great] == pivot1) {
-                        a[k] = a[less];
-                        a[less++] = pivot1;
-                    } else { // pivot1 < a[great] < pivot2
-                        a[k] = a[great];
-                    }
-                    a[great--] = pivot2;
-                } else if (ak == pivot1) { // Move a[k] to left part
-                    a[k] = a[less];
-                    a[less++] = pivot1;
-                }
-            }
-        }
-
-        // Sort center part recursively, excluding known pivot values
-        doSort(a, less, great);
     }
 
     /**
@@ -355,7 +409,7 @@
      * @param a the array to be sorted
      */
     public static void sort(long[] a) {
-        doSort(a, 0, a.length - 1);
+        sort(a, 0, a.length - 1, true);
     }
 
     /**
@@ -373,98 +427,132 @@
      */
     public static void sort(long[] a, int fromIndex, int toIndex) {
         rangeCheck(a.length, fromIndex, toIndex);
-        doSort(a, fromIndex, toIndex - 1);
+        sort(a, fromIndex, toIndex - 1, true);
     }
 
     /**
-     * Sorts the specified range of the array into ascending order. This
-     * method differs from the public {@code sort} method in that the
-     * {@code right} index is inclusive, and it does no range checking on
-     * {@code left} or {@code right}.
+     * Sorts the specified range of the array into ascending order by the
+     * Dual-Pivot Quicksort algorithm. This method differs from the public
+     * {@code sort} method in that the {@code right} index is inclusive,
+     * it does no range checking on {@code left} or {@code right}, and has
+     * boolean flag whether insertion sort with sentinel is used or not.
      *
      * @param a the array to be sorted
      * @param left the index of the first element, inclusive, to be sorted
      * @param right the index of the last element, inclusive, to be sorted
+     * @param leftmost indicates if the part is the most left in the range
      */
-    private static void doSort(long[] a, int left, int right) {
+    private static void sort(long[] a, int left, int right, boolean leftmost) {
+        int length = right - left + 1;
+
         // Use insertion sort on tiny arrays
-        if (right - left + 1 < INSERTION_SORT_THRESHOLD) {
-            for (int i = left + 1; i <= right; i++) {
-                long ai = a[i];
-                int j;
-                for (j = i - 1; j >= left && ai < a[j]; j--) {
-                    a[j + 1] = a[j];
+        if (length < INSERTION_SORT_THRESHOLD) {
+            if (!leftmost) {
+                /*
+                 * Every element in adjoining part plays the role
+                 * of sentinel, therefore this allows us to avoid
+                 * the j >= left check on each iteration.
+                 */
+                for (int j, i = left + 1; i <= right; i++) {
+                    long ai = a[i];
+                    for (j = i - 1; ai < a[j]; j--) {
+                        // assert j >= left;
+                        a[j + 1] = a[j];
+                    }
+                    a[j + 1] = ai;
                 }
-                a[j + 1] = ai;
+            } else {
+                /*
+                 * For case of leftmost part traditional (without a sentinel)
+                 * insertion sort, optimized for server JVM, is used.
+                 */
+                for (int i = left, j = i; i < right; j = ++i) {
+                    long ai = a[i + 1];
+                    while (ai < a[j]) {
+                        a[j + 1] = a[j];
+                        if (j-- == left) {
+                            break;
+                        }
+                    }
+                    a[j + 1] = ai;
+                }
             }
-        } else { // Use Dual-Pivot Quicksort on large arrays
-            dualPivotQuicksort(a, left, right);
+            return;
         }
-    }
 
-    /**
-     * Sorts the specified range of the array into ascending order by the
-     * Dual-Pivot Quicksort algorithm.
-     *
-     * @param a the array to be sorted
-     * @param left the index of the first element, inclusive, to be sorted
-     * @param right the index of the last element, inclusive, to be sorted
-     */
-    private static void dualPivotQuicksort(long[] a, int left, int right) {
-        // Compute indices of five evenly spaced elements
-        int sixth = (right - left + 1) / 6;
-        int e1 = left  + sixth;
-        int e5 = right - sixth;
+        // Inexpensive approximation of length / 7
+        int seventh = (length >>> 3) + (length >>> 6) + 1;
+
+        /*
+         * Sort five evenly spaced elements around (and including) the
+         * center element in the range. These elements will be used for
+         * pivot selection as described below. The choice for spacing
+         * these elements was empirically determined to work well on
+         * a wide variety of inputs.
+         */
         int e3 = (left + right) >>> 1; // The midpoint
-        int e4 = e3 + sixth;
-        int e2 = e3 - sixth;
+        int e2 = e3 - seventh;
+        int e1 = e2 - seventh;
+        int e4 = e3 + seventh;
+        int e5 = e4 + seventh;
 
-        // Sort these elements using a 5-element sorting network
-        long ae1 = a[e1], ae2 = a[e2], ae3 = a[e3], ae4 = a[e4], ae5 = a[e5];
+        // Sort these elements using insertion sort
+        if (a[e2] < a[e1]) { long t = a[e2]; a[e2] = a[e1]; a[e1] = t; }
 
-        if (ae1 > ae2) { long t = ae1; ae1 = ae2; ae2 = t; }
-        if (ae4 > ae5) { long t = ae4; ae4 = ae5; ae5 = t; }
-        if (ae1 > ae3) { long t = ae1; ae1 = ae3; ae3 = t; }
-        if (ae2 > ae3) { long t = ae2; ae2 = ae3; ae3 = t; }
-        if (ae1 > ae4) { long t = ae1; ae1 = ae4; ae4 = t; }
-        if (ae3 > ae4) { long t = ae3; ae3 = ae4; ae4 = t; }
-        if (ae2 > ae5) { long t = ae2; ae2 = ae5; ae5 = t; }
-        if (ae2 > ae3) { long t = ae2; ae2 = ae3; ae3 = t; }
-        if (ae4 > ae5) { long t = ae4; ae4 = ae5; ae5 = t; }
-
-        a[e1] = ae1; a[e3] = ae3; a[e5] = ae5;
+        if (a[e3] < a[e2]) { long t = a[e3]; a[e3] = a[e2]; a[e2] = t;
+            if (t < a[e1]) { a[e2] = a[e1]; a[e1] = t; }
+        }
+        if (a[e4] < a[e3]) { long t = a[e4]; a[e4] = a[e3]; a[e3] = t;
+            if (t < a[e2]) { a[e3] = a[e2]; a[e2] = t;
+                if (t < a[e1]) { a[e2] = a[e1]; a[e1] = t; }
+            }
+        }
+        if (a[e5] < a[e4]) { long t = a[e5]; a[e5] = a[e4]; a[e4] = t;
+            if (t < a[e3]) { a[e4] = a[e3]; a[e3] = t;
+                if (t < a[e2]) { a[e3] = a[e2]; a[e2] = t;
+                    if (t < a[e1]) { a[e2] = a[e1]; a[e1] = t; }
+                }
+            }
+        }
 
         /*
          * Use the second and fourth of the five sorted elements as pivots.
          * These values are inexpensive approximations of the first and
          * second terciles of the array. Note that pivot1 <= pivot2.
-         *
-         * The pivots are stored in local variables, and the first and
-         * the last of the elements to be sorted are moved to the locations
-         * formerly occupied by the pivots. When partitioning is complete,
-         * the pivots are swapped back into their final positions, and
-         * excluded from subsequent sorting.
          */
-        long pivot1 = ae2; a[e2] = a[left];
-        long pivot2 = ae4; a[e4] = a[right];
+        long pivot1 = a[e2];
+        long pivot2 = a[e4];
 
         // Pointers
-        int less  = left  + 1; // The index of first element of center part
-        int great = right - 1; // The index before first element of right part
+        int less  = left;  // The index of the first element of center part
+        int great = right; // The index before the first element of right part
 
-        boolean pivotsDiffer = (pivot1 != pivot2);
+        if (pivot1 != pivot2) {
+            /*
+             * The first and the last elements to be sorted are moved to the
+             * locations formerly occupied by the pivots. When partitioning
+             * is complete, the pivots are swapped back into their final
+             * positions, and excluded from subsequent sorting.
+             */
+            a[e2] = a[left];
+            a[e4] = a[right];
 
-        if (pivotsDiffer) {
+            /*
+             * Skip elements, which are less or greater than pivot values.
+             */
+            while (a[++less] < pivot1);
+            while (a[--great] > pivot2);
+
             /*
              * Partitioning:
              *
-             *   left part         center part                    right part
-             * +------------------------------------------------------------+
-             * | < pivot1  |  pivot1 <= && <= pivot2  |    ?    |  > pivot2 |
-             * +------------------------------------------------------------+
-             *              ^                          ^       ^
-             *              |                          |       |
-             *             less                        k     great
+             *   left part           center part                   right part
+             * +--------------------------------------------------------------+
+             * |  < pivot1  |  pivot1 <= && <= pivot2  |    ?    |  > pivot2  |
+             * +--------------------------------------------------------------+
+             *               ^                          ^       ^
+             *               |                          |       |
+             *              less                        k     great
              *
              * Invariants:
              *
@@ -472,16 +560,14 @@
              *    pivot1 <= all in [less, k)     <= pivot2
              *              all in (great, right) > pivot2
              *
-             * Pointer k is the first index of ?-part
+             * Pointer k is the first index of ?-part.
              */
             outer:
             for (int k = less; k <= great; k++) {
                 long ak = a[k];
                 if (ak < pivot1) { // Move a[k] to left part
-                    if (k != less) {
-                        a[k] = a[less];
-                        a[less] = ak;
-                    }
+                    a[k] = a[less];
+                    a[less] = ak;
                     less++;
                 } else if (ak > pivot2) { // Move a[k] to right part
                     while (a[great] > pivot2) {
@@ -491,26 +577,107 @@
                     }
                     if (a[great] < pivot1) {
                         a[k] = a[less];
-                        a[less++] = a[great];
-                        a[great--] = ak;
+                        a[less] = a[great];
+                        less++;
                     } else { // pivot1 <= a[great] <= pivot2
                         a[k] = a[great];
-                        a[great--] = ak;
+                    }
+                    a[great] = ak;
+                    great--;
+                }
+            }
+
+            // Swap pivots into their final positions
+            a[left]  = a[less  - 1]; a[less  - 1] = pivot1;
+            a[right] = a[great + 1]; a[great + 1] = pivot2;
+
+            // Sort left and right parts recursively, excluding known pivots
+            sort(a, left, less - 2, leftmost);
+            sort(a, great + 2, right, false);
+
+            /*
+             * If center part is too large (comprises > 5/7 of the array),
+             * swap internal pivot values to ends.
+             */
+            if (less < e1 && e5 < great) {
+                /*
+                 * Skip elements, which are equal to pivot values.
+                 */
+                while (a[less] == pivot1) {
+                    less++;
+                }
+                while (a[great] == pivot2) {
+                    great--;
+                }
+
+                /*
+                 * Partitioning:
+                 *
+                 *   left part         center part                  right part
+                 * +----------------------------------------------------------+
+                 * | == pivot1 |  pivot1 < && < pivot2  |    ?    | == pivot2 |
+                 * +----------------------------------------------------------+
+                 *              ^                        ^       ^
+                 *              |                        |       |
+                 *             less                      k     great
+                 *
+                 * Invariants:
+                 *
+                 *              all in (*,  less) == pivot1
+                 *     pivot1 < all in [less,  k)  < pivot2
+                 *              all in (great, *) == pivot2
+                 *
+                 * Pointer k is the first index of ?-part.
+                 */
+                outer:
+                for (int k = less; k <= great; k++) {
+                    long ak = a[k];
+                    if (ak == pivot1) { // Move a[k] to left part
+                        a[k] = a[less];
+                        a[less] = ak;
+                        less++;
+                    } else if (ak == pivot2) { // Move a[k] to right part
+                        while (a[great] == pivot2) {
+                            if (great-- == k) {
+                                break outer;
+                            }
+                        }
+                        if (a[great] == pivot1) {
+                            a[k] = a[less];
+                            /*
+                             * Even though a[great] equals to pivot1, the
+                             * assignment a[less] = pivot1 may be incorrect,
+                             * if a[great] and pivot1 are floating-point zeros
+                             * of different signs. Therefore in float and
+                             * double sorting methods we have to use more
+                             * accurate assignment a[less] = a[great].
+                             */
+                            a[less] = pivot1;
+                            less++;
+                        } else { // pivot1 < a[great] < pivot2
+                            a[k] = a[great];
+                        }
+                        a[great] = ak;
+                        great--;
                     }
                 }
             }
+
+            // Sort center part recursively
+            sort(a, less, great, false);
+
         } else { // Pivots are equal
             /*
-             * Partition degenerates to the traditional 3-way,
-             * or "Dutch National Flag", partition:
+             * Partition degenerates to the traditional 3-way
+             * (or "Dutch National Flag") schema:
              *
-             *   left part   center part            right part
-             * +----------------------------------------------+
-             * |  < pivot  |  == pivot  |    ?    |  > pivot  |
-             * +----------------------------------------------+
-             *              ^            ^       ^
-             *              |            |       |
-             *             less          k     great
+             *   left part    center part              right part
+             * +-------------------------------------------------+
+             * |  < pivot  |   == pivot   |     ?    |  > pivot  |
+             * +-------------------------------------------------+
+             *              ^              ^        ^
+             *              |              |        |
+             *             less            k      great
              *
              * Invariants:
              *
@@ -518,20 +685,19 @@
              *   all in [less, k)     == pivot
              *   all in (great, right) > pivot
              *
-             * Pointer k is the first index of ?-part
+             * Pointer k is the first index of ?-part.
              */
-            for (int k = less; k <= great; k++) {
-                long ak = a[k];
-                if (ak == pivot1) {
+            for (int k = left; k <= great; k++) {
+                if (a[k] == pivot1) {
                     continue;
                 }
+                long ak = a[k];
+
                 if (ak < pivot1) { // Move a[k] to left part
-                    if (k != less) {
-                        a[k] = a[less];
-                        a[less] = ak;
-                    }
+                    a[k] = a[less];
+                    a[less] = ak;
                     less++;
-                } else { // (a[k] > pivot1) - Move a[k] to right part
+                } else { // a[k] > pivot1 - Move a[k] to right part
                     /*
                      * We know that pivot1 == a[e3] == pivot2. Thus, we know
                      * that great will still be >= k when the following loop
@@ -539,92 +705,33 @@
                      * In other words, a[e3] acts as a sentinel for great.
                      */
                     while (a[great] > pivot1) {
+                        // assert great > k;
                         great--;
                     }
                     if (a[great] < pivot1) {
                         a[k] = a[less];
-                        a[less++] = a[great];
-                        a[great--] = ak;
+                        a[less] = a[great];
+                        less++;
                     } else { // a[great] == pivot1
+                        /*
+                         * Even though a[great] equals to pivot1, the
+                         * assignment a[k] = pivot1 may be incorrect,
+                         * if a[great] and pivot1 are floating-point
+                         * zeros of different signs. Therefore in float
+                         * and double sorting methods we have to use
+                         * more accurate assignment a[k] = a[great].
+                         */
                         a[k] = pivot1;
-                        a[great--] = ak;
                     }
+                    a[great] = ak;
+                    great--;
                 }
             }
+
+            // Sort left and right parts recursively
+            sort(a, left, less - 1, leftmost);
+            sort(a, great + 1, right, false);
         }
-
-        // Swap pivots into their final positions
-        a[left]  = a[less  - 1]; a[less  - 1] = pivot1;
-        a[right] = a[great + 1]; a[great + 1] = pivot2;
-
-        // Sort left and right parts recursively, excluding known pivot values
-        doSort(a, left,   less - 2);
-        doSort(a, great + 2, right);
-
-        /*
-         * If pivot1 == pivot2, all elements from center
-         * part are equal and, therefore, already sorted
-         */
-        if (!pivotsDiffer) {
-            return;
-        }
-
-        /*
-         * If center part is too large (comprises > 2/3 of the array),
-         * swap internal pivot values to ends
-         */
-        if (less < e1 && great > e5) {
-            while (a[less] == pivot1) {
-                less++;
-            }
-            while (a[great] == pivot2) {
-                great--;
-            }
-
-            /*
-             * Partitioning:
-             *
-             *   left part       center part                   right part
-             * +----------------------------------------------------------+
-             * | == pivot1 |  pivot1 < && < pivot2  |    ?    | == pivot2 |
-             * +----------------------------------------------------------+
-             *              ^                        ^       ^
-             *              |                        |       |
-             *             less                      k     great
-             *
-             * Invariants:
-             *
-             *              all in (*, less)  == pivot1
-             *     pivot1 < all in [less, k)   < pivot2
-             *              all in (great, *) == pivot2
-             *
-             * Pointer k is the first index of ?-part
-             */
-            outer:
-            for (int k = less; k <= great; k++) {
-                long ak = a[k];
-                if (ak == pivot2) { // Move a[k] to right part
-                    while (a[great] == pivot2) {
-                        if (great-- == k) {
-                            break outer;
-                        }
-                    }
-                    if (a[great] == pivot1) {
-                        a[k] = a[less];
-                        a[less++] = pivot1;
-                    } else { // pivot1 < a[great] < pivot2
-                        a[k] = a[great];
-                    }
-                    a[great--] = pivot2;
-                } else if (ak == pivot1) { // Move a[k] to left part
-                    a[k] = a[less];
-                    a[less++] = pivot1;
-                }
-            }
-        }
-
-        // Sort center part recursively, excluding known pivot values
-        doSort(a, less, great);
     }
 
     /**
@@ -633,7 +740,11 @@
      * @param a the array to be sorted
      */
     public static void sort(short[] a) {
-        doSort(a, 0, a.length - 1);
+        if (a.length > COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) {
+            countingSort(a, 0, a.length - 1);
+        } else {
+            sort(a, 0, a.length - 1, true);
+        }
     }
 
     /**
@@ -651,115 +762,166 @@
      */
     public static void sort(short[] a, int fromIndex, int toIndex) {
         rangeCheck(a.length, fromIndex, toIndex);
-        doSort(a, fromIndex, toIndex - 1);
+
+        if (toIndex - fromIndex > COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) {
+            countingSort(a, fromIndex, toIndex - 1);
+        } else {
+            sort(a, fromIndex, toIndex - 1, true);
+        }
     }
 
     /** The number of distinct short values. */
     private static final int NUM_SHORT_VALUES = 1 << 16;
 
     /**
-     * Sorts the specified range of the array into ascending order. This
-     * method differs from the public {@code sort} method in that the
-     * {@code right} index is inclusive, and it does no range checking on
-     * {@code left} or {@code right}.
+     * Sorts the specified range of the array by counting sort.
      *
      * @param a the array to be sorted
      * @param left the index of the first element, inclusive, to be sorted
      * @param right the index of the last element, inclusive, to be sorted
      */
-    private static void doSort(short[] a, int left, int right) {
-        // Use insertion sort on tiny arrays
-        if (right - left + 1 < INSERTION_SORT_THRESHOLD) {
-            for (int i = left + 1; i <= right; i++) {
-                short ai = a[i];
-                int j;
-                for (j = i - 1; j >= left && ai < a[j]; j--) {
-                    a[j + 1] = a[j];
-                }
-                a[j + 1] = ai;
+    private static void countingSort(short[] a, int left, int right) {
+        int[] count = new int[NUM_SHORT_VALUES];
+
+        for (int i = left; i <= right; i++) {
+            count[a[i] - Short.MIN_VALUE]++;
+        }
+        for (int i = NUM_SHORT_VALUES - 1, k = right; k >= left; i--) {
+            while (count[i] == 0) {
+                i--;
             }
-        } else if (right-left+1 > COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) {
-            // Use counting sort on huge arrays
-            int[] count = new int[NUM_SHORT_VALUES];
+            short value = (short) (i + Short.MIN_VALUE);
+            int s = count[i];
 
-            for (int i = left; i <= right; i++) {
-                count[a[i] - Short.MIN_VALUE]++;
-            }
-            for (int i = 0, k = left; i < count.length && k <= right; i++) {
-                short value = (short) (i + Short.MIN_VALUE);
-
-                for (int s = count[i]; s > 0; s--) {
-                    a[k++] = value;
-               }
-            }
-        } else { // Use Dual-Pivot Quicksort on large arrays
-            dualPivotQuicksort(a, left, right);
+            do {
+                a[k--] = value;
+            } while (--s > 0);
         }
     }
 
     /**
      * Sorts the specified range of the array into ascending order by the
-     * Dual-Pivot Quicksort algorithm.
+     * Dual-Pivot Quicksort algorithm. This method differs from the public
+     * {@code sort} method in that the {@code right} index is inclusive,
+     * it does no range checking on {@code left} or {@code right}, and has
+     * boolean flag whether insertion sort with sentinel is used or not.
      *
      * @param a the array to be sorted
      * @param left the index of the first element, inclusive, to be sorted
      * @param right the index of the last element, inclusive, to be sorted
+     * @param leftmost indicates if the part is the most left in the range
      */
-    private static void dualPivotQuicksort(short[] a, int left, int right) {
-        // Compute indices of five evenly spaced elements
-        int sixth = (right - left + 1) / 6;
-        int e1 = left  + sixth;
-        int e5 = right - sixth;
+    private static void sort(short[] a, int left, int right,boolean leftmost) {
+        int length = right - left + 1;
+
+        // Use insertion sort on tiny arrays
+        if (length < INSERTION_SORT_THRESHOLD) {
+            if (!leftmost) {
+                /*
+                 * Every element in adjoining part plays the role
+                 * of sentinel, therefore this allows us to avoid
+                 * the j >= left check on each iteration.
+                 */
+                for (int j, i = left + 1; i <= right; i++) {
+                    short ai = a[i];
+                    for (j = i - 1; ai < a[j]; j--) {
+                        // assert j >= left;
+                        a[j + 1] = a[j];
+                    }
+                    a[j + 1] = ai;
+                }
+            } else {
+                /*
+                 * For case of leftmost part traditional (without a sentinel)
+                 * insertion sort, optimized for server JVM, is used.
+                 */
+                for (int i = left, j = i; i < right; j = ++i) {
+                    short ai = a[i + 1];
+                    while (ai < a[j]) {
+                        a[j + 1] = a[j];
+                        if (j-- == left) {
+                            break;
+                        }
+                    }
+                    a[j + 1] = ai;
+                }
+            }
+            return;
+        }
+
+        // Inexpensive approximation of length / 7
+        int seventh = (length >>> 3) + (length >>> 6) + 1;
+
+        /*
+         * Sort five evenly spaced elements around (and including) the
+         * center element in the range. These elements will be used for
+         * pivot selection as described below. The choice for spacing
+         * these elements was empirically determined to work well on
+         * a wide variety of inputs.
+         */
         int e3 = (left + right) >>> 1; // The midpoint
-        int e4 = e3 + sixth;
-        int e2 = e3 - sixth;
+        int e2 = e3 - seventh;
+        int e1 = e2 - seventh;
+        int e4 = e3 + seventh;
+        int e5 = e4 + seventh;
 
-        // Sort these elements using a 5-element sorting network
-        short ae1 = a[e1], ae2 = a[e2], ae3 = a[e3], ae4 = a[e4], ae5 = a[e5];
+        // Sort these elements using insertion sort
+        if (a[e2] < a[e1]) { short t = a[e2]; a[e2] = a[e1]; a[e1] = t; }
 
-        if (ae1 > ae2) { short t = ae1; ae1 = ae2; ae2 = t; }
-        if (ae4 > ae5) { short t = ae4; ae4 = ae5; ae5 = t; }
-        if (ae1 > ae3) { short t = ae1; ae1 = ae3; ae3 = t; }
-        if (ae2 > ae3) { short t = ae2; ae2 = ae3; ae3 = t; }
-        if (ae1 > ae4) { short t = ae1; ae1 = ae4; ae4 = t; }
-        if (ae3 > ae4) { short t = ae3; ae3 = ae4; ae4 = t; }
-        if (ae2 > ae5) { short t = ae2; ae2 = ae5; ae5 = t; }
-        if (ae2 > ae3) { short t = ae2; ae2 = ae3; ae3 = t; }
-        if (ae4 > ae5) { short t = ae4; ae4 = ae5; ae5 = t; }
-
-        a[e1] = ae1; a[e3] = ae3; a[e5] = ae5;
+        if (a[e3] < a[e2]) { short t = a[e3]; a[e3] = a[e2]; a[e2] = t;
+            if (t < a[e1]) { a[e2] = a[e1]; a[e1] = t; }
+        }
+        if (a[e4] < a[e3]) { short t = a[e4]; a[e4] = a[e3]; a[e3] = t;
+            if (t < a[e2]) { a[e3] = a[e2]; a[e2] = t;
+                if (t < a[e1]) { a[e2] = a[e1]; a[e1] = t; }
+            }
+        }
+        if (a[e5] < a[e4]) { short t = a[e5]; a[e5] = a[e4]; a[e4] = t;
+            if (t < a[e3]) { a[e4] = a[e3]; a[e3] = t;
+                if (t < a[e2]) { a[e3] = a[e2]; a[e2] = t;
+                    if (t < a[e1]) { a[e2] = a[e1]; a[e1] = t; }
+                }
+            }
+        }
 
         /*
          * Use the second and fourth of the five sorted elements as pivots.
          * These values are inexpensive approximations of the first and
          * second terciles of the array. Note that pivot1 <= pivot2.
-         *
-         * The pivots are stored in local variables, and the first and
-         * the last of the elements to be sorted are moved to the locations
-         * formerly occupied by the pivots. When partitioning is complete,
-         * the pivots are swapped back into their final positions, and
-         * excluded from subsequent sorting.
          */
-        short pivot1 = ae2; a[e2] = a[left];
-        short pivot2 = ae4; a[e4] = a[right];
+        short pivot1 = a[e2];
+        short pivot2 = a[e4];
 
         // Pointers
-        int less  = left  + 1; // The index of first element of center part
-        int great = right - 1; // The index before first element of right part
+        int less  = left;  // The index of the first element of center part
+        int great = right; // The index before the first element of right part
 
-        boolean pivotsDiffer = (pivot1 != pivot2);
+        if (pivot1 != pivot2) {
+            /*
+             * The first and the last elements to be sorted are moved to the
+             * locations formerly occupied by the pivots. When partitioning
+             * is complete, the pivots are swapped back into their final
+             * positions, and excluded from subsequent sorting.
+             */
+            a[e2] = a[left];
+            a[e4] = a[right];
 
-        if (pivotsDiffer) {
+            /*
+             * Skip elements, which are less or greater than pivot values.
+             */
+            while (a[++less] < pivot1);
+            while (a[--great] > pivot2);
+
             /*
              * Partitioning:
              *
-             *   left part         center part                    right part
-             * +------------------------------------------------------------+
-             * | < pivot1  |  pivot1 <= && <= pivot2  |    ?    |  > pivot2 |
-             * +------------------------------------------------------------+
-             *              ^                          ^       ^
-             *              |                          |       |
-             *             less                        k     great
+             *   left part           center part                   right part
+             * +--------------------------------------------------------------+
+             * |  < pivot1  |  pivot1 <= && <= pivot2  |    ?    |  > pivot2  |
+             * +--------------------------------------------------------------+
+             *               ^                          ^       ^
+             *               |                          |       |
+             *              less                        k     great
              *
              * Invariants:
              *
@@ -767,16 +929,14 @@
              *    pivot1 <= all in [less, k)     <= pivot2
              *              all in (great, right) > pivot2
              *
-             * Pointer k is the first index of ?-part
+             * Pointer k is the first index of ?-part.
              */
             outer:
             for (int k = less; k <= great; k++) {
                 short ak = a[k];
                 if (ak < pivot1) { // Move a[k] to left part
-                    if (k != less) {
-                        a[k] = a[less];
-                        a[less] = ak;
-                    }
+                    a[k] = a[less];
+                    a[less] = ak;
                     less++;
                 } else if (ak > pivot2) { // Move a[k] to right part
                     while (a[great] > pivot2) {
@@ -786,26 +946,107 @@
                     }
                     if (a[great] < pivot1) {
                         a[k] = a[less];
-                        a[less++] = a[great];
-                        a[great--] = ak;
+                        a[less] = a[great];
+                        less++;
                     } else { // pivot1 <= a[great] <= pivot2
                         a[k] = a[great];
-                        a[great--] = ak;
+                    }
+                    a[great] = ak;
+                    great--;
+                }
+            }
+
+            // Swap pivots into their final positions
+            a[left]  = a[less  - 1]; a[less  - 1] = pivot1;
+            a[right] = a[great + 1]; a[great + 1] = pivot2;
+
+            // Sort left and right parts recursively, excluding known pivots
+            sort(a, left, less - 2, leftmost);
+            sort(a, great + 2, right, false);
+
+            /*
+             * If center part is too large (comprises > 5/7 of the array),
+             * swap internal pivot values to ends.
+             */
+            if (less < e1 && e5 < great) {
+                /*
+                 * Skip elements, which are equal to pivot values.
+                 */
+                while (a[less] == pivot1) {
+                    less++;
+                }
+                while (a[great] == pivot2) {
+                    great--;
+                }
+
+                /*
+                 * Partitioning:
+                 *
+                 *   left part         center part                  right part
+                 * +----------------------------------------------------------+
+                 * | == pivot1 |  pivot1 < && < pivot2  |    ?    | == pivot2 |
+                 * +----------------------------------------------------------+
+                 *              ^                        ^       ^
+                 *              |                        |       |
+                 *             less                      k     great
+                 *
+                 * Invariants:
+                 *
+                 *              all in (*,  less) == pivot1
+                 *     pivot1 < all in [less,  k)  < pivot2
+                 *              all in (great, *) == pivot2
+                 *
+                 * Pointer k is the first index of ?-part.
+                 */
+                outer:
+                for (int k = less; k <= great; k++) {
+                    short ak = a[k];
+                    if (ak == pivot1) { // Move a[k] to left part
+                        a[k] = a[less];
+                        a[less] = ak;
+                        less++;
+                    } else if (ak == pivot2) { // Move a[k] to right part
+                        while (a[great] == pivot2) {
+                            if (great-- == k) {
+                                break outer;
+                            }
+                        }
+                        if (a[great] == pivot1) {
+                            a[k] = a[less];
+                            /*
+                             * Even though a[great] equals to pivot1, the
+                             * assignment a[less] = pivot1 may be incorrect,
+                             * if a[great] and pivot1 are floating-point zeros
+                             * of different signs. Therefore in float and
+                             * double sorting methods we have to use more
+                             * accurate assignment a[less] = a[great].
+                             */
+                            a[less] = pivot1;
+                            less++;
+                        } else { // pivot1 < a[great] < pivot2
+                            a[k] = a[great];
+                        }
+                        a[great] = ak;
+                        great--;
                     }
                 }
             }
+
+            // Sort center part recursively
+            sort(a, less, great, false);
+
         } else { // Pivots are equal
             /*
-             * Partition degenerates to the traditional 3-way,
-             * or "Dutch National Flag", partition:
+             * Partition degenerates to the traditional 3-way
+             * (or "Dutch National Flag") schema:
              *
-             *   left part   center part            right part
-             * +----------------------------------------------+
-             * |  < pivot  |  == pivot  |    ?    |  > pivot  |
-             * +----------------------------------------------+
-             *              ^            ^       ^
-             *              |            |       |
-             *             less          k     great
+             *   left part    center part              right part
+             * +-------------------------------------------------+
+             * |  < pivot  |   == pivot   |     ?    |  > pivot  |
+             * +-------------------------------------------------+
+             *              ^              ^        ^
+             *              |              |        |
+             *             less            k      great
              *
              * Invariants:
              *
@@ -813,20 +1054,19 @@
              *   all in [less, k)     == pivot
              *   all in (great, right) > pivot
              *
-             * Pointer k is the first index of ?-part
+             * Pointer k is the first index of ?-part.
              */
-            for (int k = less; k <= great; k++) {
-                short ak = a[k];
-                if (ak == pivot1) {
+            for (int k = left; k <= great; k++) {
+                if (a[k] == pivot1) {
                     continue;
                 }
+                short ak = a[k];
+
                 if (ak < pivot1) { // Move a[k] to left part
-                    if (k != less) {
-                        a[k] = a[less];
-                        a[less] = ak;
-                    }
+                    a[k] = a[less];
+                    a[less] = ak;
                     less++;
-                } else { // (a[k] > pivot1) - Move a[k] to right part
+                } else { // a[k] > pivot1 - Move a[k] to right part
                     /*
                      * We know that pivot1 == a[e3] == pivot2. Thus, we know
                      * that great will still be >= k when the following loop
@@ -834,92 +1074,33 @@
                      * In other words, a[e3] acts as a sentinel for great.
                      */
                     while (a[great] > pivot1) {
+                        // assert great > k;
                         great--;
                     }
                     if (a[great] < pivot1) {
                         a[k] = a[less];
-                        a[less++] = a[great];
-                        a[great--] = ak;
+                        a[less] = a[great];
+                        less++;
                     } else { // a[great] == pivot1
+                        /*
+                         * Even though a[great] equals to pivot1, the
+                         * assignment a[k] = pivot1 may be incorrect,
+                         * if a[great] and pivot1 are floating-point
+                         * zeros of different signs. Therefore in float
+                         * and double sorting methods we have to use
+                         * more accurate assignment a[k] = a[great].
+                         */
                         a[k] = pivot1;
-                        a[great--] = ak;
                     }
+                    a[great] = ak;
+                    great--;
                 }
             }
+
+            // Sort left and right parts recursively
+            sort(a, left, less - 1, leftmost);
+            sort(a, great + 1, right, false);
         }
-
-        // Swap pivots into their final positions
-        a[left]  = a[less  - 1]; a[less  - 1] = pivot1;
-        a[right] = a[great + 1]; a[great + 1] = pivot2;
-
-        // Sort left and right parts recursively, excluding known pivot values
-        doSort(a, left,   less - 2);
-        doSort(a, great + 2, right);
-
-        /*
-         * If pivot1 == pivot2, all elements from center
-         * part are equal and, therefore, already sorted
-         */
-        if (!pivotsDiffer) {
-            return;
-        }
-
-        /*
-         * If center part is too large (comprises > 2/3 of the array),
-         * swap internal pivot values to ends
-         */
-        if (less < e1 && great > e5) {
-            while (a[less] == pivot1) {
-                less++;
-            }
-            while (a[great] == pivot2) {
-                great--;
-            }
-
-            /*
-             * Partitioning:
-             *
-             *   left part       center part                   right part
-             * +----------------------------------------------------------+
-             * | == pivot1 |  pivot1 < && < pivot2  |    ?    | == pivot2 |
-             * +----------------------------------------------------------+
-             *              ^                        ^       ^
-             *              |                        |       |
-             *             less                      k     great
-             *
-             * Invariants:
-             *
-             *              all in (*, less)  == pivot1
-             *     pivot1 < all in [less, k)   < pivot2
-             *              all in (great, *) == pivot2
-             *
-             * Pointer k is the first index of ?-part
-             */
-            outer:
-            for (int k = less; k <= great; k++) {
-                short ak = a[k];
-                if (ak == pivot2) { // Move a[k] to right part
-                    while (a[great] == pivot2) {
-                        if (great-- == k) {
-                            break outer;
-                        }
-                    }
-                    if (a[great] == pivot1) {
-                        a[k] = a[less];
-                        a[less++] = pivot1;
-                    } else { // pivot1 < a[great] < pivot2
-                        a[k] = a[great];
-                    }
-                    a[great--] = pivot2;
-                } else if (ak == pivot1) { // Move a[k] to left part
-                    a[k] = a[less];
-                    a[less++] = pivot1;
-                }
-            }
-        }
-
-        // Sort center part recursively, excluding known pivot values
-        doSort(a, less, great);
     }
 
     /**
@@ -928,7 +1109,11 @@
      * @param a the array to be sorted
      */
     public static void sort(char[] a) {
-        doSort(a, 0, a.length - 1);
+        if (a.length > COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) {
+            countingSort(a, 0, a.length - 1);
+        } else {
+            sort(a, 0, a.length - 1, true);
+        }
     }
 
     /**
@@ -946,113 +1131,166 @@
      */
     public static void sort(char[] a, int fromIndex, int toIndex) {
         rangeCheck(a.length, fromIndex, toIndex);
-        doSort(a, fromIndex, toIndex - 1);
+
+        if (toIndex - fromIndex > COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) {
+            countingSort(a, fromIndex, toIndex - 1);
+        } else {
+            sort(a, fromIndex, toIndex - 1, true);
+        }
     }
 
     /** The number of distinct char values. */
     private static final int NUM_CHAR_VALUES = 1 << 16;
 
     /**
-     * Sorts the specified range of the array into ascending order. This
-     * method differs from the public {@code sort} method in that the
-     * {@code right} index is inclusive, and it does no range checking on
-     * {@code left} or {@code right}.
+     * Sorts the specified range of the array by counting sort.
      *
      * @param a the array to be sorted
      * @param left the index of the first element, inclusive, to be sorted
      * @param right the index of the last element, inclusive, to be sorted
      */
-    private static void doSort(char[] a, int left, int right) {
-        // Use insertion sort on tiny arrays
-        if (right - left + 1 < INSERTION_SORT_THRESHOLD) {
-            for (int i = left + 1; i <= right; i++) {
-                char ai = a[i];
-                int j;
-                for (j = i - 1; j >= left && ai < a[j]; j--) {
-                    a[j + 1] = a[j];
-                }
-                a[j + 1] = ai;
+    private static void countingSort(char[] a, int left, int right) {
+        int[] count = new int[NUM_CHAR_VALUES];
+
+        for (int i = left; i <= right; i++) {
+            count[a[i]]++;
+        }
+        for (int i = 0, k = left; k <= right; i++) {
+            while (count[i] == 0) {
+                i++;
             }
-        } else if (right-left+1 > COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) {
-            // Use counting sort on huge arrays
-            int[] count = new int[NUM_CHAR_VALUES];
+            char value = (char) i;
+            int s = count[i];
 
-            for (int i = left; i <= right; i++) {
-                count[a[i]]++;
-            }
-            for (int i = 0, k = left; i < count.length && k <= right; i++) {
-                for (int s = count[i]; s > 0; s--) {
-                    a[k++] = (char) i;
-               }
-            }
-        } else { // Use Dual-Pivot Quicksort on large arrays
-            dualPivotQuicksort(a, left, right);
+            do {
+                a[k++] = value;
+            } while (--s > 0);
         }
     }
 
     /**
      * Sorts the specified range of the array into ascending order by the
-     * Dual-Pivot Quicksort algorithm.
+     * Dual-Pivot Quicksort algorithm. This method differs from the public
+     * {@code sort} method in that the {@code right} index is inclusive,
+     * it does no range checking on {@code left} or {@code right}, and has
+     * boolean flag whether insertion sort with sentinel is used or not.
      *
      * @param a the array to be sorted
      * @param left the index of the first element, inclusive, to be sorted
      * @param right the index of the last element, inclusive, to be sorted
+     * @param leftmost indicates if the part is the most left in the range
      */
-    private static void dualPivotQuicksort(char[] a, int left, int right) {
-        // Compute indices of five evenly spaced elements
-        int sixth = (right - left + 1) / 6;
-        int e1 = left  + sixth;
-        int e5 = right - sixth;
+    private static void sort(char[] a, int left, int right, boolean leftmost) {
+        int length = right - left + 1;
+
+        // Use insertion sort on tiny arrays
+        if (length < INSERTION_SORT_THRESHOLD) {
+            if (!leftmost) {
+                /*
+                 * Every element in adjoining part plays the role
+                 * of sentinel, therefore this allows us to avoid
+                 * the j >= left check on each iteration.
+                 */
+                for (int j, i = left + 1; i <= right; i++) {
+                    char ai = a[i];
+                    for (j = i - 1; ai < a[j]; j--) {
+                        // assert j >= left;
+                        a[j + 1] = a[j];
+                    }
+                    a[j + 1] = ai;
+                }
+            } else {
+                /*
+                 * For case of leftmost part traditional (without a sentinel)
+                 * insertion sort, optimized for server JVM, is used.
+                 */
+                for (int i = left, j = i; i < right; j = ++i) {
+                    char ai = a[i + 1];
+                    while (ai < a[j]) {
+                        a[j + 1] = a[j];
+                        if (j-- == left) {
+                            break;
+                        }
+                    }
+                    a[j + 1] = ai;
+                }
+            }
+            return;
+        }
+
+        // Inexpensive approximation of length / 7
+        int seventh = (length >>> 3) + (length >>> 6) + 1;
+
+        /*
+         * Sort five evenly spaced elements around (and including) the
+         * center element in the range. These elements will be used for
+         * pivot selection as described below. The choice for spacing
+         * these elements was empirically determined to work well on
+         * a wide variety of inputs.
+         */
         int e3 = (left + right) >>> 1; // The midpoint
-        int e4 = e3 + sixth;
-        int e2 = e3 - sixth;
+        int e2 = e3 - seventh;
+        int e1 = e2 - seventh;
+        int e4 = e3 + seventh;
+        int e5 = e4 + seventh;
 
-        // Sort these elements using a 5-element sorting network
-        char ae1 = a[e1], ae2 = a[e2], ae3 = a[e3], ae4 = a[e4], ae5 = a[e5];
+        // Sort these elements using insertion sort
+        if (a[e2] < a[e1]) { char t = a[e2]; a[e2] = a[e1]; a[e1] = t; }
 
-        if (ae1 > ae2) { char t = ae1; ae1 = ae2; ae2 = t; }
-        if (ae4 > ae5) { char t = ae4; ae4 = ae5; ae5 = t; }
-        if (ae1 > ae3) { char t = ae1; ae1 = ae3; ae3 = t; }
-        if (ae2 > ae3) { char t = ae2; ae2 = ae3; ae3 = t; }
-        if (ae1 > ae4) { char t = ae1; ae1 = ae4; ae4 = t; }
-        if (ae3 > ae4) { char t = ae3; ae3 = ae4; ae4 = t; }
-        if (ae2 > ae5) { char t = ae2; ae2 = ae5; ae5 = t; }
-        if (ae2 > ae3) { char t = ae2; ae2 = ae3; ae3 = t; }
-        if (ae4 > ae5) { char t = ae4; ae4 = ae5; ae5 = t; }
-
-        a[e1] = ae1; a[e3] = ae3; a[e5] = ae5;
+        if (a[e3] < a[e2]) { char t = a[e3]; a[e3] = a[e2]; a[e2] = t;
+            if (t < a[e1]) { a[e2] = a[e1]; a[e1] = t; }
+        }
+        if (a[e4] < a[e3]) { char t = a[e4]; a[e4] = a[e3]; a[e3] = t;
+            if (t < a[e2]) { a[e3] = a[e2]; a[e2] = t;
+                if (t < a[e1]) { a[e2] = a[e1]; a[e1] = t; }
+            }
+        }
+        if (a[e5] < a[e4]) { char t = a[e5]; a[e5] = a[e4]; a[e4] = t;
+            if (t < a[e3]) { a[e4] = a[e3]; a[e3] = t;
+                if (t < a[e2]) { a[e3] = a[e2]; a[e2] = t;
+                    if (t < a[e1]) { a[e2] = a[e1]; a[e1] = t; }
+                }
+            }
+        }
 
         /*
          * Use the second and fourth of the five sorted elements as pivots.
          * These values are inexpensive approximations of the first and
          * second terciles of the array. Note that pivot1 <= pivot2.
-         *
-         * The pivots are stored in local variables, and the first and
-         * the last of the elements to be sorted are moved to the locations
-         * formerly occupied by the pivots. When partitioning is complete,
-         * the pivots are swapped back into their final positions, and
-         * excluded from subsequent sorting.
          */
-        char pivot1 = ae2; a[e2] = a[left];
-        char pivot2 = ae4; a[e4] = a[right];
+        char pivot1 = a[e2];
+        char pivot2 = a[e4];
 
         // Pointers
-        int less  = left  + 1; // The index of first element of center part
-        int great = right - 1; // The index before first element of right part
+        int less  = left;  // The index of the first element of center part
+        int great = right; // The index before the first element of right part
 
-        boolean pivotsDiffer = (pivot1 != pivot2);
+        if (pivot1 != pivot2) {
+            /*
+             * The first and the last elements to be sorted are moved to the
+             * locations formerly occupied by the pivots. When partitioning
+             * is complete, the pivots are swapped back into their final
+             * positions, and excluded from subsequent sorting.
+             */
+            a[e2] = a[left];
+            a[e4] = a[right];
 
-        if (pivotsDiffer) {
+            /*
+             * Skip elements, which are less or greater than pivot values.
+             */
+            while (a[++less] < pivot1);
+            while (a[--great] > pivot2);
+
             /*
              * Partitioning:
              *
-             *   left part         center part                    right part
-             * +------------------------------------------------------------+
-             * | < pivot1  |  pivot1 <= && <= pivot2  |    ?    |  > pivot2 |
-             * +------------------------------------------------------------+
-             *              ^                          ^       ^
-             *              |                          |       |
-             *             less                        k     great
+             *   left part           center part                   right part
+             * +--------------------------------------------------------------+
+             * |  < pivot1  |  pivot1 <= && <= pivot2  |    ?    |  > pivot2  |
+             * +--------------------------------------------------------------+
+             *               ^                          ^       ^
+             *               |                          |       |
+             *              less                        k     great
              *
              * Invariants:
              *
@@ -1060,16 +1298,14 @@
              *    pivot1 <= all in [less, k)     <= pivot2
              *              all in (great, right) > pivot2
              *
-             * Pointer k is the first index of ?-part
+             * Pointer k is the first index of ?-part.
              */
             outer:
             for (int k = less; k <= great; k++) {
                 char ak = a[k];
                 if (ak < pivot1) { // Move a[k] to left part
-                    if (k != less) {
-                        a[k] = a[less];
-                        a[less] = ak;
-                    }
+                    a[k] = a[less];
+                    a[less] = ak;
                     less++;
                 } else if (ak > pivot2) { // Move a[k] to right part
                     while (a[great] > pivot2) {
@@ -1079,26 +1315,107 @@
                     }
                     if (a[great] < pivot1) {
                         a[k] = a[less];
-                        a[less++] = a[great];
-                        a[great--] = ak;
+                        a[less] = a[great];
+                        less++;
                     } else { // pivot1 <= a[great] <= pivot2
                         a[k] = a[great];
-                        a[great--] = ak;
+                    }
+                    a[great] = ak;
+                    great--;
+                }
+            }
+
+            // Swap pivots into their final positions
+            a[left]  = a[less  - 1]; a[less  - 1] = pivot1;
+            a[right] = a[great + 1]; a[great + 1] = pivot2;
+
+            // Sort left and right parts recursively, excluding known pivots
+            sort(a, left, less - 2, leftmost);
+            sort(a, great + 2, right, false);
+
+            /*
+             * If center part is too large (comprises > 5/7 of the array),
+             * swap internal pivot values to ends.
+             */
+            if (less < e1 && e5 < great) {
+                /*
+                 * Skip elements, which are equal to pivot values.
+                 */
+                while (a[less] == pivot1) {
+                    less++;
+                }
+                while (a[great] == pivot2) {
+                    great--;
+                }
+
+                /*
+                 * Partitioning:
+                 *
+                 *   left part         center part                  right part
+                 * +----------------------------------------------------------+
+                 * | == pivot1 |  pivot1 < && < pivot2  |    ?    | == pivot2 |
+                 * +----------------------------------------------------------+
+                 *              ^                        ^       ^
+                 *              |                        |       |
+                 *             less                      k     great
+                 *
+                 * Invariants:
+                 *
+                 *              all in (*,  less) == pivot1
+                 *     pivot1 < all in [less,  k)  < pivot2
+                 *              all in (great, *) == pivot2
+                 *
+                 * Pointer k is the first index of ?-part.
+                 */
+                outer:
+                for (int k = less; k <= great; k++) {
+                    char ak = a[k];
+                    if (ak == pivot1) { // Move a[k] to left part
+                        a[k] = a[less];
+                        a[less] = ak;
+                        less++;
+                    } else if (ak == pivot2) { // Move a[k] to right part
+                        while (a[great] == pivot2) {
+                            if (great-- == k) {
+                                break outer;
+                            }
+                        }
+                        if (a[great] == pivot1) {
+                            a[k] = a[less];
+                            /*
+                             * Even though a[great] equals to pivot1, the
+                             * assignment a[less] = pivot1 may be incorrect,
+                             * if a[great] and pivot1 are floating-point zeros
+                             * of different signs. Therefore in float and
+                             * double sorting methods we have to use more
+                             * accurate assignment a[less] = a[great].
+                             */
+                            a[less] = pivot1;
+                            less++;
+                        } else { // pivot1 < a[great] < pivot2
+                            a[k] = a[great];
+                        }
+                        a[great] = ak;
+                        great--;
                     }
                 }
             }
+
+            // Sort center part recursively
+            sort(a, less, great, false);
+
         } else { // Pivots are equal
             /*
-             * Partition degenerates to the traditional 3-way,
-             * or "Dutch National Flag", partition:
+             * Partition degenerates to the traditional 3-way
+             * (or "Dutch National Flag") schema:
              *
-             *   left part   center part            right part
-             * +----------------------------------------------+
-             * |  < pivot  |  == pivot  |    ?    |  > pivot  |
-             * +----------------------------------------------+
-             *              ^            ^       ^
-             *              |            |       |
-             *             less          k     great
+             *   left part    center part              right part
+             * +-------------------------------------------------+
+             * |  < pivot  |   == pivot   |     ?    |  > pivot  |
+             * +-------------------------------------------------+
+             *              ^              ^        ^
+             *              |              |        |
+             *             less            k      great
              *
              * Invariants:
              *
@@ -1106,20 +1423,19 @@
              *   all in [less, k)     == pivot
              *   all in (great, right) > pivot
              *
-             * Pointer k is the first index of ?-part
+             * Pointer k is the first index of ?-part.
              */
-            for (int k = less; k <= great; k++) {
-                char ak = a[k];
-                if (ak == pivot1) {
+            for (int k = left; k <= great; k++) {
+                if (a[k] == pivot1) {
                     continue;
                 }
+                char ak = a[k];
+
                 if (ak < pivot1) { // Move a[k] to left part
-                    if (k != less) {
-                        a[k] = a[less];
-                        a[less] = ak;
-                    }
+                    a[k] = a[less];
+                    a[less] = ak;
                     less++;
-                } else { // (a[k] > pivot1) - Move a[k] to right part
+                } else { // a[k] > pivot1 - Move a[k] to right part
                     /*
                      * We know that pivot1 == a[e3] == pivot2. Thus, we know
                      * that great will still be >= k when the following loop
@@ -1127,92 +1443,33 @@
                      * In other words, a[e3] acts as a sentinel for great.
                      */
                     while (a[great] > pivot1) {
+                        // assert great > k;
                         great--;
                     }
                     if (a[great] < pivot1) {
                         a[k] = a[less];
-                        a[less++] = a[great];
-                        a[great--] = ak;
+                        a[less] = a[great];
+                        less++;
                     } else { // a[great] == pivot1
+                        /*
+                         * Even though a[great] equals to pivot1, the
+                         * assignment a[k] = pivot1 may be incorrect,
+                         * if a[great] and pivot1 are floating-point
+                         * zeros of different signs. Therefore in float
+                         * and double sorting methods we have to use
+                         * more accurate assignment a[k] = a[great].
+                         */
                         a[k] = pivot1;
-                        a[great--] = ak;
                     }
+                    a[great] = ak;
+                    great--;
                 }
             }
+
+            // Sort left and right parts recursively
+            sort(a, left, less - 1, leftmost);
+            sort(a, great + 1, right, false);
         }
-
-        // Swap pivots into their final positions
-        a[left]  = a[less  - 1]; a[less  - 1] = pivot1;
-        a[right] = a[great + 1]; a[great + 1] = pivot2;
-
-        // Sort left and right parts recursively, excluding known pivot values
-        doSort(a, left,   less - 2);
-        doSort(a, great + 2, right);
-
-        /*
-         * If pivot1 == pivot2, all elements from center
-         * part are equal and, therefore, already sorted
-         */
-        if (!pivotsDiffer) {
-            return;
-        }
-
-        /*
-         * If center part is too large (comprises > 2/3 of the array),
-         * swap internal pivot values to ends
-         */
-        if (less < e1 && great > e5) {
-            while (a[less] == pivot1) {
-                less++;
-            }
-            while (a[great] == pivot2) {
-                great--;
-            }
-
-            /*
-             * Partitioning:
-             *
-             *   left part       center part                   right part
-             * +----------------------------------------------------------+
-             * | == pivot1 |  pivot1 < && < pivot2  |    ?    | == pivot2 |
-             * +----------------------------------------------------------+
-             *              ^                        ^       ^
-             *              |                        |       |
-             *             less                      k     great
-             *
-             * Invariants:
-             *
-             *              all in (*, less)  == pivot1
-             *     pivot1 < all in [less, k)   < pivot2
-             *              all in (great, *) == pivot2
-             *
-             * Pointer k is the first index of ?-part
-             */
-            outer:
-            for (int k = less; k <= great; k++) {
-                char ak = a[k];
-                if (ak == pivot2) { // Move a[k] to right part
-                    while (a[great] == pivot2) {
-                        if (great-- == k) {
-                            break outer;
-                        }
-                    }
-                    if (a[great] == pivot1) {
-                        a[k] = a[less];
-                        a[less++] = pivot1;
-                    } else { // pivot1 < a[great] < pivot2
-                        a[k] = a[great];
-                    }
-                    a[great--] = pivot2;
-                } else if (ak == pivot1) { // Move a[k] to left part
-                    a[k] = a[less];
-                    a[less++] = pivot1;
-                }
-            }
-        }
-
-        // Sort center part recursively, excluding known pivot values
-        doSort(a, less, great);
     }
 
     /**
@@ -1221,7 +1478,11 @@
      * @param a the array to be sorted
      */
     public static void sort(byte[] a) {
-        doSort(a, 0, a.length - 1);
+        if (a.length > COUNTING_SORT_THRESHOLD_FOR_BYTE) {
+            countingSort(a, 0, a.length - 1);
+        } else {
+            sort(a, 0, a.length - 1, true);
+        }
     }
 
     /**
@@ -1239,115 +1500,166 @@
      */
     public static void sort(byte[] a, int fromIndex, int toIndex) {
         rangeCheck(a.length, fromIndex, toIndex);
-        doSort(a, fromIndex, toIndex - 1);
+
+        if (toIndex - fromIndex > COUNTING_SORT_THRESHOLD_FOR_BYTE) {
+            countingSort(a, fromIndex, toIndex - 1);
+        } else {
+            sort(a, fromIndex, toIndex - 1, true);
+        }
     }
 
     /** The number of distinct byte values. */
     private static final int NUM_BYTE_VALUES = 1 << 8;
 
     /**
-     * Sorts the specified range of the array into ascending order. This
-     * method differs from the public {@code sort} method in that the
-     * {@code right} index is inclusive, and it does no range checking on
-     * {@code left} or {@code right}.
+     * Sorts the specified range of the array by counting sort.
      *
      * @param a the array to be sorted
      * @param left the index of the first element, inclusive, to be sorted
      * @param right the index of the last element, inclusive, to be sorted
      */
-    private static void doSort(byte[] a, int left, int right) {
-        // Use insertion sort on tiny arrays
-        if (right - left + 1 < INSERTION_SORT_THRESHOLD) {
-            for (int i = left + 1; i <= right; i++) {
-                byte ai = a[i];
-                int j;
-                for (j = i - 1; j >= left && ai < a[j]; j--) {
-                    a[j + 1] = a[j];
-                }
-                a[j + 1] = ai;
+    private static void countingSort(byte[] a, int left, int right) {
+        int[] count = new int[NUM_BYTE_VALUES];
+
+        for (int i = left; i <= right; i++) {
+            count[a[i] - Byte.MIN_VALUE]++;
+        }
+        for (int i = NUM_BYTE_VALUES - 1, k = right; k >= left; i--) {
+            while (count[i] == 0) {
+                i--;
             }
-        } else if (right - left + 1 > COUNTING_SORT_THRESHOLD_FOR_BYTE) {
-            // Use counting sort on huge arrays
-            int[] count = new int[NUM_BYTE_VALUES];
+            byte value = (byte) (i + Byte.MIN_VALUE);
+            int s = count[i];
 
-            for (int i = left; i <= right; i++) {
-                count[a[i] - Byte.MIN_VALUE]++;
-            }
-            for (int i = 0, k = left; i < count.length && k <= right; i++) {
-                byte value = (byte) (i + Byte.MIN_VALUE);
-
-                for (int s = count[i]; s > 0; s--) {
-                    a[k++] = value;
-               }
-            }
-        } else { // Use Dual-Pivot Quicksort on large arrays
-            dualPivotQuicksort(a, left, right);
+            do {
+                a[k--] = value;
+            } while (--s > 0);
         }
     }
 
     /**
      * Sorts the specified range of the array into ascending order by the
-     * Dual-Pivot Quicksort algorithm.
+     * Dual-Pivot Quicksort algorithm. This method differs from the public
+     * {@code sort} method in that