changeset 4422:ade55a65b0f2

Merge
author duke
date Wed, 05 Jul 2017 17:04:26 +0200
parents fcbbd4d49581 80dcc8ac5696
children 4061c66ba1af
files jdk/make/tools/CharsetMapping/DoubleByte-X.java jdk/make/tools/CharsetMapping/SingleByte-X.java jdk/src/share/classes/javax/swing/plaf/synth/DefaultMenuLayout.java jdk/src/share/classes/sun/awt/ComponentAccessor.java jdk/src/share/classes/sun/awt/WindowAccessor.java jdk/src/share/classes/sun/security/provider/IdentityDatabase.java jdk/src/share/classes/sun/security/provider/SystemIdentity.java jdk/src/share/classes/sun/security/provider/SystemSigner.java jdk/src/share/classes/sun/security/x509/X500Signer.java jdk/src/share/classes/sun/security/x509/X509Cert.java jdk/src/share/classes/sun/swing/plaf/synth/SynthUI.java jdk/src/share/classes/sun/tools/jar/JarVerifierStream.java jdk/src/share/classes/sun/util/CoreResourceBundleControl-XLocales.java jdk/src/share/classes/sun/util/LocaleDataMetaInfo-XLocales.java jdk/test/java/util/Formatter/Basic-X.java jdk/test/sun/tools/native2ascii/test2 jdk/test/tools/launcher/SolarisDataModel.sh jdk/test/tools/launcher/SolarisRunpath.sh jdk/test/tools/launcher/libraryCaller.c jdk/test/tools/launcher/libraryCaller.h jdk/test/tools/launcher/libraryCaller.java
diffstat 394 files changed, 11957 insertions(+), 8882 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Wed Dec 16 23:39:39 2009 -0800
+++ b/.hgignore	Wed Jul 05 17:04:26 2017 +0200
@@ -1,3 +1,3 @@
 ^build/
 ^dist/
-^nbproject/private/
+/nbproject/private/
--- a/.hgtags-top-repo	Wed Dec 16 23:39:39 2009 -0800
+++ b/.hgtags-top-repo	Wed Jul 05 17:04:26 2017 +0200
@@ -51,3 +51,4 @@
 2c88089b6e1c053597418099a14232182c387edc jdk7-b74
 d1516b9f23954b29b8e76e6f4efc467c08c78133 jdk7-b75
 c8b63075403d53a208104a8a6ea5072c1cb66aab jdk7-b76
+1f17ca8353babb13f4908c1f87d11508232518c8 jdk7-b77
--- a/Makefile	Wed Dec 16 23:39:39 2009 -0800
+++ b/Makefile	Wed Jul 05 17:04:26 2017 +0200
@@ -51,7 +51,7 @@
 
 # For start and finish echo lines
 TITLE_TEXT = Control $(PLATFORM) $(ARCH) $(RELEASE)
-DAYE_STAMP = `$(DATE) '+%y-%m-%d %H:%M'`
+DATE_STAMP = `$(DATE) '+%y-%m-%d %H:%M'`
 START_ECHO  = echo "$(TITLE_TEXT) $@ build started: $(DATE_STAMP)"
 FINISH_ECHO = echo "$(TITLE_TEXT) $@ build finished: $(DATE_STAMP)"
 
@@ -188,7 +188,7 @@
 create_fresh_product_bootdir: FRC
 	@$(START_ECHO)
 	$(MAKE) ALT_OUTPUTDIR=$(ABS_BOOTDIR_OUTPUTDIR) \
-		NO_DOCS=true \
+		GENERATE_DOCS=false \
 		BOOT_CYCLE_SETTINGS= \
 		build_product_image
 	@$(FINISH_ECHO)
@@ -196,7 +196,7 @@
 create_fresh_debug_bootdir: FRC
 	@$(START_ECHO)
 	$(MAKE) ALT_OUTPUTDIR=$(ABS_BOOTDIR_OUTPUTDIR) \
-		NO_DOCS=true \
+		GENERATE_DOCS=false \
 		BOOT_CYCLE_DEBUG_SETTINGS= \
 		build_debug_image
 	@$(FINISH_ECHO)
@@ -204,7 +204,7 @@
 create_fresh_fastdebug_bootdir: FRC
 	@$(START_ECHO)
 	$(MAKE) ALT_OUTPUTDIR=$(ABS_BOOTDIR_OUTPUTDIR) \
-		NO_DOCS=true \
+		GENERATE_DOCS=false \
 		BOOT_CYCLE_DEBUG_SETTINGS= \
 		build_fastdebug_image
 	@$(FINISH_ECHO)
@@ -253,7 +253,7 @@
 	$(MAKE) \
 		ALT_OUTPUTDIR=$(ABS_OUTPUTDIR)-$(DEBUG_NAME) \
 	        DEBUG_NAME=$(DEBUG_NAME) \
-		NO_DOCS=true \
+		GENERATE_DOCS=false \
 	        $(BOOT_CYCLE_DEBUG_SETTINGS) \
 		generic_build_repo_series
 	@$(FINISH_ECHO)
@@ -323,7 +323,7 @@
 	$(MKDIR) -p $(OPENJDK_OUTPUTDIR)
 	($(CD) $(OPENJDK_BUILDDIR) && $(MAKE) \
 	  OPENJDK=true \
-	  NO_DOCS=true \
+	  GENERATE_DOCS=false \
 	  ALT_JDK_DEVTOOLS_DIR=$(JDK_DEVTOOLS_DIR) \
 	  ALT_OUTPUTDIR=$(OPENJDK_OUTPUTDIR) \
 	  ALT_BINARY_PLUGS_PATH=$(OPENJDK_PLUGS) \
--- a/corba/.hgignore	Wed Dec 16 23:39:39 2009 -0800
+++ b/corba/.hgignore	Wed Jul 05 17:04:26 2017 +0200
@@ -1,3 +1,3 @@
 ^build/
 ^dist/
-^nbproject/private/
+/nbproject/private/
--- a/corba/.hgtags	Wed Dec 16 23:39:39 2009 -0800
+++ b/corba/.hgtags	Wed Jul 05 17:04:26 2017 +0200
@@ -51,3 +51,4 @@
 5d0cf59a3203b9f57aceebc33ae656b884987955 jdk7-b74
 0fb137085952c8e47878e240d1cb40f14de463c4 jdk7-b75
 937144222e2219939101b0129d26a872a7956b13 jdk7-b76
+6881f0383f623394b5ec73f27a5f329ff55d0467 jdk7-b77
--- a/hotspot/.hgignore	Wed Dec 16 23:39:39 2009 -0800
+++ b/hotspot/.hgignore	Wed Jul 05 17:04:26 2017 +0200
@@ -1,6 +1,6 @@
 ^build/
 ^dist/
-^nbproject/private/
+/nbproject/private/
 ^src/share/tools/hsdis/build/
 ^src/share/tools/IdealGraphVisualizer/[a-zA-Z0-9]*/build/
 ^src/share/tools/IdealGraphVisualizer/build/
--- a/hotspot/.hgtags	Wed Dec 16 23:39:39 2009 -0800
+++ b/hotspot/.hgtags	Wed Jul 05 17:04:26 2017 +0200
@@ -51,3 +51,4 @@
 f4b900403d6e4b0af51447bd13bbe23fe3a1dac7 jdk7-b74
 d8dd291a362acb656026a9c0a9da48501505a1e7 jdk7-b75
 9174bb32e934965288121f75394874eeb1fcb649 jdk7-b76
+455105fc81d941482f8f8056afaa7aa0949c9300 jdk7-b77
--- a/jaxp/.hgignore	Wed Dec 16 23:39:39 2009 -0800
+++ b/jaxp/.hgignore	Wed Jul 05 17:04:26 2017 +0200
@@ -3,4 +3,4 @@
 ^drop/
 ^drop_included/
 ^webrev/
-^nbproject/private/
+/nbproject/private/
--- a/jaxp/.hgtags	Wed Dec 16 23:39:39 2009 -0800
+++ b/jaxp/.hgtags	Wed Jul 05 17:04:26 2017 +0200
@@ -51,3 +51,4 @@
 ea7b88c676dd8b269bc858a4a17c14dc96c8aed1 jdk7-b74
 555fb78ee4cebed082ca7ddabff46d2e5b4c9026 jdk7-b75
 233a4871d3364ec305efd4a58cfd676620a03a90 jdk7-b76
+bfadab8c7b1bf806a49d3e1bc19ec919717f057a jdk7-b77
--- a/jaxws/.hgignore	Wed Dec 16 23:39:39 2009 -0800
+++ b/jaxws/.hgignore	Wed Jul 05 17:04:26 2017 +0200
@@ -3,4 +3,4 @@
 ^drop/
 ^drop_included/
 ^webrev/
-^nbproject/private/
+/nbproject/private/
--- a/jaxws/.hgtags	Wed Dec 16 23:39:39 2009 -0800
+++ b/jaxws/.hgtags	Wed Jul 05 17:04:26 2017 +0200
@@ -51,3 +51,4 @@
 f4466e1b608088c90e11beaa4b600f102608c6a1 jdk7-b74
 fcf2b8b5d606641659419f247fcee4b284c45e6e jdk7-b75
 765d2077d1e652e234d27fe85ba58a986b488503 jdk7-b76
+5b4968c110476085225d3a71c4210fad2c1116c1 jdk7-b77
--- a/jdk/.hgignore	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/.hgignore	Wed Jul 05 17:04:26 2017 +0200
@@ -1,6 +1,5 @@
 ^build/
 ^dist/
-^nbproject/private/
-^make/netbeans/.*/nbproject/private/
+/nbproject/private/
 ^make/netbeans/.*/build/
 ^make/netbeans/.*/dist/
--- a/jdk/.hgtags	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/.hgtags	Wed Jul 05 17:04:26 2017 +0200
@@ -51,3 +51,4 @@
 eacb36e30327e7ae33baa068e82ddccbd91eaae2 jdk7-b74
 8885b22565077236a927e824ef450742e434a230 jdk7-b75
 8fb602395be0f7d5af4e7e93b7df2d960faf9d17 jdk7-b76
+e6a5d095c356a547cf5b3c8885885aca5e91e09b jdk7-b77
--- a/jdk/make/java/java/Makefile	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/make/java/java/Makefile	Wed Jul 05 17:04:26 2017 +0200
@@ -390,7 +390,7 @@
 LOCALES_GEN_SH = localelist.sh
 
 $(GENSRCDIR)/sun/util/CoreResourceBundleControl.java: \
-	$(SHARE_SRC)/classes/sun/util/CoreResourceBundleControl-XLocales.java $(LOCALES_GEN_SH)
+	$(SHARE_SRC)/classes/sun/util/CoreResourceBundleControl-XLocales.java.template $(LOCALES_GEN_SH)
 	@$(prep-target) 
 	NAWK="$(NAWK)" SED="$(SED)" $(SH) $(LOCALES_GEN_SH) "$(JRE_NONEXIST_LOCALES)" \
 		$< $@ 
--- a/jdk/make/java/java/genlocales.gmk	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/make/java/java/genlocales.gmk	Wed Jul 05 17:04:26 2017 +0200
@@ -68,7 +68,7 @@
 FILES_java := $(FILES_java_orig)
 FILES_compiled_properties := $(FILES_compiled_properties_orig)
 
-LocaleDataMetaInfo_Src=$(SHARE_SRC)/classes/sun/util/LocaleDataMetaInfo-XLocales.java
+LocaleDataMetaInfo_Src=$(SHARE_SRC)/classes/sun/util/LocaleDataMetaInfo-XLocales.java.template
 LocaleDataMetaInfo_Dest=$(GENSRCDIR)/sun/util/LocaleDataMetaInfo.java
 LOCALEGEN_SH=localegen.sh
 RESOURCE_NAMES="FormatData CollationData TimeZoneNames LocaleNames CurrencyNames CalendarData"
--- a/jdk/make/java/java/localegen.sh	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/make/java/java/localegen.sh	Wed Jul 05 17:04:26 2017 +0200
@@ -27,7 +27,7 @@
 
 #
 # This script is to generate the supported locale list string and replace the
-# LocaleDataMetaInfo-XLocales.java in <ws>/src/share/classes/sun/util
+# LocaleDataMetaInfo-XLocales.java.template in <ws>/src/share/classes/sun/util
 # 
 # SORT, NAWK & SED is passed in as environment variables.
 #
--- a/jdk/make/java/jli/Makefile	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/make/java/jli/Makefile	Wed Jul 05 17:04:26 2017 +0200
@@ -96,6 +96,7 @@
 
 
 ifneq ($(PLATFORM), windows)	# UNIX systems
+        LD_RUNPATH_EXTRAS += ..
 	LIB_LOCATION = $(LIBDIR)/$(LIBARCH)/jli
 	# Note: its important to keep this order meaning -lc is the
 	# last library otherwise it could cause compatibility issues
--- a/jdk/make/java/main/java/Makefile	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/make/java/main/java/Makefile	Wed Jul 05 17:04:26 2017 +0200
@@ -61,8 +61,5 @@
 
 ifeq ($(PLATFORM), solaris)
 LDFLAGS += -R$(OPENWIN_LIB)
-endif
-
-ifeq ($(PLATFORM), solaris)
 LDFLAGS += -M mapfile-$(ARCH)
 endif
--- a/jdk/make/java/nio/Makefile	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/make/java/nio/Makefile	Wed Jul 05 17:04:26 2017 +0200
@@ -834,7 +834,7 @@
 GENCSSRC = $(BUILDDIR)/tools/CharsetMapping
 CHARSETMAPPING_JARFILE = $(BUILDTOOLJARDIR)/charsetmapping.jar
 
-$(FILES_gensbcs_out): $(GENCSSRC)/SingleByte-X.java $(GENCSSRC)/sbcs
+$(FILES_gensbcs_out): $(GENCSSRC)/SingleByte-X.java.template $(GENCSSRC)/sbcs
 	@$(prep-target)
 	$(BOOT_JAVA_CMD) -jar $(CHARSETMAPPING_JARFILE) $(GENCSSRC) $(SCS_GEN) sbcs
 
--- a/jdk/make/java/redist/Makefile	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/make/java/redist/Makefile	Wed Jul 05 17:04:26 2017 +0200
@@ -194,10 +194,8 @@
 # For backwards compatability, make a link of the 32-bit client JVM to $(LIBDIR)
 IMPORT_LIST += $(LIB_LOCATION)/$(JVM_NAME)
 
-# create a link from lib/libjvm.so to client/libjvm.so
 $(LIB_LOCATION)/$(JVM_NAME): $(LIB_LOCATION)/$(CLIENT_LOCATION)/$(JVM_NAME)
 	@$(prep-target)
-	$(LN) -s $(CLIENT_LOCATION)/$(JVM_NAME) $@
 
 #  solaris   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ solaris
 endif # 32bit solaris
--- a/jdk/make/javax/sound/Makefile	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/make/javax/sound/Makefile	Wed Jul 05 17:04:26 2017 +0200
@@ -108,22 +108,14 @@
 endif # PLATFORM linux
 
 ifeq ($(PLATFORM), solaris)
-  ifneq ($(ARCH), amd64)
-    # build with ports and direct audio
-    CPPFLAGS += -DUSE_PORTS=TRUE 	\
-                -DUSE_DAUDIO=TRUE
+  # build with ports and direct audio
+  CPPFLAGS += -DUSE_PORTS=TRUE 	\
+              -DUSE_DAUDIO=TRUE
 
-    INCLUDE_PORTS = TRUE
-    INCLUDE_DAUDIO = TRUE
-    INCLUDE_MIDI = TRUE
-  else
-    # build with empty MIDI i/o
-    INCLUDE_MIDI = TRUE
-    # build with empty ports
-    INCLUDE_PORTS = TRUE
-    # build with empty direct audio
-    INCLUDE_DAUDIO = TRUE
-  endif
+  INCLUDE_PORTS = TRUE
+  INCLUDE_DAUDIO = TRUE
+  # build with empty MIDI i/o
+  INCLUDE_MIDI = TRUE
 endif # PLATFORM solaris
 
 # for dynamic inclusion of extra sound libs: these
--- a/jdk/make/netbeans/README	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/make/netbeans/README	Wed Jul 05 17:04:26 2017 +0200
@@ -411,7 +411,7 @@
             java/util/regex/,\
             java/util/spi/,\
             java/util/zip/,\
-            **/*-XLocales.java
+            **/*-XLocales.java.template
         jtreg.tests=\
             java/util/**/*Collection/ \
             java/util/**/*Map/ \
--- a/jdk/make/sun/nio/Makefile	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/make/sun/nio/Makefile	Wed Jul 05 17:04:26 2017 +0200
@@ -82,7 +82,9 @@
 		$(FILES_MAP) $(FILES_DAT) sjis0213
 
 
-$(FILES_genout_extcs): $(GENCSDATASRC)/SingleByte-X.java  $(GENCSDATASRC)/DoubleByte-X.java \
+$(FILES_genout_extcs): \
+                $(GENCSDATASRC)/SingleByte-X.java.template  \
+		$(GENCSDATASRC)/DoubleByte-X.java.template \
 		$(GENCSDATASRC)/extsbcs $(GENCSDATASRC)/dbcs
 	@$(prep-target)
 	$(RM) -r $(GENCSEXT)
--- a/jdk/make/sun/xawt/mapfile-vers	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/make/sun/xawt/mapfile-vers	Wed Jul 05 17:04:26 2017 +0200
@@ -126,6 +126,8 @@
         Java_sun_awt_X11_XlibWrapper_ServerVendor;
         Java_sun_awt_X11_XlibWrapper_VendorRelease;
         Java_sun_awt_X11_XlibWrapper_IsXsunKPBehavior;
+        Java_sun_awt_X11_XlibWrapper_IsSunKeyboard;
+        Java_sun_awt_X11_XlibWrapper_IsKanaKeyboard;
         Java_sun_awt_X11_XlibWrapper_SetToolkitErrorHandler;
         Java_sun_awt_X11_XlibWrapper_XSetErrorHandler;
         Java_sun_awt_X11_XlibWrapper_CallErrorHandler;
@@ -306,6 +308,7 @@
         Java_sun_awt_X11_XlibWrapper_XkbTranslateKeyCode;
         Java_sun_awt_X11_XlibWrapper_XGetModifierMapping;
         Java_sun_awt_X11_XlibWrapper_XFreeModifiermap;
+        Java_sun_awt_X11_XlibWrapper_XRefreshKeyboardMapping;
         Java_sun_awt_X11_XlibWrapper_XChangeActivePointerGrab;
         Java_sun_awt_X11_XlibWrapper_XNextSecondaryLoopEvent;
         Java_sun_awt_X11_XlibWrapper_ExitSecondaryLoop;
--- a/jdk/make/tools/CharsetMapping/DoubleByte-X.java	Wed Dec 16 23:39:39 2009 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,100 +0,0 @@
-/*
- * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-// -- This file was mechanically generated: Do not edit! -- //
-
-package $PACKAGE$;
-
-import java.nio.charset.Charset;
-import java.nio.charset.CharsetDecoder;
-import java.nio.charset.CharsetEncoder;
-import java.util.Arrays;
-import sun.nio.cs.HistoricallyNamedCharset;
-import sun.nio.cs.ext.DoubleByte;
-
-public class $NAME_CLZ$ extends Charset
-                        $IMPLEMENTS$
-{
-    public $NAME_CLZ$() {
-        super("$NAME_CS$", $NAME_ALIASES$);
-    }
-
-    $HISTORICALNAME$
-
-    public boolean contains(Charset cs) {
-        $CONTAINS$
-    }
-
-    public CharsetDecoder newDecoder() {
-        initb2c();
-        return new  DoubleByte.Decoder$DECTYPE$(this, b2c, b2cSB, $B2MIN$, $B2MAX$);
-    }
-
-    public CharsetEncoder newEncoder() {
-        initc2b();
-        return new DoubleByte.Encoder$ENCTYPE$(this, c2b, c2bIndex);
-    }
-
-    $B2C$
-    static char[][] b2c = new char[b2cStr.length][];
-    static char[] b2cSB;
-    private static volatile boolean b2cInitialized = false;
-
-    static void initb2c() {
-        if (b2cInitialized)
-            return;
-        synchronized (b2c) {
-            if (b2cInitialized)
-                return;
-            for (int i = 0; i < b2cStr.length; i++) {
-                if (b2cStr[i] == null)
-                    b2c[i] = DoubleByte.B2C_UNMAPPABLE;
-                else
-                    b2c[i] = b2cStr[i].toCharArray();
-            }
-            b2cSB = b2cSBStr.toCharArray();
-            b2cInitialized = true;
-        }
-    }
-
-    static char[] c2b = new char[$C2BLENGTH$];
-    static char[] c2bIndex = new char[0x100];
-    private static volatile boolean c2bInitialized = false;
-
-    static void initc2b() {
-        if (c2bInitialized)
-            return;
-        synchronized (c2b) {
-            if (c2bInitialized)
-                return;
-            $NONROUNDTRIP_B2C$
-            $NONROUNDTRIP_C2B$
-            DoubleByte.Encoder.initC2B(b2cStr, b2cSBStr, b2cNR, c2bNR,
-                                       $B2MIN$, $B2MAX$,
-                                       c2b, c2bIndex);
-            c2bInitialized = true;
-        }
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/tools/CharsetMapping/DoubleByte-X.java.template	Wed Jul 05 17:04:26 2017 +0200
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package $PACKAGE$;
+
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
+import java.util.Arrays;
+import sun.nio.cs.HistoricallyNamedCharset;
+import sun.nio.cs.ext.DoubleByte;
+
+public class $NAME_CLZ$ extends Charset
+                        $IMPLEMENTS$
+{
+    public $NAME_CLZ$() {
+        super("$NAME_CS$", $NAME_ALIASES$);
+    }
+
+    $HISTORICALNAME$
+
+    public boolean contains(Charset cs) {
+        $CONTAINS$
+    }
+
+    public CharsetDecoder newDecoder() {
+        initb2c();
+        return new  DoubleByte.Decoder$DECTYPE$(this, b2c, b2cSB, $B2MIN$, $B2MAX$);
+    }
+
+    public CharsetEncoder newEncoder() {
+        initc2b();
+        return new DoubleByte.Encoder$ENCTYPE$(this, c2b, c2bIndex);
+    }
+
+    $B2C$
+    static char[][] b2c = new char[b2cStr.length][];
+    static char[] b2cSB;
+    private static volatile boolean b2cInitialized = false;
+
+    static void initb2c() {
+        if (b2cInitialized)
+            return;
+        synchronized (b2c) {
+            if (b2cInitialized)
+                return;
+            for (int i = 0; i < b2cStr.length; i++) {
+                if (b2cStr[i] == null)
+                    b2c[i] = DoubleByte.B2C_UNMAPPABLE;
+                else
+                    b2c[i] = b2cStr[i].toCharArray();
+            }
+            b2cSB = b2cSBStr.toCharArray();
+            b2cInitialized = true;
+        }
+    }
+
+    static char[] c2b = new char[$C2BLENGTH$];
+    static char[] c2bIndex = new char[0x100];
+    private static volatile boolean c2bInitialized = false;
+
+    static void initc2b() {
+        if (c2bInitialized)
+            return;
+        synchronized (c2b) {
+            if (c2bInitialized)
+                return;
+            $NONROUNDTRIP_B2C$
+            $NONROUNDTRIP_C2B$
+            DoubleByte.Encoder.initC2B(b2cStr, b2cSBStr, b2cNR, c2bNR,
+                                       $B2MIN$, $B2MAX$,
+                                       c2b, c2bIndex);
+            c2bInitialized = true;
+        }
+    }
+}
--- a/jdk/make/tools/CharsetMapping/SingleByte-X.java	Wed Dec 16 23:39:39 2009 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-/*
- * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-package $PACKAGE$;
-
-import java.nio.charset.Charset;
-import java.nio.charset.CharsetDecoder;
-import java.nio.charset.CharsetEncoder;
-import sun.nio.cs.StandardCharsets;
-import sun.nio.cs.SingleByte;
-import sun.nio.cs.HistoricallyNamedCharset;
-import static sun.nio.cs.CharsetMapping.*;
-
-public class $NAME_CLZ$ extends Charset implements HistoricallyNamedCharset
-{
-    public $NAME_CLZ$() {
-        super("$NAME_CS$", $NAME_ALIASES$);
-    }
-
-    public String historicalName() {
-        return "$NAME_HIS$";
-    }
-
-    public boolean contains(Charset cs) {
-        $CONTAINS$;
-    }
-
-    public CharsetDecoder newDecoder() {
-        return new SingleByte.Decoder(this, b2c);
-    }
-
-    public CharsetEncoder newEncoder() {
-        return new SingleByte.Encoder(this, c2b, c2bIndex);
-    }
-
-    public String getDecoderSingleByteMappings() {
-        return b2cTable;
-    }
-
-    public char[] getEncoderIndex2() {
-        return c2b;
-    }
-
-    public char[] getEncoderIndex1() {
-        return c2bIndex;
-    }
-
-    private final static String b2cTable = $B2CTABLE$
-
-    private final static char[] b2c = b2cTable.toCharArray();
-    private final static char[] c2b = new char[$C2BLENGTH$];
-    private final static char[] c2bIndex = new char[0x100];
-
-    static {
-        char[] b2cMap = b2c;
-        char[] c2bNR = null;
-        $NONROUNDTRIP_B2C$
-        $NONROUNDTRIP_C2B$
-        SingleByte.initC2B(b2cMap, c2bNR, c2b, c2bIndex);
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/tools/CharsetMapping/SingleByte-X.java.template	Wed Jul 05 17:04:26 2017 +0200
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package $PACKAGE$;
+
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
+import sun.nio.cs.StandardCharsets;
+import sun.nio.cs.SingleByte;
+import sun.nio.cs.HistoricallyNamedCharset;
+import static sun.nio.cs.CharsetMapping.*;
+
+public class $NAME_CLZ$ extends Charset implements HistoricallyNamedCharset
+{
+    public $NAME_CLZ$() {
+        super("$NAME_CS$", $NAME_ALIASES$);
+    }
+
+    public String historicalName() {
+        return "$NAME_HIS$";
+    }
+
+    public boolean contains(Charset cs) {
+        $CONTAINS$;
+    }
+
+    public CharsetDecoder newDecoder() {
+        return new SingleByte.Decoder(this, b2c);
+    }
+
+    public CharsetEncoder newEncoder() {
+        return new SingleByte.Encoder(this, c2b, c2bIndex);
+    }
+
+    public String getDecoderSingleByteMappings() {
+        return b2cTable;
+    }
+
+    public char[] getEncoderIndex2() {
+        return c2b;
+    }
+
+    public char[] getEncoderIndex1() {
+        return c2bIndex;
+    }
+
+    private final static String b2cTable = $B2CTABLE$
+
+    private final static char[] b2c = b2cTable.toCharArray();
+    private final static char[] c2b = new char[$C2BLENGTH$];
+    private final static char[] c2bIndex = new char[0x100];
+
+    static {
+        char[] b2cMap = b2c;
+        char[] c2bNR = null;
+        $NONROUNDTRIP_B2C$
+        $NONROUNDTRIP_C2B$
+        SingleByte.initC2B(b2cMap, c2bNR, c2b, c2bIndex);
+    }
+}
--- a/jdk/make/tools/src/build/tools/charsetmapping/GenerateDBCS.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/make/tools/src/build/tools/charsetmapping/GenerateDBCS.java	Wed Jul 05 17:04:26 2017 +0200
@@ -63,7 +63,7 @@
             int    b2Min    = toInteger(fields[8]);
             int    b2Max    = toInteger(fields[9]);
             System.out.printf("%s,%s,%s,%b,%s%n", clzName, csName, hisName, isASCII, pkgName);
-            genClass(args[0], args[1], "DoubleByte-X.java",
+            genClass(args[0], args[1], "DoubleByte-X.java.template",
                     clzName, csName, hisName, pkgName,
                     isASCII, type,
                     b1Min, b1Max, b2Min, b2Max);
--- a/jdk/make/tools/src/build/tools/charsetmapping/GenerateSBCS.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/make/tools/src/build/tools/charsetmapping/GenerateSBCS.java	Wed Jul 05 17:04:26 2017 +0200
@@ -55,7 +55,7 @@
             String pkgName  = fields[4];
             System.out.printf("%s,%s,%s,%b,%s%n", clzName, csName, hisName, isASCII, pkgName);
 
-            genClass(args[0], args[1], "SingleByte-X.java",
+            genClass(args[0], args[1], "SingleByte-X.java.template",
                      clzName, csName, hisName, pkgName, isASCII);
         }
     }
--- a/jdk/src/share/bin/java.c	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/bin/java.c	Wed Jul 05 17:04:26 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1995-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -41,15 +41,13 @@
  * options are turned into "-foo" options to the vm.  This option
  * filtering is handled in a number of places in the launcher, some of
  * it in machine-dependent code.  In this file, the function
- * CheckJVMType removes vm style options and TranslateApplicationArgs
- * removes "-J" prefixes.  On unix platforms, the
- * CreateExecutionEnvironment function from the unix java_md.c file
- * processes and removes -d<n> options.  However, in case
- * CreateExecutionEnvironment does not need to exec because
- * LD_LIBRARY_PATH is set acceptably and the data model does not need
- * to be changed, ParseArguments will screen out the redundant -d<n>
- * options and prevent them from being passed to the vm; this is done
- * by RemovableOption.
+ * CheckJvmType removes vm style options and TranslateApplicationArgs
+ * removes "-J" prefixes.  The CreateExecutionEnvironment function processes
+ * and removes -d<n> options. On unix, there is a possibility that the running
+ * data model may not match to the desired data model, in this case an exec is
+ * required to start the desired model. If the data models match, then
+ * ParseArguments will remove the -d<n> flags. If the data models do not match
+ * the CreateExecutionEnviroment will remove the -d<n> flags.
  */
 
 
@@ -1891,11 +1889,11 @@
  * Return JNI_TRUE for an option string that has no effect but should
  * _not_ be passed on to the vm; return JNI_FALSE otherwise.  On
  * Solaris SPARC, this screening needs to be done if:
- * 1) LD_LIBRARY_PATH does _not_ need to be reset and
- * 2) -d32 or -d64 is passed to a binary with a matching data model
- *    (the exec in SetLibraryPath removes -d<n> options and points the
- *    exec to the proper binary).  When this exec is not done, these options
- *    would end up getting passed onto the vm.
+ *    -d32 or -d64 is passed to a binary with an unmatched data model
+ *    (the exec in CreateExecutionEnvironment removes -d<n> options and points the
+ *    exec to the proper binary).  In the case of when the data model and the
+ *    requested version is matched, an exec would not occur, and these options
+ *    were erroneously passed to the vm.
  */
 jboolean
 RemovableOption(char * option)
--- a/jdk/src/share/classes/com/sun/beans/WeakCache.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/com/sun/beans/WeakCache.java	Wed Jul 05 17:04:26 2017 +0200
@@ -81,4 +81,11 @@
             this.map.remove(key);
         }
     }
+
+    /**
+     * Removes all of the mappings from this cache.
+     */
+    public void clear() {
+        this.map.clear();
+    }
 }
--- a/jdk/src/share/classes/com/sun/crypto/provider/HmacCore.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/com/sun/crypto/provider/HmacCore.java	Wed Jul 05 17:04:26 2017 +0200
@@ -36,7 +36,7 @@
 
 /**
  * This class constitutes the core of HMAC-<MD> algorithms, where
- * <MD> can be SHA1 or MD5, etc.
+ * <MD> can be SHA1 or MD5, etc. See RFC 2104 for spec.
  *
  * It also contains the implementation classes for the SHA-256,
  * SHA-384, and SHA-512 HMACs.
@@ -116,7 +116,7 @@
         }
 
         byte[] secret = key.getEncoded();
-        if (secret == null || secret.length == 0) {
+        if (secret == null) {
             throw new InvalidKeyException("Missing key data");
         }
 
--- a/jdk/src/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java	Wed Jul 05 17:04:26 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2005-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,21 +25,19 @@
 
 package com.sun.crypto.provider;
 
-import java.io.*;
+import java.io.ObjectStreamException;
 import java.nio.ByteBuffer;
 import java.nio.CharBuffer;
 import java.nio.charset.Charset;
 import java.util.Arrays;
 import java.security.KeyRep;
 import java.security.GeneralSecurityException;
-import java.security.InvalidKeyException;
 import java.security.NoSuchAlgorithmException;
 import java.security.NoSuchProviderException;
 import java.security.spec.InvalidKeySpecException;
 import javax.crypto.Mac;
 import javax.crypto.SecretKey;
 import javax.crypto.spec.PBEKeySpec;
-import javax.crypto.spec.SecretKeySpec;
 
 /**
  * This class represents a PBE key derived using PBKDF2 defined
@@ -123,7 +121,7 @@
         this.key = deriveKey(prf, passwdBytes, salt, iterCount, keyLength);
     }
 
-    private static byte[] deriveKey(Mac prf, byte[] password, byte[] salt,
+    private static byte[] deriveKey(final Mac prf, final byte[] password, byte[] salt,
                                     int iterCount, int keyLengthInBit) {
         int keyLength = keyLengthInBit/8;
         byte[] key = new byte[keyLength];
@@ -133,7 +131,34 @@
             int intR = keyLength - (intL - 1)*hlen; // residue
             byte[] ui = new byte[hlen];
             byte[] ti = new byte[hlen];
-            SecretKey macKey = new SecretKeySpec(password, prf.getAlgorithm());
+            // SecretKeySpec cannot be used, since password can be empty here.
+            SecretKey macKey = new SecretKey() {
+                @Override
+                public String getAlgorithm() {
+                    return prf.getAlgorithm();
+                }
+                @Override
+                public String getFormat() {
+                    return "RAW";
+                }
+                @Override
+                public byte[] getEncoded() {
+                    return password;
+                }
+                @Override
+                public int hashCode() {
+                    return Arrays.hashCode(password) * 41 +
+                            prf.getAlgorithm().toLowerCase().hashCode();
+                }
+                @Override
+                public boolean equals(Object obj) {
+                    if (this == obj) return true;
+                    if (this.getClass() != obj.getClass()) return false;
+                    SecretKey sk = (SecretKey)obj;
+                    return prf.getAlgorithm().equalsIgnoreCase(sk.getAlgorithm()) &&
+                            Arrays.equals(password, sk.getEncoded());
+                }
+            };
             prf.init(macKey);
 
             byte[] ibytes = new byte[4];
@@ -230,7 +255,7 @@
      * @throws ObjectStreamException if a new object representing
      * this PBE key could not be created
      */
-    private Object writeReplace() throws java.io.ObjectStreamException {
+    private Object writeReplace() throws ObjectStreamException {
             return new KeyRep(KeyRep.Type.SECRET, getAlgorithm(),
                               getFormat(), getEncoded());
     }
--- a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKPainter.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKPainter.java	Wed Jul 05 17:04:26 2017 +0200
@@ -24,7 +24,6 @@
  */
 package com.sun.java.swing.plaf.gtk;
 
-import sun.swing.plaf.synth.SynthUI;
 import sun.awt.UNIXToolkit;
 
 import javax.swing.plaf.synth.*;
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java	Wed Jul 05 17:04:26 2017 +0200
@@ -26,6 +26,7 @@
 package com.sun.jmx.mbeanserver;
 
 import java.lang.annotation.Annotation;
+import java.lang.ref.SoftReference;
 import java.lang.reflect.AnnotatedElement;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
@@ -33,8 +34,13 @@
 import java.lang.reflect.Proxy;
 import java.lang.reflect.UndeclaredThrowableException;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashMap;
+import java.util.List;
+import java.util.LinkedList;
+import java.util.Locale;
 import java.util.Map;
+import java.util.WeakHashMap;
 
 import javax.management.Descriptor;
 import javax.management.DescriptorKey;
@@ -506,11 +512,25 @@
             } else {
                 // Java Beans introspection
                 //
-                BeanInfo bi = java.beans.Introspector.getBeanInfo(complex.getClass());
-                PropertyDescriptor[] pds = bi.getPropertyDescriptors();
-                for (PropertyDescriptor pd : pds)
-                    if (pd.getName().equals(element))
-                        return pd.getReadMethod().invoke(complex);
+                Class<?> clazz = complex.getClass();
+                Method readMethod = null;
+                if (BeansHelper.isAvailable()) {
+                    Object bi = BeansHelper.getBeanInfo(clazz);
+                    Object[] pds = BeansHelper.getPropertyDescriptors(bi);
+                    for (Object pd: pds) {
+                        if (BeansHelper.getPropertyName(pd).equals(element)) {
+                            readMethod = BeansHelper.getReadMethod(pd);
+                            break;
+                        }
+                    }
+                } else {
+                    // Java Beans not available so use simple introspection
+                    // to locate method
+                    readMethod = SimpleIntrospector.getReadMethod(clazz, element);
+                }
+                if (readMethod != null)
+                    return readMethod.invoke(complex);
+
                 throw new AttributeNotFoundException(
                     "Could not find the getter method for the property " +
                     element + " using the Java Beans introspector");
@@ -524,4 +544,235 @@
                 new AttributeNotFoundException(e.getMessage()), e);
         }
     }
+
+    /**
+     * A simple introspector that uses reflection to analyze a class and
+     * identify its "getter" methods. This class is intended for use only when
+     * Java Beans is not present (which implies that there isn't explicit
+     * information about the bean available).
+     */
+    private static class SimpleIntrospector {
+        private SimpleIntrospector() { }
+
+        private static final String GET_METHOD_PREFIX = "get";
+        private static final String IS_METHOD_PREFIX = "is";
+
+        // cache to avoid repeated lookups
+        private static final Map<Class<?>,SoftReference<List<Method>>> cache =
+            Collections.synchronizedMap(
+                new WeakHashMap<Class<?>,SoftReference<List<Method>>> ());
+
+        /**
+         * Returns the list of methods cached for the given class, or {@code null}
+         * if not cached.
+         */
+        private static List<Method> getCachedMethods(Class<?> clazz) {
+            // return cached methods if possible
+            SoftReference<List<Method>> ref = cache.get(clazz);
+            if (ref != null) {
+                List<Method> cached = ref.get();
+                if (cached != null)
+                    return cached;
+            }
+            return null;
+        }
+
+        /**
+         * Returns {@code true} if the given method is a "getter" method (where
+         * "getter" method is a public method of the form getXXX or "boolean
+         * isXXX")
+         */
+        static boolean isReadMethod(Method method) {
+            // ignore static methods
+            int modifiers = method.getModifiers();
+            if (Modifier.isStatic(modifiers))
+                return false;
+
+            String name = method.getName();
+            Class<?>[] paramTypes = method.getParameterTypes();
+            int paramCount = paramTypes.length;
+
+            if (paramCount == 0 && name.length() > 2) {
+                // boolean isXXX()
+                if (name.startsWith(IS_METHOD_PREFIX))
+                    return (method.getReturnType() == boolean.class);
+                // getXXX()
+                if (name.length() > 3 && name.startsWith(GET_METHOD_PREFIX))
+                    return (method.getReturnType() != void.class);
+            }
+            return false;
+        }
+
+        /**
+         * Returns the list of "getter" methods for the given class. The list
+         * is ordered so that isXXX methods appear before getXXX methods - this
+         * is for compatability with the JavaBeans Introspector.
+         */
+        static List<Method> getReadMethods(Class<?> clazz) {
+            // return cached result if available
+            List<Method> cachedResult = getCachedMethods(clazz);
+            if (cachedResult != null)
+                return cachedResult;
+
+            // get list of public methods, filtering out methods that have
+            // been overridden to return a more specific type.
+            List<Method> methods =
+                StandardMBeanIntrospector.getInstance().getMethods(clazz);
+            methods = MBeanAnalyzer.eliminateCovariantMethods(methods);
+
+            // filter out the non-getter methods
+            List<Method> result = new LinkedList<Method>();
+            for (Method m: methods) {
+                if (isReadMethod(m)) {
+                    // favor isXXX over getXXX
+                    if (m.getName().startsWith(IS_METHOD_PREFIX)) {
+                        result.add(0, m);
+                    } else {
+                        result.add(m);
+                    }
+                }
+            }
+
+            // add result to cache
+            cache.put(clazz, new SoftReference<List<Method>>(result));
+
+            return result;
+        }
+
+        /**
+         * Returns the "getter" to read the given property from the given class or
+         * {@code null} if no method is found.
+         */
+        static Method getReadMethod(Class<?> clazz, String property) {
+            // first character in uppercase (compatability with JavaBeans)
+            property = property.substring(0, 1).toUpperCase(Locale.ENGLISH) +
+                property.substring(1);
+            String getMethod = GET_METHOD_PREFIX + property;
+            String isMethod = IS_METHOD_PREFIX + property;
+            for (Method m: getReadMethods(clazz)) {
+                String name = m.getName();
+                if (name.equals(isMethod) || name.equals(getMethod)) {
+                    return m;
+                }
+            }
+            return null;
+        }
+    }
+
+    /**
+     * A class that provides access to the JavaBeans Introspector and
+     * PropertyDescriptors without creating a static dependency on java.beans.
+     */
+    private static class BeansHelper {
+        private static final Class<?> introspectorClass =
+            getClass("java.beans.Introspector");
+        private static final Class<?> beanInfoClass =
+            (introspectorClass == null) ? null : getClass("java.beans.BeanInfo");
+        private static final Class<?> getPropertyDescriptorClass =
+            (beanInfoClass == null) ? null : getClass("java.beans.PropertyDescriptor");
+
+        private static final Method getBeanInfo =
+            getMethod(introspectorClass, "getBeanInfo", Class.class);
+        private static final Method getPropertyDescriptors =
+            getMethod(beanInfoClass, "getPropertyDescriptors");
+        private static final Method getPropertyName =
+            getMethod(getPropertyDescriptorClass, "getName");
+        private static final Method getReadMethod =
+            getMethod(getPropertyDescriptorClass, "getReadMethod");
+
+        private static Class<?> getClass(String name) {
+            try {
+                return Class.forName(name, true, null);
+            } catch (ClassNotFoundException e) {
+                return null;
+            }
+        }
+        private static Method getMethod(Class<?> clazz,
+                                        String name,
+                                        Class<?>... paramTypes)
+        {
+            if (clazz != null) {
+                try {
+                    return clazz.getMethod(name, paramTypes);
+                } catch (NoSuchMethodException e) {
+                    throw new AssertionError(e);
+                }
+            } else {
+                return null;
+            }
+        }
+
+        private BeansHelper() { }
+
+        /**
+         * Returns {@code true} if java.beans is available.
+         */
+        static boolean isAvailable() {
+            return introspectorClass != null;
+        }
+
+        /**
+         * Invokes java.beans.Introspector.getBeanInfo(Class)
+         */
+        static Object getBeanInfo(Class<?> clazz) throws Exception {
+            try {
+                return getBeanInfo.invoke(null, clazz);
+            } catch (InvocationTargetException e) {
+                Throwable cause = e.getCause();
+                if (cause instanceof Exception)
+                    throw (Exception)cause;
+                throw new AssertionError(e);
+            } catch (IllegalAccessException iae) {
+                throw new AssertionError(iae);
+            }
+        }
+
+        /**
+         * Invokes java.beans.BeanInfo.getPropertyDescriptors()
+         */
+        static Object[] getPropertyDescriptors(Object bi) {
+            try {
+                return (Object[])getPropertyDescriptors.invoke(bi);
+            } catch (InvocationTargetException e) {
+                Throwable cause = e.getCause();
+                if (cause instanceof RuntimeException)
+                    throw (RuntimeException)cause;
+                throw new AssertionError(e);
+            } catch (IllegalAccessException iae) {
+                throw new AssertionError(iae);
+            }
+        }
+
+        /**
+         * Invokes java.beans.PropertyDescriptor.getName()
+         */
+        static String getPropertyName(Object pd) {
+            try {
+                return (String)getPropertyName.invoke(pd);
+            } catch (InvocationTargetException e) {
+                Throwable cause = e.getCause();
+                if (cause instanceof RuntimeException)
+                    throw (RuntimeException)cause;
+                throw new AssertionError(e);
+            } catch (IllegalAccessException iae) {
+                throw new AssertionError(iae);
+            }
+        }
+
+        /**
+         * Invokes java.beans.PropertyDescriptor.getReadMethod()
+         */
+        static Method getReadMethod(Object pd) {
+            try {
+                return (Method)getReadMethod.invoke(pd);
+            } catch (InvocationTargetException e) {
+                Throwable cause = e.getCause();
+                if (cause instanceof RuntimeException)
+                    throw (RuntimeException)cause;
+                throw new AssertionError(e);
+            } catch (IllegalAccessException iae) {
+                throw new AssertionError(iae);
+            }
+        }
+    }
 }
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanIntrospector.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanIntrospector.java	Wed Jul 05 17:04:26 2017 +0200
@@ -175,7 +175,7 @@
     /**
      * Get the methods to be analyzed to build the MBean interface.
      */
-    List<Method> getMethods(final Class<?> mbeanType) throws Exception {
+    List<Method> getMethods(final Class<?> mbeanType) {
         return Arrays.asList(mbeanType.getMethods());
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/MidiDeviceReceiver.java	Wed Jul 05 17:04:26 2017 +0200
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.Receiver;
+
+/**
+ * A Receiver with reference to it's MidiDevice object.
+ *
+ * @author Karl Helgason
+ */
+public interface MidiDeviceReceiver extends Receiver {
+
+    /** Obtains the MidiDevice object associated with this Receiver.
+     */
+    public MidiDevice getMidiDevice();
+
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SoftAudioBuffer.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftAudioBuffer.java	Wed Jul 05 17:04:26 2017 +0200
@@ -48,6 +48,30 @@
         converter = AudioFloatConverter.getConverter(format);
     }
 
+    public void swap(SoftAudioBuffer swap)
+    {
+        int bak_size = size;
+        float[] bak_buffer = buffer;
+        boolean bak_empty = empty;
+        AudioFormat bak_format = format;
+        AudioFloatConverter bak_converter = converter;
+        byte[] bak_converter_buffer = converter_buffer;
+
+        size = swap.size;
+        buffer = swap.buffer;
+        empty = swap.empty;
+        format = swap.format;
+        converter = swap.converter;
+        converter_buffer = swap.converter_buffer;
+
+        swap.size = bak_size;
+        swap.buffer = bak_buffer;
+        swap.empty = bak_empty;
+        swap.format = bak_format;
+        swap.converter = bak_converter;
+        swap.converter_buffer = bak_converter_buffer;
+    }
+
     public AudioFormat getFormat() {
         return format;
     }
--- a/jdk/src/share/classes/com/sun/media/sound/SoftChannel.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftChannel.java	Wed Jul 05 17:04:26 2017 +0200
@@ -218,6 +218,15 @@
     }
 
     private int findFreeVoice(int x) {
+        if(x == -1)
+        {
+            // x = -1 means that there where no available voice
+            // last time we called findFreeVoice
+            // and it hasn't changed because no audio has been
+            // rendered in the meantime.
+            // Therefore we have to return -1.
+            return -1;
+        }
         for (int i = x; i < voices.length; i++)
             if (!voices[i].active)
                 return i;
@@ -328,7 +337,7 @@
     }
 
     protected void initVoice(SoftVoice voice, SoftPerformer p, int voiceID,
-            int noteNumber, int velocity, ModelConnectionBlock[] connectionBlocks,
+            int noteNumber, int velocity, int delay, ModelConnectionBlock[] connectionBlocks,
             ModelChannelMixer channelmixer, boolean releaseTriggered) {
         if (voice.active) {
             // Voice is active , we must steal the voice
@@ -363,7 +372,7 @@
         voice.objects.put("midi_cc", co_midi_cc);
         voice.objects.put("midi_rpn", co_midi_rpn);
         voice.objects.put("midi_nrpn", co_midi_nrpn);
-        voice.noteOn(noteNumber, velocity);
+        voice.noteOn(noteNumber, velocity, delay);
         voice.setMute(mute);
         voice.setSoloMute(solomute);
         if (releaseTriggered)
@@ -399,14 +408,21 @@
     }
 
     public void noteOn(int noteNumber, int velocity) {
+        noteOn(noteNumber, velocity, 0);
+    }
+
+    /* A special noteOn with delay parameter, which is used to
+     * start note within control buffers.
+     */
+    protected void noteOn(int noteNumber, int velocity, int delay) {
         noteNumber = restrict7Bit(noteNumber);
         velocity = restrict7Bit(velocity);
-        noteOn_internal(noteNumber, velocity);
+        noteOn_internal(noteNumber, velocity, delay);
         if (current_mixer != null)
             current_mixer.noteOn(noteNumber, velocity);
     }
 
-    private void noteOn_internal(int noteNumber, int velocity) {
+    private void noteOn_internal(int noteNumber, int velocity, int delay) {
 
         if (velocity == 0) {
             noteOff_internal(noteNumber, 64);
@@ -490,6 +506,7 @@
             int tunedKey = (int)(Math.round(tuning.getTuning()[noteNumber]/100.0));
             play_noteNumber = noteNumber;
             play_velocity = velocity;
+            play_delay = delay;
             play_releasetriggered = false;
             lastVelocity[noteNumber] = velocity;
             current_director.noteOn(tunedKey, velocity);
@@ -594,6 +611,7 @@
             play_noteNumber = noteNumber;
             play_velocity = lastVelocity[noteNumber];
             play_releasetriggered = true;
+            play_delay = 0;
             current_director.noteOff(tunedKey, velocity);
 
         }
@@ -604,12 +622,14 @@
     private int voiceNo = 0;
     private int play_noteNumber = 0;
     private int play_velocity = 0;
+    private int play_delay = 0;
     private boolean play_releasetriggered = false;
 
     public void play(int performerIndex, ModelConnectionBlock[] connectionBlocks) {
 
         int noteNumber = play_noteNumber;
         int velocity = play_velocity;
+        int delay = play_delay;
         boolean releasetriggered = play_releasetriggered;
 
         SoftPerformer p = current_instrument.getPerformers()[performerIndex];
@@ -633,7 +653,7 @@
         if (voiceNo == -1)
             return;
 
-        initVoice(voices[voiceNo], p, prevVoiceID, noteNumber, velocity,
+        initVoice(voices[voiceNo], p, prevVoiceID, noteNumber, velocity, delay,
                 connectionBlocks, current_mixer, releasetriggered);
     }
 
--- a/jdk/src/share/classes/com/sun/media/sound/SoftLimiter.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftLimiter.java	Wed Jul 05 17:04:26 2017 +0200
@@ -79,7 +79,7 @@
             if (silentcounter > 60) {
                 if (!mix) {
                     bufferLout.clear();
-                    bufferRout.clear();
+                    if (bufferRout != null) bufferRout.clear();
                 }
                 return;
             }
--- a/jdk/src/share/classes/com/sun/media/sound/SoftMainMixer.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftMainMixer.java	Wed Jul 05 17:04:26 2017 +0200
@@ -26,7 +26,6 @@
 
 import java.io.IOException;
 import java.io.InputStream;
-import java.util.Arrays;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Set;
@@ -46,28 +45,37 @@
  */
 public class SoftMainMixer {
 
+    // A private class thats contains a ModelChannelMixer and it's private buffers.
+    // This becomes necessary when we want to have separate delay buffers for each channel mixer.
+    private class SoftChannelMixerContainer
+    {
+        ModelChannelMixer mixer;
+        SoftAudioBuffer[] buffers;
+    }
+
     public final static int CHANNEL_LEFT = 0;
     public final static int CHANNEL_RIGHT = 1;
     public final static int CHANNEL_MONO = 2;
-    public final static int CHANNEL_EFFECT1 = 3;
-    public final static int CHANNEL_EFFECT2 = 4;
-    public final static int CHANNEL_EFFECT3 = 5;
-    public final static int CHANNEL_EFFECT4 = 6;
+    public final static int CHANNEL_DELAY_LEFT = 3;
+    public final static int CHANNEL_DELAY_RIGHT = 4;
+    public final static int CHANNEL_DELAY_MONO = 5;
+    public final static int CHANNEL_EFFECT1 = 6;
+    public final static int CHANNEL_EFFECT2 = 7;
+    public final static int CHANNEL_DELAY_EFFECT1 = 8;
+    public final static int CHANNEL_DELAY_EFFECT2 = 9;
     public final static int CHANNEL_LEFT_DRY = 10;
     public final static int CHANNEL_RIGHT_DRY = 11;
     public final static int CHANNEL_SCRATCH1 = 12;
     public final static int CHANNEL_SCRATCH2 = 13;
-    public final static int CHANNEL_CHANNELMIXER_LEFT = 14;
-    public final static int CHANNEL_CHANNELMIXER_RIGHT = 15;
-    public final static int CHANNEL_CHANNELMIXER_MONO = 16;
     protected boolean active_sensing_on = false;
     private long msec_last_activity = -1;
     private boolean pusher_silent = false;
     private int pusher_silent_count = 0;
-    private long msec_pos = 0;
+    private long sample_pos = 0;
     protected boolean readfully = true;
     private Object control_mutex;
     private SoftSynthesizer synth;
+    private float samplerate = 44100;
     private int nrofchannels = 2;
     private SoftVoice[] voicestatus = null;
     private SoftAudioBuffer[] buffers;
@@ -75,7 +83,10 @@
     private SoftAudioProcessor chorus;
     private SoftAudioProcessor agc;
     private long msec_buffer_len = 0;
+    private int buffer_len = 0;
     protected TreeMap<Long, Object> midimessages = new TreeMap<Long, Object>();
+    private int delay_midievent = 0;
+    private int max_delay_midievent = 0;
     double last_volume_left = 1.0;
     double last_volume_right = 1.0;
     private double[] co_master_balance = new double[1];
@@ -83,9 +94,9 @@
     private double[] co_master_coarse_tuning = new double[1];
     private double[] co_master_fine_tuning = new double[1];
     private AudioInputStream ais;
-    private Set<ModelChannelMixer> registeredMixers = null;
+    private Set<SoftChannelMixerContainer> registeredMixers = null;
     private Set<ModelChannelMixer> stoppedMixers = null;
-    private ModelChannelMixer[] cur_registeredMixers = null;
+    private SoftChannelMixerContainer[] cur_registeredMixers = null;
     protected SoftControl co_master = new SoftControl() {
 
         double[] balance = co_master_balance;
@@ -413,26 +424,68 @@
         Iterator<Entry<Long, Object>> iter = midimessages.entrySet().iterator();
         while (iter.hasNext()) {
             Entry<Long, Object> entry = iter.next();
-            if (entry.getKey() > (timeStamp + 100))
+            if (entry.getKey() >= (timeStamp + msec_buffer_len))
                 return;
+            long msec_delay = entry.getKey() - timeStamp;
+            delay_midievent = (int)(msec_delay * (samplerate / 1000000.0) + 0.5);
+            if(delay_midievent > max_delay_midievent)
+                delay_midievent = max_delay_midievent;
+            if(delay_midievent < 0)
+                delay_midievent = 0;
             processMessage(entry.getValue());
             iter.remove();
         }
+        delay_midievent = 0;
     }
 
     protected void processAudioBuffers() {
+
+        if(synth.weakstream != null && synth.weakstream.silent_samples != 0)
+        {
+            sample_pos += synth.weakstream.silent_samples;
+            synth.weakstream.silent_samples = 0;
+        }
+
         for (int i = 0; i < buffers.length; i++) {
-            buffers[i].clear();
+            if(i != CHANNEL_DELAY_LEFT &&
+                    i != CHANNEL_DELAY_RIGHT &&
+                    i != CHANNEL_DELAY_MONO &&
+                    i != CHANNEL_DELAY_EFFECT1 &&
+                    i != CHANNEL_DELAY_EFFECT2)
+                buffers[i].clear();
+        }
+
+        if(!buffers[CHANNEL_DELAY_LEFT].isSilent())
+        {
+            buffers[CHANNEL_LEFT].swap(buffers[CHANNEL_DELAY_LEFT]);
+        }
+        if(!buffers[CHANNEL_DELAY_RIGHT].isSilent())
+        {
+            buffers[CHANNEL_RIGHT].swap(buffers[CHANNEL_DELAY_RIGHT]);
+        }
+        if(!buffers[CHANNEL_DELAY_MONO].isSilent())
+        {
+            buffers[CHANNEL_MONO].swap(buffers[CHANNEL_DELAY_MONO]);
+        }
+        if(!buffers[CHANNEL_DELAY_EFFECT1].isSilent())
+        {
+            buffers[CHANNEL_EFFECT1].swap(buffers[CHANNEL_DELAY_EFFECT1]);
+        }
+        if(!buffers[CHANNEL_DELAY_EFFECT2].isSilent())
+        {
+            buffers[CHANNEL_EFFECT2].swap(buffers[CHANNEL_DELAY_EFFECT2]);
         }
 
         double volume_left;
         double volume_right;
 
-        ModelChannelMixer[] act_registeredMixers;
+        SoftChannelMixerContainer[] act_registeredMixers;
 
         // perform control logic
         synchronized (control_mutex) {
 
+            long msec_pos = (long)(sample_pos * (1000000.0 / samplerate));
+
             processMessages(msec_pos);
 
             if (active_sensing_on) {
@@ -450,7 +503,7 @@
             for (int i = 0; i < voicestatus.length; i++)
                 if (voicestatus[i].active)
                     voicestatus[i].processControlLogic();
-            msec_pos += msec_buffer_len;
+            sample_pos += buffer_len;
 
             double volume = co_master_volume[0];
             volume_left = volume;
@@ -469,7 +522,7 @@
             if (cur_registeredMixers == null) {
                 if (registeredMixers != null) {
                     cur_registeredMixers =
-                            new ModelChannelMixer[registeredMixers.size()];
+                            new SoftChannelMixerContainer[registeredMixers.size()];
                     registeredMixers.toArray(cur_registeredMixers);
                 }
             }
@@ -483,44 +536,61 @@
 
         if (act_registeredMixers != null) {
 
-            // Reroute default left,right output
-            // to channelmixer left,right input/output
+            // Make backup of left,right,mono channels
             SoftAudioBuffer leftbak = buffers[CHANNEL_LEFT];
             SoftAudioBuffer rightbak = buffers[CHANNEL_RIGHT];
             SoftAudioBuffer monobak = buffers[CHANNEL_MONO];
-            buffers[CHANNEL_LEFT] = buffers[CHANNEL_CHANNELMIXER_LEFT];
-            buffers[CHANNEL_RIGHT] = buffers[CHANNEL_CHANNELMIXER_RIGHT];
-            buffers[CHANNEL_MONO] = buffers[CHANNEL_CHANNELMIXER_MONO];
+            SoftAudioBuffer delayleftbak = buffers[CHANNEL_DELAY_LEFT];
+            SoftAudioBuffer delayrightbak = buffers[CHANNEL_DELAY_RIGHT];
+            SoftAudioBuffer delaymonobak = buffers[CHANNEL_DELAY_MONO];
 
             int bufferlen = buffers[CHANNEL_LEFT].getSize();
 
             float[][] cbuffer = new float[nrofchannels][];
-            cbuffer[0] = buffers[CHANNEL_LEFT].array();
-            if (nrofchannels != 1)
-                cbuffer[1] = buffers[CHANNEL_RIGHT].array();
-
             float[][] obuffer = new float[nrofchannels][];
             obuffer[0] = leftbak.array();
             if (nrofchannels != 1)
                 obuffer[1] = rightbak.array();
 
-            for (ModelChannelMixer cmixer : act_registeredMixers) {
-                for (int i = 0; i < cbuffer.length; i++)
-                    Arrays.fill(cbuffer[i], 0);
+            for (SoftChannelMixerContainer cmixer : act_registeredMixers) {
+
+                // Reroute default left,right output
+                // to channelmixer left,right input/output
+                buffers[CHANNEL_LEFT] =  cmixer.buffers[CHANNEL_LEFT];
+                buffers[CHANNEL_RIGHT] = cmixer.buffers[CHANNEL_RIGHT];
+                buffers[CHANNEL_MONO] = cmixer.buffers[CHANNEL_MONO];
+                buffers[CHANNEL_DELAY_LEFT] = cmixer.buffers[CHANNEL_DELAY_LEFT];
+                buffers[CHANNEL_DELAY_RIGHT] = cmixer.buffers[CHANNEL_DELAY_RIGHT];
+                buffers[CHANNEL_DELAY_MONO] = cmixer.buffers[CHANNEL_DELAY_MONO];
+
+                buffers[CHANNEL_LEFT].clear();
+                buffers[CHANNEL_RIGHT].clear();
                 buffers[CHANNEL_MONO].clear();
+
+                if(!buffers[CHANNEL_DELAY_LEFT].isSilent())
+                {
+                    buffers[CHANNEL_LEFT].swap(buffers[CHANNEL_DELAY_LEFT]);
+                }
+                if(!buffers[CHANNEL_DELAY_RIGHT].isSilent())
+                {
+                    buffers[CHANNEL_RIGHT].swap(buffers[CHANNEL_DELAY_RIGHT]);
+                }
+                if(!buffers[CHANNEL_DELAY_MONO].isSilent())
+                {
+                    buffers[CHANNEL_MONO].swap(buffers[CHANNEL_DELAY_MONO]);
+                }
+
+                cbuffer[0] = buffers[CHANNEL_LEFT].array();
+                if (nrofchannels != 1)
+                    cbuffer[1] = buffers[CHANNEL_RIGHT].array();
+
                 boolean hasactivevoices = false;
                 for (int i = 0; i < voicestatus.length; i++)
                     if (voicestatus[i].active)
-                        if (voicestatus[i].channelmixer == cmixer) {
+                        if (voicestatus[i].channelmixer == cmixer.mixer) {
                             voicestatus[i].processAudioLogic(buffers);
                             hasactivevoices = true;
                         }
-                if (!cmixer.process(cbuffer, 0, bufferlen)) {
-                    synchronized (control_mutex) {
-                        registeredMixers.remove(cmixer);
-                        cur_registeredMixers = null;
-                    }
-                }
 
                 if(!buffers[CHANNEL_MONO].isSilent())
                 {
@@ -542,6 +612,13 @@
                     }
                 }
 
+                if (!cmixer.mixer.process(cbuffer, 0, bufferlen)) {
+                    synchronized (control_mutex) {
+                        registeredMixers.remove(cmixer);
+                        cur_registeredMixers = null;
+                    }
+                }
+
                 for (int i = 0; i < cbuffer.length; i++) {
                     float[] cbuff = cbuffer[i];
                     float[] obuff = obuffer[i];
@@ -554,7 +631,7 @@
                         if (stoppedMixers != null) {
                             if (stoppedMixers.contains(cmixer)) {
                                 stoppedMixers.remove(cmixer);
-                                cmixer.stop();
+                                cmixer.mixer.stop();
                             }
                         }
                     }
@@ -565,6 +642,9 @@
             buffers[CHANNEL_LEFT] = leftbak;
             buffers[CHANNEL_RIGHT] = rightbak;
             buffers[CHANNEL_MONO] = monobak;
+            buffers[CHANNEL_DELAY_LEFT] = delayleftbak;
+            buffers[CHANNEL_DELAY_RIGHT] = delayrightbak;
+            buffers[CHANNEL_DELAY_MONO] = delaymonobak;
 
         }
 
@@ -650,14 +730,23 @@
         if(buffers[CHANNEL_LEFT].isSilent()
             && buffers[CHANNEL_RIGHT].isSilent())
         {
-            pusher_silent_count++;
-            if(pusher_silent_count > 5)
+
+            int midimessages_size;
+            synchronized (control_mutex) {
+                midimessages_size = midimessages.size();
+            }
+
+            if(midimessages_size == 0)
             {
-                pusher_silent_count = 0;
-                synchronized (control_mutex) {
-                    pusher_silent = true;
-                    if(synth.weakstream != null)
-                        synth.weakstream.setInputStream(null);
+                pusher_silent_count++;
+                if(pusher_silent_count > 5)
+                {
+                    pusher_silent_count = 0;
+                    synchronized (control_mutex) {
+                        pusher_silent = true;
+                        if(synth.weakstream != null)
+                            synth.weakstream.setInputStream(null);
+                    }
                 }
             }
         }
@@ -672,13 +761,18 @@
     // Must only we called within control_mutex synchronization
     public void activity()
     {
-        msec_last_activity = msec_pos;
+        long silent_samples = 0;
         if(pusher_silent)
         {
             pusher_silent = false;
             if(synth.weakstream != null)
+            {
                 synth.weakstream.setInputStream(ais);
+                silent_samples = synth.weakstream.silent_samples;
+            }
         }
+        msec_last_activity = (long)((sample_pos + silent_samples)
+                * (1000000.0 / samplerate));
     }
 
     public void stopMixer(ModelChannelMixer mixer) {
@@ -689,15 +783,22 @@
 
     public void registerMixer(ModelChannelMixer mixer) {
         if (registeredMixers == null)
-            registeredMixers = new HashSet<ModelChannelMixer>();
-        registeredMixers.add(mixer);
+            registeredMixers = new HashSet<SoftChannelMixerContainer>();
+        SoftChannelMixerContainer mixercontainer = new SoftChannelMixerContainer();
+        mixercontainer.buffers = new SoftAudioBuffer[6];
+        for (int i = 0; i < mixercontainer.buffers.length; i++) {
+            mixercontainer.buffers[i] =
+                new SoftAudioBuffer(buffer_len, synth.getFormat());
+        }
+        mixercontainer.mixer = mixer;
+        registeredMixers.add(mixercontainer);
         cur_registeredMixers = null;
     }
 
     public SoftMainMixer(SoftSynthesizer synth) {
         this.synth = synth;
 
-        msec_pos = 0;
+        sample_pos = 0;
 
         co_master_balance[0] = 0.5;
         co_master_volume[0] = 1;
@@ -705,14 +806,18 @@
         co_master_fine_tuning[0] = 0.5;
 
         msec_buffer_len = (long) (1000000.0 / synth.getControlRate());
-
+        samplerate = synth.getFormat().getSampleRate();
         nrofchannels = synth.getFormat().getChannels();
 
         int buffersize = (int) (synth.getFormat().getSampleRate()
                                 / synth.getControlRate());
 
+        buffer_len = buffersize;
+
+        max_delay_midievent = buffersize;
+
         control_mutex = synth.control_mutex;
-        buffers = new SoftAudioBuffer[17];
+        buffers = new SoftAudioBuffer[14];
         for (int i = 0; i < buffers.length; i++) {
             buffers[i] = new SoftAudioBuffer(buffersize, synth.getFormat());
         }
@@ -994,7 +1099,10 @@
 
         switch (cmd) {
         case ShortMessage.NOTE_ON:
-            softchannel.noteOn(data1, data2);
+            if(delay_midievent != 0)
+                softchannel.noteOn(data1, data2, delay_midievent);
+            else
+                softchannel.noteOn(data1, data2);
             break;
         case ShortMessage.NOTE_OFF:
             softchannel.noteOff(data1, data2);
@@ -1021,7 +1129,15 @@
     }
 
     public long getMicrosecondPosition() {
-        return msec_pos;
+        if(pusher_silent)
+        {
+            if(synth.weakstream != null)
+            {
+                return (long)((sample_pos  + synth.weakstream.silent_samples)
+                        * (1000000.0 / samplerate));
+            }
+        }
+        return (long)(sample_pos * (1000000.0 / samplerate));
     }
 
     public void close() {
--- a/jdk/src/share/classes/com/sun/media/sound/SoftReceiver.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftReceiver.java	Wed Jul 05 17:04:26 2017 +0200
@@ -26,8 +26,8 @@
 
 import java.util.TreeMap;
 
+import javax.sound.midi.MidiDevice;
 import javax.sound.midi.MidiMessage;
-import javax.sound.midi.Receiver;
 import javax.sound.midi.ShortMessage;
 
 /**
@@ -35,7 +35,7 @@
  *
  * @author Karl Helgason
  */
-public class SoftReceiver implements Receiver {
+public class SoftReceiver implements MidiDeviceReceiver {
 
     protected boolean open = true;
     private Object control_mutex;
@@ -51,6 +51,10 @@
             this.midimessages = mainmixer.midimessages;
     }
 
+    public MidiDevice getMidiDevice() {
+        return synth;
+    }
+
     public void send(MidiMessage message, long timeStamp) {
 
         synchronized (control_mutex) {
@@ -60,6 +64,7 @@
 
         if (timeStamp != -1) {
             synchronized (control_mutex) {
+                mainmixer.activity();
                 while (midimessages.get(timeStamp) != null)
                     timeStamp++;
                 if (message instanceof ShortMessage
--- a/jdk/src/share/classes/com/sun/media/sound/SoftSynthesizer.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftSynthesizer.java	Wed Jul 05 17:04:26 2017 +0200
@@ -66,6 +66,8 @@
         public SoftAudioPusher pusher = null;
         public AudioInputStream jitter_stream = null;
         public SourceDataLine sourceDataLine = null;
+        public volatile long silent_samples = 0;
+        private int framesize = 0;
         private WeakReference<AudioInputStream> weak_stream_link;
         private AudioFloatConverter converter;
         private float[] silentbuffer = null;
@@ -101,6 +103,8 @@
                      silentbuffer = new float[flen];
                  converter.toByteArray(silentbuffer, flen, b, off);
 
+                 silent_samples += (long)((len / framesize));
+
                  if(pusher != null)
                  if(weak_stream_link.get() == null)
                  {
@@ -136,6 +140,7 @@
             weak_stream_link = new WeakReference<AudioInputStream>(stream);
             converter = AudioFloatConverter.getConverter(stream.getFormat());
             samplesize = stream.getFormat().getFrameSize() / stream.getFormat().getChannels();
+            framesize = stream.getFormat().getFrameSize();
         }
 
         public AudioInputStream getAudioInputStream()
--- a/jdk/src/share/classes/com/sun/media/sound/SoftVoice.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftVoice.java	Wed Jul 05 17:04:26 2017 +0200
@@ -43,6 +43,7 @@
     private int noteOn_noteNumber = 0;
     private int noteOn_velocity = 0;
     private int noteOff_velocity = 0;
+    private int delay = 0;
     protected ModelChannelMixer channelmixer = null;
     protected double tunedKey = 0;
     protected SoftTuning tuning = null;
@@ -294,7 +295,7 @@
         tunedKey = tuning.getTuning(noteNumber) / 100.0;
     }
 
-    protected void noteOn(int noteNumber, int velocity) {
+    protected void noteOn(int noteNumber, int velocity, int delay) {
 
         sustain = false;
         sostenuto = false;
@@ -308,6 +309,7 @@
 
         noteOn_noteNumber = noteNumber;
         noteOn_velocity = velocity;
+        this.delay = delay;
 
         lastMuteValue = 0;
         lastSoloMuteValue = 0;
@@ -562,7 +564,7 @@
 
             if (stealer_channel != null) {
                 stealer_channel.initVoice(this, stealer_performer,
-                        stealer_voiceID, stealer_noteNumber, stealer_velocity,
+                        stealer_voiceID, stealer_noteNumber, stealer_velocity, 0,
                         stealer_extendedConnectionBlocks, stealer_channelmixer,
                         stealer_releaseTriggered);
                 stealer_releaseTriggered = false;
@@ -733,23 +735,55 @@
     }
 
     protected void mixAudioStream(SoftAudioBuffer in, SoftAudioBuffer out,
+            SoftAudioBuffer dout,
             float amp_from, float amp_to) {
         int bufferlen = in.getSize();
         if (amp_from < 0.000000001 && amp_to < 0.000000001)
             return;
-        if (amp_from == amp_to) {
-            float[] fout = out.array();
-            float[] fin = in.array();
-            for (int i = 0; i < bufferlen; i++)
-                fout[i] += fin[i] * amp_to;
-        } else {
-            float amp = amp_from;
-            float amp_delta = (amp_to - amp_from) / bufferlen;
-            float[] fout = out.array();
-            float[] fin = in.array();
-            for (int i = 0; i < bufferlen; i++) {
-                amp += amp_delta;
-                fout[i] += fin[i] * amp;
+        if(dout != null && delay != 0)
+        {
+            if (amp_from == amp_to) {
+                float[] fout = out.array();
+                float[] fin = in.array();
+                int j = 0;
+                for (int i = delay; i < bufferlen; i++)
+                    fout[i] += fin[j++] * amp_to;
+                fout = dout.array();
+                for (int i = 0; i < delay; i++)
+                    fout[i] += fin[j++] * amp_to;
+            } else {
+                float amp = amp_from;
+                float amp_delta = (amp_to - amp_from) / bufferlen;
+                float[] fout = out.array();
+                float[] fin = in.array();
+                int j = 0;
+                for (int i = delay; i < bufferlen; i++) {
+                    amp += amp_delta;
+                    fout[i] += fin[j++] * amp;
+                }
+                fout = dout.array();
+                for (int i = 0; i < delay; i++) {
+                    amp += amp_delta;
+                    fout[i] += fin[j++] * amp;
+                }
+            }
+        }
+        else
+        {
+            if (amp_from == amp_to) {
+                float[] fout = out.array();
+                float[] fin = in.array();
+                for (int i = 0; i < bufferlen; i++)
+                    fout[i] += fin[i] * amp_to;
+            } else {
+                float amp = amp_from;
+                float amp_delta = (amp_to - amp_from) / bufferlen;
+                float[] fout = out.array();
+                float[] fin = in.array();
+                for (int i = 0; i < bufferlen; i++) {
+                    amp += amp_delta;
+                    fout[i] += fin[i] * amp;
+                }
             }
         }
 
@@ -785,6 +819,13 @@
         SoftAudioBuffer mono = buffer[SoftMainMixer.CHANNEL_MONO];
         SoftAudioBuffer eff1 = buffer[SoftMainMixer.CHANNEL_EFFECT1];
         SoftAudioBuffer eff2 = buffer[SoftMainMixer.CHANNEL_EFFECT2];
+
+        SoftAudioBuffer dleft = buffer[SoftMainMixer.CHANNEL_DELAY_LEFT];
+        SoftAudioBuffer dright = buffer[SoftMainMixer.CHANNEL_DELAY_RIGHT];
+        SoftAudioBuffer dmono = buffer[SoftMainMixer.CHANNEL_DELAY_MONO];
+        SoftAudioBuffer deff1 = buffer[SoftMainMixer.CHANNEL_DELAY_EFFECT1];
+        SoftAudioBuffer deff2 = buffer[SoftMainMixer.CHANNEL_DELAY_EFFECT2];
+
         SoftAudioBuffer leftdry = buffer[SoftMainMixer.CHANNEL_LEFT_DRY];
         SoftAudioBuffer rightdry = buffer[SoftMainMixer.CHANNEL_RIGHT_DRY];
 
@@ -799,42 +840,42 @@
 
         if (nrofchannels == 1) {
             out_mixer_left = (out_mixer_left + out_mixer_right) / 2;
-            mixAudioStream(leftdry, left, last_out_mixer_left, out_mixer_left);
+            mixAudioStream(leftdry, left, dleft, last_out_mixer_left, out_mixer_left);
             if (rightdry != null)
-                mixAudioStream(rightdry, left, last_out_mixer_left,
+                mixAudioStream(rightdry, left, dleft, last_out_mixer_left,
                         out_mixer_left);
         } else {
             if(rightdry == null &&
                     last_out_mixer_left == last_out_mixer_right &&
                     out_mixer_left == out_mixer_right)
             {
-                mixAudioStream(leftdry, mono, last_out_mixer_left, out_mixer_left);
+                mixAudioStream(leftdry, mono, dmono, last_out_mixer_left, out_mixer_left);
             }
             else
             {
-                mixAudioStream(leftdry, left, last_out_mixer_left, out_mixer_left);
+                mixAudioStream(leftdry, left, dleft, last_out_mixer_left, out_mixer_left);
                 if (rightdry != null)
-                    mixAudioStream(rightdry, right, last_out_mixer_right,
+                    mixAudioStream(rightdry, right, dright, last_out_mixer_right,
                         out_mixer_right);
                 else
-                    mixAudioStream(leftdry, right, last_out_mixer_right,
+                    mixAudioStream(leftdry, right, dright, last_out_mixer_right,
                         out_mixer_right);
             }
         }
 
         if (rightdry == null) {
-            mixAudioStream(leftdry, eff1, last_out_mixer_effect1,
+            mixAudioStream(leftdry, eff1, deff1, last_out_mixer_effect1,
                     out_mixer_effect1);
-            mixAudioStream(leftdry, eff2, last_out_mixer_effect2,
+            mixAudioStream(leftdry, eff2, deff2, last_out_mixer_effect2,
                     out_mixer_effect2);
         } else {
-            mixAudioStream(leftdry, eff1, last_out_mixer_effect1 * 0.5f,
+            mixAudioStream(leftdry, eff1, deff1, last_out_mixer_effect1 * 0.5f,
                     out_mixer_effect1 * 0.5f);
-            mixAudioStream(leftdry, eff2, last_out_mixer_effect2 * 0.5f,
+            mixAudioStream(leftdry, eff2, deff2, last_out_mixer_effect2 * 0.5f,
                     out_mixer_effect2 * 0.5f);
-            mixAudioStream(rightdry, eff1, last_out_mixer_effect1 * 0.5f,
+            mixAudioStream(rightdry, eff1, deff1, last_out_mixer_effect1 * 0.5f,
                     out_mixer_effect1 * 0.5f);
-            mixAudioStream(rightdry, eff2, last_out_mixer_effect2 * 0.5f,
+            mixAudioStream(rightdry, eff2, deff2, last_out_mixer_effect2 * 0.5f,
                     out_mixer_effect2 * 0.5f);
         }
 
--- a/jdk/src/share/classes/com/sun/security/auth/PolicyFile.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/com/sun/security/auth/PolicyFile.java	Wed Jul 05 17:04:26 2017 +0200
@@ -34,8 +34,6 @@
 
 import java.security.AccessController;
 import java.security.CodeSource;
-import java.security.Identity;
-import java.security.IdentityScope;
 import java.security.KeyStore;
 import java.security.KeyStoreException;
 import java.security.Permission;
@@ -267,7 +265,7 @@
     private boolean initialized = false;
 
     private boolean expandProperties = true;
-    private boolean ignoreIdentityScope = false;
+    private boolean ignoreIdentityScope = true;
 
     // for use with the reflection API
 
@@ -459,9 +457,6 @@
         }
     }
 
-    /** the scope to check */
-    private static IdentityScope scope = null;
-
     /**
      * Checks public key. If it is marked as trusted in
      * the identity database, add it to the policy
--- a/jdk/src/share/classes/com/sun/security/jgss/ExtendedGSSContext.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/com/sun/security/jgss/ExtendedGSSContext.java	Wed Jul 05 17:04:26 2017 +0200
@@ -99,4 +99,58 @@
      */
     public Object inquireSecContext(InquireType type)
             throws GSSException;
+
+    /**
+     * Requests that the delegation policy be respected. When a true value is
+     * requested, the underlying context would use the delegation policy
+     * defined by the environment as a hint to determine whether credentials
+     * delegation should be performed. This request can only be made on the
+     * context initiator's side and it has to be done prior to the first
+     * call to <code>initSecContext</code>.
+     * <p>
+     * When this flag is false, delegation will only be tried when the
+     * {@link GSSContext#requestCredDeleg(boolean) credentials delegation flag}
+     * is true.
+     * <p>
+     * When this flag is true but the
+     * {@link GSSContext#requestCredDeleg(boolean) credentials delegation flag}
+     * is false, delegation will be only tried if the delegation policy permits
+     * delegation.
+     * <p>
+     * When both this flag and the
+     * {@link GSSContext#requestCredDeleg(boolean) credentials delegation flag}
+     * are true, delegation will be always tried. However, if the delegation
+     * policy does not permit delegation, the value of
+     * {@link #getDelegPolicyState} will be false, even
+     * if delegation is performed successfully.
+     * <p>
+     * In any case, if the delegation is not successful, the value returned
+     * by {@link GSSContext#getCredDelegState()} is false, and the value
+     * returned by {@link #getDelegPolicyState()} is also false.
+     * <p>
+     * Not all mechanisms support delegation policy. Therefore, the
+     * application should check to see if the request was honored with the
+     * {@link #getDelegPolicyState() getDelegPolicyState} method. When
+     * delegation policy is not supported, <code>requestDelegPolicy</code>
+     * should return silently without throwing an exception.
+     * <p>
+     * Note: for the Kerberos 5 mechanism, the delegation policy is expressed
+     * through the OK-AS-DELEGATE flag in the service ticket. When it's true,
+     * the KDC permits delegation to the target server. In a cross-realm
+     * environment, in order for delegation be permitted, all cross-realm TGTs
+     * on the authentication path must also have the OK-AS-DELAGATE flags set.
+     * @param state true if the policy should be respected
+     * @throws GSSException containing the following
+     * major error codes:
+     *   {@link GSSException#FAILURE GSSException.FAILURE}
+     */
+    public void requestDelegPolicy(boolean state) throws GSSException;
+
+    /**
+     * Returns the delegation policy response. Called after a security context
+     * is established. This method can be only called on the initiator's side.
+     * See {@link ExtendedGSSContext#requestDelegPolicy}.
+     * @return the delegation policy response
+     */
+    public boolean getDelegPolicyState();
 }
--- a/jdk/src/share/classes/com/sun/tools/hat/internal/model/JavaStatic.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/com/sun/tools/hat/internal/model/JavaStatic.java	Wed Jul 05 17:04:26 2017 +0200
@@ -57,7 +57,10 @@
             id = ((JavaObjectRef)value).getId();
         }
         value = value.dereference(snapshot, field);
-        if (value.isHeapAllocated()) {
+        if (value.isHeapAllocated() &&
+            clazz.getLoader() == snapshot.getNullThing()) {
+            // static fields are only roots if they are in classes
+            //    loaded by the root classloader.
             JavaHeapObject ho = (JavaHeapObject) value;
             String s = "Static reference from " + clazz.getName()
                        + "." + field.getName();
--- a/jdk/src/share/classes/com/sun/tracing/ProviderFactory.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/com/sun/tracing/ProviderFactory.java	Wed Jul 05 17:04:26 2017 +0200
@@ -4,7 +4,10 @@
 import java.util.HashSet;
 import java.io.PrintStream;
 import java.lang.reflect.Field;
-import java.util.logging.Logger;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import sun.security.action.GetPropertyAction;
 
 import sun.tracing.NullProviderFactory;
 import sun.tracing.PrintStreamProviderFactory;
@@ -52,23 +55,17 @@
         HashSet<ProviderFactory> factories = new HashSet<ProviderFactory>();
 
         // Try to instantiate a DTraceProviderFactory
-        String prop = null;
-        try { prop = System.getProperty("com.sun.tracing.dtrace"); }
-        catch (java.security.AccessControlException e) {
-            Logger.getAnonymousLogger().fine(
-                "Cannot access property com.sun.tracing.dtrace");
-        }
+        String prop = AccessController.doPrivileged(
+            new GetPropertyAction("com.sun.tracing.dtrace"));
+
         if ( (prop == null || !prop.equals("disable")) &&
              DTraceProviderFactory.isSupported() ) {
             factories.add(new DTraceProviderFactory());
         }
 
         // Try to instantiate an output stream factory
-        try { prop = System.getProperty("sun.tracing.stream"); }
-        catch (java.security.AccessControlException e) {
-            Logger.getAnonymousLogger().fine(
-                "Cannot access property sun.tracing.stream");
-        }
+        prop = AccessController.doPrivileged(
+            new GetPropertyAction("sun.tracing.stream"));
         if (prop != null) {
             for (String spec : prop.split(",")) {
                 PrintStream ps = getPrintStreamFromSpec(spec);
@@ -89,22 +86,29 @@
         }
     }
 
-    private static PrintStream getPrintStreamFromSpec(String spec) {
+    private static PrintStream getPrintStreamFromSpec(final String spec) {
         try {
             // spec is in the form of <class>.<field>, where <class> is
             // a fully specified class name, and <field> is a static member
             // in that class.  The <field> must be a 'PrintStream' or subtype
             // in order to be used.
-            int fieldpos = spec.lastIndexOf('.');
-            Class<?> cls = Class.forName(spec.substring(0, fieldpos));
-            Field f = cls.getField(spec.substring(fieldpos + 1));
-            Class<?> fieldType = f.getType();
+            final int fieldpos = spec.lastIndexOf('.');
+            final Class<?> cls = Class.forName(spec.substring(0, fieldpos));
+
+            Field f = AccessController.doPrivileged(new PrivilegedExceptionAction<Field>() {
+                public Field run() throws NoSuchFieldException {
+                    return cls.getField(spec.substring(fieldpos + 1));
+                }
+            });
+
             return (PrintStream)f.get(null);
-        } catch (Exception e) {
-            Logger.getAnonymousLogger().warning(
-                "Could not parse sun.tracing.stream property: " + e);
+        } catch (ClassNotFoundException e) {
+            throw new AssertionError(e);
+        } catch (IllegalAccessException e) {
+            throw new AssertionError(e);
+        } catch (PrivilegedActionException e) {
+            throw new AssertionError(e);
         }
-        return null;
     }
 }
 
--- a/jdk/src/share/classes/java/awt/Component.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/java/awt/Component.java	Wed Jul 05 17:04:26 2017 +0200
@@ -871,7 +871,7 @@
                 return comp.canBeFocusOwner();
             }
 
-            public boolean isVisible_NoClientCode(Component comp) {
+            public boolean isVisible(Component comp) {
                 return comp.isVisible_NoClientCode();
             }
             public void setRequestFocusController
@@ -885,6 +885,71 @@
             public void setAppContext(Component comp, AppContext appContext) {
                  comp.appContext = appContext;
             }
+            public Container getParent(Component comp) {
+                return comp.getParent_NoClientCode();
+            }
+            public void setParent(Component comp, Container parent) {
+                comp.parent = parent;
+            }
+            public void setSize(Component comp, int width, int height) {
+                comp.width = width;
+                comp.height = height;
+            }
+            public Point getLocation(Component comp) {
+                return comp.location_NoClientCode();
+            }
+            public void setLocation(Component comp, int x, int y) {
+                comp.x = x;
+                comp.y = y;
+            }
+            public boolean isEnabled(Component comp) {
+                return comp.isEnabledImpl();
+            }
+            public boolean isDisplayable(Component comp) {
+                return comp.peer != null;
+            }
+            public Cursor getCursor(Component comp) {
+                return comp.getCursor_NoClientCode();
+            }
+            public ComponentPeer getPeer(Component comp) {
+                return comp.peer;
+            }
+            public void setPeer(Component comp, ComponentPeer peer) {
+                comp.peer = peer;
+            }
+            public boolean isLightweight(Component comp) {
+                return (comp.peer instanceof LightweightPeer);
+            }
+            public boolean getIgnoreRepaint(Component comp) {
+                return comp.ignoreRepaint;
+            }
+            public int getWidth(Component comp) {
+                return comp.width;
+            }
+            public int getHeight(Component comp) {
+                return comp.height;
+            }
+            public int getX(Component comp) {
+                return comp.x;
+            }
+            public int getY(Component comp) {
+                return comp.y;
+            }
+            public Color getForeground(Component comp) {
+                return comp.foreground;
+            }
+            public Color getBackground(Component comp) {
+                return comp.background;
+            }
+            public void setBackground(Component comp, Color background) {
+                comp.background = background;
+            }
+            public Font getFont(Component comp) {
+                return comp.getFont_NoClientCode();
+            }
+            public void processEvent(Component comp, AWTEvent e) {
+                comp.processEvent(e);
+            }
         });
     }
 
@@ -8021,7 +8086,7 @@
     Container getNativeContainer() {
         Container p = parent;
         while (p != null && p.peer instanceof LightweightPeer) {
-            p = p.getParent();
+            p = p.getParent_NoClientCode();
         }
         return p;
     }
--- a/jdk/src/share/classes/java/awt/EventDispatchThread.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/java/awt/EventDispatchThread.java	Wed Jul 05 17:04:26 2017 +0200
@@ -104,11 +104,8 @@
         } else {
             stopEvent.dispatch();
         }
-        synchronized (theQueue) {
-            if (theQueue.getDispatchThread() == this) {
-                theQueue.detachDispatchThread();
-            }
-        }
+
+        theQueue.detachDispatchThread(this, false);
     }
 
     public void stopDispatching() {
@@ -142,35 +139,7 @@
                 }
             });
         } finally {
-            /*
-             * This synchronized block is to secure that the event dispatch
-             * thread won't die in the middle of posting a new event to the
-             * associated event queue. It is important because we notify
-             * that the event dispatch thread is busy after posting a new event
-             * to its queue, so the EventQueue.dispatchThread reference must
-             * be valid at that point.
-             */
-            synchronized (theQueue) {
-                if (theQueue.getDispatchThread() == this) {
-                    theQueue.detachDispatchThread();
-                }
-                /*
-                 * Event dispatch thread dies in case of an uncaught exception.
-                 * A new event dispatch thread for this queue will be started
-                 * only if a new event is posted to it. In case if no more
-                 * events are posted after this thread died all events that
-                 * currently are in the queue will never be dispatched.
-                 */
-                /*
-                 * Fix for 4648733. Check both the associated java event
-                 * queue and the PostEventQueue.
-                 */
-                if (theQueue.peekEvent() != null ||
-                    !SunToolkit.isPostEventQueueEmpty()) {
-                    theQueue.initDispatchThread();
-                }
-                AWTAutoShutdown.getInstance().notifyThreadFree(this);
-            }
+            theQueue.detachDispatchThread(this, true);
         }
     }
 
--- a/jdk/src/share/classes/java/awt/EventQueue.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/java/awt/EventQueue.java	Wed Jul 05 17:04:26 2017 +0200
@@ -45,6 +45,9 @@
 import sun.awt.EventQueueItem;
 import sun.awt.AWTAccessor;
 
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+
 /**
  * <code>EventQueue</code> is a platform-independent class
  * that queues events, both from the underlying peer classes
@@ -127,6 +130,14 @@
      */
     private EventQueue previousQueue;
 
+    /*
+     * A single lock to synchronize the push()/pop() and related operations with
+     * all the EventQueues from the AppContext. Synchronization on any particular
+     * event queue(s) is not enough: we should lock the whole stack.
+     */
+    private final Lock pushPopLock;
+    private final Condition pushPopCond;
+
     private EventDispatchThread dispatchThread;
 
     private final ThreadGroup threadGroup =
@@ -158,11 +169,11 @@
     static {
         AWTAccessor.setEventQueueAccessor(
             new AWTAccessor.EventQueueAccessor() {
-                public EventQueue getNextQueue(EventQueue eventQueue) {
-                    return eventQueue.nextQueue;
+                public Thread getDispatchThread(EventQueue eventQueue) {
+                    return eventQueue.getDispatchThread();
                 }
-                public Thread getDispatchThread(EventQueue eventQueue) {
-                    return eventQueue.dispatchThread;
+                public boolean isDispatchThreadImpl(EventQueue eventQueue) {
+                    return eventQueue.isDispatchThreadImpl();
                 }
             });
     }
@@ -179,6 +190,9 @@
          * may call AppContext.getAppContext() before createNewAppContext()
          * completes thus causing mess in thread group to appcontext mapping.
          */
+
+        pushPopLock = (Lock)AppContext.getAppContext().get(AppContext.EVENT_QUEUE_LOCK_KEY);
+        pushPopCond = (Condition)AppContext.getAppContext().get(AppContext.EVENT_QUEUE_COND_KEY);
     }
 
     /**
@@ -207,7 +221,8 @@
      */
     final void postEventPrivate(AWTEvent theEvent) {
         theEvent.isPosted = true;
-        synchronized(this) {
+        pushPopLock.lock();
+        try {
             if (dispatchThread == null && nextQueue == null) {
                 if (theEvent.getSource() == AWTAutoShutdown.getInstance()) {
                     return;
@@ -221,6 +236,8 @@
                 return;
             }
             postEvent(theEvent, getPriority(theEvent));
+        } finally {
+            pushPopLock.unlock();
         }
     }
 
@@ -280,9 +297,9 @@
                 if (theEvent.getSource() != AWTAutoShutdown.getInstance()) {
                     AWTAutoShutdown.getInstance().notifyThreadBusy(dispatchThread);
                 }
-                notifyAll();
+                pushPopCond.signalAll();
             } else if (notifyID) {
-                notifyAll();
+                pushPopCond.signalAll();
             }
         } else {
             // The event was not coalesced or has non-Component source.
@@ -290,7 +307,7 @@
             queues[priority].tail.next = newItem;
             queues[priority].tail = newItem;
             if (notifyID) {
-                notifyAll();
+                pushPopCond.signalAll();
             }
         }
     }
@@ -482,7 +499,8 @@
              * event queues are nested with push()/pop().
              */
             SunToolkit.flushPendingEvents();
-            synchronized (this) {
+            pushPopLock.lock();
+            try {
                 for (int i = NUM_PRIORITIES - 1; i >= 0; i--) {
                     if (queues[i].head != null) {
                         EventQueueItem entry = queues[i].head;
@@ -495,7 +513,9 @@
                     }
                 }
                 AWTAutoShutdown.getInstance().notifyThreadFree(dispatchThread);
-                wait();
+                pushPopCond.await();
+            } finally {
+                pushPopLock.unlock();
             }
         } while(true);
     }
@@ -508,7 +528,8 @@
              * event queues are nested with push()/pop().
              */
             SunToolkit.flushPendingEvents();
-            synchronized (this) {
+            pushPopLock.lock();
+            try {
                 for (int i = 0; i < NUM_PRIORITIES; i++) {
                     for (EventQueueItem entry = queues[i].head, prev = null;
                          entry != null; prev = entry, entry = entry.next)
@@ -527,9 +548,11 @@
                         }
                     }
                 }
-                this.waitForID = id;
-                wait();
-                this.waitForID = 0;
+                waitForID = id;
+                pushPopCond.await();
+                waitForID = 0;
+            } finally {
+                pushPopLock.unlock();
             }
         } while(true);
     }
@@ -539,11 +562,16 @@
      * without removing it.
      * @return the first event
      */
-    public synchronized AWTEvent peekEvent() {
-        for (int i = NUM_PRIORITIES - 1; i >= 0; i--) {
-            if (queues[i].head != null) {
-                return queues[i].head.event;
+    public AWTEvent peekEvent() {
+        pushPopLock.lock();
+        try {
+            for (int i = NUM_PRIORITIES - 1; i >= 0; i--) {
+                if (queues[i].head != null) {
+                    return queues[i].head.event;
+                }
             }
+        } finally {
+            pushPopLock.unlock();
         }
 
         return null;
@@ -555,14 +583,19 @@
      * @return the first event of the specified id or <code>null</code>
      *    if there is no such event
      */
-    public synchronized AWTEvent peekEvent(int id) {
-        for (int i = NUM_PRIORITIES - 1; i >= 0; i--) {
-            EventQueueItem q = queues[i].head;
-            for (; q != null; q = q.next) {
-                if (q.event.getID() == id) {
-                    return q.event;
+    public AWTEvent peekEvent(int id) {
+        pushPopLock.lock();
+        try {
+            for (int i = NUM_PRIORITIES - 1; i >= 0; i--) {
+                EventQueueItem q = queues[i].head;
+                for (; q != null; q = q.next) {
+                    if (q.event.getID() == id) {
+                        return q.event;
+                    }
                 }
             }
+        } finally {
+            pushPopLock.unlock();
         }
 
         return null;
@@ -661,17 +694,27 @@
     public static long getMostRecentEventTime() {
         return Toolkit.getEventQueue().getMostRecentEventTimeImpl();
     }
-    private synchronized long getMostRecentEventTimeImpl() {
-        return (Thread.currentThread() == dispatchThread)
-            ? mostRecentEventTime
-            : System.currentTimeMillis();
+    private long getMostRecentEventTimeImpl() {
+        pushPopLock.lock();
+        try {
+            return (Thread.currentThread() == dispatchThread)
+                ? mostRecentEventTime
+                : System.currentTimeMillis();
+        } finally {
+            pushPopLock.unlock();
+        }
     }
 
     /**
      * @return most recent event time on all threads.
      */
-    synchronized long getMostRecentEventTimeEx() {
-        return mostRecentEventTime;
+    long getMostRecentEventTimeEx() {
+        pushPopLock.lock();
+        try {
+            return mostRecentEventTime;
+        } finally {
+            pushPopLock.unlock();
+        }
     }
 
     /**
@@ -689,10 +732,15 @@
     public static AWTEvent getCurrentEvent() {
         return Toolkit.getEventQueue().getCurrentEventImpl();
     }
-    private synchronized AWTEvent getCurrentEventImpl() {
-        return (Thread.currentThread() == dispatchThread)
-            ? ((AWTEvent)currentEvent.get())
-            : null;
+    private AWTEvent getCurrentEventImpl() {
+        pushPopLock.lock();
+        try {
+                return (Thread.currentThread() == dispatchThread)
+                ? ((AWTEvent)currentEvent.get())
+                : null;
+        } finally {
+            pushPopLock.unlock();
+        }
     }
 
     /**
@@ -706,21 +754,22 @@
      * @throws NullPointerException if <code>newEventQueue</code> is <code>null</code>
      * @since           1.2
      */
-    public synchronized void push(EventQueue newEventQueue) {
+    public void push(EventQueue newEventQueue) {
         if (eventLog.isLoggable(PlatformLogger.FINE)) {
             eventLog.fine("EventQueue.push(" + newEventQueue + ")");
         }
 
-        if (nextQueue != null) {
-            nextQueue.push(newEventQueue);
-            return;
-        }
+        pushPopLock.lock();
+        try {
+            EventQueue toPush = this;
+            while (toPush.nextQueue != null) {
+                toPush = toPush.nextQueue;
+            }
 
-        synchronized (newEventQueue) {
             // Transfer all events forward to new EventQueue.
-            while (peekEvent() != null) {
+            while (toPush.peekEvent() != null) {
                 try {
-                    newEventQueue.postEventPrivate(getNextEvent());
+                    newEventQueue.postEventPrivate(toPush.getNextEvent());
                 } catch (InterruptedException ie) {
                     if (eventLog.isLoggable(PlatformLogger.FINE)) {
                         eventLog.fine("Interrupted push", ie);
@@ -728,27 +777,30 @@
                 }
             }
 
-            newEventQueue.previousQueue = this;
-        }
-        /*
-         * Stop the event dispatch thread associated with the currently
-         * active event queue, so that after the new queue is pushed
-         * on the top this event dispatch thread won't prevent AWT from
-         * being automatically shut down.
-         * Use stopDispatchingLater() to avoid deadlock: stopDispatching()
-         * waits for the dispatch thread to exit, so if the dispatch
-         * thread attempts to synchronize on this EventQueue object
-         * it will never exit since we already hold this lock.
-         */
-        if (dispatchThread != null) {
-            dispatchThread.stopDispatchingLater();
-        }
+            newEventQueue.previousQueue = toPush;
 
-        nextQueue = newEventQueue;
+            /*
+             * Stop the event dispatch thread associated with the currently
+             * active event queue, so that after the new queue is pushed
+             * on the top this event dispatch thread won't prevent AWT from
+             * being automatically shut down.
+             * Use stopDispatchingLater() to avoid deadlock: stopDispatching()
+             * waits for the dispatch thread to exit, which in turn waits
+             * for the lock in EQ.detachDispatchThread(), which is hold by
+             * this method.
+             */
+            if (toPush.dispatchThread != null) {
+                toPush.dispatchThread.stopDispatchingLater();
+            }
 
-        AppContext appContext = AppContext.getAppContext();
-        if (appContext.get(AppContext.EVENT_QUEUE_KEY) == this) {
-            appContext.put(AppContext.EVENT_QUEUE_KEY, newEventQueue);
+            toPush.nextQueue = newEventQueue;
+
+            AppContext appContext = AppContext.getAppContext();
+            if (appContext.get(AppContext.EVENT_QUEUE_KEY) == toPush) {
+                appContext.put(AppContext.EVENT_QUEUE_KEY, newEventQueue);
+            }
+        } finally {
+            pushPopLock.unlock();
         }
     }
 
@@ -770,25 +822,24 @@
             eventLog.fine("EventQueue.pop(" + this + ")");
         }
 
-        // To prevent deadlock, we lock on the previous EventQueue before
-        // this one.  This uses the same locking order as everything else
-        // in EventQueue.java, so deadlock isn't possible.
-        EventQueue prev = previousQueue;
-        synchronized ((prev != null) ? prev : this) {
-          synchronized(this) {
-            if (nextQueue != null) {
-                nextQueue.pop();
-                return;
+        EventDispatchThread dt = null;
+        pushPopLock.lock();
+        try {
+            EventQueue toPop = this;
+            while (toPop.nextQueue != null) {
+                toPop = toPop.nextQueue;
             }
-            if (previousQueue == null) {
+            EventQueue prev = toPop.previousQueue;
+            if (prev == null) {
                 throw new EmptyStackException();
             }
+            toPop.previousQueue = null;
 
             // Transfer all events back to previous EventQueue.
-            previousQueue.nextQueue = null;
-            while (peekEvent() != null) {
+            prev.nextQueue = null;
+            while (toPop.peekEvent() != null) {
                 try {
-                    previousQueue.postEventPrivate(getNextEvent());
+                    prev.postEventPrivate(toPop.getNextEvent());
                 } catch (InterruptedException ie) {
                     if (eventLog.isLoggable(PlatformLogger.FINE)) {
                         eventLog.fine("Interrupted pop", ie);
@@ -797,14 +848,14 @@
             }
             AppContext appContext = AppContext.getAppContext();
             if (appContext.get(AppContext.EVENT_QUEUE_KEY) == this) {
-                appContext.put(AppContext.EVENT_QUEUE_KEY, previousQueue);
+                appContext.put(AppContext.EVENT_QUEUE_KEY, prev);
             }
 
-            previousQueue = null;
-          }
+            dt = toPop.dispatchThread;
+        } finally {
+            pushPopLock.unlock();
         }
 
-        EventDispatchThread dt = this.dispatchThread;
         if (dt != null) {
             dt.stopDispatching(); // Must be done outside synchronized
                                   // block to avoid possible deadlock
@@ -833,16 +884,27 @@
      */
     public static boolean isDispatchThread() {
         EventQueue eq = Toolkit.getEventQueue();
-        EventQueue next = eq.nextQueue;
-        while (next != null) {
-            eq = next;
-            next = eq.nextQueue;
+        return eq.isDispatchThreadImpl();
+    }
+
+    final boolean isDispatchThreadImpl() {
+        EventQueue eq = this;
+        pushPopLock.lock();
+        try {
+            EventQueue next = eq.nextQueue;
+            while (next != null) {
+                eq = next;
+                next = eq.nextQueue;
+            }
+            return (Thread.currentThread() == eq.dispatchThread);
+        } finally {
+            pushPopLock.unlock();
         }
-        return (Thread.currentThread() == eq.dispatchThread);
     }
 
     final void initDispatchThread() {
-        synchronized (this) {
+        pushPopLock.lock();
+        try {
             AppContext appContext = AppContext.getAppContext();
             if (dispatchThread == null && !threadGroup.isDestroyed() && !appContext.isDisposed()) {
                 dispatchThread = (EventDispatchThread)
@@ -861,11 +923,45 @@
                 AWTAutoShutdown.getInstance().notifyThreadBusy(dispatchThread);
                 dispatchThread.start();
             }
+        } finally {
+            pushPopLock.unlock();
         }
     }
 
-    final void detachDispatchThread() {
-        dispatchThread = null;
+    final void detachDispatchThread(EventDispatchThread edt, boolean restart) {
+        /*
+         * This synchronized block is to secure that the event dispatch
+         * thread won't die in the middle of posting a new event to the
+         * associated event queue. It is important because we notify
+         * that the event dispatch thread is busy after posting a new event
+         * to its queue, so the EventQueue.dispatchThread reference must
+         * be valid at that point.
+         */
+        pushPopLock.lock();
+        try {
+            EventDispatchThread oldDispatchThread = dispatchThread;
+            if (dispatchThread == edt) {
+                dispatchThread = null;
+            }
+            if (restart) {
+                /*
+                 * Event dispatch thread dies in case of an uncaught exception.
+                 * A new event dispatch thread for this queue will be started
+                 * only if a new event is posted to it. In case if no more
+                 * events are posted after this thread died all events that
+                 * currently are in the queue will never be dispatched.
+                 *
+                 * Fix for 4648733. Check both the associated java event
+                 * queue and the PostEventQueue.
+                 */
+                if ((peekEvent() != null) || !SunToolkit.isPostEventQueueEmpty()) {
+                    initDispatchThread();
+                }
+                AWTAutoShutdown.getInstance().notifyThreadFree(oldDispatchThread);
+            }
+        } finally {
+            pushPopLock.unlock();
+        }
     }
 
     /*
@@ -878,7 +974,12 @@
      * @see    java.awt.EventQueue#detachDispatchThread
      */
     final EventDispatchThread getDispatchThread() {
-        return dispatchThread;
+        pushPopLock.lock();
+        try {
+            return dispatchThread;
+        } finally {
+            pushPopLock.unlock();
+        }
     }
 
     /*
@@ -895,7 +996,8 @@
      */
     final void removeSourceEvents(Object source, boolean removeAllEvents) {
         SunToolkit.flushPendingEvents();
-        synchronized (this) {
+        pushPopLock.lock();
+        try {
             for (int i = 0; i < NUM_PRIORITIES; i++) {
                 EventQueueItem entry = queues[i].head;
                 EventQueueItem prev = null;
@@ -928,43 +1030,49 @@
                 }
                 queues[i].tail = prev;
             }
+        } finally {
+            pushPopLock.unlock();
         }
     }
 
     static void setCurrentEventAndMostRecentTime(AWTEvent e) {
         Toolkit.getEventQueue().setCurrentEventAndMostRecentTimeImpl(e);
     }
-    private synchronized void setCurrentEventAndMostRecentTimeImpl(AWTEvent e)
-    {
-        if (Thread.currentThread() != dispatchThread) {
-            return;
+    private void setCurrentEventAndMostRecentTimeImpl(AWTEvent e) {
+        pushPopLock.lock();
+        try {
+            if (Thread.currentThread() != dispatchThread) {
+                return;
+            }
+
+            currentEvent = new WeakReference(e);
+
+            // This series of 'instanceof' checks should be replaced with a
+            // polymorphic type (for example, an interface which declares a
+            // getWhen() method). However, this would require us to make such
+            // a type public, or to place it in sun.awt. Both of these approaches
+            // have been frowned upon. So for now, we hack.
+            //
+            // In tiger, we will probably give timestamps to all events, so this
+            // will no longer be an issue.
+            long mostRecentEventTime2 = Long.MIN_VALUE;
+            if (e instanceof InputEvent) {
+                InputEvent ie = (InputEvent)e;
+                mostRecentEventTime2 = ie.getWhen();
+            } else if (e instanceof InputMethodEvent) {
+                InputMethodEvent ime = (InputMethodEvent)e;
+                mostRecentEventTime2 = ime.getWhen();
+            } else if (e instanceof ActionEvent) {
+                ActionEvent ae = (ActionEvent)e;
+                mostRecentEventTime2 = ae.getWhen();
+            } else if (e instanceof InvocationEvent) {
+                InvocationEvent ie = (InvocationEvent)e;
+                mostRecentEventTime2 = ie.getWhen();
+            }
+            mostRecentEventTime = Math.max(mostRecentEventTime, mostRecentEventTime2);
+        } finally {
+            pushPopLock.unlock();
         }
-
-        currentEvent = new WeakReference(e);
-
-        // This series of 'instanceof' checks should be replaced with a
-        // polymorphic type (for example, an interface which declares a
-        // getWhen() method). However, this would require us to make such
-        // a type public, or to place it in sun.awt. Both of these approaches
-        // have been frowned upon. So for now, we hack.
-        //
-        // In tiger, we will probably give timestamps to all events, so this
-        // will no longer be an issue.
-        long mostRecentEventTime2 = Long.MIN_VALUE;
-        if (e instanceof InputEvent) {
-            InputEvent ie = (InputEvent)e;
-            mostRecentEventTime2 = ie.getWhen();
-        } else if (e instanceof InputMethodEvent) {
-            InputMethodEvent ime = (InputMethodEvent)e;
-            mostRecentEventTime2 = ime.getWhen();
-        } else if (e instanceof ActionEvent) {
-            ActionEvent ae = (ActionEvent)e;
-            mostRecentEventTime2 = ae.getWhen();
-        } else if (e instanceof InvocationEvent) {
-            InvocationEvent ie = (InvocationEvent)e;
-            mostRecentEventTime2 = ie.getWhen();
-        }
-        mostRecentEventTime = Math.max(mostRecentEventTime, mostRecentEventTime2);
     }
 
     /**
@@ -1045,15 +1153,18 @@
      * or starts a new one otherwise.
      */
     private void wakeup(boolean isShutdown) {
-        synchronized(this) {
+        pushPopLock.lock();
+        try {
             if (nextQueue != null) {
                 // Forward call to the top of EventQueue stack.
                 nextQueue.wakeup(isShutdown);
             } else if (dispatchThread != null) {
-                notifyAll();
+                pushPopCond.signalAll();
             } else if (!isShutdown) {
                 initDispatchThread();
             }
+        } finally {
+            pushPopLock.unlock();
         }
     }
 }
--- a/jdk/src/share/classes/java/awt/KeyboardFocusManager.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/java/awt/KeyboardFocusManager.java	Wed Jul 05 17:04:26 2017 +0200
@@ -53,8 +53,7 @@
 import java.util.StringTokenizer;
 import java.util.WeakHashMap;
 
-import java.util.logging.Level;
-import java.util.logging.Logger;
+import sun.util.logging.PlatformLogger;
 
 import sun.awt.AppContext;
 import sun.awt.HeadlessToolkit;
@@ -111,7 +110,7 @@
 {
 
     // Shared focus engine logger
-    private static final Logger focusLog = Logger.getLogger("java.awt.focus.KeyboardFocusManager");
+    private static final PlatformLogger focusLog = PlatformLogger.getLogger("java.awt.focus.KeyboardFocusManager");
 
     static {
         /* ensure that the necessary native libraries are loaded */
@@ -154,7 +153,7 @@
      */
     private static native void initIDs();
 
-    private static final Logger log = Logger.getLogger("java.awt.KeyboardFocusManager");
+    private static final PlatformLogger log = PlatformLogger.getLogger("java.awt.KeyboardFocusManager");
 
     /**
      * The identifier for the Forward focus traversal keys.
@@ -504,8 +503,8 @@
             if (this == getCurrentKeyboardFocusManager()) {
                 return focusOwner;
             } else {
-                if (focusLog.isLoggable(Level.FINER)) {
-                    focusLog.log(Level.FINER, "This manager is " + this + ", current is " + getCurrentKeyboardFocusManager());
+                if (focusLog.isLoggable(PlatformLogger.FINER)) {
+                    focusLog.finer("This manager is " + this + ", current is " + getCurrentKeyboardFocusManager());
                 }
                 throw new SecurityException(notPrivileged);
             }
@@ -609,9 +608,9 @@
     }
 
     void setNativeFocusOwner(Component comp) {
-        if (focusLog.isLoggable(Level.FINEST)) {
-            focusLog.log(Level.FINEST, "Calling peer {0} setCurrentFocusOwner for {1}",
-                         new Object[] {String.valueOf(peer), String.valueOf(comp)});
+        if (focusLog.isLoggable(PlatformLogger.FINEST)) {
+            focusLog.finest("Calling peer {0} setCurrentFocusOwner for {1}",
+                            String.valueOf(peer), String.valueOf(comp));
         }
         peer.setCurrentFocusOwner(comp);
     }
@@ -673,8 +672,8 @@
             if (this == getCurrentKeyboardFocusManager()) {
                 return permanentFocusOwner;
             } else {
-                if (focusLog.isLoggable(Level.FINER)) {
-                    focusLog.log(Level.FINER, "This manager is " + this + ", current is " + getCurrentKeyboardFocusManager());
+                if (focusLog.isLoggable(PlatformLogger.FINER)) {
+                    focusLog.finer("This manager is " + this + ", current is " + getCurrentKeyboardFocusManager());
                 }
                 throw new SecurityException(notPrivileged);
             }
@@ -781,8 +780,8 @@
             if (this == getCurrentKeyboardFocusManager()) {
                return focusedWindow;
             } else {
-                if (focusLog.isLoggable(Level.FINER)) {
-                    focusLog.log(Level.FINER, "This manager is " + this + ", current is " + getCurrentKeyboardFocusManager());
+                if (focusLog.isLoggable(PlatformLogger.FINER)) {
+                    focusLog.finer("This manager is " + this + ", current is " + getCurrentKeyboardFocusManager());
                 }
                 throw new SecurityException(notPrivileged);
             }
@@ -885,8 +884,8 @@
             if (this == getCurrentKeyboardFocusManager()) {
                return activeWindow;
             } else {
-                if (focusLog.isLoggable(Level.FINER)) {
-                    focusLog.log(Level.FINER, "This manager is " + this + ", current is " + getCurrentKeyboardFocusManager());
+                if (focusLog.isLoggable(PlatformLogger.FINER)) {
+                    focusLog.finer("This manager is " + this + ", current is " + getCurrentKeyboardFocusManager());
                 }
                 throw new SecurityException(notPrivileged);
             }
@@ -919,8 +918,8 @@
         Window oldActiveWindow;
         synchronized (KeyboardFocusManager.class) {
             oldActiveWindow = getActiveWindow();
-            if (focusLog.isLoggable(Level.FINER)) {
-                focusLog.log(Level.FINER, "Setting global active window to " + activeWindow + ", old active " + oldActiveWindow);
+            if (focusLog.isLoggable(PlatformLogger.FINER)) {
+                focusLog.finer("Setting global active window to " + activeWindow + ", old active " + oldActiveWindow);
             }
 
             try {
@@ -1215,8 +1214,8 @@
             if (this == getCurrentKeyboardFocusManager()) {
                 return currentFocusCycleRoot;
             } else {
-                if (focusLog.isLoggable(Level.FINER)) {
-                    focusLog.log(Level.FINER, "This manager is " + this + ", current is " + getCurrentKeyboardFocusManager());
+                if (focusLog.isLoggable(PlatformLogger.FINER)) {
+                    focusLog.finer("This manager is " + this + ", current is " + getCurrentKeyboardFocusManager());
                 }
                 throw new SecurityException(notPrivileged);
             }
@@ -2149,9 +2148,9 @@
 
         HeavyweightFocusRequest(Component heavyweight, Component descendant,
                                 boolean temporary, CausedFocusEvent.Cause cause) {
-            if (log.isLoggable(Level.FINE)) {
+            if (log.isLoggable(PlatformLogger.FINE)) {
                 if (heavyweight == null) {
-                    log.log(Level.FINE, "Assertion (heavyweight != null) failed");
+                    log.fine("Assertion (heavyweight != null) failed");
                 }
             }
 
@@ -2161,12 +2160,12 @@
         }
         boolean addLightweightRequest(Component descendant,
                                       boolean temporary, CausedFocusEvent.Cause cause) {
-            if (log.isLoggable(Level.FINE)) {
+            if (log.isLoggable(PlatformLogger.FINE)) {
                 if (this == HeavyweightFocusRequest.CLEAR_GLOBAL_FOCUS_OWNER) {
-                    log.log(Level.FINE, "Assertion (this != HeavyweightFocusRequest.CLEAR_GLOBAL_FOCUS_OWNER) failed");
+                    log.fine("Assertion (this != HeavyweightFocusRequest.CLEAR_GLOBAL_FOCUS_OWNER) failed");
                 }
                 if (descendant == null) {
-                    log.log(Level.FINE, "Assertion (descendant != null) failed");
+                    log.fine("Assertion (descendant != null) failed");
                 }
             }
 
@@ -2339,12 +2338,12 @@
         (Component heavyweight, Component descendant, boolean temporary,
          boolean focusedWindowChangeAllowed, long time, CausedFocusEvent.Cause cause)
     {
-        if (log.isLoggable(Level.FINE)) {
+        if (log.isLoggable(PlatformLogger.FINE)) {
             if (heavyweight == null) {
-                log.log(Level.FINE, "Assertion (heavyweight != null) failed");
+                log.fine("Assertion (heavyweight != null) failed");
             }
             if (time == 0) {
-                log.log(Level.FINE, "Assertion (time != 0) failed");
+                log.fine("Assertion (time != 0) failed");
             }
         }
 
@@ -2361,31 +2360,31 @@
         Component currentFocusOwner = thisManager.getGlobalFocusOwner();
         Component nativeFocusOwner = thisManager.getNativeFocusOwner();
         Window nativeFocusedWindow = thisManager.getNativeFocusedWindow();
-        if (focusLog.isLoggable(Level.FINER)) {
-            focusLog.log(Level.FINER, "SNFH for {0} in {1}",
-                         new Object[] {String.valueOf(descendant), String.valueOf(heavyweight)});
+        if (focusLog.isLoggable(PlatformLogger.FINER)) {
+            focusLog.finer("SNFH for {0} in {1}",
+                           String.valueOf(descendant), String.valueOf(heavyweight));
         }
-        if (focusLog.isLoggable(Level.FINEST)) {
-            focusLog.log(Level.FINEST, "0. Current focus owner {0}",
-                         String.valueOf(currentFocusOwner));
-            focusLog.log(Level.FINEST, "0. Native focus owner {0}",
-                         String.valueOf(nativeFocusOwner));
-            focusLog.log(Level.FINEST, "0. Native focused window {0}",
-                         String.valueOf(nativeFocusedWindow));
+        if (focusLog.isLoggable(PlatformLogger.FINEST)) {
+            focusLog.finest("0. Current focus owner {0}",
+                            String.valueOf(currentFocusOwner));
+            focusLog.finest("0. Native focus owner {0}",
+                            String.valueOf(nativeFocusOwner));
+            focusLog.finest("0. Native focused window {0}",
+                            String.valueOf(nativeFocusedWindow));
         }
         synchronized (heavyweightRequests) {
             HeavyweightFocusRequest hwFocusRequest = getLastHWRequest();
-            if (focusLog.isLoggable(Level.FINEST)) {
-                focusLog.log(Level.FINEST, "Request {0}", String.valueOf(hwFocusRequest));
+            if (focusLog.isLoggable(PlatformLogger.FINEST)) {
+                focusLog.finest("Request {0}", String.valueOf(hwFocusRequest));
             }
             if (hwFocusRequest == null &&
                 heavyweight == nativeFocusOwner)
             {
                 if (descendant == currentFocusOwner) {
                     // Redundant request.
-                    if (focusLog.isLoggable(Level.FINEST))
-                        focusLog.log(Level.FINEST, "1. SNFH_FAILURE for {0}",
-                                     String.valueOf(descendant));
+                    if (focusLog.isLoggable(PlatformLogger.FINEST))
+                        focusLog.finest("1. SNFH_FAILURE for {0}",
+                                        String.valueOf(descendant));
                     return SNFH_FAILURE;
                 }
 
@@ -2417,8 +2416,8 @@
                 // SunToolkit.postPriorityEvent(newFocusOwnerEvent);
                 SunToolkit.postEvent(descendant.appContext, newFocusOwnerEvent);
 
-                if (focusLog.isLoggable(Level.FINEST))
-                    focusLog.log(Level.FINEST, "2. SNFH_HANDLED for {0}", String.valueOf(descendant));
+                if (focusLog.isLoggable(PlatformLogger.FINEST))
+                    focusLog.finest("2. SNFH_HANDLED for {0}", String.valueOf(descendant));
                 return SNFH_SUCCESS_HANDLED;
             } else if (hwFocusRequest != null &&
                        hwFocusRequest.heavyweight == heavyweight) {
@@ -2431,7 +2430,7 @@
                     manager.enqueueKeyEvents(time, descendant);
                 }
 
-                if (focusLog.isLoggable(Level.FINEST))
+                if (focusLog.isLoggable(PlatformLogger.FINEST))
                     focusLog.finest("3. SNFH_HANDLED for lightweight" +
                                     descendant + " in " + heavyweight);
                 return SNFH_SUCCESS_HANDLED;
@@ -2454,7 +2453,7 @@
                                              (hwFocusRequest != null)
                                              ? hwFocusRequest.heavyweight
                                              : nativeFocusedWindow)) {
-                        if (focusLog.isLoggable(Level.FINEST))
+                        if (focusLog.isLoggable(PlatformLogger.FINEST))
                             focusLog.finest("4. SNFH_FAILURE for " + descendant);
                         return SNFH_FAILURE;
                     }
@@ -2464,7 +2463,7 @@
                 heavyweightRequests.add
                     (new HeavyweightFocusRequest(heavyweight, descendant,
                                                  temporary, cause));
-                if (focusLog.isLoggable(Level.FINEST))
+                if (focusLog.isLoggable(PlatformLogger.FINEST))
                     focusLog.finest("5. SNFH_PROCEED for " + descendant);
                 return SNFH_SUCCESS_PROCEED;
             }
@@ -2855,14 +2854,14 @@
         }
 
         KeyboardFocusManager manager = getCurrentKeyboardFocusManager();
-        if (focusLog.isLoggable(Level.FINER)) {
+        if (focusLog.isLoggable(PlatformLogger.FINER)) {
             if (event instanceof FocusEvent || event instanceof WindowEvent) {
-                focusLog.log(Level.FINER, ">>> {0}", new Object[] {String.valueOf(event)});
+                focusLog.finer(">>> {0}", String.valueOf(event));
             }
-            if (focusLog.isLoggable(Level.FINER) && event instanceof KeyEvent) {
-                focusLog.log(Level.FINER, "    focus owner is {0}",
-                                          new Object[] {String.valueOf(manager.getGlobalFocusOwner())});
-                focusLog.log(Level.FINER, ">>> {0}", new Object[] {String.valueOf(event)});
+            if (focusLog.isLoggable(PlatformLogger.FINER) && event instanceof KeyEvent) {
+                focusLog.finer("    focus owner is {0}",
+                               String.valueOf(manager.getGlobalFocusOwner()));
+                focusLog.finer(">>> {0}", String.valueOf(event));
             }
         }
 
@@ -2946,9 +2945,9 @@
         }
     }
     static void removeLastFocusRequest(Component heavyweight) {
-        if (log.isLoggable(Level.FINE)) {
+        if (log.isLoggable(PlatformLogger.FINE)) {
             if (heavyweight == null) {
-                log.log(Level.FINE, "Assertion (heavyweight != null) failed");
+                log.fine("Assertion (heavyweight != null) failed");
             }
         }
 
--- a/jdk/src/share/classes/java/awt/Window.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/java/awt/Window.java	Wed Jul 05 17:04:26 2017 +0200
@@ -148,6 +148,51 @@
 public class Window extends Container implements Accessible {
 
     /**
+     * Enumeration of available <i>window types</i>.
+     *
+     * A window type defines the generic visual appearance and behavior of a
+     * top-level window. For example, the type may affect the kind of
+     * decorations of a decorated {@code Frame} or {@code Dialog} instance.
+     * <p>
+     * Some platforms may not fully support a certain window type. Depending on
+     * the level of support, some properties of the window type may be
+     * disobeyed.
+     *
+     * @see   #getType
+     * @see   #setType
+     * @since 1.7
+     */
+    public static enum Type {
+        /**
+         * Represents a <i>normal</i> window.
+         *
+         * This is the default type for objects of the {@code Window} class or
+         * its descendants. Use this type for regular top-level windows.
+         */
+        NORMAL,
+
+        /**
+         * Represents a <i>utility</i> window.
+         *
+         * A utility window is usually a small window such as a toolbar or a
+         * palette. The native system may render the window with smaller
+         * title-bar if the window is either a {@code Frame} or a {@code
+         * Dialog} object, and if it has its decorations enabled.
+         */
+        UTILITY,
+
+        /**
+         * Represents a <i>popup</i> window.
+         *
+         * A popup window is a temporary window such as a drop-down menu or a
+         * tooltip. On some platforms, windows of that type may be forcibly
+         * made undecorated even if they are instances of the {@code Frame} or
+         * {@code Dialog} class, and have decorations enabled.
+         */
+        POPUP
+    }
+
+    /**
      * This represents the warning message that is
      * to be displayed in a non secure window. ie :
      * a window that has a security manager installed for
@@ -2718,6 +2763,52 @@
     }
 
     /**
+     * Window type.
+     *
+     * Synchronization: ObjectLock
+     */
+    private Type type = Type.NORMAL;
+
+    /**
+     * Sets the type of the window.
+     *
+     * This method can only be called while the window is not displayable.
+     *
+     * @throws IllegalComponentStateException if the window
+     *         is displayable.
+     * @throws IllegalArgumentException if the type is {@code null}
+     * @see    Component#isDisplayable
+     * @see    #getType
+     * @since 1.7
+     */
+    public void setType(Type type) {
+        if (type == null) {
+            throw new IllegalArgumentException("type should not be null.");
+        }
+        synchronized (getTreeLock()) {
+            if (isDisplayable()) {
+                throw new IllegalComponentStateException(
+                        "The window is displayable.");
+            }
+            synchronized (getObjectLock()) {
+                this.type = type;
+            }
+        }
+    }
+
+    /**
+     * Returns the type of the window.
+     *
+     * @see   #setType
+     * @since 1.7
+     */
+    public Type getType() {
+        synchronized (getObjectLock()) {
+            return type;
+        }
+    }
+
+    /**
      * The window serialized data version.
      *
      * @serial
@@ -3873,6 +3964,18 @@
             public void setLWRequestStatus(Window changed, boolean status) {
                 changed.syncLWRequests = status;
             }
+
+            public boolean isAutoRequestFocus(Window w) {
+                return w.autoRequestFocus;
+            }
+
+            public boolean isTrayIconWindow(Window w) {
+                return w.isTrayIconWindow;
+            }
+
+            public void setTrayIconWindow(Window w, boolean isTrayIconWindow) {
+                w.isTrayIconWindow = isTrayIconWindow;
+            }
         }); // WindowAccessor
     } // static
 
--- a/jdk/src/share/classes/java/beans/IndexedPropertyDescriptor.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/java/beans/IndexedPropertyDescriptor.java	Wed Jul 05 17:04:26 2017 +0200
@@ -313,11 +313,14 @@
     }
 
     /**
-     * Gets the <code>Class</code> object of the indexed properties' type.
-     * The returned <code>Class</code> may describe a primitive type such as <code>int</code>.
+     * Returns the Java type info for the indexed property.
+     * Note that the {@code Class} object may describe
+     * primitive Java types such as {@code int}.
+     * This type is returned by the indexed read method
+     * or is used as the parameter type of the indexed write method.
      *
-     * @return The <code>Class</code> for the indexed properties' type; may return <code>null</code>
-     *         if the type cannot be determined.
+     * @return the {@code Class} object that represents the Java type info,
+     *         or {@code null} if the type cannot be determined
      */
     public synchronized Class<?> getIndexedPropertyType() {
         Class type = getIndexedPropertyType0();
--- a/jdk/src/share/classes/java/beans/Introspector.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/java/beans/Introspector.java	Wed Jul 05 17:04:26 2017 +0200
@@ -25,26 +25,19 @@
 
 package java.beans;
 
+import com.sun.beans.WeakCache;
 import com.sun.beans.finder.BeanInfoFinder;
 import com.sun.beans.finder.ClassFinder;
 
-import java.lang.ref.Reference;
-import java.lang.ref.SoftReference;
-
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-
-import java.util.Collections;
 import java.util.Map;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.EventListener;
 import java.util.List;
-import java.util.WeakHashMap;
 import java.util.TreeMap;
 
 import sun.awt.AppContext;
@@ -85,20 +78,7 @@
  * patterns to identify property accessors, event sources, or public
  * methods.  We then proceed to analyze the class's superclass and add
  * in the information from it (and possibly on up the superclass chain).
- *
  * <p>
- * Because the Introspector caches BeanInfo classes for better performance,
- * take care if you use it in an application that uses
- * multiple class loaders.
- * In general, when you destroy a <code>ClassLoader</code>
- * that has been used to introspect classes,
- * you should use the
- * {@link #flushCaches <code>Introspector.flushCaches</code>}
- * or
- * {@link #flushFromCaches <code>Introspector.flushFromCaches</code>} method
- * to flush all of the introspected classes out of the cache.
- *
- * <P>
  * For more information about introspection and design patterns, please
  * consult the
  *  <a href="http://java.sun.com/products/javabeans/docs/index.html">JavaBeans specification</a>.
@@ -112,8 +92,8 @@
     public final static int IGNORE_ALL_BEANINFO        = 3;
 
     // Static Caches to speed up introspection.
-    private static Map declaredMethodCache =
-        Collections.synchronizedMap(new WeakHashMap());
+    private static WeakCache<Class<?>, Method[]> declaredMethodCache =
+            new WeakCache<Class<?>, Method[]>();
 
     private static final Object BEANINFO_CACHE = new Object();
 
@@ -174,20 +154,21 @@
         if (!ReflectUtil.isPackageAccessible(beanClass)) {
             return (new Introspector(beanClass, null, USE_ALL_BEANINFO)).getBeanInfo();
         }
-        Map<Class<?>, BeanInfo> map;
         synchronized (BEANINFO_CACHE) {
-            map = (Map<Class<?>, BeanInfo>) AppContext.getAppContext().get(BEANINFO_CACHE);
-            if (map == null) {
-                map = Collections.synchronizedMap(new WeakHashMap<Class<?>, BeanInfo>());
-                AppContext.getAppContext().put(BEANINFO_CACHE, map);
+            WeakCache<Class<?>, BeanInfo> beanInfoCache =
+                    (WeakCache<Class<?>, BeanInfo>) AppContext.getAppContext().get(BEANINFO_CACHE);
+
+            if (beanInfoCache == null) {
+                beanInfoCache = new WeakCache<Class<?>, BeanInfo>();
+                AppContext.getAppContext().put(BEANINFO_CACHE, beanInfoCache);
             }
+            BeanInfo beanInfo = beanInfoCache.get(beanClass);
+            if (beanInfo == null) {
+                beanInfo = (new Introspector(beanClass, null, USE_ALL_BEANINFO)).getBeanInfo();
+                beanInfoCache.put(beanClass, beanInfo);
+            }
+            return beanInfo;
         }
-        BeanInfo bi = map.get(beanClass);
-        if (bi == null) {
-            bi = (new Introspector(beanClass, null, USE_ALL_BEANINFO)).getBeanInfo();
-            map.put(beanClass, bi);
-        }
-        return bi;
     }
 
     /**
@@ -359,11 +340,13 @@
      */
 
     public static void flushCaches() {
-        Map map = (Map) AppContext.getAppContext().get(BEANINFO_CACHE);
-        if (map != null) {
-            map.clear();
+        synchronized (BEANINFO_CACHE) {
+            WeakCache beanInfoCache = (WeakCache) AppContext.getAppContext().get(BEANINFO_CACHE);
+            if (beanInfoCache != null) {
+                beanInfoCache.clear();
+            }
+            declaredMethodCache.clear();
         }
-        declaredMethodCache.clear();
     }
 
     /**
@@ -385,11 +368,13 @@
         if (clz == null) {
             throw new NullPointerException();
         }
-        Map map = (Map) AppContext.getAppContext().get(BEANINFO_CACHE);
-        if (map != null) {
-            map.remove(clz);
+        synchronized (BEANINFO_CACHE) {
+            WeakCache beanInfoCache = (WeakCache) AppContext.getAppContext().get(BEANINFO_CACHE);
+            if (beanInfoCache != null) {
+                beanInfoCache.put(clz, null);
+            }
+            declaredMethodCache.put(clz, null);
         }
-        declaredMethodCache.remove(clz);
     }
 
     //======================================================================
@@ -1272,41 +1257,26 @@
     /*
      * Internal method to return *public* methods within a class.
      */
-    private static synchronized Method[] getPublicDeclaredMethods(Class clz) {
+    private static Method[] getPublicDeclaredMethods(Class clz) {
         // Looking up Class.getDeclaredMethods is relatively expensive,
         // so we cache the results.
-        Method[] result = null;
         if (!ReflectUtil.isPackageAccessible(clz)) {
             return new Method[0];
         }
-        final Class fclz = clz;
-        Reference ref = (Reference)declaredMethodCache.get(fclz);
-        if (ref != null) {
-            result = (Method[])ref.get();
-            if (result != null) {
-                return result;
+        synchronized (BEANINFO_CACHE) {
+            Method[] result = declaredMethodCache.get(clz);
+            if (result == null) {
+                result = clz.getMethods();
+                for (int i = 0; i < result.length; i++) {
+                    Method method = result[i];
+                    if (!method.getDeclaringClass().equals(clz)) {
+                        result[i] = null;
+                    }
+                }
+                declaredMethodCache.put(clz, result);
             }
+            return result;
         }
-
-        // We have to raise privilege for getDeclaredMethods
-        result = (Method[]) AccessController.doPrivileged(new PrivilegedAction() {
-                public Object run() {
-                    return fclz.getDeclaredMethods();
-                }
-            });
-
-
-        // Null out any non-public methods.
-        for (int i = 0; i < result.length; i++) {
-            Method method = result[i];
-            int mods = method.getModifiers();
-            if (!Modifier.isPublic(mods)) {
-                result[i] = null;
-            }
-        }
-        // Add it to the cache.
-        declaredMethodCache.put(fclz, new SoftReference(result));
-        return result;
     }
 
     //======================================================================
--- a/jdk/src/share/classes/java/beans/PropertyDescriptor.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/java/beans/PropertyDescriptor.java	Wed Jul 05 17:04:26 2017 +0200
@@ -164,14 +164,16 @@
     }
 
     /**
-     * Gets the Class object for the property.
+     * Returns the Java type info for the property.
+     * Note that the {@code Class} object may describe
+     * primitive Java types such as {@code int}.
+     * This type is returned by the read method
+     * or is used as the parameter type of the write method.
+     * Returns {@code null} if the type is an indexed property
+     * that does not support non-indexed access.
      *
-     * @return The Java type info for the property.  Note that
-     * the "Class" object may describe a built-in Java type such as "int".
-     * The result may be "null" if this is an indexed property that
-     * does not support non-indexed access.
-     * <p>
-     * This is the type that will be returned by the ReadMethod.
+     * @return the {@code Class} object that represents the Java type info,
+     *         or {@code null} if the type cannot be determined
      */
     public synchronized Class<?> getPropertyType() {
         Class type = getPropertyType0();
--- a/jdk/src/share/classes/java/lang/ClassLoader.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/java/lang/ClassLoader.java	Wed Jul 05 17:04:26 2017 +0200
@@ -175,15 +175,8 @@
 public abstract class ClassLoader {
 
     private static native void registerNatives();
-
-    // Set of classes which are registered as parallel capable class loaders
-    private static final Set<Class<? extends ClassLoader>> parallelLoaders
-        = Collections.newSetFromMap(Collections.synchronizedMap
-              (new WeakHashMap<Class<? extends ClassLoader>, Boolean>()));
-
     static {
         registerNatives();
-        parallelLoaders.add(ClassLoader.class);
     }
 
     // The parent class loader for delegation
@@ -191,6 +184,52 @@
     // must be added *after* it.
     private final ClassLoader parent;
 
+    /**
+     * Encapsulates the set of parallel capable loader types.
+     */
+    private static class ParallelLoaders {
+        private ParallelLoaders() {}
+
+        // the set of parallel capable loader types
+        private static final Set<Class<? extends ClassLoader>> loaderTypes =
+            Collections.newSetFromMap(
+                new WeakHashMap<Class<? extends ClassLoader>, Boolean>());
+        static {
+            synchronized (loaderTypes) { loaderTypes.add(ClassLoader.class); }
+        }
+
+        /**
+         * Registers the given class loader type as parallel capabale.
+         * Returns {@code true} is successfully registered; {@code false} if
+         * loader's super class is not registered.
+         */
+        static boolean register(Class<? extends ClassLoader> c) {
+            synchronized (loaderTypes) {
+                if (loaderTypes.contains(c.getSuperclass())) {
+                    // register the class loader as parallel capable
+                    // if and only if all of its super classes are.
+                    // Note: given current classloading sequence, if
+                    // the immediate super class is parallel capable,
+                    // all the super classes higher up must be too.
+                    loaderTypes.add(c);
+                    return true;
+                } else {
+                    return false;
+                }
+            }
+        }
+
+        /**
+         * Returns {@code true} if the given class loader type is
+         * registered as parallel capable.
+         */
+        static boolean isRegistered(Class<? extends ClassLoader> c) {
+            synchronized (loaderTypes) {
+                return loaderTypes.contains(c);
+            }
+        }
+    }
+
     // Maps class name to the corresponding lock object when the current
     // class loader is parallel capable.
     // Note: VM also uses this field to decide if the current class loader
@@ -237,7 +276,7 @@
 
     private ClassLoader(Void unused, ClassLoader parent) {
         this.parent = parent;
-        if (parallelLoaders.contains(this.getClass())) {
+        if (ParallelLoaders.isRegistered(this.getClass())) {
             parallelLockMap = new ConcurrentHashMap<String, Object>();
             package2certs = new ConcurrentHashMap<String, Certificate[]>();
             domains =
@@ -1194,24 +1233,7 @@
      * @since   1.7
      */
     protected static boolean registerAsParallelCapable() {
-        Class<? extends ClassLoader> caller = getCaller(1);
-        Class superCls = caller.getSuperclass();
-        boolean result = false;
-        // Explicit synchronization needed for composite action
-        synchronized (parallelLoaders) {
-            if (!parallelLoaders.contains(caller)) {
-                if (parallelLoaders.contains(superCls)) {
-                    // register the immediate caller as parallel capable
-                    // if and only if all of its super classes are.
-                    // Note: given current classloading sequence, if
-                    // the immediate super class is parallel capable,
-                    // all the super classes higher up must be too.
-                    result = true;
-                    parallelLoaders.add(caller);
-                }
-            } else result = true;
-        }
-        return result;
+        return ParallelLoaders.register(getCaller(1));
     }
 
     /**
@@ -2174,4 +2196,3 @@
         return sys;
     }
 }
-
--- a/jdk/src/share/classes/java/lang/System.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/java/lang/System.java	Wed Jul 05 17:04:26 2017 +0200
@@ -620,6 +620,20 @@
     }
 
     /**
+     * Returns the system-dependent line separator string.  It always
+     * returns the same value - the initial value of the {@linkplain
+     * #getProperty(String) system property} {@code line.separator}.
+     *
+     * <p>On UNIX systems, it returns {@code "\n"}; on Microsoft
+     * Windows systems it returns {@code "\r\n"}.
+     */
+    public static String lineSeparator() {
+        return lineSeparator;
+    }
+
+    private static String lineSeparator;
+
+    /**
      * Sets the system properties to the <code>Properties</code>
      * argument.
      * <p>
@@ -1104,6 +1118,7 @@
     private static void initializeSystemClass() {
         props = new Properties();
         initProperties(props);
+        lineSeparator = props.getProperty("line.separator");
         sun.misc.Version.init();
 
         // Workaround until DownloadManager initialization is revisited.
@@ -1192,7 +1207,7 @@
     }
 
     /* returns the class of the caller. */
-    static Class getCallerClass() {
+    static Class<?> getCallerClass() {
         // NOTE use of more generic Reflection.getCallerClass()
         return Reflection.getCallerClass(3);
     }
--- a/jdk/src/share/classes/java/net/CookieManager.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/java/net/CookieManager.java	Wed Jul 05 17:04:26 2017 +0200
@@ -30,6 +30,7 @@
 import java.util.Collections;
 import java.util.Comparator;
 import java.io.IOException;
+import sun.util.logging.PlatformLogger;
 
 /**
  * CookieManager provides a concrete implementation of {@link CookieHandler},
@@ -263,6 +264,7 @@
         if (cookieJar == null)
             return;
 
+    PlatformLogger logger = PlatformLogger.getLogger("java.net.CookieManager");
         for (String headerKey : responseHeaders.keySet()) {
             // RFC 2965 3.2.2, key must be 'Set-Cookie2'
             // we also accept 'Set-Cookie' here for backward compatibility
@@ -277,7 +279,16 @@
 
             for (String headerValue : responseHeaders.get(headerKey)) {
                 try {
-                    List<HttpCookie> cookies = HttpCookie.parse(headerValue);
+                    List<HttpCookie> cookies;
+                    try {
+                        cookies = HttpCookie.parse(headerValue);
+                    } catch (IllegalArgumentException e) {
+                        // Bogus header, make an empty list and log the error
+                        cookies = java.util.Collections.EMPTY_LIST;
+                        if (logger.isLoggable(PlatformLogger.SEVERE)) {
+                            logger.severe("Invalid cookie for " + uri + ": " + headerValue);
+                        }
+                    }
                     for (HttpCookie cookie : cookies) {
                         if (cookie.getPath() == null) {
                             // If no path is specified, then by default
--- a/jdk/src/share/classes/java/net/HttpCookie.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/java/net/HttpCookie.java	Wed Jul 05 17:04:26 2017 +0200
@@ -1036,7 +1036,7 @@
                         int version = Integer.parseInt(attrValue);
                         cookie.setVersion(version);
                     } catch (NumberFormatException ignored) {
-                        throw new IllegalArgumentException("Illegal cookie version attribute");
+                        // Just ignore bogus version, it will default to 0 or 1
                     }
                 }
             });
@@ -1147,12 +1147,15 @@
     }
 
     private static String stripOffSurroundingQuote(String str) {
-        if (str != null && str.length() > 0 &&
+        if (str != null && str.length() > 2 &&
             str.charAt(0) == '"' && str.charAt(str.length() - 1) == '"') {
             return str.substring(1, str.length() - 1);
-        } else {
-            return str;
         }
+        if (str != null && str.length() > 2 &&
+            str.charAt(0) == '\'' && str.charAt(str.length() - 1) == '\'') {
+            return str.substring(1, str.length() - 1);
+        }
+        return str;
     }
 
     private static boolean equalsIgnoreCase(String s, String t) {
--- a/jdk/src/share/classes/java/nio/channels/Selector.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/java/nio/channels/Selector.java	Wed Jul 05 17:04:26 2017 +0200
@@ -25,6 +25,7 @@
 
 package java.nio.channels;
 
+import java.io.Closeable;
 import java.io.IOException;
 import java.nio.channels.spi.SelectorProvider;
 import java.util.Set;
@@ -202,7 +203,7 @@
  * @see SelectionKey
  */
 
-public abstract class Selector {
+public abstract class Selector implements Closeable {
 
     /**
      * Initializes a new instance of this class.
--- a/jdk/src/share/classes/java/util/DualPivotQuicksort.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/java/util/DualPivotQuicksort.java	Wed Jul 05 17:04:26 2017 +0200
@@ -36,12 +36,12 @@
  * @author Jon Bentley
  * @author Josh Bloch
  *
- * @version 2009.11.16 m765.827.v12a
+ * @version 2009.11.29 m765.827.12i
  */
 final class DualPivotQuicksort {
 
     /**
-     * Suppresses default constructor.
+     * Prevents instantiation.
      */
     private DualPivotQuicksort() {}
 
@@ -84,7 +84,7 @@
      * Sorts the specified range of the array into ascending order. The range
      * to be sorted extends from the index {@code fromIndex}, inclusive, to
      * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex},
-     * the range to be sorted is empty.
+     * the range to be sorted is empty (and the call is a no-op).
      *
      * @param a the array to be sorted
      * @param fromIndex the index of the first element, inclusive, to be sorted
@@ -101,8 +101,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}.
+     * {@code right} index is inclusive, and it does no range checking
+     * on {@code left} or {@code right}.
      *
      * @param a the array to be sorted
      * @param left the index of the first element, inclusive, to be sorted
@@ -111,13 +111,13 @@
     private static void doSort(int[] a, int left, int right) {
         // Use insertion sort on tiny arrays
         if (right - left + 1 < INSERTION_SORT_THRESHOLD) {
-            for (int k = left + 1; k <= right; k++) {
-                int ak = a[k];
+            for (int i = left + 1; i <= right; i++) {
+                int ai = a[i];
                 int j;
-                for (j = k - 1; j >= left && ak < a[j]; j--) {
+                for (j = i - 1; j >= left && ai < a[j]; j--) {
                     a[j + 1] = a[j];
                 }
-                a[j + 1] = ak;
+                a[j + 1] = ai;
             }
         } else { // Use Dual-Pivot Quicksort on large arrays
             dualPivotQuicksort(a, left, right);
@@ -162,7 +162,7 @@
          * second terciles of the array. Note that pivot1 <= pivot2.
          *
          * The pivots are stored in local variables, and the first and
-         * the last of the sorted elements are moved to the locations
+         * 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.
@@ -170,27 +170,26 @@
         int pivot1 = ae2; a[e2] = a[left];
         int pivot2 = ae4; a[e4] = a[right];
 
-        /*
-         * Partitioning
-         *
-         *   left part         center part                  right part
-         * ------------------------------------------------------------
-         * [ < pivot1  |  pivot1 <= && <= pivot2  |   ?   |  > pivot2 ]
-         * ------------------------------------------------------------
-         *              ^                          ^     ^
-         *              |                          |     |
-         *             less                        k   great
-         */
-
         // 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
 
-        boolean pivotsDiffer = pivot1 != pivot2;
+        boolean pivotsDiffer = (pivot1 != pivot2);
 
         if (pivotsDiffer) {
             /*
+             * Partitioning:
+             *
+             *   left part         center part                    right part
+             * +------------------------------------------------------------+
+             * | < pivot1  |  pivot1 <= && <= pivot2  |    ?    |  > pivot2 |
+             * +------------------------------------------------------------+
+             *              ^                          ^       ^
+             *              |                          |       |
+             *             less                        k     great
+             *
              * Invariants:
+             *
              *              all in (left, less)   < pivot1
              *    pivot1 <= all in [less, k)     <= pivot2
              *              all in (great, right) > pivot2
@@ -200,37 +199,37 @@
             outer:
             for (int k = less; k <= great; k++) {
                 int ak = a[k];
-                if (ak < pivot1) {
-                    if (k > less) {
+                if (ak < pivot1) { // Move a[k] to left part
+                    if (k != less) {
                         a[k] = a[less];
                         a[less] = ak;
                     }
                     less++;
-                } else if (ak > pivot2) {
+                } else if (ak > pivot2) { // Move a[k] to right part
                     while (a[great] > pivot2) {
-                        if (k == great--) {
+                        if (great-- == k) {
                             break outer;
                         }
                     }
-                    a[k] = a[great];
-                    a[great--] = ak;
-
-                    if ((ak = a[k]) < pivot1) {
+                    if (a[great] < pivot1) {
                         a[k] = a[less];
-                        a[less++] = ak;
+                        a[less++] = a[great];
+                        a[great--] = ak;
+                    } else { // pivot1 <= a[great] <= pivot2
+                        a[k] = a[great];
+                        a[great--] = ak;
                     }
                 }
             }
         } 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", partition:
              *
              *   left part   center part            right part
-             * -------------------------------------------------
-             * [  < pivot  |  == pivot  |    ?    |  > pivot   ]
-             * -------------------------------------------------
-             *
+             * +----------------------------------------------+
+             * |  < pivot  |  == pivot  |    ?    |  > pivot  |
+             * +----------------------------------------------+
              *              ^            ^       ^
              *              |            |       |
              *             less          k     great
@@ -243,30 +242,34 @@
              *
              * Pointer k is the first index of ?-part
              */
-            outer:
             for (int k = less; k <= great; k++) {
                 int ak = a[k];
                 if (ak == pivot1) {
                     continue;
                 }
-                if (ak < pivot1) {
-                    if (k > less) {
+                if (ak < pivot1) { // Move a[k] to left part
+                    if (k != less) {
                         a[k] = a[less];
                         a[less] = ak;
                     }
                     less++;
-                } else { // a[k] > pivot
+                } 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
+                     * terminates, even though we don't test for it explicitly.
+                     * In other words, a[e3] acts as a sentinel for great.
+                     */
                     while (a[great] > pivot1) {
-                        if (k == great--) {
-                            break outer;
-                        }
+                        great--;
                     }
-                    a[k] = a[great];
-                    a[great--] = ak;
-
-                    if ((ak = a[k]) <  pivot1) {
+                    if (a[great] < pivot1) {
                         a[k] = a[less];
-                        a[less++] = ak;
+                        a[less++] = a[great];
+                        a[great--] = ak;
+                    } else { // a[great] == pivot1
+                        a[k] = pivot1;
+                        a[great--] = ak;
                     }
                 }
             }
@@ -289,26 +292,55 @@
         }
 
         /*
-         * If center part is too large (comprises > 5/6 of
-         * the array), swap internal pivot values to ends
+         * If center part is too large (comprises > 2/3 of the array),
+         * swap internal pivot values to ends
          */
-        if (less < e1 && e5 < great) {
+        if (less < e1 && great > e5) {
             while (a[less] == pivot1) {
                 less++;
             }
             while (a[great] == pivot2) {
                 great--;
             }
-            for (int k = less + 1; k <= 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) {
-                    a[k++] = a[less];
+                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;
-                } else if (ak == pivot2) {
-                    a[k] = a[great];
-                    a[great--] = pivot2;
-                } else {
-                    k++;
                 }
             }
         }
@@ -330,7 +362,7 @@
      * Sorts the specified range of the array into ascending order. The range
      * to be sorted extends from the index {@code fromIndex}, inclusive, to
      * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex},
-     * the range to be sorted is empty.
+     * the range to be sorted is empty (and the call is a no-op).
      *
      * @param a the array to be sorted
      * @param fromIndex the index of the first element, inclusive, to be sorted
@@ -357,13 +389,13 @@
     private static void doSort(long[] a, int left, int right) {
         // Use insertion sort on tiny arrays
         if (right - left + 1 < INSERTION_SORT_THRESHOLD) {
-            for (int k = left + 1; k <= right; k++) {
-                long ak = a[k];
+            for (int i = left + 1; i <= right; i++) {
+                long ai = a[i];
                 int j;
-                for (j = k - 1; j >= left && ak < a[j]; j--) {
+                for (j = i - 1; j >= left && ai < a[j]; j--) {
                     a[j + 1] = a[j];
                 }
-                a[j + 1] = ak;
+                a[j + 1] = ai;
             }
         } else { // Use Dual-Pivot Quicksort on large arrays
             dualPivotQuicksort(a, left, right);
@@ -408,7 +440,7 @@
          * second terciles of the array. Note that pivot1 <= pivot2.
          *
          * The pivots are stored in local variables, and the first and
-         * the last of the sorted elements are moved to the locations
+         * 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.
@@ -416,27 +448,26 @@
         long pivot1 = ae2; a[e2] = a[left];
         long pivot2 = ae4; a[e4] = a[right];
 
-        /*
-         * Partitioning
-         *
-         *   left part         center part                  right part
-         * ------------------------------------------------------------
-         * [ < pivot1  |  pivot1 <= && <= pivot2  |   ?   |  > pivot2 ]
-         * ------------------------------------------------------------
-         *              ^                          ^     ^
-         *              |                          |     |
-         *             less                        k   great
-         */
-
         // 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
 
-        boolean pivotsDiffer = pivot1 != pivot2;
+        boolean pivotsDiffer = (pivot1 != pivot2);
 
         if (pivotsDiffer) {
             /*
+             * Partitioning:
+             *
+             *   left part         center part                    right part
+             * +------------------------------------------------------------+
+             * | < pivot1  |  pivot1 <= && <= pivot2  |    ?    |  > pivot2 |
+             * +------------------------------------------------------------+
+             *              ^                          ^       ^
+             *              |                          |       |
+             *             less                        k     great
+             *
              * Invariants:
+             *
              *              all in (left, less)   < pivot1
              *    pivot1 <= all in [less, k)     <= pivot2
              *              all in (great, right) > pivot2
@@ -446,37 +477,37 @@
             outer:
             for (int k = less; k <= great; k++) {
                 long ak = a[k];
-                if (ak < pivot1) {
-                    if (k > less) {
+                if (ak < pivot1) { // Move a[k] to left part
+                    if (k != less) {
                         a[k] = a[less];
                         a[less] = ak;
                     }
                     less++;
-                } else if (ak > pivot2) {
+                } else if (ak > pivot2) { // Move a[k] to right part
                     while (a[great] > pivot2) {
-                        if (k == great--) {
+                        if (great-- == k) {
                             break outer;
                         }
                     }
-                    a[k] = a[great];
-                    a[great--] = ak;
-
-                    if ((ak = a[k]) <  pivot1) {
+                    if (a[great] < pivot1) {
                         a[k] = a[less];
-                        a[less++] = ak;
+                        a[less++] = a[great];
+                        a[great--] = ak;
+                    } else { // pivot1 <= a[great] <= pivot2
+                        a[k] = a[great];
+                        a[great--] = ak;
                     }
                 }
             }
         } 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", partition:
              *
              *   left part   center part            right part
-             * -------------------------------------------------
-             * [  < pivot  |  == pivot  |    ?    |  > pivot   ]
-             * -------------------------------------------------
-             *
+             * +----------------------------------------------+
+             * |  < pivot  |  == pivot  |    ?    |  > pivot  |
+             * +----------------------------------------------+
              *              ^            ^       ^
              *              |            |       |
              *             less          k     great
@@ -489,30 +520,34 @@
              *
              * Pointer k is the first index of ?-part
              */
-            outer:
             for (int k = less; k <= great; k++) {
                 long ak = a[k];
                 if (ak == pivot1) {
                     continue;
                 }
-                if (ak < pivot1) {
-                    if (k > less) {
+                if (ak < pivot1) { // Move a[k] to left part
+                    if (k != less) {
                         a[k] = a[less];
                         a[less] = ak;
                     }
                     less++;
-                } else { // a[k] > pivot
+                } 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
+                     * terminates, even though we don't test for it explicitly.
+                     * In other words, a[e3] acts as a sentinel for great.
+                     */
                     while (a[great] > pivot1) {
-                        if (k == great--) {
-                            break outer;
-                        }
+                        great--;
                     }
-                    a[k] = a[great];
-                    a[great--] = ak;
-
-                    if ((ak = a[k]) <  pivot1) {
+                    if (a[great] < pivot1) {
                         a[k] = a[less];
-                        a[less++] = ak;
+                        a[less++] = a[great];
+                        a[great--] = ak;
+                    } else { // a[great] == pivot1
+                        a[k] = pivot1;
+                        a[great--] = ak;
                     }
                 }
             }
@@ -535,26 +570,55 @@
         }
 
         /*
-         * If center part is too large (comprises > 5/6 of
-         * the array), swap internal pivot values to ends
+         * If center part is too large (comprises > 2/3 of the array),
+         * swap internal pivot values to ends
          */
-        if (less < e1 && e5 < great) {
+        if (less < e1 && great > e5) {
             while (a[less] == pivot1) {
                 less++;
             }
             while (a[great] == pivot2) {
                 great--;
             }
-            for (int k = less + 1; k <= 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) {
-                    a[k++] = a[less];
+                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;
-                } else if (ak == pivot2) {
-                    a[k] = a[great];
-                    a[great--] = pivot2;
-                } else {
-                    k++;
                 }
             }
         }
@@ -576,7 +640,7 @@
      * Sorts the specified range of the array into ascending order. The range
      * to be sorted extends from the index {@code fromIndex}, inclusive, to
      * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex},
-     * the range to be sorted is empty.
+     * the range to be sorted is empty (and the call is a no-op).
      *
      * @param a the array to be sorted
      * @param fromIndex the index of the first element, inclusive, to be sorted
@@ -606,13 +670,13 @@
     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 k = left + 1; k <= right; k++) {
-                short ak = a[k];
+            for (int i = left + 1; i <= right; i++) {
+                short ai = a[i];
                 int j;
-                for (j = k - 1; j >= left && ak < a[j]; j--) {
+                for (j = i - 1; j >= left && ai < a[j]; j--) {
                     a[j + 1] = a[j];
                 }
-                a[j + 1] = ak;
+                a[j + 1] = ai;
             }
         } else if (right-left+1 > COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) {
             // Use counting sort on huge arrays
@@ -671,7 +735,7 @@
          * second terciles of the array. Note that pivot1 <= pivot2.
          *
          * The pivots are stored in local variables, and the first and
-         * the last of the sorted elements are moved to the locations
+         * 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.
@@ -679,27 +743,26 @@
         short pivot1 = ae2; a[e2] = a[left];
         short pivot2 = ae4; a[e4] = a[right];
 
-        /*
-         * Partitioning
-         *
-         *   left part         center part                  right part
-         * ------------------------------------------------------------
-         * [ < pivot1  |  pivot1 <= && <= pivot2  |   ?   |  > pivot2 ]
-         * ------------------------------------------------------------
-         *              ^                          ^     ^
-         *              |                          |     |
-         *             less                        k   great
-         */
-
         // 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
 
-        boolean pivotsDiffer = pivot1 != pivot2;
+        boolean pivotsDiffer = (pivot1 != pivot2);
 
         if (pivotsDiffer) {
             /*
+             * Partitioning:
+             *
+             *   left part         center part                    right part
+             * +------------------------------------------------------------+
+             * | < pivot1  |  pivot1 <= && <= pivot2  |    ?    |  > pivot2 |
+             * +------------------------------------------------------------+
+             *              ^                          ^       ^
+             *              |                          |       |
+             *             less                        k     great
+             *
              * Invariants:
+             *
              *              all in (left, less)   < pivot1
              *    pivot1 <= all in [less, k)     <= pivot2
              *              all in (great, right) > pivot2
@@ -709,37 +772,37 @@
             outer:
             for (int k = less; k <= great; k++) {
                 short ak = a[k];
-                if (ak < pivot1) {
-                    if (k > less) {
+                if (ak < pivot1) { // Move a[k] to left part
+                    if (k != less) {
                         a[k] = a[less];
                         a[less] = ak;
                     }
                     less++;
-                } else if (ak > pivot2) {
+                } else if (ak > pivot2) { // Move a[k] to right part
                     while (a[great] > pivot2) {
-                        if (k == great--) {
+                        if (great-- == k) {
                             break outer;
                         }
                     }
-                    a[k] = a[great];
-                    a[great--] = ak;
-
-                    if ((ak = a[k]) <  pivot1) {
+                    if (a[great] < pivot1) {
                         a[k] = a[less];
-                        a[less++] = ak;
+                        a[less++] = a[great];
+                        a[great--] = ak;
+                    } else { // pivot1 <= a[great] <= pivot2
+                        a[k] = a[great];
+                        a[great--] = ak;
                     }
                 }
             }
         } 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", partition:
              *
              *   left part   center part            right part
-             * -------------------------------------------------
-             * [  < pivot  |  == pivot  |    ?    |  > pivot   ]
-             * -------------------------------------------------
-             *
+             * +----------------------------------------------+
+             * |  < pivot  |  == pivot  |    ?    |  > pivot  |
+             * +----------------------------------------------+
              *              ^            ^       ^
              *              |            |       |
              *             less          k     great
@@ -752,30 +815,34 @@
              *
              * Pointer k is the first index of ?-part
              */
-            outer:
             for (int k = less; k <= great; k++) {
                 short ak = a[k];
                 if (ak == pivot1) {
                     continue;
                 }
-                if (ak < pivot1) {
-                    if (k > less) {
+                if (ak < pivot1) { // Move a[k] to left part
+                    if (k != less) {
                         a[k] = a[less];
                         a[less] = ak;
                     }
                     less++;
-                } else { // a[k] > pivot
+                } 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
+                     * terminates, even though we don't test for it explicitly.
+                     * In other words, a[e3] acts as a sentinel for great.
+                     */
                     while (a[great] > pivot1) {
-                        if (k == great--) {
-                            break outer;
-                        }
+                        great--;
                     }
-                    a[k] = a[great];
-                    a[great--] = ak;
-
-                    if ((ak = a[k]) <  pivot1) {
+                    if (a[great] < pivot1) {
                         a[k] = a[less];
-                        a[less++] = ak;
+                        a[less++] = a[great];
+                        a[great--] = ak;
+                    } else { // a[great] == pivot1
+                        a[k] = pivot1;
+                        a[great--] = ak;
                     }
                 }
             }
@@ -798,26 +865,55 @@
         }
 
         /*
-         * If center part is too large (comprises > 5/6 of
-         * the array), swap internal pivot values to ends
+         * If center part is too large (comprises > 2/3 of the array),
+         * swap internal pivot values to ends
          */
-        if (less < e1 && e5 < great) {
+        if (less < e1 && great > e5) {
             while (a[less] == pivot1) {
                 less++;
             }
             while (a[great] == pivot2) {
                 great--;
             }
-            for (int k = less + 1; k <= 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) {
-                    a[k++] = a[less];
+                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;
-                } else if (ak == pivot2) {
-                    a[k] = a[great];
-                    a[great--] = pivot2;
-                } else {
-                    k++;
                 }
             }
         }
@@ -839,7 +935,7 @@
      * Sorts the specified range of the array into ascending order. The range
      * to be sorted extends from the index {@code fromIndex}, inclusive, to
      * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex},
-     * the range to be sorted is empty.
+     * the range to be sorted is empty (and the call is a no-op).
      *
      * @param a the array to be sorted
      * @param fromIndex the index of the first element, inclusive, to be sorted
@@ -869,13 +965,13 @@
     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 k = left + 1; k <= right; k++) {
-                char ak = a[k];
+            for (int i = left + 1; i <= right; i++) {
+                char ai = a[i];
                 int j;
-                for (j = k - 1; j >= left && ak < a[j]; j--) {
+                for (j = i - 1; j >= left && ai < a[j]; j--) {
                     a[j + 1] = a[j];
                 }
-                a[j + 1] = ak;
+                a[j + 1] = ai;
             }
         } else if (right-left+1 > COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) {
             // Use counting sort on huge arrays
@@ -932,7 +1028,7 @@
          * second terciles of the array. Note that pivot1 <= pivot2.
          *
          * The pivots are stored in local variables, and the first and
-         * the last of the sorted elements are moved to the locations
+         * 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.
@@ -940,27 +1036,26 @@
         char pivot1 = ae2; a[e2] = a[left];
         char pivot2 = ae4; a[e4] = a[right];
 
-        /*
-         * Partitioning
-         *
-         *   left part         center part                  right part
-         * ------------------------------------------------------------
-         * [ < pivot1  |  pivot1 <= && <= pivot2  |   ?   |  > pivot2 ]
-         * ------------------------------------------------------------
-         *              ^                          ^     ^
-         *              |                          |     |
-         *             less                        k   great
-         */
-
         // 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
 
-        boolean pivotsDiffer = pivot1 != pivot2;
+        boolean pivotsDiffer = (pivot1 != pivot2);
 
         if (pivotsDiffer) {
             /*
+             * Partitioning:
+             *
+             *   left part         center part                    right part
+             * +------------------------------------------------------------+
+             * | < pivot1  |  pivot1 <= && <= pivot2  |    ?    |  > pivot2 |
+             * +------------------------------------------------------------+
+             *              ^                          ^       ^
+             *              |                          |       |
+             *             less                        k     great
+             *
              * Invariants:
+             *
              *              all in (left, less)   < pivot1
              *    pivot1 <= all in [less, k)     <= pivot2
              *              all in (great, right) > pivot2
@@ -970,37 +1065,37 @@
             outer:
             for (int k = less; k <= great; k++) {
                 char ak = a[k];
-                if (ak < pivot1) {
-                    if (k > less) {
+                if (ak < pivot1) { // Move a[k] to left part
+                    if (k != less) {
                         a[k] = a[less];
                         a[less] = ak;
                     }
                     less++;
-                } else if (ak > pivot2) {
+                } else if (ak > pivot2) { // Move a[k] to right part
                     while (a[great] > pivot2) {
-                        if (k == great--) {
+                        if (great-- == k) {
                             break outer;
                         }
                     }
-                    a[k] = a[great];
-                    a[great--] = ak;
-
-                    if ((ak = a[k]) <  pivot1) {
+                    if (a[great] < pivot1) {
                         a[k] = a[less];
-                        a[less++] = ak;
+                        a[less++] = a[great];
+                        a[great--] = ak;
+                    } else { // pivot1 <= a[great] <= pivot2
+                        a[k] = a[great];
+                        a[great--] = ak;
                     }
                 }
             }
         } 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", partition:
              *
              *   left part   center part            right part
-             * -------------------------------------------------
-             * [  < pivot  |  == pivot  |    ?    |  > pivot   ]
-             * -------------------------------------------------
-             *
+             * +----------------------------------------------+
+             * |  < pivot  |  == pivot  |    ?    |  > pivot  |
+             * +----------------------------------------------+
              *              ^            ^       ^
              *              |            |       |
              *             less          k     great
@@ -1013,30 +1108,34 @@
              *
              * Pointer k is the first index of ?-part
              */
-            outer:
             for (int k = less; k <= great; k++) {
                 char ak = a[k];
                 if (ak == pivot1) {
                     continue;
                 }
-                if (ak < pivot1) {
-                    if (k > less) {
+                if (ak < pivot1) { // Move a[k] to left part
+                    if (k != less) {
                         a[k] = a[less];
                         a[less] = ak;
                     }
                     less++;
-                } else { // a[k] > pivot
+                } 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
+                     * terminates, even though we don't test for it explicitly.
+                     * In other words, a[e3] acts as a sentinel for great.
+                     */
                     while (a[great] > pivot1) {
-                        if (k == great--) {
-                            break outer;
-                        }
+                        great--;
                     }
-                    a[k] = a[great];
-                    a[great--] = ak;
-
-                    if ((ak = a[k]) <  pivot1) {
+                    if (a[great] < pivot1) {
                         a[k] = a[less];
-                        a[less++] = ak;
+                        a[less++] = a[great];
+                        a[great--] = ak;
+                    } else { // a[great] == pivot1
+                        a[k] = pivot1;
+                        a[great--] = ak;
                     }
                 }
             }
@@ -1059,26 +1158,55 @@
         }
 
         /*
-         * If center part is too large (comprises > 5/6 of
-         * the array), swap internal pivot values to ends
+         * If center part is too large (comprises > 2/3 of the array),
+         * swap internal pivot values to ends
          */
-        if (less < e1 && e5 < great) {
+        if (less < e1 && great > e5) {
             while (a[less] == pivot1) {
                 less++;
             }
             while (a[great] == pivot2) {
                 great--;
             }
-            for (int k = less + 1; k <= 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) {
-                    a[k++] = a[less];
+                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;
-                } else if (ak == pivot2) {
-                    a[k] = a[great];
-                    a[great--] = pivot2;
-                } else {
-                    k++;
                 }
             }
         }
@@ -1100,7 +1228,7 @@
      * Sorts the specified range of the array into ascending order. The range
      * to be sorted extends from the index {@code fromIndex}, inclusive, to
      * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex},
-     * the range to be sorted is empty.
+     * the range to be sorted is empty (and the call is a no-op).
      *
      * @param a the array to be sorted
      * @param fromIndex the index of the first element, inclusive, to be sorted
@@ -1130,13 +1258,13 @@
     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 k = left + 1; k <= right; k++) {
-                byte ak = a[k];
+            for (int i = left + 1; i <= right; i++) {
+                byte ai = a[i];
                 int j;
-                for (j = k - 1; j >= left && ak < a[j]; j--) {
+                for (j = i - 1; j >= left && ai < a[j]; j--) {
                     a[j + 1] = a[j];
                 }
-                a[j + 1] = ak;
+                a[j + 1] = ai;
             }
         } else if (right - left + 1 > COUNTING_SORT_THRESHOLD_FOR_BYTE) {
             // Use counting sort on huge arrays
@@ -1195,7 +1323,7 @@
          * second terciles of the array. Note that pivot1 <= pivot2.
          *
          * The pivots are stored in local variables, and the first and
-         * the last of the sorted elements are moved to the locations
+         * 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.
@@ -1203,27 +1331,26 @@
         byte pivot1 = ae2; a[e2] = a[left];
         byte pivot2 = ae4; a[e4] = a[right];
 
-        /*
-         * Partitioning
-         *
-         *   left part         center part                  right part
-         * ------------------------------------------------------------
-         * [ < pivot1  |  pivot1 <= && <= pivot2  |   ?   |  > pivot2 ]
-         * ------------------------------------------------------------
-         *              ^                          ^     ^
-         *              |                          |     |
-         *             less                        k   great
-         */
-
         // 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
 
-        boolean pivotsDiffer = pivot1 != pivot2;
+        boolean pivotsDiffer = (pivot1 != pivot2);
 
         if (pivotsDiffer) {
             /*
+             * Partitioning:
+             *
+             *   left part         center part                    right part
+             * +------------------------------------------------------------+
+             * | < pivot1  |  pivot1 <= && <= pivot2  |    ?    |  > pivot2 |
+             * +------------------------------------------------------------+
+             *              ^                          ^       ^
+             *              |                          |       |
+             *             less                        k     great
+             *
              * Invariants:
+             *
              *              all in (left, less)   < pivot1
              *    pivot1 <= all in [less, k)     <= pivot2
              *              all in (great, right) > pivot2
@@ -1233,37 +1360,37 @@
             outer:
             for (int k = less; k <= great; k++) {
                 byte ak = a[k];
-                if (ak < pivot1) {
-                    if (k > less) {
+                if (ak < pivot1) { // Move a[k] to left part
+                    if (k != less) {
                         a[k] = a[less];
                         a[less] = ak;
                     }
                     less++;
-                } else if (ak > pivot2) {
+                } else if (ak > pivot2) { // Move a[k] to right part
                     while (a[great] > pivot2) {
-                        if (k == great--) {
+                        if (great-- == k) {
                             break outer;
                         }
                     }
-                    a[k] = a[great];
-                    a[great--] = ak;
-
-                    if ((ak = a[k]) <  pivot1) {
+                    if (a[great] < pivot1) {
                         a[k] = a[less];
-                        a[less++] = ak;
+                        a[less++] = a[great];
+                        a[great--] = ak;
+                    } else { // pivot1 <= a[great] <= pivot2
+                        a[k] = a[great];
+                        a[great--] = ak;
                     }
                 }
             }
         } 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", partition:
              *
              *   left part   center part            right part
-             * -------------------------------------------------
-             * [  < pivot  |  == pivot  |    ?    |  > pivot   ]
-             * -------------------------------------------------
-             *
+             * +----------------------------------------------+
+             * |  < pivot  |  == pivot  |    ?    |  > pivot  |
+             * +----------------------------------------------+
              *              ^            ^       ^
              *              |            |       |
              *             less          k     great
@@ -1276,30 +1403,34 @@
              *
              * Pointer k is the first index of ?-part
              */
-            outer:
             for (int k = less; k <= great; k++) {
                 byte ak = a[k];
                 if (ak == pivot1) {
                     continue;
                 }
-                if (ak < pivot1) {
-                    if (k > less) {
+                if (ak < pivot1) { // Move a[k] to left part
+                    if (k != less) {
                         a[k] = a[less];
                         a[less] = ak;
                     }
                     less++;
-                } else { // a[k] > pivot
+                } 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
+                     * terminates, even though we don't test for it explicitly.
+                     * In other words, a[e3] acts as a sentinel for great.
+                     */
                     while (a[great] > pivot1) {
-                        if (k == great--) {
-                            break outer;
-                        }
+                        great--;
                     }
-                    a[k] = a[great];
-                    a[great--] = ak;
-
-                    if ((ak = a[k]) <  pivot1) {
+                    if (a[great] < pivot1) {
                         a[k] = a[less];
-                        a[less++] = ak;
+                        a[less++] = a[great];
+                        a[great--] = ak;
+                    } else { // a[great] == pivot1
+                        a[k] = pivot1;
+                        a[great--] = ak;
                     }
                 }
             }
@@ -1322,26 +1453,55 @@
         }
 
         /*
-         * If center part is too large (comprises > 5/6 of
-         * the array), swap internal pivot values to ends
+         * If center part is too large (comprises > 2/3 of the array),
+         * swap internal pivot values to ends
          */
-        if (less < e1 && e5 < great) {
+        if (less < e1 && great > e5) {
             while (a[less] == pivot1) {
                 less++;
             }
             while (a[great] == pivot2) {
                 great--;
             }
-            for (int k = less + 1; k <= 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++) {
                 byte ak = a[k];
-                if (ak == pivot1) {
-                    a[k++] = a[less];
+                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;
-                } else if (ak == pivot2) {
-                    a[k] = a[great];
-                    a[great--] = pivot2;
-                } else {
-                    k++;
                 }
             }
         }
@@ -1371,7 +1531,7 @@
      * Sorts the specified range of the array into ascending order. The range
      * to be sorted extends from the index {@code fromIndex}, inclusive, to
      * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex},
-     * the range to be sorted is empty.
+     * the range to be sorted is empty  and the call is a no-op).
      *
      * <p>The {@code <} relation does not provide a total order on all float
      * values: {@code -0.0f == 0.0f} is {@code true} and a {@code Float.NaN}
@@ -1485,13 +1645,13 @@
     private static void doSort(float[] a, int left, int right) {
         // Use insertion sort on tiny arrays
         if (right - left + 1 < INSERTION_SORT_THRESHOLD) {
-            for (int k = left + 1; k <= right; k++) {
-                float ak = a[k];
+            for (int i = left + 1; i <= right; i++) {
+                float ai = a[i];
                 int j;
-                for (j = k - 1; j >= left && ak < a[j]; j--) {
+                for (j = i - 1; j >= left && ai < a[j]; j--) {
                     a[j + 1] = a[j];
                 }
-                a[j + 1] = ak;
+                a[j + 1] = ai;
             }
         } else { // Use Dual-Pivot Quicksort on large arrays
             dualPivotQuicksort(a, left, right);
@@ -1536,7 +1696,7 @@
          * second terciles of the array. Note that pivot1 <= pivot2.
          *
          * The pivots are stored in local variables, and the first and
-         * the last of the sorted elements are moved to the locations
+         * 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.
@@ -1544,27 +1704,26 @@
         float pivot1 = ae2; a[e2] = a[left];
         float pivot2 = ae4; a[e4] = a[right];
 
-        /*
-         * Partitioning
-         *
-         *   left part         center part                  right part
-         * ------------------------------------------------------------
-         * [ < pivot1  |  pivot1 <= && <= pivot2  |   ?   |  > pivot2 ]
-         * ------------------------------------------------------------
-         *              ^                          ^     ^
-         *              |                          |     |
-         *             less                        k   great
-         */
-
         // 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
 
-        boolean pivotsDiffer = pivot1 != pivot2;
+        boolean pivotsDiffer = (pivot1 != pivot2);
 
         if (pivotsDiffer) {
             /*
+             * Partitioning:
+             *
+             *   left part         center part                    right part
+             * +------------------------------------------------------------+
+             * | < pivot1  |  pivot1 <= && <= pivot2  |    ?    |  > pivot2 |
+             * +------------------------------------------------------------+
+             *              ^                          ^       ^
+             *              |                          |       |
+             *             less                        k     great
+             *
              * Invariants:
+             *
              *              all in (left, less)   < pivot1
              *    pivot1 <= all in [less, k)     <= pivot2
              *              all in (great, right) > pivot2
@@ -1574,37 +1733,37 @@
             outer:
             for (int k = less; k <= great; k++) {
                 float ak = a[k];
-                if (ak < pivot1) {
-                    if (k > less) {
+                if (ak < pivot1) { // Move a[k] to left part
+                    if (k != less) {
                         a[k] = a[less];
                         a[less] = ak;
                     }
                     less++;
-                } else if (ak > pivot2) {
+                } else if (ak > pivot2) { // Move a[k] to right part
                     while (a[great] > pivot2) {
-                        if (k == great--) {
+                        if (great-- == k) {
                             break outer;
                         }
                     }
-                    a[k] = a[great];
-                    a[great--] = ak;
-
-                    if ((ak = a[k]) <  pivot1) {
+                    if (a[great] < pivot1) {
                         a[k] = a[less];
-                        a[less++] = ak;
+                        a[less++] = a[great];
+                        a[great--] = ak;
+                    } else { // pivot1 <= a[great] <= pivot2
+                        a[k] = a[great];
+                        a[great--] = ak;
                     }
                 }
             }
         } 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", partition:
              *
              *   left part   center part            right part
-             * -------------------------------------------------
-             * [  < pivot  |  == pivot  |    ?    |  > pivot   ]
-             * -------------------------------------------------
-             *
+             * +----------------------------------------------+
+             * |  < pivot  |  == pivot  |    ?    |  > pivot  |
+             * +----------------------------------------------+
              *              ^            ^       ^
              *              |            |       |
              *             less          k     great
@@ -1617,30 +1776,34 @@
              *
              * Pointer k is the first index of ?-part
              */
-            outer:
             for (int k = less; k <= great; k++) {
                 float ak = a[k];
                 if (ak == pivot1) {
                     continue;
                 }
-                if (ak < pivot1) {
-                    if (k > less) {
+                if (ak < pivot1) { // Move a[k] to left part
+                    if (k != less) {
                         a[k] = a[less];
                         a[less] = ak;
                     }
                     less++;
-                } else { // a[k] > pivot
+                } 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
+                     * terminates, even though we don't test for it explicitly.
+                     * In other words, a[e3] acts as a sentinel for great.
+                     */
                     while (a[great] > pivot1) {
-                        if (k == great--) {
-                            break outer;
-                        }
+                        great--;
                     }
-                    a[k] = a[great];
-                    a[great--] = ak;
-
-                    if ((ak = a[k]) <  pivot1) {
+                    if (a[great] < pivot1) {
                         a[k] = a[less];
-                        a[less++] = ak;
+                        a[less++] = a[great];
+                        a[great--] = ak;
+                    } else { // a[great] == pivot1
+                        a[k] = pivot1;
+                        a[great--] = ak;
                     }
                 }
             }
@@ -1663,26 +1826,55 @@
         }
 
         /*
-         * If center part is too large (comprises > 5/6 of
-         * the array), swap internal pivot values to ends
+         * If center part is too large (comprises > 2/3 of the array),
+         * swap internal pivot values to ends
          */
-        if (less < e1 && e5 < great) {
+        if (less < e1 && great > e5) {
             while (a[less] == pivot1) {
                 less++;
             }
             while (a[great] == pivot2) {
                 great--;
             }
-            for (int k = less + 1; k <= 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++) {
                 float ak = a[k];
-                if (ak == pivot1) {
-                    a[k++] = a[less];
+                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;
-                } else if (ak == pivot2) {
-                    a[k] = a[great];
-                    a[great--] = pivot2;
-                } else {
-                    k++;
                 }
             }
         }
@@ -1712,7 +1904,7 @@
      * Sorts the specified range of the array into ascending order. The range
      * to be sorted extends from the index {@code fromIndex}, inclusive, to
      * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex},
-     * the range to be sorted is empty.
+     * the range to be sorted is empty (and the call is a no-op).
      *
      * <p>The {@code <} relation does not provide a total order on all double
      * values: {@code -0.0d == 0.0d} is {@code true} and a {@code Double.NaN}
@@ -1826,13 +2018,13 @@
     private static void doSort(double[] a, int left, int right) {
         // Use insertion sort on tiny arrays
         if (right - left + 1 < INSERTION_SORT_THRESHOLD) {
-            for (int k = left + 1; k <= right; k++) {
-                double ak = a[k];
+            for (int i = left + 1; i <= right; i++) {
+                double ai = a[i];
                 int j;
-                for (j = k - 1; j >= left && ak < a[j]; j--) {
+                for (j = i - 1; j >= left && ai < a[j]; j--) {
                     a[j + 1] = a[j];
                 }
-                a[j + 1] = ak;
+                a[j + 1] = ai;
             }
         } else { // Use Dual-Pivot Quicksort on large arrays
             dualPivotQuicksort(a, left, right);
@@ -1877,7 +2069,7 @@
          * second terciles of the array. Note that pivot1 <= pivot2.
          *
          * The pivots are stored in local variables, and the first and
-         * the last of the sorted elements are moved to the locations
+         * 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.
@@ -1885,27 +2077,26 @@
         double pivot1 = ae2; a[e2] = a[left];
         double pivot2 = ae4; a[e4] = a[right];
 
-        /*
-         * Partitioning
-         *
-         *   left part         center part                  right part
-         * ------------------------------------------------------------
-         * [ < pivot1  |  pivot1 <= && <= pivot2  |   ?   |  > pivot2 ]
-         * ------------------------------------------------------------
-         *              ^                          ^     ^
-         *              |                          |     |
-         *             less                        k   great
-         */
-
         // 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
 
-        boolean pivotsDiffer = pivot1 != pivot2;
+        boolean pivotsDiffer = (pivot1 != pivot2);
 
         if (pivotsDiffer) {
             /*
+             * Partitioning:
+             *
+             *   left part         center part                    right part
+             * +------------------------------------------------------------+
+             * | < pivot1  |  pivot1 <= && <= pivot2  |    ?    |  > pivot2 |
+             * +------------------------------------------------------------+
+             *              ^                          ^       ^
+             *              |                          |       |
+             *             less                        k     great
+             *
              * Invariants:
+             *
              *              all in (left, less)   < pivot1
              *    pivot1 <= all in [less, k)     <= pivot2
              *              all in (great, right) > pivot2
@@ -1915,37 +2106,37 @@
             outer:
             for (int k = less; k <= great; k++) {
                 double ak = a[k];
-                if (ak < pivot1) {
-                    if (k > less) {
+                if (ak < pivot1) { // Move a[k] to left part
+                    if (k != less) {
                         a[k] = a[less];
                         a[less] = ak;
                     }
                     less++;
-                } else if (ak > pivot2) {
+                } else if (ak > pivot2) { // Move a[k] to right part
                     while (a[great] > pivot2) {
-                        if (k == great--) {
+                        if (great-- == k) {
                             break outer;
                         }
                     }
-                    a[k] = a[great];
-                    a[great--] = ak;
-
-                    if ((ak = a[k]) <  pivot1) {
+                    if (a[great] < pivot1) {
                         a[k] = a[less];
-                        a[less++] = ak;
+                        a[less++] = a[great];
+                        a[great--] = ak;
+                    } else { // pivot1 <= a[great] <= pivot2
+                        a[k] = a[great];
+                        a[great--] = ak;
                     }
                 }
             }
         } 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", partition:
              *
              *   left part   center part            right part
-             * -------------------------------------------------
-             * [  < pivot  |  == pivot  |    ?    |  > pivot   ]
-             * -------------------------------------------------
-             *
+             * +----------------------------------------------+
+             * |  < pivot  |  == pivot  |    ?    |  > pivot  |
+             * +----------------------------------------------+
              *              ^            ^       ^
              *              |            |       |
              *             less          k     great
@@ -1958,30 +2149,34 @@
              *
              * Pointer k is the first index of ?-part
              */
-            outer:
             for (int k = less; k <= great; k++) {
                 double ak = a[k];
                 if (ak == pivot1) {
                     continue;
                 }
-                if (ak < pivot1) {
-                    if (k > less) {
+                if (ak < pivot1) { // Move a[k] to left part
+                    if (k != less) {
                         a[k] = a[less];
                         a[less] = ak;
                     }
                     less++;
-                } else { // a[k] > pivot
+                } 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
+                     * terminates, even though we don't test for it explicitly.
+                     * In other words, a[e3] acts as a sentinel for great.
+                     */
                     while (a[great] > pivot1) {
-                        if (k == great--) {
-                            break outer;
-                        }
+                        great--;
                     }
-                    a[k] = a[great];
-                    a[great--] = ak;
-
-                    if ((ak = a[k]) <  pivot1) {
+                    if (a[great] < pivot1) {
                         a[k] = a[less];
-                        a[less++] = ak;
+                        a[less++] = a[great];
+                        a[great--] = ak;
+                    } else { // a[great] == pivot1
+                        a[k] = pivot1;
+                        a[great--] = ak;
                     }
                 }
             }
@@ -2004,26 +2199,55 @@
         }
 
         /*
-         * If center part is too large (comprises > 5/6 of
-         * the array), swap internal pivot values to ends
+         * If center part is too large (comprises > 2/3 of the array),
+         * swap internal pivot values to ends
          */
-        if (less < e1 && e5 < great) {
+        if (less < e1 && great > e5) {
             while (a[less] == pivot1) {
                 less++;
             }
             while (a[great] == pivot2) {
                 great--;
             }
-            for (int k = less + 1; k <= 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++) {
                 double ak = a[k];
-                if (ak == pivot1) {
-                    a[k++] = a[less];
+                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;
-                } else if (ak == pivot2) {
-                    a[k] = a[great];
-                    a[great--] = pivot2;
-                } else {
-                    k++;
                 }
             }
         }
--- a/jdk/src/share/classes/java/util/Formatter.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/java/util/Formatter.java	Wed Jul 05 17:04:26 2017 +0200
@@ -2552,9 +2552,6 @@
         private boolean dt = false;
         private char c;
 
-        // cache the line separator
-        private String ls;
-
         private int index(String s) {
             if (s != null) {
                 try {
@@ -2702,9 +2699,7 @@
                 printHashCode(arg);
                 break;
             case Conversion.LINE_SEPARATOR:
-                if (ls == null)
-                    ls = System.getProperty("line.separator");
-                a.append(ls);
+                a.append(System.lineSeparator());
                 break;
             case Conversion.PERCENT_SIGN:
                 a.append('%');
--- a/jdk/src/share/classes/java/util/zip/Deflater.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/java/util/zip/Deflater.java	Wed Jul 05 17:04:26 2017 +0200
@@ -318,7 +318,7 @@
     /**
      * Compresses the input data and fills specified buffer with compressed
      * data. Returns actual number of bytes of compressed data. A return value
-     * of 0 indicates that {@link needsInput() needsInput} should be called
+     * of 0 indicates that {@link #needsInput() needsInput} should be called
      * in order to determine if more input data is required.
      *
      * <p>This method uses {@link #NO_FLUSH} as its compression flush mode.
@@ -339,7 +339,7 @@
     /**
      * Compresses the input data and fills specified buffer with compressed
      * data. Returns actual number of bytes of compressed data. A return value
-     * of 0 indicates that {@link needsInput() needsInput} should be called
+     * of 0 indicates that {@link #needsInput() needsInput} should be called
      * in order to determine if more input data is required.
      *
      * <p>This method uses {@link #NO_FLUSH} as its compression flush mode.
--- a/jdk/src/share/classes/java/util/zip/DeflaterOutputStream.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/java/util/zip/DeflaterOutputStream.java	Wed Jul 05 17:04:26 2017 +0200
@@ -66,7 +66,7 @@
      * @param def the compressor ("deflater")
      * @param size the output buffer size
      * @param syncFlush
-     *        if {@code true} the {@link flush()} method of this
+     *        if {@code true} the {@link #flush()} method of this
      *        instance flushes the compressor with flush mode
      *        {@link Deflater#SYNC_FLUSH} before flushing the output
      *        stream, otherwise only flushes the output stream
@@ -114,7 +114,7 @@
      * @param out the output stream
      * @param def the compressor ("deflater")
      * @param syncFlush
-     *        if {@code true} the {@link flush()} method of this
+     *        if {@code true} the {@link #flush()} method of this
      *        instance flushes the compressor with flush mode
      *        {@link Deflater#SYNC_FLUSH} before flushing the output
      *        stream, otherwise only flushes the output stream
@@ -151,7 +151,7 @@
      *
      * @param out the output stream
      * @param syncFlush
-     *        if {@code true} the {@link flush()} method of this
+     *        if {@code true} the {@link #flush()} method of this
      *        instance flushes the compressor with flush mode
      *        {@link Deflater#SYNC_FLUSH} before flushing the output
      *        stream, otherwise only flushes the output stream
@@ -262,10 +262,10 @@
     /**
      * Flushes the compressed output stream.
      *
-     * If {@link DeflaterOutputStream(OutputStream, Deflater, int, boolean)
+     * If {@link #DeflaterOutputStream(OutputStream, Deflater, int, boolean)
      * syncFlush} is {@code true} when this compressed output stream is
-     * constructed this method flushes the underlying {@code compressor}
-     * first with the flush mode {@link Deflater#SYNC_FLUSH} to force
+     * constructed, this method first flushes the underlying {@code compressor}
+     * with the flush mode {@link Deflater#SYNC_FLUSH} to force
      * all pending data to be flushed out to the output stream and then
      * flushes the output stream. Otherwise this method only flushes the
      * output stream without flushing the {@code compressor}.
--- a/jdk/src/share/classes/javax/naming/InitialContext.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/javax/naming/InitialContext.java	Wed Jul 05 17:04:26 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1999-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -198,6 +198,8 @@
      *
      * <p> This constructor will not modify <tt>environment</tt>
      * or save a reference to it, but may save a clone.
+     * Caller should not modify mutable keys and values in
+     * <tt>environment</tt> after it has been passed to the constructor.
      *
      * @param environment
      *          environment used to create the initial context.
--- a/jdk/src/share/classes/javax/naming/directory/InitialDirContext.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/javax/naming/directory/InitialDirContext.java	Wed Jul 05 17:04:26 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2004 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1999-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -86,6 +86,8 @@
      *
      * <p> This constructor will not modify <tt>environment</tt>
      * or save a reference to it, but may save a clone.
+     * Caller should not modify mutable keys and values in
+     * <tt>environment</tt> after it has been passed to the constructor.
      *
      * @param environment
      *          environment used to create the initial DirContext.
--- a/jdk/src/share/classes/javax/naming/ldap/InitialLdapContext.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/javax/naming/ldap/InitialLdapContext.java	Wed Jul 05 17:04:26 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2004 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1999-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -110,6 +110,8 @@
      *
      * <p> This constructor will not modify its parameters or
      * save references to them, but may save a clone or copy.
+     * Caller should not modify mutable keys and values in
+     * <tt>environment</tt> after it has been passed to the constructor.
      *
      * <p> <tt>connCtls</tt> is used as the underlying context instance's
      * connection request controls.  See the class description
--- a/jdk/src/share/classes/javax/security/auth/Subject.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/javax/security/auth/Subject.java	Wed Jul 05 17:04:26 2017 +0200
@@ -40,7 +40,6 @@
 import java.security.PrivilegedActionException;
 import java.security.ProtectionDomain;
 import sun.security.util.ResourcesMgr;
-import sun.security.util.SecurityConstants;
 
 /**
  * <p> A <code>Subject</code> represents a grouping of related information
@@ -239,7 +238,7 @@
     public void setReadOnly() {
         java.lang.SecurityManager sm = System.getSecurityManager();
         if (sm != null) {
-            sm.checkPermission(new AuthPermission("setReadOnly"));
+            sm.checkPermission(AuthPermissionHolder.SET_READ_ONLY_PERMISSION);
         }
 
         this.readOnly = true;
@@ -285,7 +284,7 @@
 
         java.lang.SecurityManager sm = System.getSecurityManager();
         if (sm != null) {
-            sm.checkPermission(new AuthPermission("getSubject"));
+            sm.checkPermission(AuthPermissionHolder.GET_SUBJECT_PERMISSION);
         }
 
         if (acc == null) {
@@ -343,7 +342,7 @@
 
         java.lang.SecurityManager sm = System.getSecurityManager();
         if (sm != null) {
-            sm.checkPermission(SecurityConstants.DO_AS_PERMISSION);
+            sm.checkPermission(AuthPermissionHolder.DO_AS_PERMISSION);
         }
         if (action == null)
             throw new NullPointerException
@@ -402,7 +401,7 @@
 
         java.lang.SecurityManager sm = System.getSecurityManager();
         if (sm != null) {
-            sm.checkPermission(SecurityConstants.DO_AS_PERMISSION);
+            sm.checkPermission(AuthPermissionHolder.DO_AS_PERMISSION);
         }
 
         if (action == null)
@@ -456,7 +455,7 @@
 
         java.lang.SecurityManager sm = System.getSecurityManager();
         if (sm != null) {
-            sm.checkPermission(SecurityConstants.DO_AS_PRIVILEGED_PERMISSION);
+            sm.checkPermission(AuthPermissionHolder.DO_AS_PRIVILEGED_PERMISSION);
         }
 
         if (action == null)
@@ -520,7 +519,7 @@
 
         java.lang.SecurityManager sm = System.getSecurityManager();
         if (sm != null) {
-            sm.checkPermission(SecurityConstants.DO_AS_PRIVILEGED_PERMISSION);
+            sm.checkPermission(AuthPermissionHolder.DO_AS_PRIVILEGED_PERMISSION);
         }
 
         if (action == null)
@@ -1044,16 +1043,13 @@
                     if (sm != null) {
                         switch (which) {
                         case Subject.PRINCIPAL_SET:
-                            sm.checkPermission(new AuthPermission
-                                        ("modifyPrincipals"));
+                            sm.checkPermission(AuthPermissionHolder.MODIFY_PRINCIPALS_PERMISSION);
                             break;
                         case Subject.PUB_CREDENTIAL_SET:
-                            sm.checkPermission(new AuthPermission
-                                        ("modifyPublicCredentials"));
+                            sm.checkPermission(AuthPermissionHolder.MODIFY_PUBLIC_CREDENTIALS_PERMISSION);
                             break;
                         default:
-                            sm.checkPermission(new AuthPermission
-                                        ("modifyPrivateCredentials"));
+                            sm.checkPermission(AuthPermissionHolder.MODIFY_PRIVATE_CREDENTIALS_PERMISSION);
                             break;
                         }
                     }
@@ -1073,16 +1069,13 @@
             if (sm != null) {
                 switch (which) {
                 case Subject.PRINCIPAL_SET:
-                    sm.checkPermission
-                        (new AuthPermission("modifyPrincipals"));
+                    sm.checkPermission(AuthPermissionHolder.MODIFY_PRINCIPALS_PERMISSION);
                     break;
                 case Subject.PUB_CREDENTIAL_SET:
-                    sm.checkPermission
-                        (new AuthPermission("modifyPublicCredentials"));
+                    sm.checkPermission(AuthPermissionHolder.MODIFY_PUBLIC_CREDENTIALS_PERMISSION);
                     break;
                 default:
-                    sm.checkPermission
-                        (new AuthPermission("modifyPrivateCredentials"));
+                    sm.checkPermission(AuthPermissionHolder.MODIFY_PRIVATE_CREDENTIALS_PERMISSION);
                     break;
                 }
             }
@@ -1405,4 +1398,27 @@
             return set.add(o);
         }
     }
+
+    static class AuthPermissionHolder {
+        static final AuthPermission DO_AS_PERMISSION =
+            new AuthPermission("doAs");
+
+        static final AuthPermission DO_AS_PRIVILEGED_PERMISSION =
+            new AuthPermission("doAsPrivileged");
+
+        static final AuthPermission SET_READ_ONLY_PERMISSION =
+            new AuthPermission("setReadOnly");
+
+        static final AuthPermission GET_SUBJECT_PERMISSION =
+            new AuthPermission("getSubject");
+
+        static final AuthPermission MODIFY_PRINCIPALS_PERMISSION =
+            new AuthPermission("modifyPrincipals");
+
+        static final AuthPermission MODIFY_PUBLIC_CREDENTIALS_PERMISSION =
+            new AuthPermission("modifyPublicCredentials");
+
+        static final AuthPermission MODIFY_PRIVATE_CREDENTIALS_PERMISSION =
+            new AuthPermission("modifyPrivateCredentials");
+    }
 }
--- a/jdk/src/share/classes/javax/swing/AbstractListModel.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/AbstractListModel.java	Wed Jul 05 17:04:26 2017 +0200
@@ -42,9 +42,11 @@
  * has been added to the <code>java.beans</code> package.
  * Please see {@link java.beans.XMLEncoder}.
  *
+ * @param <E> the type of the elements of this model
+ *
  * @author Hans Muller
  */
-public abstract class AbstractListModel implements ListModel, Serializable
+public abstract class AbstractListModel<E> implements ListModel<E>, Serializable
 {
     protected EventListenerList listenerList = new EventListenerList();
 
--- a/jdk/src/share/classes/javax/swing/DefaultListCellRenderer.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/DefaultListCellRenderer.java	Wed Jul 05 17:04:26 2017 +0200
@@ -71,7 +71,7 @@
  * @author Hans Muller
  */
 public class DefaultListCellRenderer extends JLabel
-    implements ListCellRenderer, Serializable
+    implements ListCellRenderer<Object>, Serializable
 {
 
    /**
@@ -111,7 +111,7 @@
     }
 
     public Component getListCellRendererComponent(
-        JList list,
+        JList<?> list,
         Object value,
         int index,
         boolean isSelected,
--- a/jdk/src/share/classes/javax/swing/DefaultListModel.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/DefaultListModel.java	Wed Jul 05 17:04:26 2017 +0200
@@ -48,11 +48,13 @@
  * has been added to the <code>java.beans</code> package.
  * Please see {@link java.beans.XMLEncoder}.
  *
+ * @param <E> the type of the elements of this model
+ *
  * @author Hans Muller
  */
-public class DefaultListModel extends AbstractListModel
+public class DefaultListModel<E> extends AbstractListModel<E>
 {
-    private Vector delegate = new Vector();
+    private Vector<E> delegate = new Vector<E>();
 
     /**
      * Returns the number of components in this list.
@@ -83,7 +85,7 @@
      *             list
      * @see #get(int)
      */
-    public Object getElementAt(int index) {
+    public E getElementAt(int index) {
         return delegate.elementAt(index);
     }
 
@@ -175,7 +177,7 @@
      * @return  an enumeration of the components of this list
      * @see Vector#elements()
      */
-    public Enumeration<?> elements() {
+    public Enumeration<E> elements() {
         return delegate.elements();
     }
 
@@ -260,7 +262,7 @@
      * @see #get(int)
      * @see Vector#elementAt(int)
      */
-    public Object elementAt(int index) {
+    public E elementAt(int index) {
         return delegate.elementAt(index);
     }
 
@@ -271,7 +273,7 @@
      * @return     the first component of this list
      * @see Vector#firstElement()
      */
-    public Object firstElement() {
+    public E firstElement() {
         return delegate.firstElement();
     }
 
@@ -283,13 +285,13 @@
      * @return  the last component of the list
      * @see Vector#lastElement()
      */
-    public Object lastElement() {
+    public E lastElement() {
         return delegate.lastElement();
     }
 
     /**
      * Sets the component at the specified <code>index</code> of this
-     * list to be the specified object. The previous component at that
+     * list to be the specified element. The previous component at that
      * position is discarded.
      * <p>
      * Throws an <code>ArrayIndexOutOfBoundsException</code> if the index
@@ -300,13 +302,13 @@
      *    <code>List</code> interface defined in the 1.2 Collections framework.
      * </blockquote>
      *
-     * @param      obj     what the component is to be set to
+     * @param      element what the component is to be set to
      * @param      index   the specified index
      * @see #set(int,Object)
      * @see Vector#setElementAt(Object,int)
      */
-    public void setElementAt(Object obj, int index) {
-        delegate.setElementAt(obj, index);
+    public void setElementAt(E element, int index) {
+        delegate.setElementAt(element, index);
         fireContentsChanged(this, index, index);
     }
 
@@ -331,7 +333,7 @@
     }
 
     /**
-     * Inserts the specified object as a component in this list at the
+     * Inserts the specified element as a component in this list at the
      * specified <code>index</code>.
      * <p>
      * Throws an <code>ArrayIndexOutOfBoundsException</code> if the index
@@ -342,26 +344,26 @@
      *    <code>List</code> interface defined in the 1.2 Collections framework.
      * </blockquote>
      *
-     * @param      obj     the component to insert
+     * @param      element the component to insert
      * @param      index   where to insert the new component
      * @exception  ArrayIndexOutOfBoundsException  if the index was invalid
      * @see #add(int,Object)
      * @see Vector#insertElementAt(Object,int)
      */
-    public void insertElementAt(Object obj, int index) {
-        delegate.insertElementAt(obj, index);
+    public void insertElementAt(E element, int index) {
+        delegate.insertElementAt(element, index);
         fireIntervalAdded(this, index, index);
     }
 
     /**
      * Adds the specified component to the end of this list.
      *
-     * @param   obj   the component to be added
+     * @param   element   the component to be added
      * @see Vector#addElement(Object)
      */
-    public void addElement(Object obj) {
+    public void addElement(E element) {
         int index = delegate.size();
-        delegate.addElement(obj);
+        delegate.addElement(element);
         fireIntervalAdded(this, index, index);
     }
 
@@ -441,7 +443,7 @@
      *
      * @param index index of element to return
      */
-    public Object get(int index) {
+    public E get(int index) {
         return delegate.elementAt(index);
     }
 
@@ -457,8 +459,8 @@
      * @param element element to be stored at the specified position
      * @return the element previously at the specified position
      */
-    public Object set(int index, Object element) {
-        Object rv = delegate.elementAt(index);
+    public E set(int index, E element) {
+        E rv = delegate.elementAt(index);
         delegate.setElementAt(element, index);
         fireContentsChanged(this, index, index);
         return rv;
@@ -474,7 +476,7 @@
      * @param index index at which the specified element is to be inserted
      * @param element element to be inserted
      */
-    public void add(int index, Object element) {
+    public void add(int index, E element) {
         delegate.insertElementAt(element, index);
         fireIntervalAdded(this, index, index);
     }
@@ -488,9 +490,10 @@
      * (<code>index &lt; 0 || index &gt;= size()</code>).
      *
      * @param index the index of the element to removed
+     * @return the element previously at the specified position
      */
-    public Object remove(int index) {
-        Object rv = delegate.elementAt(index);
+    public E remove(int index) {
+        E rv = delegate.elementAt(index);
         delegate.removeElementAt(index);
         fireIntervalRemoved(this, index, index);
         return rv;
--- a/jdk/src/share/classes/javax/swing/JList.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/JList.java	Wed Jul 05 17:04:26 2017 +0200
@@ -25,11 +25,24 @@
 
 package javax.swing;
 
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Cursor;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.GraphicsEnvironment;
+import java.awt.HeadlessException;
+import java.awt.Insets;
+import java.awt.Point;
+import java.awt.Rectangle;
 import java.awt.event.*;
-import java.awt.*;
 
 import java.util.Vector;
 import java.util.Locale;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
@@ -59,28 +72,30 @@
  * constructor that automatically builds a read-only {@code ListModel} instance
  * for you:
  * <pre>
+ * {@code
  * // Create a JList that displays strings from an array
  *
  * String[] data = {"one", "two", "three", "four"};
- * JList myList = new JList(data);
+ * JList<String> myList = new JList<String>(data);
  *
  * // Create a JList that displays the superclasses of JList.class, by
  * // creating it with a Vector populated with this data
  *
- * Vector superClasses = new Vector();
- * Class rootClass = javax.swing.JList.class;
- * for(Class cls = rootClass; cls != null; cls = cls.getSuperclass()) {
+ * Vector<Class<?>> superClasses = new Vector<Class<?>>();
+ * Class<JList> rootClass = javax.swing.JList.class;
+ * for(Class<?> cls = rootClass; cls != null; cls = cls.getSuperclass()) {
  *     superClasses.addElement(cls);
  * }
- * JList myList = new JList(superClasses);
+ * JList<Class<?>> myList = new JList<Class<?>>(superClasses);
  *
  * // The automatically created model is stored in JList's "model"
  * // property, which you can retrieve
  *
- * ListModel model = myList.getModel();
+ * ListModel<Class<?>> model = myList.getModel();
  * for(int i = 0; i < model.getSize(); i++) {
  *     System.out.println(model.getElementAt(i));
  * }
+ * }
  * </pre>
  * <p>
  * A {@code ListModel} can be supplied directly to a {@code JList} by way of a
@@ -103,12 +118,14 @@
  * notifying listeners. For example, a read-only implementation of
  * {@code AbstractListModel}:
  * <pre>
+ * {@code
  * // This list model has about 2^16 elements.  Enjoy scrolling.
  *
- * ListModel bigData = new AbstractListModel() {
+ * ListModel<String> bigData = new AbstractListModel<String>() {
  *     public int getSize() { return Short.MAX_VALUE; }
- *     public Object getElementAt(int index) { return "Index " + index; }
+ *     public String getElementAt(int index) { return "Index " + index; }
  * };
+ * }
  * </pre>
  * <p>
  * The selection state of a {@code JList} is managed by another separate
@@ -150,9 +167,10 @@
  * component to render, is installed by the lists's {@code ListUI}. You can
  * substitute your own renderer using code like this:
  * <pre>
+ * {@code
  *  // Display an icon and a string for each object in the list.
  *
- * class MyCellRenderer extends JLabel implements ListCellRenderer {
+ * class MyCellRenderer extends JLabel implements ListCellRenderer<Object> {
  *     final static ImageIcon longIcon = new ImageIcon("long.gif");
  *     final static ImageIcon shortIcon = new ImageIcon("short.gif");
  *
@@ -160,7 +178,7 @@
  *     // We just reconfigure the JLabel each time we're called.
  *
  *     public Component getListCellRendererComponent(
- *       JList list,              // the list
+ *       JList<?> list,           // the list
  *       Object value,            // value to display
  *       int index,               // cell index
  *       boolean isSelected,      // is the cell selected
@@ -184,6 +202,7 @@
  * }
  *
  * myList.setCellRenderer(new MyCellRenderer());
+ * }
  * </pre>
  * <p>
  * Another job for the cell renderer is in helping to determine sizing
@@ -195,7 +214,8 @@
  * automatically based on a single prototype value:
  * <a name="prototype_example">
  * <pre>
- * JList bigDataList = new JList(bigData);
+ * {@code
+ * JList<String> bigDataList = new JList<String>(bigData);
  *
  * // We don't want the JList implementation to compute the width
  * // or height of all of the list cells, so we give it a string
@@ -204,6 +224,7 @@
  * // properties.
  *
  * bigDataList.setPrototypeCellValue("Index 1234567890");
+ * }
  * </pre>
  * <p>
  * {@code JList} doesn't implement scrolling directly. To create a list that
@@ -260,13 +281,15 @@
  * @see ListCellRenderer
  * @see DefaultListCellRenderer
  *
+ * @param <E> the type of the elements of this list
+ *
  * @beaninfo
  *   attribute: isContainer false
  * description: A component which allows for the selection of one or more objects from a list.
  *
  * @author Hans Muller
  */
-public class JList extends JComponent implements Scrollable, Accessible
+public class JList<E> extends JComponent implements Scrollable, Accessible
 {
     /**
      * @see #getUIClassID
@@ -301,15 +324,15 @@
     private int fixedCellWidth = -1;
     private int fixedCellHeight = -1;
     private int horizontalScrollIncrement = -1;
-    private Object prototypeCellValue;
+    private E prototypeCellValue;
     private int visibleRowCount = 8;
     private Color selectionForeground;
     private Color selectionBackground;
     private boolean dragEnabled;
 
     private ListSelectionModel selectionModel;
-    private ListModel dataModel;
-    private ListCellRenderer cellRenderer;
+    private ListModel<E> dataModel;
+    private ListCellRenderer<? super E> cellRenderer;
     private ListSelectionListener selectionListener;
 
     /**
@@ -402,7 +425,7 @@
      * @param dataModel the model for the list
      * @exception IllegalArgumentException if the model is {@code null}
      */
-    public JList(ListModel dataModel)
+    public JList(ListModel<E> dataModel)
     {
         if (dataModel == null) {
             throw new IllegalArgumentException("dataModel must be non null");
@@ -437,12 +460,12 @@
      * @param  listData  the array of Objects to be loaded into the data model,
      *                   {@code non-null}
      */
-    public JList(final Object[] listData)
+    public JList(final E[] listData)
     {
         this (
-            new AbstractListModel() {
+            new AbstractListModel<E>() {
                 public int getSize() { return listData.length; }
-                public Object getElementAt(int i) { return listData[i]; }
+                public E getElementAt(int i) { return listData[i]; }
             }
         );
     }
@@ -462,11 +485,11 @@
      * @param  listData  the <code>Vector</code> to be loaded into the
      *                   data model, {@code non-null}
      */
-    public JList(final Vector<?> listData) {
+    public JList(final Vector<? extends E> listData) {
         this (
-            new AbstractListModel() {
+            new AbstractListModel<E>() {
                 public int getSize() { return listData.size(); }
-                public Object getElementAt(int i) { return listData.elementAt(i); }
+                public E getElementAt(int i) { return listData.elementAt(i); }
             }
         );
     }
@@ -477,9 +500,9 @@
      */
     public JList() {
         this (
-            new AbstractListModel() {
+            new AbstractListModel<E>() {
               public int getSize() { return 0; }
-              public Object getElementAt(int i) { return "No Data Model"; }
+              public E getElementAt(int i) { throw new IndexOutOfBoundsException("No Data Model"); }
             }
         );
     }
@@ -526,7 +549,7 @@
     public void updateUI() {
         setUI((ListUI)UIManager.getUI(this));
 
-        ListCellRenderer renderer = getCellRenderer();
+        ListCellRenderer<? super E> renderer = getCellRenderer();
         if (renderer instanceof Component) {
             SwingUtilities.updateComponentTreeUI((Component)renderer);
         }
@@ -560,8 +583,8 @@
      */
     private void updateFixedCellSize()
     {
-        ListCellRenderer cr = getCellRenderer();
-        Object value = getPrototypeCellValue();
+        ListCellRenderer<? super E> cr = getCellRenderer();
+        E value = getPrototypeCellValue();
 
         if ((cr != null) && (value != null)) {
             Component c = cr.getListCellRendererComponent(this, value, 0, false, false);
@@ -592,7 +615,7 @@
      * @return the value of the {@code prototypeCellValue} property
      * @see #setPrototypeCellValue
      */
-    public Object getPrototypeCellValue() {
+    public E getPrototypeCellValue() {
         return prototypeCellValue;
     }
 
@@ -632,8 +655,8 @@
      *   attribute: visualUpdate true
      * description: The cell prototype value, used to compute cell width and height.
      */
-    public void setPrototypeCellValue(Object prototypeCellValue) {
-        Object oldValue = this.prototypeCellValue;
+    public void setPrototypeCellValue(E prototypeCellValue) {
+        E oldValue = this.prototypeCellValue;
         this.prototypeCellValue = prototypeCellValue;
 
         /* If the prototypeCellValue has changed and is non-null,
@@ -727,7 +750,7 @@
      * @see #setCellRenderer
      */
     @Transient
-    public ListCellRenderer getCellRenderer() {
+    public ListCellRenderer<? super E> getCellRenderer() {
         return cellRenderer;
     }
 
@@ -755,8 +778,8 @@
      *   attribute: visualUpdate true
      * description: The component used to draw the cells.
      */
-    public void setCellRenderer(ListCellRenderer cellRenderer) {
-        ListCellRenderer oldValue = this.cellRenderer;
+    public void setCellRenderer(ListCellRenderer<? super E> cellRenderer) {
+        ListCellRenderer<? super E> oldValue = this.cellRenderer;
         this.cellRenderer = cellRenderer;
 
         /* If the cellRenderer has changed and prototypeCellValue
@@ -1455,7 +1478,7 @@
      * @since 1.4
      */
     public int getNextMatch(String prefix, int startIndex, Position.Bias bias) {
-        ListModel model = getModel();
+        ListModel<E> model = getModel();
         int max = model.getSize();
         if (prefix == null) {
             throw new IllegalArgumentException();
@@ -1469,16 +1492,16 @@
         int increment = (bias == Position.Bias.Forward) ? 1 : -1;
         int index = startIndex;
         do {
-            Object o = model.getElementAt(index);
-
-            if (o != null) {
+            E element = model.getElementAt(index);
+
+            if (element != null) {
                 String string;
 
-                if (o instanceof String) {
-                    string = ((String)o).toUpperCase();
+                if (element instanceof String) {
+                    string = ((String)element).toUpperCase();
                 }
                 else {
-                    string = o.toString();
+                    string = element.toString();
                     if (string != null) {
                         string = string.toUpperCase();
                     }
@@ -1516,7 +1539,7 @@
         if(event != null) {
             Point p = event.getPoint();
             int index = locationToIndex(p);
-            ListCellRenderer r = getCellRenderer();
+            ListCellRenderer<? super E> r = getCellRenderer();
             Rectangle cellBounds;
 
             if (index != -1 && r != null && (cellBounds =
@@ -1634,7 +1657,7 @@
      *                          list of items
      * @see #setModel
      */
-    public ListModel getModel() {
+    public ListModel<E> getModel() {
         return dataModel;
     }
 
@@ -1656,11 +1679,11 @@
      *   attribute: visualUpdate true
      * description: The object that contains the data to be drawn by this JList.
      */
-    public void setModel(ListModel model) {
+    public void setModel(ListModel<E> model) {
         if (model == null) {
             throw new IllegalArgumentException("model must be non null");
         }
-        ListModel oldValue = dataModel;
+        ListModel<E> oldValue = dataModel;
         dataModel = model;
         firePropertyChange("model", oldValue, dataModel);
         clearSelection();
@@ -1668,7 +1691,7 @@
 
 
     /**
-     * Constructs a read-only <code>ListModel</code> from an array of objects,
+     * Constructs a read-only <code>ListModel</code> from an array of items,
      * and calls {@code setModel} with this model.
      * <p>
      * Attempts to pass a {@code null} value to this method results in
@@ -1676,15 +1699,15 @@
      * references the given array directly. Attempts to modify the array
      * after invoking this method results in undefined behavior.
      *
-     * @param listData an array of {@code Objects} containing the items to
+     * @param listData an array of {@code E} containing the items to
      *        display in the list
      * @see #setModel
      */
-    public void setListData(final Object[] listData) {
+    public void setListData(final E[] listData) {
         setModel (
-            new AbstractListModel() {
+            new AbstractListModel<E>() {
                 public int getSize() { return listData.length; }
-                public Object getElementAt(int i) { return listData[i]; }
+                public E getElementAt(int i) { return listData[i]; }
             }
         );
     }
@@ -1703,11 +1726,11 @@
      *                                          display in the list
      * @see #setModel
      */
-    public void setListData(final Vector<?> listData) {
+    public void setListData(final Vector<? extends E> listData) {
         setModel (
-            new AbstractListModel() {
+            new AbstractListModel<E>() {
                 public int getSize() { return listData.size(); }
-                public Object getElementAt(int i) { return listData.elementAt(i); }
+                public E getElementAt(int i) { return listData.elementAt(i); }
             }
         );
     }
@@ -2235,10 +2258,13 @@
      * @see #isSelectedIndex
      * @see #getModel
      * @see #addListSelectionListener
+     *
+     * @deprecated As of JDK 1.7, replaced by {@link #getSelectedValuesList()}
      */
+    @Deprecated
     public Object[] getSelectedValues() {
         ListSelectionModel sm = getSelectionModel();
-        ListModel dm = getModel();
+        ListModel<E> dm = getModel();
 
         int iMin = sm.getMinSelectionIndex();
         int iMax = sm.getMaxSelectionIndex();
@@ -2259,6 +2285,37 @@
         return rv;
     }
 
+    /**
+     * Returns a list of all the selected items, in increasing order based
+     * on their indices in the list.
+     *
+     * @return the selected items, or an empty list if nothing is selected
+     * @see #isSelectedIndex
+     * @see #getModel
+     * @see #addListSelectionListener
+     *
+     * @since 1.7
+     */
+    public List<E> getSelectedValuesList() {
+        ListSelectionModel sm = getSelectionModel();
+        ListModel<E> dm = getModel();
+
+        int iMin = sm.getMinSelectionIndex();
+        int iMax = sm.getMaxSelectionIndex();
+
+        if ((iMin < 0) || (iMax < 0)) {
+            return Collections.emptyList();
+        }
+
+        List<E> selectedItems = new ArrayList<E>();
+        for(int i = iMin; i <= iMax; i++) {
+            if (sm.isSelectedIndex(i)) {
+                selectedItems.add(dm.getElementAt(i));
+            }
+        }
+        return selectedItems;
+    }
+
 
     /**
      * Returns the smallest selected cell index; <i>the selection</i> when only
@@ -2291,7 +2348,7 @@
      * @see #getModel
      * @see #addListSelectionListener
      */
-    public Object getSelectedValue() {
+    public E getSelectedValue() {
         int i = getMinSelectionIndex();
         return (i == -1) ? null : getModel().getElementAt(i);
     }
@@ -2309,7 +2366,7 @@
             setSelectedIndex(-1);
         else if(!anObject.equals(getSelectedValue())) {
             int i,c;
-            ListModel dm = getModel();
+            ListModel<E> dm = getModel();
             for(i=0,c=dm.getSize();i<c;i++)
                 if(anObject.equals(dm.getElementAt(i))){
                     setSelectedIndex(i);
@@ -3138,14 +3195,14 @@
            */
         protected class AccessibleJListChild extends AccessibleContext
                 implements Accessible, AccessibleComponent {
-            private JList     parent = null;
+            private JList<E>     parent = null;
             private int       indexInParent;
             private Component component = null;
             private AccessibleContext accessibleContext = null;
-            private ListModel listModel;
-            private ListCellRenderer cellRenderer = null;
-
-            public AccessibleJListChild(JList parent, int indexInParent) {
+            private ListModel<E> listModel;
+            private ListCellRenderer<? super E> cellRenderer = null;
+
+            public AccessibleJListChild(JList<E> parent, int indexInParent) {
                 this.parent = parent;
                 this.setAccessibleParent(parent);
                 this.indexInParent = indexInParent;
@@ -3175,7 +3232,7 @@
                 if ((parent != null)
                         && (listModel != null)
                         && cellRenderer != null) {
-                    Object value = listModel.getElementAt(index);
+                    E value = listModel.getElementAt(index);
                     boolean isSelected = parent.isSelectedIndex(index);
                     boolean isFocussed = parent.isFocusOwner()
                             && (index == parent.getLeadSelectionIndex());
--- a/jdk/src/share/classes/javax/swing/JTable.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/JTable.java	Wed Jul 05 17:04:26 2017 +0200
@@ -1337,7 +1337,11 @@
                 return (TableCellRenderer)renderer;
             }
             else {
-                return getDefaultRenderer(columnClass.getSuperclass());
+                Class c = columnClass.getSuperclass();
+                if (c == null && columnClass != Object.class) {
+                    c = Object.class;
+                }
+                return getDefaultRenderer(c);
             }
         }
     }
--- a/jdk/src/share/classes/javax/swing/ListCellRenderer.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/ListCellRenderer.java	Wed Jul 05 17:04:26 2017 +0200
@@ -33,12 +33,13 @@
  * the cells in a JList.  For example, to use a JLabel as a
  * ListCellRenderer, you would write something like this:
  * <pre>
- * class MyCellRenderer extends JLabel implements ListCellRenderer {
+ * {@code
+ * class MyCellRenderer extends JLabel implements ListCellRenderer<Object> {
  *     public MyCellRenderer() {
  *         setOpaque(true);
  *     }
  *
- *     public Component getListCellRendererComponent(JList list,
+ *     public Component getListCellRendererComponent(JList<?> list,
  *                                                   Object value,
  *                                                   int index,
  *                                                   boolean isSelected,
@@ -75,14 +76,17 @@
  *         return this;
  *     }
  * }
+ * }
  * </pre>
  *
+ * @param <E> the type of values this renderer can be used for
+ *
  * @see JList
  * @see DefaultListCellRenderer
  *
  * @author Hans Muller
  */
-public interface ListCellRenderer
+public interface ListCellRenderer<E>
 {
     /**
      * Return a component that has been configured to display the specified
@@ -104,8 +108,8 @@
      * @see ListModel
      */
     Component getListCellRendererComponent(
-        JList list,
-        Object value,
+        JList<? extends E> list,
+        E value,
         int index,
         boolean isSelected,
         boolean cellHasFocus);
--- a/jdk/src/share/classes/javax/swing/ListModel.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/ListModel.java	Wed Jul 05 17:04:26 2017 +0200
@@ -35,10 +35,12 @@
  * length of the data model must be reported to all of the
  * ListDataListeners.
  *
+ * @param <E> the type of the elements of this model
+ *
  * @author Hans Muller
  * @see JList
  */
-public interface ListModel
+public interface ListModel<E>
 {
   /**
    * Returns the length of the list.
@@ -51,7 +53,7 @@
    * @param index the requested index
    * @return the value at <code>index</code>
    */
-  Object getElementAt(int index);
+  E getElementAt(int index);
 
   /**
    * Adds a listener to the list that's notified each time a change
--- a/jdk/src/share/classes/javax/swing/Popup.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/Popup.java	Wed Jul 05 17:04:26 2017 +0200
@@ -227,12 +227,8 @@
         HeavyWeightWindow(Window parent) {
             super(parent);
             setFocusableWindowState(false);
-            Toolkit tk = Toolkit.getDefaultToolkit();
-            if (tk instanceof SunToolkit) {
-                // all the short-lived windows like Popups should be
-                // OverrideRedirect on X11 platforms
-                ((SunToolkit)tk).setOverrideRedirect(this);
-            }
+            setType(Window.Type.POPUP);
+
             // Popups are typically transient and most likely won't benefit
             // from true double buffering.  Turn it off here.
             getRootPane().setUseTrueDoubleBuffering(false);
--- a/jdk/src/share/classes/javax/swing/plaf/ComponentUI.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/ComponentUI.java	Wed Jul 05 17:04:26 2017 +0200
@@ -60,13 +60,13 @@
     }
 
     /**
-     * Configures the specified component appropriate for the look and feel.
+     * Configures the specified component appropriately for the look and feel.
      * This method is invoked when the <code>ComponentUI</code> instance is being installed
      * as the UI delegate on the specified component.  This method should
      * completely configure the component for the look and feel,
      * including the following:
      * <ol>
-     * <li>Install any default property values for color, fonts, borders,
+     * <li>Install default property values for color, fonts, borders,
      *     icons, opacity, etc. on the component.  Whenever possible,
      *     property values initialized by the client program should <i>not</i>
      *     be overridden.
@@ -116,7 +116,7 @@
     }
 
     /**
-     * Paints the specified component appropriate for the look and feel.
+     * Paints the specified component appropriately for the look and feel.
      * This method is invoked from the <code>ComponentUI.update</code> method when
      * the specified component is being painted.  Subclasses should override
      * this method and use the specified <code>Graphics</code> object to
@@ -134,15 +134,15 @@
     }
 
     /**
-     * Notifies this UI delegate that it's time to paint the specified
+     * Notifies this UI delegate that it is time to paint the specified
      * component.  This method is invoked by <code>JComponent</code>
      * when the specified component is being painted.
-     * By default this method will fill the specified component with
-     * its background color (if its <code>opaque</code> property is
-     * <code>true</code>) and then immediately call <code>paint</code>.
-     * In general this method need not be overridden by subclasses;
-     * all look-and-feel rendering code should reside in the <code>paint</code>
-     * method.
+     *
+     * <p>By default this method fills the specified component with
+     * its background color if its {@code opaque} property is {@code true},
+     * and then immediately calls {@code paint}. In general this method need
+     * not be overridden by subclasses; all look-and-feel rendering code should
+     * reside in the {@code paint} method.
      *
      * @param g the <code>Graphics</code> context in which to paint
      * @param c the component being painted;
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicComboBoxEditor.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicComboBoxEditor.java	Wed Jul 05 17:04:26 2017 +0200
@@ -24,14 +24,10 @@
  */
 package javax.swing.plaf.basic;
 
-import javax.swing.*;
+import javax.swing.ComboBoxEditor;
+import javax.swing.JTextField;
 import javax.swing.border.Border;
-
-import javax.swing.text.AttributeSet;
-import javax.swing.text.BadLocationException;
-import javax.swing.text.PlainDocument;
-
-import java.awt.*;
+import java.awt.Component;
 import java.awt.event.*;
 
 import java.lang.reflect.Method;
@@ -73,12 +69,17 @@
      * @param anObject the displayed value of the editor
      */
     public void setItem(Object anObject) {
+        String text;
+
         if ( anObject != null )  {
-            editor.setText(anObject.toString());
-
+            text = anObject.toString();
             oldValue = anObject;
         } else {
-            editor.setText("");
+            text = "";
+        }
+        // workaround for 4530952
+        if (! text.equals(editor.getText())) {
+            editor.setText(text);
         }
     }
 
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicComboBoxUI.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicComboBoxUI.java	Wed Jul 05 17:04:26 2017 +0200
@@ -30,7 +30,6 @@
 import javax.swing.*;
 import javax.accessibility.*;
 import javax.swing.plaf.*;
-import javax.swing.border.*;
 import javax.swing.text.*;
 import javax.swing.event.*;
 import java.beans.PropertyChangeListener;
@@ -189,19 +188,20 @@
     /**
      * Indicates whether or not the combo box button should be square.
      * If square, then the width and height are equal, and are both set to
-     * the height of the combo (minus appropriate insets).
+     * the height of the combo minus appropriate insets.
+     *
+     * @since 1.7
      */
-    private boolean squareButton = true;
+    protected boolean squareButton = true;
 
     /**
-     * Optional: if specified, these insets act as padding around the cell
-     * renderer when laying out and painting the "selected" item in the
-     * combo box. BasicComboBoxUI uses a single combo box renderer for rendering
-     * both the main combo box item and also all the items in the dropdown
-     * for the combo box. padding allows you to specify addition insets in
-     * addition to those specified by the cell renderer.
+     * If specified, these insets act as padding around the cell renderer when
+     * laying out and painting the "selected" item in the combo box. These
+     * insets add to those specified by the cell renderer.
+     *
+     * @since 1.7
      */
-    private Insets padding;
+    protected Insets padding;
 
     // Used for calculating the default size.
     private static ListCellRenderer getDefaultListCellRenderer() {
@@ -345,7 +345,7 @@
     }
 
     /**
-     * Create and install the listeners for the combo box and its model.
+     * Creates and installs listeners for the combo box and its model.
      * This method is called when the UI is installed.
      */
     protected void installListeners() {
@@ -379,8 +379,8 @@
     }
 
     /**
-     * Uninstalls the default colors, default font, default renderer, and default
-     * editor into the JComboBox.
+     * Uninstalls the default colors, default font, default renderer,
+     * and default editor from the combo box.
      */
     protected void uninstallDefaults() {
         LookAndFeel.installColorsAndFont( comboBox,
@@ -391,7 +391,7 @@
     }
 
     /**
-     * Remove the installed listeners from the combo box and its model.
+     * Removes the installed listeners from the combo box and its model.
      * The number and types of listeners removed and in this method should be
      * the same that was added in <code>installListeners</code>
      */
@@ -839,7 +839,7 @@
     }
 
     /**
-     * Creates an button which will be used as the control to show or hide
+     * Creates a button which will be used as the control to show or hide
      * the popup portion of the combo box.
      *
      * @return a button which represents the popup control
@@ -1392,12 +1392,17 @@
     }
 
     /**
-     * This has been refactored out in hopes that it may be investigated and
-     * simplified for the next major release. adding/removing
-     * the component to the currentValuePane and changing the font may be
-     * redundant operations.
+     * Returns the size a component would have if used as a cell renderer.
+     *
+     * @param comp a {@code Component} to check
+     * @return size of the component
+     * @since 1.7
      */
-    private Dimension getSizeForComponent(Component comp) {
+    protected Dimension getSizeForComponent(Component comp) {
+        // This has been refactored out in hopes that it may be investigated and
+        // simplified for the next major release. adding/removing
+        // the component to the currentValuePane and changing the font may be
+        // redundant operations.
         currentValuePane.add(comp);
         comp.setFont(comboBox.getFont());
         Dimension d = comp.getPreferredSize();
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicLabelUI.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicLabelUI.java	Wed Jul 05 17:04:26 2017 +0200
@@ -141,11 +141,10 @@
     }
 
     /**
-     * Paint the label text in the foreground color, if the label
-     * is opaque then paint the entire background with the background
-     * color.  The Label text is drawn by paintEnabledText() or
-     * paintDisabledText().  The locations of the label parts are computed
-     * by layoutCL.
+     * Paints the label text with the foreground color, if the label is opaque
+     * then paints the entire background with the background color. The Label
+     * text is drawn by {@link #paintEnabledText} or {@link #paintDisabledText}.
+     * The locations of the label parts are computed by {@link #layoutCL}.
      *
      * @see #paintEnabledText
      * @see #paintDisabledText
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicListUI.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicListUI.java	Wed Jul 05 17:04:26 2017 +0200
@@ -685,7 +685,7 @@
 
 
     /**
-     * Create and install the listeners for the JList, its model, and its
+     * Creates and installs the listeners for the JList, its model, and its
      * selectionModel.  This method is called at installUI() time.
      *
      * @see #installUI
@@ -728,7 +728,7 @@
 
 
     /**
-     * Remove the listeners for the JList, its model, and its
+     * Removes the listeners from the JList, its model, and its
      * selectionModel.  All of the listener fields, are reset to
      * null here.  This method is called at uninstallUI() time,
      * it should be kept in sync with installListeners.
@@ -764,8 +764,8 @@
 
 
     /**
-     * Initialize JList properties, e.g. font, foreground, and background,
-     * and add the CellRendererPane.  The font, foreground, and background
+     * Initializes list properties such as font, foreground, and background,
+     * and adds the CellRendererPane. The font, foreground, and background
      * properties are only set if their current value is either null
      * or a UIResource, other properties are set if the current
      * value is null.
@@ -820,9 +820,9 @@
 
 
     /**
-     * Set the JList properties that haven't been explicitly overridden to
-     * null.  A property is considered overridden if its current value
-     * is not a UIResource.
+     * Sets the list properties that have not been explicitly overridden to
+     * {@code null}. A property is considered overridden if its current value
+     * is not a {@code UIResource}.
      *
      * @see #installDefaults
      * @see #uninstallUI
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicMenuItemUI.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicMenuItemUI.java	Wed Jul 05 17:04:26 2017 +0200
@@ -32,7 +32,6 @@
 
 import javax.swing.*;
 import javax.swing.event.*;
-import javax.swing.border.*;
 import javax.swing.plaf.*;
 import javax.swing.text.View;
 
@@ -54,7 +53,12 @@
     protected Color disabledForeground;
     protected Color acceleratorForeground;
     protected Color acceleratorSelectionForeground;
-    private   String acceleratorDelimiter;
+
+    /**
+     * Accelerator delimiter string, such as {@code '+'} in {@code 'Ctrl+C'}.
+     * @since 1.7
+     */
+    protected String acceleratorDelimiter;
 
     protected int defaultTextIconGap;
     protected Font acceleratorFont;
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java	Wed Jul 05 17:04:26 2017 +0200
@@ -93,10 +93,13 @@
      * scrollbar. */
     private boolean supportsAbsolutePositioning;
 
-    /** Hint as to what width (when vertical) or height (when horizontal)
+    /**
+     * Hint as to what width (when vertical) or height (when horizontal)
      * should be.
+     *
+     * @since 1.7
      */
-    private int scrollBarWidth;
+    protected int scrollBarWidth;
 
     private Handler handler;
 
@@ -117,18 +120,18 @@
      * number. If negative, then an overlap between the button and track will occur,
      * which is useful for shaped buttons.
      *
-     * TODO This should be made protected in a feature release
+     * @since 1.7
      */
-    private int incrGap;
+    protected int incrGap;
 
     /**
      * Distance between the decrement button and the track. This may be a negative
      * number. If negative, then an overlap between the button and track will occur,
      * which is useful for shaped buttons.
      *
-     * TODO This should be made protected in a feature release
+     * @since 1.7
      */
-    private int decrGap;
+    protected int decrGap;
 
     static void loadActionMap(LazyActionMap map) {
         map.put(new Actions(Actions.POSITIVE_UNIT_INCREMENT));
@@ -586,7 +589,7 @@
 
 
     /**
-     * Return the smallest acceptable size for the thumb.  If the scrollbar
+     * Returns the smallest acceptable size for the thumb.  If the scrollbar
      * becomes so small that this size isn't available, the thumb will be
      * hidden.
      * <p>
@@ -601,7 +604,7 @@
     }
 
     /**
-     * Return the largest acceptable size for the thumb.  To create a fixed
+     * Returns the largest acceptable size for the thumb.  To create a fixed
      * size thumb one make this method and <code>getMinimumThumbSize</code>
      * return the same value.
      * <p>
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicSliderUI.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicSliderUI.java	Wed Jul 05 17:04:26 2017 +0200
@@ -1409,9 +1409,10 @@
     }
 
     /**
-     * Returns a value give a y position.  If yPos is past the track at the top or the
-     * bottom it will set the value to the min or max of the slider, depending if the
-     * slider is inverted or not.
+     * Returns the value at the y position. If {@code yPos} is beyond the
+     * track at the the bottom or the top, this method sets the value to either
+     * the minimum or maximum value of the slider, depending on if the slider
+     * is inverted or not.
      */
     public int valueForYPosition( int yPos ) {
         int value;
@@ -1440,9 +1441,10 @@
     }
 
     /**
-     * Returns a value give an x position.  If xPos is past the track at the left or the
-     * right it will set the value to the min or max of the slider, depending if the
-     * slider is inverted or not.
+     * Returns the value at the x position.  If {@code xPos} is beyond the
+     * track at the left or the right, this method sets the value to either the
+     * minimum or maximum value of the slider, depending on if the slider is
+     * inverted or not.
      */
     public int valueForXPosition( int xPos ) {
         int value;
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicSpinnerUI.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicSpinnerUI.java	Wed Jul 05 17:04:26 2017 +0200
@@ -268,7 +268,7 @@
     }
 
     /**
-     * Create a <code>LayoutManager</code> that manages the <code>editor</code>,
+     * Creates a <code>LayoutManager</code> that manages the <code>editor</code>,
      * <code>nextButton</code>, and <code>previousButton</code>
      * children of the JSpinner.  These three children must be
      * added with a constraint that identifies their role:
@@ -286,7 +286,7 @@
 
 
     /**
-     * Create a <code>PropertyChangeListener</code> that can be
+     * Creates a <code>PropertyChangeListener</code> that can be
      * added to the JSpinner itself.  Typically, this listener
      * will call replaceEditor when the "editor" property changes,
      * since it's the <code>SpinnerUI's</code> responsibility to
@@ -302,16 +302,13 @@
 
 
     /**
-     * Create a component that will replace the spinner models value
-     * with the object returned by <code>spinner.getPreviousValue</code>.
-     * By default the <code>previousButton</code> is a JButton. This
-     * method invokes <code>installPreviousButtonListeners</code> to
-     * install the necessary listeners to update the <code>JSpinner</code>'s
-     * model in response to a user gesture. If a previousButton isn't needed
-     * (in a subclass) then override this method to return null.
+     * Creates a decrement button, i.e. component that replaces the spinner
+     * value with the object returned by <code>spinner.getPreviousValue</code>.
+     * By default the <code>previousButton</code> is a {@code JButton}. If the
+     * decrement button is not needed this method should return {@code null}.
      *
-     * @return a component that will replace the spinners model with the
-     *     next value in the sequence, or null
+     * @return a component that will replace the spinner's value with the
+     *     previous value in the sequence, or {@code null}
      * @see #installUI
      * @see #createNextButton
      * @see #installPreviousButtonListeners
@@ -325,15 +322,13 @@
 
 
     /**
-     * Create a component that will replace the spinner models value
-     * with the object returned by <code>spinner.getNextValue</code>.
-     * By default the <code>nextButton</code> is a JButton
-     * who's <code>ActionListener</code> updates it's <code>JSpinner</code>
-     * ancestors model.  If a nextButton isn't needed (in a subclass)
-     * then override this method to return null.
+     * Creates an increment button, i.e. component that replaces the spinner
+     * value with the object returned by <code>spinner.getNextValue</code>.
+     * By default the <code>nextButton</code> is a {@code JButton}. If the
+     * increment button is not needed this method should return {@code null}.
      *
-     * @return a component that will replace the spinners model with the
-     *     next value in the sequence, or null
+     * @return a component that will replace the spinner's value with the
+     *     next value in the sequence, or {@code null}
      * @see #installUI
      * @see #createPreviousButton
      * @see #installNextButtonListeners
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicSplitPaneUI.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicSplitPaneUI.java	Wed Jul 05 17:04:26 2017 +0200
@@ -829,7 +829,7 @@
 
     /**
      * Returns the default non continuous layout divider, which is an
-     * instanceof Canvas that fills the background in dark gray.
+     * instance of {@code Canvas} that fills in the background with dark gray.
      */
     protected Component createDefaultNonContinuousLayoutDivider() {
         return new Canvas() {
@@ -1041,11 +1041,11 @@
 
 
     /**
-     * Messaged after the JSplitPane the receiver is providing the look
-     * and feel for paints its children.
+     * Called when the specified split pane has finished painting
+     * its children.
      */
-    public void finishedPaintingChildren(JSplitPane jc, Graphics g) {
-        if(jc == splitPane && getLastDragLocation() != -1 &&
+    public void finishedPaintingChildren(JSplitPane sp, Graphics g) {
+        if(sp == splitPane && getLastDragLocation() != -1 &&
            !isContinuousLayout() && !draggingHW) {
             Dimension      size = splitPane.getSize();
 
@@ -1062,7 +1062,7 @@
 
 
     /**
-     * Messaged to paint the look and feel.
+     * @inheritDoc
      */
     public void paint(Graphics g, JComponent jc) {
         if (!painted && splitPane.getDividerLocation()<0) {
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicTableHeaderUI.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicTableHeaderUI.java	Wed Jul 05 17:04:26 2017 +0200
@@ -306,7 +306,7 @@
     }
 
     /**
-     * Initialize JTableHeader properties, e.g. font, foreground, and background.
+     * Initializes JTableHeader properties such as font, foreground, and background.
      * The font, foreground, and background properties are only set if their
      * current value is either null or a UIResource, other properties are set
      * if the current value is null.
@@ -403,9 +403,9 @@
     }
 
     /**
-     * This method gets called every time the rollover column in the table
-     * header is updated. Every look and feel supporting rollover effect
-     * in table header should override this method and repaint the header.
+     * This method gets called every time when a rollover column in the table
+     * header is updated. Every look and feel that supports a rollover effect
+     * in a table header should override this method and repaint the header.
      *
      * @param oldColumn the index of the previous rollover column or -1 if the
      * mouse was not over a column
@@ -736,7 +736,6 @@
     }
 
     private Dimension createHeaderSize(long width) {
-        TableColumnModel columnModel = header.getColumnModel();
         // None of the callers include the intercell spacing, do it here.
         if (width > Integer.MAX_VALUE) {
             width = Integer.MAX_VALUE;
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicTextUI.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicTextUI.java	Wed Jul 05 17:04:26 2017 +0200
@@ -37,6 +37,7 @@
 import javax.swing.event.*;
 import javax.swing.border.Border;
 import javax.swing.plaf.UIResource;
+import javax.swing.plaf.synth.SynthUI;
 import sun.swing.DefaultLookup;
 import sun.awt.AppContext;
 import javax.swing.plaf.basic.DragRecognitionSupport.BeforeDrag;
@@ -221,8 +222,7 @@
         // is ==, which is the case for the windows look and feel.
         // Until an appropriate solution is found, the code is being
         // reverted to what it was before the original fix.
-        if (this instanceof sun.swing.plaf.synth.SynthUI ||
-                (c instanceof JTextArea)) {
+        if (this instanceof SynthUI || (c instanceof JTextArea)) {
             return;
         }
         Color background = c.getBackground();
@@ -289,7 +289,7 @@
     protected abstract String getPropertyPrefix();
 
     /**
-     * Initializes component properties, e.g. font, foreground,
+     * Initializes component properties, such as font, foreground,
      * background, caret color, selection color, selected text color,
      * disabled text color, and border color.  The font, foreground, and
      * background properties are only set if their current value is either null
@@ -377,9 +377,9 @@
     }
 
     /**
-     * Sets the component properties that haven't been explicitly overridden to
-     * null.  A property is considered overridden if its current value
-     * is not a UIResource.
+     * Sets the component properties that have not been explicitly overridden
+     * to {@code null}.  A property is considered overridden if its current
+     * value is not a {@code UIResource}.
      *
      * @see #installDefaults
      * @see #uninstallUI
@@ -756,18 +756,18 @@
      * things.
      * <ol>
      * <li>
-     * Set the associated component to opaque (can be changed
+     * Sets the associated component to opaque (can be changed
      * easily by a subclass or on JTextComponent directly),
      * which is the most common case.  This will cause the
      * component's background color to be painted.
      * <li>
-     * Install the default caret and highlighter into the
+     * Installs the default caret and highlighter into the
      * associated component.
      * <li>
-     * Attach to the editor and model.  If there is no
+     * Attaches to the editor and model.  If there is no
      * model, a default one is created.
      * <li>
-     * create the view factory and the view hierarchy used
+     * Creates the view factory and the view hierarchy used
      * to represent the model.
      * </ol>
      *
@@ -784,7 +784,7 @@
 
             // This is a workaround as these should not override what synth has
             // set them to
-            if (!(this instanceof sun.swing.plaf.synth.SynthUI)){
+            if (! (this instanceof SynthUI)) {
                 // common case is background painted... this can
                 // easily be changed by subclasses or from outside
                 // of the component.
@@ -857,9 +857,9 @@
      * To prevent this from happening twice, this method is
      * reimplemented to simply paint.
      * <p>
-     * <em>NOTE:</em> Superclass is also not thread-safe in
-     * it's rendering of the background, although that's not
-     * an issue with the default rendering.
+     * <em>NOTE:</em> NOTE: Superclass is also not thread-safe in its
+     * rendering of the background, although that is not an issue with the
+     * default rendering.
      */
     public void update(Graphics g, JComponent c) {
         paint(g, c);
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicToolBarUI.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicToolBarUI.java	Wed Jul 05 17:04:26 2017 +0200
@@ -669,7 +669,7 @@
 
     /**
      * Sets the border of the component to have a rollover border which
-     * was created by <code>createRolloverBorder</code>.
+     * was created by the {@link #createRolloverBorder} method.
      *
      * @param c component which will have a rollover border installed
      * @see #createRolloverBorder
@@ -709,7 +709,7 @@
 
     /**
      * Sets the border of the component to have a non-rollover border which
-     * was created by <code>createNonRolloverBorder</code>.
+     * was created by the {@link #createNonRolloverBorder} method.
      *
      * @param c component which will have a non-rollover border installed
      * @see #createNonRolloverBorder
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicTreeUI.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicTreeUI.java	Wed Jul 05 17:04:26 2017 +0200
@@ -30,16 +30,12 @@
 import java.awt.*;
 import java.awt.event.*;
 import java.awt.datatransfer.*;
-import java.awt.dnd.*;
 import java.beans.*;
-import java.io.*;
 import java.util.Enumeration;
 import java.util.Hashtable;
-import java.util.TooManyListenersException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
-import javax.swing.plaf.ActionMapUIResource;
 import javax.swing.plaf.ComponentUI;
 import javax.swing.plaf.UIResource;
 import javax.swing.plaf.TreeUI;
@@ -1244,11 +1240,26 @@
         drawingCache.clear();
     }
 
-    private boolean isDropLine(JTree.DropLocation loc) {
+    /**
+     * Tells if a {@code DropLocation} should be indicated by a line between
+     * nodes. This is meant for {@code javax.swing.DropMode.INSERT} and
+     * {@code javax.swing.DropMode.ON_OR_INSERT} drop modes.
+     *
+     * @param loc a {@code DropLocation}
+     * @return {@code true} if the drop location should be shown as a line
+     * @since 1.7
+     */
+    protected boolean isDropLine(JTree.DropLocation loc) {
         return loc != null && loc.getPath() != null && loc.getChildIndex() != -1;
     }
 
-    private void paintDropLine(Graphics g) {
+    /**
+     * Paints the drop line.
+     *
+     * @param g {@code Graphics} object to draw on
+     * @since 1.7
+     */
+    protected void paintDropLine(Graphics g) {
         JTree.DropLocation loc = tree.getDropLocation();
         if (!isDropLine(loc)) {
             return;
@@ -1262,7 +1273,14 @@
         }
     }
 
-    private Rectangle getDropLineRect(JTree.DropLocation loc) {
+    /**
+     * Returns a ubounding box for the drop line.
+     *
+     * @param loc a {@code DropLocation}
+     * @return bounding box for the drop line
+     * @since 1.7
+     */
+    protected Rectangle getDropLineRect(JTree.DropLocation loc) {
         Rectangle rect;
         TreePath path = loc.getPath();
         int index = loc.getChildIndex();
@@ -1684,7 +1702,7 @@
                     treeState.setExpandedState(path, true);
                 }
             }
-            updateLeadRow();
+            updateLeadSelectionRow();
             updateSize();
         }
     }
@@ -2425,11 +2443,21 @@
         return tree.getLeadSelectionPath();
     }
 
-    private void updateLeadRow() {
+    /**
+     * Updates the lead row of the selection.
+     * @since 1.7
+     */
+    protected void updateLeadSelectionRow() {
         leadRow = getRowForPath(tree, getLeadSelectionPath());
     }
 
-    private int getLeadSelectionRow() {
+    /**
+     * Returns the lead row of the selection.
+     *
+     * @return selection lead row
+     * @since 1.7
+     */
+    protected int getLeadSelectionRow() {
         return leadRow;
     }
 
@@ -3345,7 +3373,7 @@
 
                 if (changeName == JTree.LEAD_SELECTION_PATH_PROPERTY) {
                     if (!ignoreLAChange) {
-                        updateLeadRow();
+                        updateLeadSelectionRow();
                         repaintPath((TreePath)event.getOldValue());
                         repaintPath((TreePath)event.getNewValue());
                     }
@@ -3763,7 +3791,7 @@
                 completeEditing();
                 if(path != null && tree.isVisible(path)) {
                     treeState.setExpandedState(path, false);
-                    updateLeadRow();
+                    updateLeadSelectionRow();
                     updateSize();
                 }
             }
@@ -3823,7 +3851,7 @@
             if(treeState != null && e != null) {
                 treeState.treeNodesInserted(e);
 
-                updateLeadRow();
+                updateLeadSelectionRow();
 
                 TreePath       path = e.getTreePath();
 
@@ -3848,7 +3876,7 @@
             if(treeState != null && e != null) {
                 treeState.treeNodesRemoved(e);
 
-                updateLeadRow();
+                updateLeadSelectionRow();
 
                 TreePath       path = e.getTreePath();
 
@@ -3862,7 +3890,7 @@
             if(treeState != null && e != null) {
                 treeState.treeStructureChanged(e);
 
-                updateLeadRow();
+                updateLeadSelectionRow();
 
                 TreePath       pPath = e.getTreePath();
 
--- a/jdk/src/share/classes/javax/swing/plaf/basic/DefaultMenuLayout.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/basic/DefaultMenuLayout.java	Wed Jul 05 17:04:26 2017 +0200
@@ -34,7 +34,7 @@
 /**
  * The default layout manager for Popup menus and menubars.  This
  * class is an extension of BoxLayout which adds the UIResource tag
- * so that plauggable L&Fs can distinguish it from user-installed
+ * so that pluggable L&Fs can distinguish it from user-installed
  * layout managers on menus.
  *
  * @author Georges Saab
--- a/jdk/src/share/classes/javax/swing/plaf/nimbus/NimbusLookAndFeel.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/nimbus/NimbusLookAndFeel.java	Wed Jul 05 17:04:26 2017 +0200
@@ -257,13 +257,41 @@
 
     /**
      * @inheritDoc
-     * @return true
+     * @return {@code true}
      */
     @Override public boolean shouldUpdateStyleOnAncestorChanged() {
         return true;
     }
 
     /**
+     * @inheritDoc
+     *
+     * <p>Overridden to return {@code true} when one of the following
+     * properties change:
+     * <ul>
+     *   <li>{@code "Nimbus.Overrides"}
+     *   <li>{@code "Nimbus.Overrides.InheritDefaults"}
+     *   <li>{@code "JComponent.sizeVariant"}
+     * </ul>
+     *
+     * @since 1.7
+     */
+    @Override
+    protected boolean shouldUpdateStyleOnEvent(PropertyChangeEvent ev) {
+        String eName = ev.getPropertyName();
+
+        // Always update when overrides or size variant change
+        if ("Nimbus.Overrides" == eName ||
+            "Nimbus.Overrides.InheritDefaults" == eName ||
+            "JComponent.sizeVariant" == eName) {
+
+            return true;
+        }
+
+        return super.shouldUpdateStyleOnEvent(ev);
+    }
+
+    /**
      * <p>Registers a third party component with the NimbusLookAndFeel.</p>
      *
      * <p>Regions represent Components and areas within Components that act as
--- a/jdk/src/share/classes/javax/swing/plaf/nimbus/package.html	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/nimbus/package.html	Wed Jul 05 17:04:26 2017 +0200
@@ -88,12 +88,11 @@
 <p><strong>Note:</strong>
 Most of the Swing API is <em>not</em> thread safe.
 For details, see
-<a
-href="http://java.sun.com/docs/books/tutorial/uiswing/overview/threads.html"
-target="_top">Threads and Swing</a>,
+<a href="http://java.sun.com/docs/books/tutorial/uiswing/concurrency/index.html"
+   target="_top">Concurrency in Swing</a>,
 a section in
 <em><a href="http://java.sun.com/docs/books/tutorial/"
-target="_top">The Java Tutorial</a></em>.
+       target="_top">The Java Tutorial</a></em>.
 
 @since 1.7
 @serial exclude
--- a/jdk/src/share/classes/javax/swing/plaf/synth/DefaultMenuLayout.java	Wed Dec 16 23:39:39 2009 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
- * Copyright 2002-2008 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-package javax.swing.plaf.synth;
-
-import javax.swing.*;
-import javax.swing.plaf.UIResource;
-
-import java.awt.Container;
-import java.awt.Dimension;
-
-/**
- * The default layout manager for Popup menus and menubars.  This
- * class is an extension of BoxLayout which adds the UIResource tag
- * so that plauggable L&Fs can distinguish it from user-installed
- * layout managers on menus.
- *
- * Derived from javax.swing.plaf.basic.DefaultMenuLayout
- *
- * @author Georges Saab
- */
-
-class DefaultMenuLayout extends BoxLayout implements UIResource {
-    public DefaultMenuLayout(Container target, int axis) {
-        super(target, axis);
-    }
-
-    public Dimension preferredLayoutSize(Container target) {
-        if (target instanceof JPopupMenu) {
-            JPopupMenu popupMenu = (JPopupMenu) target;
-
-            popupMenu.putClientProperty(
-                    SynthMenuItemLayoutHelper.MAX_ACC_OR_ARROW_WIDTH, null);
-            sun.swing.MenuItemLayoutHelper.clearUsedClientProperties(popupMenu);
-
-            if (popupMenu.getComponentCount() == 0) {
-                return new Dimension(0, 0);
-            }
-        }
-
-        // Make BoxLayout recalculate cached preferred sizes
-        super.invalidateLayout(target);
-
-        return super.preferredLayoutSize(target);
-    }
-}
--- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthBorder.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthBorder.java	Wed Jul 05 17:04:26 2017 +0200
@@ -29,7 +29,6 @@
 import javax.swing.text.JTextComponent;
 import javax.swing.border.*;
 import javax.swing.plaf.UIResource;
-import sun.swing.plaf.synth.SynthUI;
 
 /**
  * SynthBorder is a border that delegates to a Painter. The Insets
--- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthButtonUI.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthButtonUI.java	Wed Jul 05 17:04:26 2017 +0200
@@ -25,40 +25,49 @@
 
 package javax.swing.plaf.synth;
 
+import javax.swing.*;
 import java.awt.*;
-import java.awt.event.*;
-import java.io.Serializable;
-import javax.swing.*;
-import javax.swing.border.*;
-import java.awt.*;
-import java.awt.event.*;
 import java.beans.*;
 import javax.swing.plaf.*;
 import javax.swing.plaf.basic.BasicButtonUI;
 import javax.swing.plaf.basic.BasicHTML;
 import javax.swing.text.View;
-import sun.swing.plaf.synth.SynthUI;
-import sun.swing.plaf.synth.DefaultSynthStyle;
 
 /**
- * Synth's ButtonUI implementation.
+ * Provides the Synth L&F UI delegate for
+ * {@link javax.swing.JButton}.
  *
  * @author Scott Violet
+ * @since 1.7
  */
-class SynthButtonUI extends BasicButtonUI implements
+public class SynthButtonUI extends BasicButtonUI implements
                                  PropertyChangeListener, SynthUI {
     private SynthStyle style;
 
+    /**
+     * Creates a new UI object for the given component.
+     *
+     * @param c component to create UI object for
+     * @return the UI object
+     */
     public static ComponentUI createUI(JComponent c) {
         return new SynthButtonUI();
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     protected void installDefaults(AbstractButton b) {
         updateStyle(b);
 
         LookAndFeel.installProperty(b, "rolloverEnabled", Boolean.TRUE);
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     protected void installListeners(AbstractButton b) {
         super.installListeners(b);
         b.addPropertyChangeListener(this);
@@ -99,11 +108,19 @@
         context.dispose();
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     protected void uninstallListeners(AbstractButton b) {
         super.uninstallListeners(b);
         b.removePropertyChangeListener(this);
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     protected void uninstallDefaults(AbstractButton b) {
         SynthContext context = getContext(b, ENABLED);
 
@@ -112,20 +129,20 @@
         style = null;
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     public SynthContext getContext(JComponent c) {
         return getContext(c, getComponentState(c));
     }
 
     SynthContext getContext(JComponent c, int state) {
-        Region region = getRegion(c);
+        Region region = SynthLookAndFeel.getRegion(c);
         return SynthContext.getContext(SynthContext.class, c, region,
                                        style, state);
     }
 
-    private Region getRegion(JComponent c) {
-        return SynthLookAndFeel.getRegion(c);
-    }
-
     /**
      * Returns the current state of the passed in <code>AbstractButton</code>.
      */
@@ -164,6 +181,10 @@
         return state;
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     public int getBaseline(JComponent c, int width, int height) {
         if (c == null) {
             throw new NullPointerException("Component must be non-null");
@@ -215,6 +236,10 @@
     //          Paint Methods
     // ********************************
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     public void update(Graphics g, JComponent c) {
         SynthContext context = getContext(c);
 
@@ -224,6 +249,10 @@
         context.dispose();
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     public void paint(Graphics g, JComponent c) {
         SynthContext context = getContext(c);
 
@@ -231,6 +260,12 @@
         context.dispose();
     }
 
+    /**
+     * Paints the specified component.
+     *
+     * @param context context for the component being painted
+     * @param g {@code Graphics} object used for painting
+     */
     protected void paint(SynthContext context, Graphics g) {
         AbstractButton b = (AbstractButton)context.getComponent();
 
@@ -253,19 +288,22 @@
         }
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     public void paintBorder(SynthContext context, Graphics g, int x,
                             int y, int w, int h) {
         context.getPainter().paintButtonBorder(context, g, x, y, w, h);
     }
 
     /**
-     * Returns the default icon. This should NOT callback
+     * Returns the default icon. This should not callback
      * to the JComponent.
      *
-     * @param b AbstractButton the icon is associated with
+     * @param b button the icon is associated with
      * @return default icon
      */
-
     protected Icon getDefaultIcon(AbstractButton b) {
         SynthContext context = getContext(b);
         Icon icon = context.getStyle().getIcon(context, getPropertyPrefix() + "icon");
@@ -274,7 +312,11 @@
     }
 
     /**
-     * Returns the Icon to use in painting the button.
+     * Returns the Icon to use for painting the button. The icon is chosen with
+     * respect to the current state of the button.
+     *
+     * @param b button the icon is associated with
+     * @return an icon
      */
     protected Icon getIcon(AbstractButton b) {
         Icon icon = b.getIcon();
@@ -374,7 +416,7 @@
     /**
      * Returns the amount to shift the text/icon when painting.
      */
-    protected int getTextShiftOffset(SynthContext state) {
+    private int getTextShiftOffset(SynthContext state) {
         AbstractButton button = (AbstractButton)state.getComponent();
         ButtonModel model = button.getModel();
 
@@ -389,6 +431,11 @@
     // ********************************
     //          Layout Methods
     // ********************************
+
+    /**
+     * @inheritDoc
+     */
+    @Override
     public Dimension getMinimumSize(JComponent c) {
         if (c.getComponentCount() > 0 && c.getLayout() != null) {
             return null;
@@ -406,6 +453,10 @@
         return size;
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     public Dimension getPreferredSize(JComponent c) {
         if (c.getComponentCount() > 0 && c.getLayout() != null) {
             return null;
@@ -423,6 +474,10 @@
         return size;
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     public Dimension getMaximumSize(JComponent c) {
         if (c.getComponentCount() > 0 && c.getLayout() != null) {
             return null;
@@ -442,7 +497,8 @@
     }
 
     /**
-     * Returns the Icon used in calculating the pref/min/max size.
+     * Returns the Icon used in calculating the
+     * preferred/minimum/maximum size.
      */
     protected Icon getSizingIcon(AbstractButton b) {
         Icon icon = getEnabledIcon(b, b.getIcon());
@@ -452,6 +508,10 @@
         return icon;
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     public void propertyChange(PropertyChangeEvent e) {
         if (SynthLookAndFeel.shouldUpdateStyle(e)) {
             updateStyle((AbstractButton)e.getSource());
--- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthCheckBoxMenuItemUI.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthCheckBoxMenuItemUI.java	Wed Jul 05 17:04:26 2017 +0200
@@ -27,56 +27,50 @@
 
 
 import java.awt.*;
-import java.awt.event.*;
 import javax.swing.*;
 import javax.swing.plaf.*;
-import javax.swing.border.*;
-import java.io.Serializable;
 
 
 /**
- * Synth's CheckBoxMenuItemUI.
+ * Provides the Synth L&F UI delegate for
+ * {@link javax.swing.JCheckBoxMenuItem}.
  *
  * @author Leif Samuelsson
  * @author Georges Saab
  * @author David Karlton
  * @author Arnaud Weber
+ * @since 1.7
  */
-class SynthCheckBoxMenuItemUI extends SynthMenuItemUI {
+public class SynthCheckBoxMenuItemUI extends SynthMenuItemUI {
 
+    /**
+     * Creates a new UI object for the given component.
+     *
+     * @param c component to create UI object for
+     * @return the UI object
+     */
     public static ComponentUI createUI(JComponent c) {
         return new SynthCheckBoxMenuItemUI();
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     protected String getPropertyPrefix() {
         return "CheckBoxMenuItem";
     }
 
-    public void processMouseEvent(JMenuItem item, MouseEvent e,
-                                  MenuElement path[], MenuSelectionManager manager) {
-        Point p = e.getPoint();
-        if (p.x >= 0 && p.x < item.getWidth() && p.y >= 0 && p.y < item.getHeight()) {
-            if (e.getID() == MouseEvent.MOUSE_RELEASED) {
-                manager.clearSelectedPath();
-                item.doClick(0);
-            } else {
-                manager.setSelectedPath(path);
-            }
-        } else if (item.getModel().isArmed()) {
-            int c = path.length - 1;
-            MenuElement newPath[] = new MenuElement[c];
-            for (int i = 0; i < c; i++) {
-                newPath[i] = path[i];
-            }
-            manager.setSelectedPath(newPath);
-        }
-    }
-
+    @Override
     void paintBackground(SynthContext context, Graphics g, JComponent c) {
         context.getPainter().paintCheckBoxMenuItemBackground(context, g, 0, 0,
                                                   c.getWidth(), c.getHeight());
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     public void paintBorder(SynthContext context, Graphics g, int x,
                             int y, int w, int h) {
         context.getPainter().paintCheckBoxMenuItemBorder(context, g, x, y, w, h);
--- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthCheckBoxUI.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthCheckBoxUI.java	Wed Jul 05 17:04:26 2017 +0200
@@ -25,36 +25,51 @@
 
 package javax.swing.plaf.synth;
 
-import javax.swing.*;
-import java.awt.*;
-import java.awt.event.*;
-import javax.swing.plaf.*;
-import java.io.Serializable;
+import javax.swing.JComponent;
+import java.awt.Graphics;
+import javax.swing.plaf.ComponentUI;
 
 
 /**
- * Synth's CheckBoxUI.
+ * Provides the Synth L&F UI delegate for
+ * {@link javax.swing.JCheckBox}.
  *
  * @author Jeff Dinkins
+ * @since 1.7
  */
-class SynthCheckBoxUI extends SynthRadioButtonUI {
+public class SynthCheckBoxUI extends SynthRadioButtonUI {
 
     // ********************************
     //            Create PLAF
     // ********************************
+    /**
+     * Creates a new UI object for the given component.
+     *
+     * @param b component to create UI object for
+     * @return the UI object
+     */
     public static ComponentUI createUI(JComponent b) {
         return new SynthCheckBoxUI();
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     protected String getPropertyPrefix() {
         return "CheckBox.";
     }
 
+    @Override
     void paintBackground(SynthContext context, Graphics g, JComponent c) {
         context.getPainter().paintCheckBoxBackground(context, g, 0, 0,
                                                   c.getWidth(), c.getHeight());
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     public void paintBorder(SynthContext context, Graphics g, int x,
                             int y, int w, int h) {
         context.getPainter().paintCheckBoxBorder(context, g, x, y, w, h);
--- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthColorChooserUI.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthColorChooserUI.java	Wed Jul 05 17:04:26 2017 +0200
@@ -28,34 +28,39 @@
 
 import javax.swing.*;
 import javax.swing.colorchooser.*;
-import javax.swing.event.*;
-import javax.swing.border.*;
 import javax.swing.plaf.*;
 import javax.swing.plaf.basic.BasicColorChooserUI;
-import java.util.*;
 import java.awt.*;
-import java.awt.image.*;
-import java.awt.event.*;
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
-import java.io.Serializable;
-import sun.swing.plaf.synth.SynthUI;
 
 
 /**
- * Synth's ColorChooserUI.
+ * Provides the Synth L&F UI delegate for
+ * {@link javax.swing.JColorChooser}.
  *
  * @author Tom Santos
  * @author Steve Wilson
+ * @since 1.7
  */
-class SynthColorChooserUI extends BasicColorChooserUI implements
+public class SynthColorChooserUI extends BasicColorChooserUI implements
         PropertyChangeListener, SynthUI {
     private SynthStyle style;
 
+    /**
+     * Creates a new UI object for the given component.
+     *
+     * @param c component to create UI object for
+     * @return the UI object
+     */
     public static ComponentUI createUI(JComponent c) {
         return new SynthColorChooserUI();
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     protected AbstractColorChooserPanel[] createDefaultChoosers() {
         SynthContext context = getContext(chooser, ENABLED);
         AbstractColorChooserPanel[] panels = (AbstractColorChooserPanel[])
@@ -68,6 +73,10 @@
         return panels;
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     protected void installDefaults() {
         super.installDefaults();
         updateStyle(chooser);
@@ -79,6 +88,10 @@
         context.dispose();
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     protected void uninstallDefaults() {
         SynthContext context = getContext(chooser, ENABLED);
 
@@ -88,16 +101,28 @@
         super.uninstallDefaults();
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     protected void installListeners() {
         super.installListeners();
         chooser.addPropertyChangeListener(this);
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     protected void uninstallListeners() {
         chooser.removePropertyChangeListener(this);
         super.uninstallListeners();
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     public SynthContext getContext(JComponent c) {
         return getContext(c, getComponentState(c));
     }
@@ -107,14 +132,14 @@
                     SynthLookAndFeel.getRegion(c), style, state);
     }
 
-    private Region getRegion(JComponent c) {
-        return SynthLookAndFeel.getRegion(c);
-    }
-
     private int getComponentState(JComponent c) {
         return SynthLookAndFeel.getComponentState(c);
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     public void update(Graphics g, JComponent c) {
         SynthContext context = getContext(c);
 
@@ -125,6 +150,10 @@
         context.dispose();
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     public void paint(Graphics g, JComponent c) {
         SynthContext context = getContext(c);
 
@@ -132,14 +161,29 @@
         context.dispose();
     }
 
+    /**
+     * Paints the specified component.
+     * This implementation does not perform any actions.
+     *
+     * @param context context for the component being painted
+     * @param g {@code Graphics} object used for painting
+     */
     protected void paint(SynthContext context, Graphics g) {
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     public void paintBorder(SynthContext context, Graphics g, int x,
                             int y, int w, int h) {
         context.getPainter().paintColorChooserBorder(context, g, x, y,w,h);
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     public void propertyChange(PropertyChangeEvent e) {
         if (SynthLookAndFeel.shouldUpdateStyle(e)) {
             updateStyle((JColorChooser)e.getSource());
--- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthComboBoxUI.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthComboBoxUI.java	Wed Jul 05 17:04:26 2017 +0200
@@ -27,21 +27,21 @@
 
 import java.awt.*;
 import java.awt.event.*;
-import java.lang.reflect.*;
 import javax.swing.*;
 import javax.swing.plaf.*;
 import javax.swing.event.*;
 import javax.swing.plaf.basic.*;
 import java.beans.PropertyChangeListener;
 import java.beans.PropertyChangeEvent;
-import sun.swing.plaf.synth.SynthUI;
 
 /**
- * Synth's ComboBoxUI.
+ * Provides the Synth L&F UI delegate for
+ * {@link javax.swing.JComboBox}.
  *
  * @author Scott Violet
+ * @since 1.7
  */
-class SynthComboBoxUI extends BasicComboBoxUI implements
+public class SynthComboBoxUI extends BasicComboBoxUI implements
                               PropertyChangeListener, SynthUI {
     private SynthStyle style;
     private boolean useListColors;
@@ -93,12 +93,11 @@
     private boolean forceOpaque = false;
 
     /**
-     * NOTE: This serves the same purpose as the same field in BasicComboBoxUI.
-     * It is here because I could not give the padding field in
-     * BasicComboBoxUI protected access in an update release.
+     * Creates a new UI object for the given component.
+     *
+     * @param c component to create UI object for
+     * @return the UI object
      */
-    private Insets padding;
-
     public static ComponentUI createUI(JComponent c) {
         return new SynthComboBoxUI();
     }
@@ -118,21 +117,6 @@
 
     @Override
     protected void installDefaults() {
-        //NOTE: This next line of code was added because, since squareButton in
-        //BasicComboBoxUI is private, I need to have some way of reading it from UIManager.
-        //This is an incomplete solution (since it implies that squareButons,
-        //once set, cannot be reset per state. Probably ok, but not always ok).
-        //This line of code should be removed at the same time that squareButton
-        //is made protected in the super class.
-        super.installDefaults();
-
-        //This is here instead of in updateStyle because the value for padding
-        //needs to remain consistent with the value for padding in
-        //BasicComboBoxUI. I wouldn't have this value here at all if not
-        //for the fact that I cannot make "padding" protected in any way
-        //for an update release. This *should* be fixed in Java 7
-        padding = UIManager.getInsets("ComboBox.padding");
-
         updateStyle(comboBox);
     }
 
@@ -142,6 +126,7 @@
 
         style = SynthLookAndFeel.updateStyle(context, this);
         if (style != oldStyle) {
+            padding = (Insets) style.get(context, "ComboBox.padding");
             popupInsets = (Insets)style.get(context, "ComboBox.popupInsets");
             useListColors = style.getBoolean(context,
                     "ComboBox.rendererUseListColors", true);
@@ -149,6 +134,8 @@
                     "ComboBox.buttonWhenNotEditable", false);
             pressedWhenPopupVisible = style.getBoolean(context,
                     "ComboBox.pressedWhenPopupVisible", false);
+            squareButton = style.getBoolean(context,
+                    "ComboBox.squareButton", true);
 
             if (oldStyle != null) {
                 uninstallKeyboardActions();
@@ -164,6 +151,9 @@
         }
     }
 
+    /**
+     * @inheritDoc
+     */
     @Override
     protected void installListeners() {
         comboBox.addPropertyChangeListener(this);
@@ -172,6 +162,9 @@
         super.installListeners();
     }
 
+    /**
+     * @inheritDoc
+     */
     @Override
     public void uninstallUI(JComponent c) {
         if (popup instanceof SynthComboPopup) {
@@ -181,6 +174,9 @@
         buttonHandler = null;
     }
 
+    /**
+     * @inheritDoc
+     */
     @Override
     protected void uninstallDefaults() {
         SynthContext context = getContext(comboBox, ENABLED);
@@ -190,6 +186,9 @@
         style = null;
     }
 
+    /**
+     * @inheritDoc
+     */
     @Override
     protected void uninstallListeners() {
         editorFocusHandler.unregister();
@@ -200,6 +199,9 @@
         super.uninstallListeners();
     }
 
+    /**
+     * @inheritDoc
+     */
     @Override
     public SynthContext getContext(JComponent c) {
         return getContext(c, getComponentState(c));
@@ -210,10 +212,6 @@
                     SynthLookAndFeel.getRegion(c), style, state);
     }
 
-    private Region getRegion(JComponent c) {
-        return SynthLookAndFeel.getRegion(c);
-    }
-
     private int getComponentState(JComponent c) {
         // currently we have a broken situation where if a developer
         // takes the border from a JComboBox and sets it on a JTextField
@@ -252,6 +250,9 @@
         }
     }
 
+    /**
+     * @inheritDoc
+     */
     @Override
     protected ComboPopup createPopup() {
         SynthComboPopup p = new SynthComboPopup(comboBox);
@@ -259,11 +260,17 @@
         return p;
     }
 
+    /**
+     * @inheritDoc
+     */
     @Override
     protected ListCellRenderer createRenderer() {
         return new SynthComboBoxRenderer();
     }
 
+    /**
+     * @inheritDoc
+     */
     @Override
     protected ComboBoxEditor createEditor() {
         return new SynthComboBoxEditor();
@@ -273,6 +280,9 @@
     // end UI Initialization
     //======================
 
+    /**
+     * @inheritDoc
+     */
     @Override
     public void propertyChange(PropertyChangeEvent e) {
         if (SynthLookAndFeel.shouldUpdateStyle(e)) {
@@ -280,6 +290,9 @@
         }
     }
 
+    /**
+     * @inheritDoc
+     */
     @Override
     protected JButton createArrowButton() {
         SynthArrowButton button = new SynthArrowButton(SwingConstants.SOUTH);
@@ -291,6 +304,9 @@
     //=================================
     // begin ComponentUI Implementation
 
+    /**
+     * @inheritDoc
+     */
     @Override
     public void update(Graphics g, JComponent c) {
         SynthContext context = getContext(c);
@@ -302,6 +318,9 @@
         context.dispose();
     }
 
+    /**
+     * @inheritDoc
+     */
     @Override
     public void paint(Graphics g, JComponent c) {
         SynthContext context = getContext(c);
@@ -310,6 +329,12 @@
         context.dispose();
     }
 
+    /**
+     * Paints the specified component.
+     *
+     * @param context context for the component being painted
+     * @param g {@code Graphics} object used for painting
+     */
     protected void paint(SynthContext context, Graphics g) {
         hasFocus = comboBox.hasFocus();
         if ( !comboBox.isEditable() ) {
@@ -318,6 +343,9 @@
         }
     }
 
+    /**
+     * @inheritDoc
+     */
     @Override
     public void paintBorder(SynthContext context, Graphics g, int x,
                             int y, int w, int h) {
@@ -375,7 +403,7 @@
     }
 
     /**
-     * Return the default size of an empty display area of the combo box using
+     * Returns the default size of an empty display area of the combo box using
      * the current renderer and font.
      *
      * This method was overridden to use SynthComboBoxRenderer instead of
@@ -394,23 +422,6 @@
     }
 
     /**
-     * This has been refactored out in hopes that it may be investigated and
-     * simplified for the next major release. adding/removing
-     * the component to the currentValuePane and changing the font may be
-     * redundant operations.
-     *
-     * NOTE: This method was copied in its entirety from BasicComboBoxUI. Might
-     * want to make it protected in BasicComboBoxUI in Java 7
-     */
-    private Dimension getSizeForComponent(Component comp) {
-        currentValuePane.add(comp);
-        comp.setFont(comboBox.getFont());
-        Dimension d = comp.getPreferredSize();
-        currentValuePane.remove(comp);
-        return d;
-    }
-
-    /**
      * From BasicComboBoxRenderer v 1.18.
      *
      * Be aware that SynthFileChooserUIImpl relies on the fact that the default
@@ -478,85 +489,17 @@
     }
 
 
-    /**
-     * From BasicCombBoxEditor v 1.24.
-     */
-    private static class SynthComboBoxEditor implements
-                              ComboBoxEditor, UIResource {
-        protected JTextField editor;
-        private Object oldValue;
+    private static class SynthComboBoxEditor
+            extends BasicComboBoxEditor.UIResource {
 
-        public SynthComboBoxEditor() {
-            editor = new JTextField("",9);
-            editor.setName("ComboBox.textField");
-        }
-
-        @Override
-        public Component getEditorComponent() {
-            return editor;
-        }
-
-        /**
-         * Sets the item that should be edited.
-         *
-         * @param anObject the displayed value of the editor
-         */
-        @Override
-        public void setItem(Object anObject) {
-            String text;
-
-            if ( anObject != null )  {
-                text = anObject.toString();
-                oldValue = anObject;
-            } else {
-                text = "";
-            }
-            // workaround for 4530952
-            if (!text.equals(editor.getText())) {
-                editor.setText(text);
-            }
-        }
-
-        @Override
-        public Object getItem() {
-            Object newValue = editor.getText();
-
-            if (oldValue != null && !(oldValue instanceof String))  {
-                // The original value is not a string. Should return the value in it's
-                // original type.
-                if (newValue.equals(oldValue.toString())) {
-                    return oldValue;
-                } else {
-                    // Must take the value from the editor and get the value and cast it to the new type.
-                    Class<?> cls = oldValue.getClass();
-                    try {
-                        Method method = cls.getMethod("valueOf", new Class[]{String.class});
-                        newValue = method.invoke(oldValue, new Object[] { editor.getText()});
-                    } catch (Exception ex) {
-                        // Fail silently and return the newValue (a String object)
-                    }
-                }
-            }
-            return newValue;
-        }
-
-        @Override
-        public void selectAll() {
-            editor.selectAll();
-            editor.requestFocus();
-        }
-
-        @Override
-        public void addActionListener(ActionListener l) {
-            editor.addActionListener(l);
-        }
-
-        @Override
-        public void removeActionListener(ActionListener l) {
-            editor.removeActionListener(l);
+        @Override public JTextField createEditorComponent() {
+            JTextField f = new JTextField("", 9);
+            f.setName("ComboBox.textField");
+            return f;
         }
     }
 
+
     /**
      * Handles all the logic for treating the combo as a button when it is
      * not editable, and when shouldActLikeButton() is true. This class is a
@@ -620,7 +563,7 @@
         //------------------------------------------------------------------
 
         /**
-         * {@inheritDoc}
+         * @inheritDoc
          *
          * Ensures that isPressed() will return true if the combo is pressed,
          * or the arrowButton is pressed, <em>or</em> if the combo popup is
@@ -634,7 +577,7 @@
         }
 
         /**
-         * {@inheritDoc}
+         * @inheritDoc
          *
          * Ensures that the armed state is in sync with the pressed state
          * if shouldActLikeButton is true. Without this method, the arrow
@@ -649,7 +592,7 @@
         }
 
         /**
-         * {@inheritDoc}
+         * @inheritDoc
          *
          * Ensures that isRollover() will return true if the combo is
          * rolled over, or the arrowButton is rolled over.
@@ -660,7 +603,7 @@
         }
 
         /**
-         * {@inheritDoc}
+         * @inheritDoc
          *
          * Forwards pressed states to the internal "pressed" field
          */
@@ -671,7 +614,7 @@
         }
 
         /**
-         * {@inheritDoc}
+         * @inheritDoc
          *
          * Forwards rollover states to the internal "over" field
          */
--- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthDefaultLookup.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthDefaultLookup.java	Wed Jul 05 17:04:26 2017 +0200
@@ -27,7 +27,6 @@
 import sun.swing.DefaultLookup;
 import javax.swing.JComponent;
 import javax.swing.plaf.ComponentUI;
-import sun.swing.plaf.synth.SynthUI;
 
 /**
  * SynthDefaultLookup redirects all lookup calls to the SynthContext.
--- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthDesktopIconUI.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthDesktopIconUI.java	Wed Jul 05 17:04:26 2017 +0200
@@ -28,36 +28,44 @@
 import java.awt.*;
 import java.awt.event.*;
 import javax.swing.*;
-import javax.swing.event.*;
-import javax.swing.border.*;
 import javax.swing.plaf.*;
 import javax.swing.plaf.basic.BasicDesktopIconUI;
 import java.beans.*;
-import java.io.Serializable;
-import sun.swing.plaf.synth.SynthUI;
 
 
 /**
- * Synth L&F for a minimized window on a desktop.
+ * Provides the Synth L&F UI delegate for a minimized internal frame on a desktop.
  *
  * @author Joshua Outwater
+ * @since 1.7
  */
-class SynthDesktopIconUI extends BasicDesktopIconUI implements SynthUI,
-                                        ActionListener, PropertyChangeListener {
+public class SynthDesktopIconUI extends BasicDesktopIconUI
+                                implements SynthUI, PropertyChangeListener {
     private SynthStyle style;
+    private Handler handler = new Handler();
 
+    /**
+     * Creates a new UI object for the given component.
+     *
+     * @param c component to create UI object for
+     * @return the UI object
+     */
     public static ComponentUI createUI(JComponent c)    {
         return new SynthDesktopIconUI();
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     protected void installComponents() {
         if (UIManager.getBoolean("InternalFrame.useTaskBar")) {
             iconPane = new JToggleButton(frame.getTitle(), frame.getFrameIcon()) {
-                public String getToolTipText() {
+                @Override public String getToolTipText() {
                     return getText();
                 }
 
-                public JPopupMenu getComponentPopupMenu() {
+                @Override public JPopupMenu getComponentPopupMenu() {
                     return frame.getComponentPopupMenu();
                 }
             };
@@ -73,24 +81,37 @@
         desktopIcon.add(iconPane, BorderLayout.CENTER);
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     protected void installListeners() {
         super.installListeners();
         desktopIcon.addPropertyChangeListener(this);
 
         if (iconPane instanceof JToggleButton) {
             frame.addPropertyChangeListener(this);
-            ((JToggleButton)iconPane).addActionListener(this);
+            ((JToggleButton)iconPane).addActionListener(handler);
         }
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     protected void uninstallListeners() {
         if (iconPane instanceof JToggleButton) {
+            ((JToggleButton)iconPane).removeActionListener(handler);
             frame.removePropertyChangeListener(this);
         }
         desktopIcon.removePropertyChangeListener(this);
         super.uninstallListeners();
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     protected void installDefaults() {
         updateStyle(desktopIcon);
     }
@@ -101,6 +122,10 @@
         context.dispose();
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     protected void uninstallDefaults() {
         SynthContext context = getContext(desktopIcon, ENABLED);
         style.uninstallDefaults(context);
@@ -108,12 +133,16 @@
         style = null;
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     public SynthContext getContext(JComponent c) {
         return getContext(c, getComponentState(c));
     }
 
     private SynthContext getContext(JComponent c, int state) {
-        Region region = getRegion(c);
+        Region region = SynthLookAndFeel.getRegion(c);
         return SynthContext.getContext(SynthContext.class, c, region,
                                        style, state);
     }
@@ -122,10 +151,10 @@
         return SynthLookAndFeel.getComponentState(c);
     }
 
-    Region getRegion(JComponent c) {
-        return SynthLookAndFeel.getRegion(c);
-    }
-
+    /**
+     * @inheritDoc
+     */
+    @Override
     public void update(Graphics g, JComponent c) {
         SynthContext context = getContext(c);
 
@@ -136,6 +165,10 @@
         context.dispose();
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     public void paint(Graphics g, JComponent c) {
         SynthContext context = getContext(c);
 
@@ -143,33 +176,24 @@
         context.dispose();
     }
 
+    /**
+     * Paints the specified component. This implementation does nothing.
+     *
+     * @param context context for the component being painted
+     * @param g {@code Graphics} object used for painting
+     */
     protected void paint(SynthContext context, Graphics g) {
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     public void paintBorder(SynthContext context, Graphics g, int x,
                             int y, int w, int h) {
         context.getPainter().paintDesktopIconBorder(context, g, x, y, w, h);
     }
 
-    public void actionPerformed(ActionEvent evt) {
-        if (evt.getSource() instanceof JToggleButton) {
-            // Either iconify the frame or deiconify and activate it.
-            JToggleButton button = (JToggleButton)evt.getSource();
-            try {
-                boolean selected = button.isSelected();
-                if (!selected && !frame.isIconifiable()) {
-                    button.setSelected(true);
-                } else {
-                    frame.setIcon(!selected);
-                    if (selected) {
-                        frame.setSelected(true);
-                    }
-                }
-            } catch (PropertyVetoException e2) {
-            }
-        }
-    }
-
     public void propertyChange(PropertyChangeEvent evt) {
         if (evt.getSource() instanceof JInternalFrame.JDesktopIcon) {
             if (SynthLookAndFeel.shouldUpdateStyle(evt)) {
@@ -191,4 +215,25 @@
             }
         }
     }
+
+    private final class Handler implements ActionListener {
+        public void actionPerformed(ActionEvent evt) {
+            if (evt.getSource() instanceof JToggleButton) {
+                // Either iconify the frame or deiconify and activate it.
+                JToggleButton button = (JToggleButton)evt.getSource();
+                try {
+                    boolean selected = button.isSelected();
+                    if (!selected && !frame.isIconifiable()) {
+                        button.setSelected(true);
+                    } else {
+                        frame.setIcon(!selected);
+                        if (selected) {
+                            frame.setSelected(true);
+                        }
+                    }
+                } catch (PropertyVetoException e2) {
+                }
+            }
+        }
+    }
 }
--- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthDesktopPaneUI.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthDesktopPaneUI.java	Wed Jul 05 17:04:26 2017 +0200
@@ -29,34 +29,38 @@
 import javax.swing.border.*;
 import javax.swing.plaf.*;
 import javax.swing.plaf.basic.BasicDesktopPaneUI;
-
 import java.beans.*;
-
 import java.awt.event.*;
-import java.awt.Dimension;
-import java.awt.Insets;
-import java.awt.Graphics;
-import java.awt.KeyboardFocusManager;
 import java.awt.*;
-import java.util.Vector;
-import sun.swing.plaf.synth.SynthUI;
 
 /**
- * Synth L&F for a desktop.
+ * Provides the Synth L&F UI delegate for
+ * {@link javax.swing.JDesktopPane}.
  *
  * @author Joshua Outwater
  * @author Steve Wilson
+ * @since 1.7
  */
-class SynthDesktopPaneUI extends BasicDesktopPaneUI implements
+public class SynthDesktopPaneUI extends BasicDesktopPaneUI implements
                   PropertyChangeListener, SynthUI {
     private SynthStyle style;
     private TaskBar taskBar;
     private DesktopManager oldDesktopManager;
 
+    /**
+     * Creates a new UI object for the given component.
+     *
+     * @param c component to create UI object for
+     * @return the UI object
+     */
     public static ComponentUI createUI(JComponent c) {
         return new SynthDesktopPaneUI();
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     protected void installListeners() {
         super.installListeners();
         desktop.addPropertyChangeListener(this);
@@ -68,6 +72,10 @@
         }
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     protected void installDefaults() {
         updateStyle(desktop);
 
@@ -114,6 +122,10 @@
         context.dispose();
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     protected void uninstallListeners() {
         if (taskBar != null) {
             desktop.removeComponentListener(taskBar);
@@ -123,6 +135,10 @@
         super.uninstallListeners();
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     protected void uninstallDefaults() {
         SynthContext context = getContext(desktop, ENABLED);
 
@@ -147,6 +163,10 @@
         }
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     protected void installDesktopManager() {
         if (UIManager.getBoolean("InternalFrame.useTaskBar")) {
             desktopManager = oldDesktopManager = desktop.getDesktopManager();
@@ -159,6 +179,10 @@
         }
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     protected void uninstallDesktopManager() {
         if (oldDesktopManager != null && !(oldDesktopManager instanceof UIResource)) {
             desktopManager = desktop.getDesktopManager();
@@ -397,7 +421,10 @@
         }
     }
 
-
+    /**
+     * @inheritDoc
+     */
+    @Override
     public SynthContext getContext(JComponent c) {
         return getContext(c, getComponentState(c));
     }
@@ -407,14 +434,14 @@
                      SynthLookAndFeel.getRegion(c), style, state);
     }
 
-    private Region getRegion(JComponent c) {
-        return SynthLookAndFeel.getRegion(c);
-    }
-
     private int getComponentState(JComponent c) {
         return SynthLookAndFeel.getComponentState(c);
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     public void update(Graphics g, JComponent c) {
         SynthContext context = getContext(c);
 
@@ -425,6 +452,10 @@
         context.dispose();
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     public void paint(Graphics g, JComponent c) {
         SynthContext context = getContext(c);
 
@@ -432,14 +463,28 @@
         context.dispose();
     }
 
+    /**
+     * Paints the specified component. This implementation does nothing.
+     *
+     * @param context context for the component being painted
+     * @param g {@code Graphics} object used for painting
+     */
     protected void paint(SynthContext context, Graphics g) {
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     public void paintBorder(SynthContext context, Graphics g, int x,
                             int y, int w, int h) {
         context.getPainter().paintDesktopPaneBorder(context, g, x, y, w, h);
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     public void propertyChange(PropertyChangeEvent evt) {
         if (SynthLookAndFeel.shouldUpdateStyle(evt)) {
             updateStyle((JDesktopPane)evt.getSource());
--- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthEditorPaneUI.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthEditorPaneUI.java	Wed Jul 05 17:04:26 2017 +0200
@@ -31,47 +31,52 @@
 import javax.swing.plaf.*;
 import javax.swing.plaf.basic.BasicEditorPaneUI;
 import java.beans.PropertyChangeEvent;
-import sun.swing.plaf.synth.SynthUI;
 
 /**
- * Provides the look and feel for a JEditorPane in the
- * Synth look and feel.
+ * Provides the Synth L&F UI delegate for
+ * {@link javax.swing.JEditorPane}.
  *
  * @author  Shannon Hickey
+ * @since 1.7
  */
-class SynthEditorPaneUI extends BasicEditorPaneUI implements SynthUI {
+public class SynthEditorPaneUI extends BasicEditorPaneUI implements SynthUI {
     private SynthStyle style;
     /*
      * I would prefer to use UIResource instad of this.
      * Unfortunately Boolean is a final class
      */
     private Boolean localTrue = Boolean.TRUE;
-    private Boolean localFalse = Boolean.FALSE;
 
     /**
-     * Creates a UI for the JTextPane.
+     * Creates a new UI object for the given component.
      *
-     * @param c the JTextPane component
-     * @return the UI
+     * @param c component to create UI object for
+     * @return the UI object
      */
     public static ComponentUI createUI(JComponent c) {
         return new SynthEditorPaneUI();
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     protected void installDefaults() {
         // Installs the text cursor on the component
         super.installDefaults();
         JComponent c = getComponent();
         Object clientProperty =
             c.getClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES);
-        if (clientProperty == null
-            || clientProperty == localFalse) {
-            c.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES,
-                                localTrue);
+        if (clientProperty == null) {
+            c.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES, localTrue);
         }
         updateStyle(getComponent());
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     protected void uninstallDefaults() {
         SynthContext context = getContext(getComponent(), ENABLED);
         JComponent c = getComponent();
@@ -84,7 +89,7 @@
         Object clientProperty =
             c.getClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES);
         if (clientProperty == localTrue) {
-            getComponent().putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES,
+            c.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES,
                                              Boolean.FALSE);
         }
         super.uninstallDefaults();
@@ -100,6 +105,7 @@
      *
      * @param evt the property change event
      */
+    @Override
     protected void propertyChange(PropertyChangeEvent evt) {
         if (SynthLookAndFeel.shouldUpdateStyle(evt)) {
             updateStyle((JTextComponent)evt.getSource());
@@ -124,6 +130,10 @@
         context.dispose();
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     public SynthContext getContext(JComponent c) {
         return getContext(c, getComponentState(c));
     }
@@ -137,6 +147,10 @@
         return SynthLookAndFeel.getComponentState(c);
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     public void update(Graphics g, JComponent c) {
         SynthContext context = getContext(c);
 
@@ -146,10 +160,20 @@
         context.dispose();
     }
 
+    /**
+     * Paints the specified component.
+     *
+     * @param context context for the component being painted
+     * @param g {@code Graphics} object used for painting
+     */
     protected void paint(SynthContext context, Graphics g) {
         super.paint(g, getComponent());
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     protected void paintBackground(Graphics g) {
         // Overriden to do nothing, all our painting is done from update/paint.
     }
@@ -159,6 +183,10 @@
                                                   c.getWidth(), c.getHeight());
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     public void paintBorder(SynthContext context, Graphics g, int x,
                             int y, int w, int h) {
         context.getPainter().paintEditorPaneBorder(context, g, x, y, w, h);
--- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthFormattedTextFieldUI.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthFormattedTextFieldUI.java	Wed Jul 05 17:04:26 2017 +0200
@@ -24,16 +24,17 @@
  */
 package javax.swing.plaf.synth;
 
-import java.awt.*;
-import javax.swing.*;
+import java.awt.Graphics;
+import javax.swing.JComponent;
 import javax.swing.plaf.ComponentUI;
 
 /**
- * Provides the look and feel implementation for
- * <code>JFormattedTextField</code>.
+ * Provides the Synth L&F UI delegate for
+ * {@link javax.swing.JFormattedTextField}.
  *
+ * @since 1.7
  */
-class SynthFormattedTextFieldUI extends SynthTextFieldUI {
+public class SynthFormattedTextFieldUI extends SynthTextFieldUI {
     /**
      * Creates a UI for a JFormattedTextField.
      *
@@ -51,15 +52,24 @@
      *
      * @return the name "FormattedTextField"
      */
+    @Override
     protected String getPropertyPrefix() {
         return "FormattedTextField";
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     void paintBackground(SynthContext context, Graphics g, JComponent c) {
         context.getPainter().paintFormattedTextFieldBackground(context, g, 0,
                              0, c.getWidth(), c.getHeight());
     }
 
+    /**
+     * @inheritDoc
+     */
+    @Override
     public void paintBorder(SynthContext context, Graphics g, int x,
                             int y, int w, int h) {
         context.getPainter().paintFormattedTextFieldBorder(context, g, x, y,
--- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthInternalFrameTitlePane.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthInternalFrameTitlePane.java	Wed Jul 05 17:04:26 2017 +0200
@@ -30,14 +30,9 @@
 import javax.swing.*;
 import javax.swing.plaf.*;
 import javax.swing.plaf.basic.BasicInternalFrameTitlePane;
-import javax.swing.border.*;
-import javax.swing.event.InternalFrameEvent;
-import java.util.EventListener;
 import java.beans.PropertyChangeListener;
 import java.beans.PropertyChangeEvent;
-import java.beans.VetoableChangeListener;
 import java.beans.PropertyVetoException;
-import sun.swing.plaf.synth.SynthUI;
 import sun.swing.SwingUtilities2;
 
 /**
--- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthInternalFrameUI.java	Wed Dec 16 23:39:39 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthInternalFrameUI.java	Wed Jul 05 17:04:26 2017 +0200
@@ -27,52 +27,61 @@
 
 import java.awt.*;
 import java.awt.event.*;
-import java.awt.peer.LightweightPeer;
-
 import javax.swing.*;
 import javax.swing.plaf.*;
 import javax.swing.plaf.basic.BasicInternalFrameUI;
-import javax.swing.event.*;
-
 import java.beans.*;
-import java.io.Serializable;
-import sun.swing.plaf.synth.SynthUI;
 
 
 /**
- * Synth's InternalFrameUI.
+ * Provides the Synth L&F UI delegate for
+ * {@link javax.swing.JInternalFrame}.
  *
  * @author David Kloba
  * @author Joshua Outwater
  * @author Rich Schiavi
+ * @since 1.7
  */
-class SynthInternalFrameUI extends BasicInternalFrameUI implements SynthUI,
-        PropertyChangeListener {
+public class SynthInternalFrameUI extends BasicInternalFrameUI
+                                  implements SynthUI, PropertyChangeListener {
     private SynthStyle style;
 
-    private static DesktopManager sharedDesktopManager;
-    private boolean componentListenerAdded = false;
-<